\n\n'},a.prototype.startEditor=function(){var a,b,c,d,e;return a=alchemy.conf.divSelector,d=this.editorContainerHTML,b=alchemy.dash.select("#control-dash").append("div").attr("id","editor").html(d),b.select("#editor-header").on("click",function(){return alchemy.dash.select("#element-options").classed("in")?alchemy.dash.select("#editor-header>span").attr("class","fa fa-2x fa-caret-right"):alchemy.dash.select("#editor-header>span").attr("class","fa fa-2x fa-caret-down")}),c=b.select("#element-options ul #editor-interactions").on("click",function(){return d3.select(this).attr("class",function(){return"editor"===alchemy.get.state()?(alchemy.set.state("interactions","default"),"inactive list-group-item"):(alchemy.set.state("interactions","editor"),"active list-group-item")}).html(function(){return"editor"===alchemy.get.state()?"Disable Editor Interactions":"Enable Editor Interactions"})}),b.select("#element-options ul #remove").on("click",function(){return alchemy.editor.remove()}),e=this.utils,c.on("click",function(){return alchemy.dash.select("#editor-interactions").classed("active")?(e.disableEditor(),alchemy.dash.select("#editor-interactions").classed({active:!1,inactive:!0}).html("Editor mode disabled, click to enable editor interactions")):(e.enableEditor(),alchemy.dash.select("#editor-interactions").classed({active:!0,inactive:!1}).html("Editor mode enabled, click to disable editor interactions"))})},a.prototype.nodeEditor=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;c=alchemy.conf.divSelector,d=alchemy.dash.select("#control-dash #editor"),i=d.select("#element-options"),f=this.elementEditorHTML("Node"),e=i.append("div").attr("id","node-editor").html(f),e.attr("class",function(){var a;return a=alchemy.dash.select("#editor-interactions").classed("active"),a?"enabled":"hidden"}),b=d.select("#node-editor form #add-property"),b.select("#node-add-prop-key").attr("placeholder","New Property Name").attr("value",null),b.select("#node-add-prop-value").attr("placeholder","New Property Value").attr("value",null),alchemy.dash.select("#add-property-form").on("submit",function(){var a,b;return event.preventDefault(),a=alchemy.dash.select("#add-prop-key").property("value"),a=a.replace(/\s/g,"_"),b=alchemy.dash.select("#add-prop-value").property("value"),l(a,b,!0),alchemy.dash.selectAll("#add-property .edited-property").classed({"edited-property":!1}),this.reset()}),g=alchemy._nodes[a.id].getProperties(),alchemy.vis.select("#node-"+a.id).classed({editing:!0}),k=d.select("#node-editor #properties-list");for(j in g)m=g[j],h=k.append("div").attr("id","node-"+j).attr("class","property form-inline form-group"),h.append("label").attr("for","node-"+j+"-input").attr("class","form-control property-name").text(""+j),h.append("input").attr("id","node-"+j+"-input").attr("class","form-control property-value").attr("value",""+m);return alchemy.dash.select("#properties-list").on("submit",function(){var a,b,c,d,e,f,g;for(event.preventDefault(),b=alchemy.dash.selectAll(".edited-property"),g=b[0],e=0,f=g.length;f>e;e++)j=g[e],c=alchemy.dash.select(j),a=c.select("label").text(),d=c.select("input").attr("value"),l(a,d,!1);return alchemy.dash.selectAll("#node-properties-list .edited-property").classed({"edited-property":!1}),this.reset()}),d3.selectAll("#add-prop-key, #add-prop-value, .property").on("keydown",function(){return 13===d3.event.keyCode&&event.preventDefault(),d3.select(this).classed({"edited-property":!0})}),l=function(b,c,d){var e,f;return f=a.id,""!==b&&""!==c?(alchemy._nodes[f].setProperty(""+b,""+c),e=alchemy._drawNodes,e.updateNode(alchemy.viz.select("#node-"+f)),d===!0?(alchemy.dash.select("#node-add-prop-key").attr("value","property added/updated to key: "+b),alchemy.dash.select("#node-add-prop-value").attr("value","property at "+b+" updated to: "+c)):alchemy.dash.select("#node-"+b+"-input").attr("value","property at "+b+" updated to: "+c)):d===!0?(alchemy.dash.select("#node-add-prop-key").attr("value","null or invalid input"),alchemy.dash.select("#node-add-prop-value").attr("value","null or invlid input")):alchemy.dash.select("#node-"+b+"-input").attr("value","null or invalid input")}},a.prototype.editorClear=function(){return alchemy.dash.selectAll(".node").classed({editing:!1}),alchemy.dash.selectAll(".edge").classed({editing:!1}),alchemy.dash.select("#node-editor").remove(),alchemy.dash.select("#edge-editor").remove(),alchemy.dash.select("#node-add-prop-submit").attr("placeholder",function(){return alchemy.vis.selectAll(".selected").empty()?"select a node or edge to edit properties":"add a property to this element"})},a.prototype.edgeEditor=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;c=alchemy.conf.divSelector,f=alchemy.dash("#control-dash #editor"),i=f.select("#element-options"),h=this.elementEditorHTML("Edge"),g=i.append("div").attr("id","edge-editor").html(h),g.attr("class",function(){return alchemy.dash.select("#editor-interactions").classed("active")?"enabled":"hidden"}),b=f.select("#edge-editor form #add-property"),b.select("#add-prop-key").attr("placeholder","New Property Name").attr("value",null),b.select("#add-prop-value").attr("placeholder","New Property Value").attr("value",null),d=alchemy._edges[a.id].getProperties(),alchemy.vis.select("#edge-"+a.id).classed({editing:!0}),k=f.select("#edge-editor #properties-list");for(j in d)m=d[j],e=k.append("div").attr("id","edge-"+j).attr("class","property form-inline form-group"),e.append("label").attr("for","edge-"+j+"-input").attr("class","form-control property-name").text(""+j),e.append("input").attr("id","edge-"+j+"-input").attr("class","form-control property-value").attr("value",""+m);return alchemy.dash.selectAll("#add-prop-key, #add-prop-value, .property").on("keydown",function(){return 13===d3.event.keyCode&&event.preventDefault(),d3.select(this).classed({"edited-property":!0})}),alchemy.dash.select("#add-property-form").on("submit",function(){var a,b;return event.preventDefault(),a=alchemy.dash.select("#add-prop-key").property("value"),a=a.replace(/\s/g,"_"),b=alchemy.dash.select("#add-prop-value").property("value"),l(a,b,!0),alchemy.dash.selectAll("#add-property .edited-property").classed({"edited-property":!1}),this.reset()}),d3.select("#properties-list").on("submit",function(){var a,b,c,d,e,f,g;for(event.preventDefault(),b=alchemy.dash.selectAll(".edited-property"),g=b[0],e=0,f=g.length;f>e;e++)j=g[e],c=alchemy.dash.select(j),a=c.select("label").text(),d=c.select("input").property("value"),l(a,d,!1);return alchemy.dash.selectAll("#properties-list .edited-property").classed({"edited-property":!1}),this.reset()}),l=function(b,c,d){var e,f,g;return f=a.id,""!==b&&""!==c?(alchemy._edges[f].setProperty(""+b,""+c),g=alchemy.vis.select("#edge-"+f),e=new alchemy.drawing.DrawEdges,e.updateEdge(alchemy.vis.select("#edge-"+f)),d===!0?(alchemy.dash.select("#add-prop-key").attr("value","property added/updated to key: "+b),alchemy.dash.select("#add-prop-value").attr("value","property at "+b+" updated to: "+c)):alchemy.dash.select("#edge-"+b+"-input").attr("value","property at "+b+" updated to: "+c)):d===!0?(alchemy.dash.select("#add-prop-key").attr("value","null or invalid input"),alchemy.dash.select("#add-prop-value").attr("value","null or invlid input")):alchemy.dash.select("#edge-"+b+"-input").attr("value","null or invalid input")}},a}(),alchemy.editor.Interactions=function(){function a(){this.reset=c(this.reset,this),this.deleteSelected=c(this.deleteSelected,this),this.addNodeDragended=c(this.addNodeDragended,this),this.addNodeDragging=c(this.addNodeDragging,this),this.addNodeStart=c(this.addNodeStart,this),this.edgeClick=c(this.edgeClick,this),this.nodeClick=c(this.nodeClick,this),this.nodeMouseUp=c(this.nodeMouseUp,this),this.editor=new alchemy.editor.Editor}return a.prototype.nodeMouseOver=function(){var a;return d3.select(this).select("circle").empty()||(a=d3.select(this).select("circle").attr("r"),d3.select(this).select("circle").attr("r",3*a)),this},a.prototype.nodeMouseUp=function(a){return this.sourceNode!==a?(this.mouseUpNode=!0,this.targetNode=a,this.click=!1):this.click=!0,this},a.prototype.nodeMouseOut=function(){var a;return d3.select(this).select("circle").empty()||(a=d3.select(this).select("circle").attr("r"),d3.select(this).select("circle").attr("r",a/3)),this},a.prototype.nodeClick=function(a){var b;return d3.event.stopPropagation(),alchemy.vis.select("#node-"+a.id).empty()||(b=alchemy.vis.select("#node-"+a.id).classed("selected"),alchemy.vis.select("#node-"+a.id).classed("selected",!b)),this.editor.editorClear(),this.editor.nodeEditor(a)},a.prototype.edgeClick=function(a){return d3.event.stopPropagation(),this.editor.editorClear(),this.editor.edgeEditor(a)},a.prototype.addNodeStart=function(a){return d3.event.sourceEvent.stopPropagation(),this.sourceNode=a,alchemy.vis.select("#dragline").classed({hidden:!1}),this},a.prototype.addNodeDragging=function(){var a,b;return a=d3.event.x,b=d3.event.y,alchemy.vis.select("#dragline").attr("x1",this.sourceNode.x).attr("y1",this.sourceNode.y).attr("x2",a).attr("y2",b).attr("style","stroke: #FFF"),this},a.prototype.addNodeDragended=function(){var a,b,c;return this.click||(this.mouseUpNode||(a=alchemy.vis.select("#dragline"),b=a.attr("x2"),c=a.attr("y2"),this.targetNode={id:""+_.uniqueId("addedNode_"),x:parseFloat(b),y:parseFloat(c),caption:"node added"}),this.newEdge={id:""+this.sourceNode.id+"-"+this.targetNode.id,source:this.sourceNode.id,target:this.targetNode.id,caption:"edited"},alchemy.editor.update(this.targetNode,this.newEdge)),this.reset(),this},a.prototype.deleteSelected=function(){switch(d3.event.keyCode){case 8:case 46:if("INPUT"!==d3.select(d3.event.target).node().tagName)return d3.event.preventDefault(),alchemy.editor.remove()}},a.prototype.reset=function(){return this.mouseUpNode=null,this.sourceNode=null,this.targetNode=null,this.newEdge=null,this.click=null,alchemy.vis.select("#dragline").classed({hidden:!0}).attr("x1",0).attr("y1",0).attr("x2",0).attr("y2",0),this},a}(),alchemy.editor.Utils=function(){function a(){this.enableEditor=c(this.enableEditor,this),this.drawNodes=alchemy._drawNodes,this.drawEdges=alchemy._drawEdges}return a.prototype.enableEditor=function(){var a,b,c;return alchemy.set.state("interactions","editor"),a=alchemy.vis.append("line").attr("id","dragline"),this.drawNodes.updateNode(alchemy.node),this.drawEdges.updateEdge(alchemy.edge),c=alchemy.vis.selectAll(".selected"),b=new alchemy.editor.Editor,c.empty()||1!==c.length?c.classed({selected:!1}):c.classed("node")?(b.nodeEditor(c.datum()),alchemy.dash.select("#node-editor").attr("class","enabled").style("opacity",1)):c.classed("edge")?(b.edgeEditor(c.datum()),alchemy.dash.select("#edge-editor").attr("class","enabled").style("opacity",1)):void 0},a.prototype.disableEditor=function(){return alchemy.setState("interactions","default"),alchemy.vis.select("#dragline").remove(),alchemy.dash.select("#node-editor").transition().duration(300).style("opacity",0),alchemy.dash.select("#node-editor").transition().delay(300).attr("class","hidden"),this.drawNodes.updateNode(alchemy.node),alchemy.vis.selectAll(".node").classed({selected:!1})},a.prototype.remove=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(e=alchemy.vis.selectAll(".selected.node"),j=e[0],l=[],f=0,h=j.length;h>f;f++)if(b=j[f],c=alchemy.vis.select(b).data()[0].id,d=alchemy._nodes[c],null!=d){for(k=d.adjacentEdges,g=0,i=k.length;i>g;g++)a=k[g],alchemy._edges=_.omit(alchemy._edges,""+a),alchemy.edge=alchemy.edge.data(_.map(alchemy._edges,function(a){return a._d3}),function(a){return a.id}),alchemy.vis.select("#edge-"+a).remove();alchemy._nodes=_.omit(alchemy._nodes,""+c),alchemy.node=alchemy.node.data(_.map(alchemy._nodes,function(a){return a._d3}),function(a){return a.id}),alchemy.vis.select(b).remove(),l.push("editor"===alchemy.get.state("interactions")?alchemy.modifyElements.nodeEditorClear():void 0)}else l.push(void 0);return l},a.prototype.addNode=function(a){var b;return b=alchemy._nodes[a.id]=new alchemy.models.Node({id:""+a.id}),b.setProperty("caption",a.caption),b.setD3Property("x",a.x),b.setD3Property("y",a.y),alchemy.node=alchemy.node.data(_.map(alchemy._nodes,function(a){return a._d3}),function(a){return a.id})},a.prototype.addEdge=function(a){var b;return b=alchemy._edges[a.id]=new alchemy.models.Edge(a),alchemy.edge=alchemy.edge.data(_.map(alchemy._edges,function(a){return a._d3}),function(a){return a.id})},a.prototype.update=function(a,b){return this.mouseUpNode?(alchemy.editor.addEdge(b),this.drawEdges.createEdge(alchemy.edge)):(alchemy.editor.addNode(a),alchemy.editor.addEdge(b),this.drawEdges.createEdge(alchemy.edge),this.drawNodes.createNode(alchemy.node)),alchemy.layout.tick()},a}(),alchemy.models.Edge=function(){function a(a,b){var d,e;null==b&&(b=null),this.allNodesActive=c(this.allNodesActive,this),this.getStyles=c(this.getStyles,this),this.getProperties=c(this.getProperties,this),this.setProperties=c(this.setProperties,this),this._setCaption=c(this._setCaption,this),this._setID=c(this._setID,this),this._setD3Properties=c(this._setD3Properties,this),d=alchemy,e=d.conf,this.id=this._setID(a),this._index=b,this._state="active",this._properties=a,this._edgeType=this._setEdgeType(),this._style=null!=e.edgeStyle[this._edgeType]?_.merge(_.clone(e.edgeStyle.all),e.edgeStyle[this._edgeType]):_.clone(e.edgeStyle.all),this._d3=_.merge({id:this.id,pos:this._index,edgeType:this._edgeType,source:d._nodes[this._properties.source]._d3,target:d._nodes[this._properties.target]._d3},d.svgStyles.edge.populate(this)),this._setCaption(a,e),d._nodes[""+a.source]._addEdge(""+this.id+"-"+this._index),d._nodes[""+a.target]._addEdge(""+this.id+"-"+this._index)}return a.prototype._setD3Properties=function(a){return _.merge(this._d3,a)},a.prototype._setID=function(a){return null!=a.id?a.id:""+a.source+"-"+a.target},a.prototype._setCaption=function(a,b){var c,d;return c=b.edgeCaption,d=function(a){switch(typeof c){case"string":return a[c];case"function":return c(a)}}(a),d?this._d3.caption=d:void 0},a.prototype._setEdgeType=function(){var a,b,c;return a=alchemy.conf,a.edgeTypes&&(_.isPlainObject(a.edgeTypes)?(c=Object.keys(alchemy.conf.edgeTypes),b=this._properties[c]):"string"==typeof a.edgeTypes&&(b=this._properties[a.edgeTypes])),void 0===b&&(b="all"),this._setD3Properties("edgeType",b),b},a.prototype.setProperties=function(a,b){return null==b&&(b=null),_.isPlainObject(a)?(_.assign(this._properties,a),"source"in a&&this._setD3Properties({source:alchemy._nodes[a.source]._d3}),"target"in a&&this._setD3Properties({target:alchemy._nodes[a.target]._d3})):(this._properties[a]=b,("source"===a||"target"===a)&&this._setD3Properties({property:alchemy._nodes[b]._d3})),this},a.prototype.getProperties=function(){var a,b,c;return a=arguments[0],b=2<=arguments.length?d.call(arguments,1):[],null==a&&(a=null),null==a&&0===b.length?this._properties:0!==b.length?(c=_.union([a],b),_.pick(this._properties,c)):this._properties[a]},a.prototype.getStyles=function(a){return null==a&&(a=null),null!=a?this._style[a]:this._style},a.prototype.setStyles=function(a,b){return null==b&&(b=null),void 0===a&&(a=alchemy.svgStyles.edge.populate(this)),_.isPlainObject(a)?_.assign(this._style,a):"string"==typeof a&&(this._style[a]=b),this._setD3Properties(alchemy.svgStyles.edge.update(this)),alchemy._drawEdges.updateEdge(this._d3),this},a.prototype.toggleHidden=function(){return this._state="hidden"===this._state?"active":"hidden",this.setStyles()},a.prototype.allNodesActive=function(){var a,b;return a=alchemy.vis.select("#node-"+this.properties.source),b=alchemy.vis.select("#node-"+this.properties.target),!a.classed("inactive")&&!b.classed("inactive")},a}(),alchemy.models.Node=function(){function a(a){this.getStyles=c(this.getStyles,this),this.removeProperty=c(this.removeProperty,this),this.setProperty=c(this.setProperty,this),this.getProperties=c(this.getProperties,this),this._setD3Properties=c(this._setD3Properties,this),this._setNodeType=c(this._setNodeType,this);var b,d;b=alchemy,d=b.conf,this.id=a.id,this._properties=a,this._d3=_.merge({id:this.id,root:this._properties[d.rootNodes]},b.svgStyles.node.populate(this)),this._nodeType=this._setNodeType(),this._style=d.nodeStyle[this._nodeType]?d.nodeStyle[this._nodeType]:d.nodeStyle.all,this._state="active",this._adjacentEdges=[]}return a.prototype._setNodeType=function(){var a,b,c,d;return a=alchemy.conf,a.nodeTypes&&(_.isPlainObject(a.nodeTypes)?(b=Object.keys(alchemy.conf.nodeTypes),d=_.values(a.nodeTypes),c=this._properties[b]):"string"==typeof a.nodeTypes&&(c=this._properties[a.nodeTypes])),void 0===c&&(c="all"),this._setD3Properties("nodeType",c),c},a.prototype._setD3Properties=function(a){return _.merge(this._d3,a)},a.prototype._addEdge=function(a){return this._adjacentEdges=_.union(this._adjacentEdges,[a])},a.prototype.getProperties=function(){var a,b,c;return a=arguments[0],b=2<=arguments.length?d.call(arguments,1):[],null==a&&(a=null),null==a&&0===b.length?this._properties:0!==b.length?(c=_.union([a],b),_.pick(this._properties,c)):this._properties[a]},a.prototype.setProperty=function(a,b){return null==b&&(b=null),_.isPlainObject(a)?_.assign(this._properties,a):this._properties[a]=b,this},a.prototype.removeProperty=function(a){return null!=this._properties.property&&_.omit(this._properties,a),this},a.prototype.getStyles=function(a){return null==a&&(a=null),null!=a?this._style[a]:this._style},a.prototype.setStyles=function(a,b){return null==b&&(b=null),void 0===a?a=alchemy.svgStyles.node.populate(this):_.isPlainObject(a)?_.assign(this._style,a):this._style[a]=b,this._setD3Properties(alchemy.svgStyles.node.populate(this)),alchemy._drawNodes.updateNode(this._d3),this},a.prototype.toggleHidden=function(){return this._state="hidden"===this._state?"active":"hidden",this.setStyles(),_.each(this._adjacentEdges,function(a){var b,c,d,e;return e=a.split("-"),c=e[0],d=e[1],b=e[2],alchemy._edges[""+c+"-"+d][b].toggleHidden()})},a.prototype.outDegree=function(){return this._adjacentEdges.length},a}(),alchemy.themes={"default":{backgroundColour:"#000000",nodeStyle:{all:{radius:function(){return 10},color:function(){return"#68B9FE"},borderColor:function(){return"#127DC1"},borderWidth:function(a,b){return b/3},captionColor:function(){return"#FFFFFF"},captionBackground:function(){return null},captionSize:12,selected:{color:function(){return"#FFFFFF"},borderColor:function(){return"#349FE3"}},highlighted:{color:function(){return"#EEEEFF"}},hidden:{color:function(){return"none"},borderColor:function(){return"none"}}}},edgeStyle:{all:{width:4,color:"#CCC",opacity:.2,directed:!0,curved:!0,selected:{opacity:1},highlighted:{opacity:1},hidden:{opacity:0}}}},white:{backgroundColour:"#FFFFFF",nodeStyle:{all:{radius:function(){return 10},color:function(){return"#68B9FE"},borderColor:function(){return"#127DC1"},borderWidth:function(a,b){return b/3},captionColor:function(){return"#FFFFFF"},captionBackground:function(){return null},captionSize:12,selected:{color:function(){return"#FFFFFF"},borderColor:function(){return"38DD38"}},highlighted:{color:function(){return"#EEEEFF"}},hidden:{color:function(){return"none"},borderColor:function(){return"none"}}}},edgeStyle:{all:{width:4,color:"#333",opacity:.4,directed:!1,curved:!1,selected:{color:"#38DD38",opacity:.9},highlighted:{color:"#383838",opacity:.7},hidden:{opacity:0}}}}},alchemy.utils.warnings={dataWarning:function(){var a;return alchemy.conf.dataWarning&&"function"==typeof alchemy.conf.dataWarning?alchemy.conf.dataWarning():"default"===alchemy.conf.dataWarning?(a='
\n
\n
\n
\n \n
Sorry!
\n
\n
\n
'+alchemy.conf.warningMessage+'
\n
\n \n
\n
\n
',$("body").append(a),$("#no-results").modal("show")):void 0
+(function(){"Alchemy.js is a graph drawing application for the web.\nCopyright (C) 2014 GraphAlchemist, Inc.\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Affero General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nalong with this program. If not, see .\nlets";var a,b,c=function(a,b){return function(){return a.apply(b,arguments)}},d=[].slice;a=function(){function a(){this.allEdges=c(this.allEdges,this),this.allNodes=c(this.allNodes,this),this.getEdges=c(this.getEdges,this),this.getNodes=c(this.getNodes,this),this.begin=c(this.begin,this),this.version="0.3.1",this.layout={},this.interactions={},this.utils={},this.visControls={},this.styles={},this.models={},this.drawing={},this.editor={},this.log={},this.currentRelationshipTypes={},this.state={interactions:"default",layout:"default"},this._nodes={},this._edges={}}return a.prototype.begin=function(a){return this.setConf(a),"string"==typeof alchemy.conf.dataSource?d3.json(alchemy.conf.dataSource,alchemy.startGraph):"object"==typeof alchemy.conf.dataSource&&alchemy.startGraph(alchemy.conf.dataSource),this},a.prototype.setConf=function(a){var b,c;null!=a.theme&&_.merge(alchemy.defaults,alchemy.themes[""+a.theme]);for(b in a)c=a[b],"clusterColors"===b&&(a.clusterColours=c),"backgroundColor"===b&&(a.backgroundColour=c),"nodeColor"===b&&(a.nodeColour=c);return this.conf=_.merge(alchemy.defaults,a)},a.prototype.getNodes=function(){var a,b,c,e,f,g,h;if(a=arguments[0],b=2<=arguments.length?d.call(arguments,1):[]){for(b.push(a),e=_.union(b),f=[],g=0,h=e.length;h>g;g++)c=e[g],f.push(alchemy._nodes[c].properties);return f}return[this._nodes[a].properties]},a.prototype.getEdges=function(a,b){var c,d,e;return null==a&&(a=null),null==b&&(b=null),null!=a&&null!=b?(d=""+a+"-"+b,c=this._edges[d],[c.properties]):null!=a&&null==b?(e=_.map(this._edges,function(b){return b.properties.source===a||b.properties.target===a?b.properties:void 0}),_.compact(e)):void 0},a.prototype.allNodes=function(){return _.map(this._nodes,function(a){return a.properties})},a.prototype.allEdges=function(){return _.map(this._edges,function(a){return a.properties})},a}(),b={},"undefined"!=typeof module&&module.exports?module.exports=new a:this.alchemy=new a,alchemy.create={nodes:function(){var a,b,c,e,f,g,h;if(b=arguments[0],c=2<=arguments.length?d.call(arguments,1):[],e=function(a){var b;return alchemy._nodes[a.id]?console.warn("A node with the id "+a.id+" already exists.\nConsider using the alchemy.get.nodes() method to \nretrieve the node and then using the Node methods."):(b=new alchemy.models.Node(a),alchemy._nodes[a.id]=b,[b])},0!==c.length){for(c.push(b),f=[],g=0,h=c.length;h>g;g++)a=c[g],e(a);return f}return e(b)},edges:function(){var a,b,c;return a=arguments[0],b=2<=arguments.length?d.call(arguments,1):[],c=function(a){var b,c;return a.id&&!alchemy._edges[a.id]?(b=new alchemy.models.Edge(a),alchemy._edges[a.id]=[b],[b]):a.id&&alchemy._edges[a.id]?console.warn("An edge with that id "+someEdgeMap.id+" already exists.\nConsider using the alchemy.get.edge() method to \nretrieve the edge and then using the Edge methods.\nNote: id's are not required for edges. Alchemy will create\nan unlimited number of edges for the same source and target node.\nSimply omit 'id' when creating the edge."):(c=alchemy._edges[""+a.source+"-"+a.target],c?(b=new alchemy.models.Edge(a,c.length),c.push(b),[b]):(b=new alchemy.models.Edge(a,0),alchemy._edges[""+a.source+"-"+a.target]=[b],[b]))},0!==b.length?console.warn("Make sure this function supports multiple arguments"):c(a)}},alchemy.get={nodes:function(){var a,b,c;return b=arguments[0],c=2<=arguments.length?d.call(arguments,1):[],null!=b?(a=_.map(arguments,function(a){return String(a)}),_.filter(alchemy._nodes,function(b,c){return _.contains(a,c)?b:void 0})):console.warn("Please specify a node id.")},edges:function(a,b){var c,d,e;return null==a&&(a=null),null==b&&(b=null),null!=a&&null!=b?(d=""+a+"-"+b,c=alchemy._edges[d],[c]):null!=a&&null==b?(null!=alchemy._edges[a]?[_.flatten(alchemy._edges[a])]:e=_.map(alchemy._edges,function(b){return b.properties.source===a||b.properties.target===a?b.properties:void 0}),_.compact(e)):void 0},allNodes:function(a){return null!=a?_.filter(alchemy._nodes,function(b){return b._nodeType===a?b:void 0}):_.map(alchemy._nodes,function(a){return a})},activeNodes:function(){return _.filter(alchemy._nodes,function(a){return"active"===a._state?a:void 0})},allEdges:function(){return _.flatten(_.map(alchemy._edges,function(a){var b,c,d,e;for(e=[],c=0,d=a.length;d>c;c++)b=a[c],e.push(b);return e}))},state:function(){return null!=alchemy.state.key?alchemy.state.key:void 0},clusters:function(){var a,b;return a=alchemy.layout._clustering.clusterMap,b={},_.each(a,function(a,c){return b[c]=_.select(alchemy.get.allNodes(),function(a){return a.getProperties()[alchemy.conf.clusterKey]===c})}),b},clusterColours:function(){var a,b;return b=alchemy.layout._clustering.clusterMap,a={},_.each(b,function(b,c){return a[c]=alchemy.conf.clusterColours[b%alchemy.conf.clusterColours.length]}),a}},alchemy.set={state:function(a,b){return alchemy.state.key=b}},alchemy.clustering=function(){function a(){var a,b,c,d,e,f,g,h;c=alchemy._nodes,b=alchemy.conf,a=this,this.clusterKey=b.clusterKey,this.identifyClusters(),d=-500,h=function(a){var b,d;return b=c[a.source.id]._properties[this.clusterKey],d=c[a.target.id]._properties[this.clusterKey],b===d?.15:0},e=function(){return.7},g=function(a){return c=alchemy._nodes,c[a.source.id]._properties.root||c[a.target.id]._properties.root?300:c[a.source.id]._properties[this.clusterKey]===c[a.target.id]._properties[this.clusterKey]?10:600},f=function(a){return 8*a},this.layout={charge:d,linkStrength:function(a){return h(a)},friction:function(){return e()},linkDistancefn:function(a){return g(a)},gravity:function(a){return f(a)}}}return a.prototype.identifyClusters=function(){var a,b,c;return b=alchemy.get.allNodes(),a=_.uniq(_.map(_.values(b),function(a){return a.getProperties()[alchemy.conf.clusterKey]})),this.clusterMap=_.zipObject(a,function(){c=[];for(var b=0,d=a.length;d>=0?d>=b:b>=d;d>=0?b++:b--)c.push(b);return c}.apply(this))},a.prototype.getClusterColour=function(a){var b;return b=this.clusterMap[a]%alchemy.conf.clusterColours.length,alchemy.conf.clusterColours[b]},a.prototype.edgeGradient=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;for(c=alchemy.vis.select(""+alchemy.conf.divSelector+" svg"),b={},j=alchemy._nodes,n=_.map(a,function(a){return a._d3}),l=0,m=n.length;m>l;l++)if(d=n[l],!j[d.source.id]._properties.root&&!j[d.target.id]._properties.root&&j[d.source.id]._properties[this.clusterKey]!==j[d.target.id]._properties[this.clusterKey]&&j[d.target.id]._properties[this.clusterKey]!==j[d.source.id]._properties[this.clusterKey]){if(h=j[d.source.id]._properties[this.clusterKey]+"-"+j[d.target.id]._properties[this.clusterKey],h in b)continue;h in b||(k=this.getClusterColour(j[d.target.id]._properties[this.clusterKey]),e=this.getClusterColour(j[d.source.id]._properties[this.clusterKey]),b[h]={startColour:k,endColour:e})}o=[];for(i in b)g="cluster-gradient-"+i,f=c.append("svg:linearGradient").attr("id",g),f.append("svg:stop").attr("offset","0%").attr("stop-color",b[i].startColour),o.push(f.append("svg:stop").attr("offset","100%").attr("stop-color",b[i].endColour));return o},a}(),alchemy.clusterControls={init:function(){var a;return a="",alchemy.dash.select("#clustering-container").append("div").attr("id","cluster-key-container").attr("class","property form-inline form-group").html(a).style("display","none"),alchemy.dash.select("#cluster_control_header").on("click",function(){var a,b;return b=alchemy.dash.select("#cluster-key-container"),a=b.style("display")}),element.style("display",function(){return"block"===display?"none":"block"}),"none"===alchemy.dash.select("#cluster-key-container").style("display")?alchemy.dash.select("#cluster-arrow").attr("class","fa fa-2x fa-caret-right"):alchemy.dash.select("#cluster-arrow").attr("class","fa fa-2x fa-caret-down"),alchemy.dash.select("#cluster-key").on("keydown",function(){return"Enter"===d3.event.keyIdentifier?(alchemy.conf.cluster=!0,alchemy.conf.clusterKey=this.value,alchemy.generateLayout()):void 0})}},alchemy.controlDash={init:function(){var a;return this.dashIsShown()?(a=alchemy.conf.divSelector,alchemy.dash=d3.select(""+a).append("div").attr("id","control-dash-wrapper").attr("class","col-md-4 initial"),alchemy.dash.append("i").attr("id","dash-toggle").attr("class","fa fa-flask col-md-offset-12"),alchemy.dash.append("div").attr("id","control-dash").attr("class","col-md-12"),alchemy.dash.select("#dash-toggle").on("click",alchemy.interactions.toggleControlDash),alchemy.controlDash.zoomCtrl(),alchemy.controlDash.search(),alchemy.controlDash.filters(),alchemy.controlDash.stats(),alchemy.controlDash.clustering()):void 0},search:function(){return alchemy.conf.search?(alchemy.dash.select("#control-dash").append("div").attr("id","search").html("
\n\n'},a.prototype.startEditor=function(){var a,b,c,d,e;return a=alchemy.conf.divSelector,d=this.editorContainerHTML,b=alchemy.dash.select("#control-dash").append("div").attr("id","editor").html(d),b.select("#editor-header").on("click",function(){return alchemy.dash.select("#element-options").classed("in")?alchemy.dash.select("#editor-header>span").attr("class","fa fa-2x fa-caret-right"):alchemy.dash.select("#editor-header>span").attr("class","fa fa-2x fa-caret-down")}),c=b.select("#element-options ul #editor-interactions").on("click",function(){return d3.select(this).attr("class",function(){return"editor"===alchemy.get.state()?(alchemy.set.state("interactions","default"),"inactive list-group-item"):(alchemy.set.state("interactions","editor"),"active list-group-item")}).html(function(){return"editor"===alchemy.get.state()?"Disable Editor Interactions":"Enable Editor Interactions"})}),b.select("#element-options ul #remove").on("click",function(){return alchemy.editor.remove()}),e=this.utils,c.on("click",function(){return alchemy.dash.select("#editor-interactions").classed("active")?(e.disableEditor(),alchemy.dash.select("#editor-interactions").classed({active:!1,inactive:!0}).html("Editor mode disabled, click to enable editor interactions")):(e.enableEditor(),alchemy.dash.select("#editor-interactions").classed({active:!0,inactive:!1}).html("Editor mode enabled, click to disable editor interactions"))})},a.prototype.nodeEditor=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;c=alchemy.conf.divSelector,d=alchemy.dash.select("#control-dash #editor"),i=d.select("#element-options"),f=this.elementEditorHTML("Node"),e=i.append("div").attr("id","node-editor").html(f),e.attr("class",function(){var a;return a=alchemy.dash.select("#editor-interactions").classed("active"),a?"enabled":"hidden"}),b=d.select("#node-editor form #add-property"),b.select("#node-add-prop-key").attr("placeholder","New Property Name").attr("value",null),b.select("#node-add-prop-value").attr("placeholder","New Property Value").attr("value",null),alchemy.dash.select("#add-property-form").on("submit",function(){var a,b;return event.preventDefault(),a=alchemy.dash.select("#add-prop-key").property("value"),a=a.replace(/\s/g,"_"),b=alchemy.dash.select("#add-prop-value").property("value"),l(a,b,!0),alchemy.dash.selectAll("#add-property .edited-property").classed({"edited-property":!1}),this.reset()}),g=alchemy._nodes[a.id].getProperties(),alchemy.vis.select("#node-"+a.id).classed({editing:!0}),k=d.select("#node-editor #properties-list");for(j in g)m=g[j],h=k.append("div").attr("id","node-"+j).attr("class","property form-inline form-group"),h.append("label").attr("for","node-"+j+"-input").attr("class","form-control property-name").text(""+j),h.append("input").attr("id","node-"+j+"-input").attr("class","form-control property-value").attr("value",""+m);return alchemy.dash.select("#properties-list").on("submit",function(){var a,b,c,d,e,f,g;for(event.preventDefault(),b=alchemy.dash.selectAll(".edited-property"),g=b[0],e=0,f=g.length;f>e;e++)j=g[e],c=alchemy.dash.select(j),a=c.select("label").text(),d=c.select("input").attr("value"),l(a,d,!1);return alchemy.dash.selectAll("#node-properties-list .edited-property").classed({"edited-property":!1}),this.reset()}),d3.selectAll("#add-prop-key, #add-prop-value, .property").on("keydown",function(){return 13===d3.event.keyCode&&event.preventDefault(),d3.select(this).classed({"edited-property":!0})}),l=function(b,c,d){var e,f;return f=a.id,""!==b&&""!==c?(alchemy._nodes[f].setProperty(""+b,""+c),e=alchemy._drawNodes,e.updateNode(alchemy.viz.select("#node-"+f)),d===!0?(alchemy.dash.select("#node-add-prop-key").attr("value","property added/updated to key: "+b),alchemy.dash.select("#node-add-prop-value").attr("value","property at "+b+" updated to: "+c)):alchemy.dash.select("#node-"+b+"-input").attr("value","property at "+b+" updated to: "+c)):d===!0?(alchemy.dash.select("#node-add-prop-key").attr("value","null or invalid input"),alchemy.dash.select("#node-add-prop-value").attr("value","null or invlid input")):alchemy.dash.select("#node-"+b+"-input").attr("value","null or invalid input")}},a.prototype.editorClear=function(){return alchemy.dash.selectAll(".node").classed({editing:!1}),alchemy.dash.selectAll(".edge").classed({editing:!1}),alchemy.dash.select("#node-editor").remove(),alchemy.dash.select("#edge-editor").remove(),alchemy.dash.select("#node-add-prop-submit").attr("placeholder",function(){return alchemy.vis.selectAll(".selected").empty()?"select a node or edge to edit properties":"add a property to this element"})},a.prototype.edgeEditor=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;c=alchemy.conf.divSelector,f=alchemy.dash("#control-dash #editor"),i=f.select("#element-options"),h=this.elementEditorHTML("Edge"),g=i.append("div").attr("id","edge-editor").html(h),g.attr("class",function(){return alchemy.dash.select("#editor-interactions").classed("active")?"enabled":"hidden"}),b=f.select("#edge-editor form #add-property"),b.select("#add-prop-key").attr("placeholder","New Property Name").attr("value",null),b.select("#add-prop-value").attr("placeholder","New Property Value").attr("value",null),d=alchemy._edges[a.id].getProperties(),alchemy.vis.select("#edge-"+a.id).classed({editing:!0}),k=f.select("#edge-editor #properties-list");for(j in d)m=d[j],e=k.append("div").attr("id","edge-"+j).attr("class","property form-inline form-group"),e.append("label").attr("for","edge-"+j+"-input").attr("class","form-control property-name").text(""+j),e.append("input").attr("id","edge-"+j+"-input").attr("class","form-control property-value").attr("value",""+m);return alchemy.dash.selectAll("#add-prop-key, #add-prop-value, .property").on("keydown",function(){return 13===d3.event.keyCode&&event.preventDefault(),d3.select(this).classed({"edited-property":!0})}),alchemy.dash.select("#add-property-form").on("submit",function(){var a,b;return event.preventDefault(),a=alchemy.dash.select("#add-prop-key").property("value"),a=a.replace(/\s/g,"_"),b=alchemy.dash.select("#add-prop-value").property("value"),l(a,b,!0),alchemy.dash.selectAll("#add-property .edited-property").classed({"edited-property":!1}),this.reset()}),d3.select("#properties-list").on("submit",function(){var a,b,c,d,e,f,g;for(event.preventDefault(),b=alchemy.dash.selectAll(".edited-property"),g=b[0],e=0,f=g.length;f>e;e++)j=g[e],c=alchemy.dash.select(j),a=c.select("label").text(),d=c.select("input").property("value"),l(a,d,!1);return alchemy.dash.selectAll("#properties-list .edited-property").classed({"edited-property":!1}),this.reset()}),l=function(b,c,d){var e,f,g;return f=a.id,""!==b&&""!==c?(alchemy._edges[f].setProperty(""+b,""+c),g=alchemy.vis.select("#edge-"+f),e=new alchemy.drawing.DrawEdges,e.updateEdge(alchemy.vis.select("#edge-"+f)),d===!0?(alchemy.dash.select("#add-prop-key").attr("value","property added/updated to key: "+b),alchemy.dash.select("#add-prop-value").attr("value","property at "+b+" updated to: "+c)):alchemy.dash.select("#edge-"+b+"-input").attr("value","property at "+b+" updated to: "+c)):d===!0?(alchemy.dash.select("#add-prop-key").attr("value","null or invalid input"),alchemy.dash.select("#add-prop-value").attr("value","null or invlid input")):alchemy.dash.select("#edge-"+b+"-input").attr("value","null or invalid input")}},a}(),alchemy.editor.Interactions=function(){function a(){this.reset=c(this.reset,this),this.deleteSelected=c(this.deleteSelected,this),this.addNodeDragended=c(this.addNodeDragended,this),this.addNodeDragging=c(this.addNodeDragging,this),this.addNodeStart=c(this.addNodeStart,this),this.edgeClick=c(this.edgeClick,this),this.nodeClick=c(this.nodeClick,this),this.nodeMouseUp=c(this.nodeMouseUp,this),this.editor=new alchemy.editor.Editor}return a.prototype.nodeMouseOver=function(){var a;return d3.select(this).select("circle").empty()||(a=d3.select(this).select("circle").attr("r"),d3.select(this).select("circle").attr("r",3*a)),this},a.prototype.nodeMouseUp=function(a){return this.sourceNode!==a?(this.mouseUpNode=!0,this.targetNode=a,this.click=!1):this.click=!0,this},a.prototype.nodeMouseOut=function(){var a;return d3.select(this).select("circle").empty()||(a=d3.select(this).select("circle").attr("r"),d3.select(this).select("circle").attr("r",a/3)),this},a.prototype.nodeClick=function(a){var b;return d3.event.stopPropagation(),alchemy.vis.select("#node-"+a.id).empty()||(b=alchemy.vis.select("#node-"+a.id).classed("selected"),alchemy.vis.select("#node-"+a.id).classed("selected",!b)),this.editor.editorClear(),this.editor.nodeEditor(a)},a.prototype.edgeClick=function(a){return d3.event.stopPropagation(),this.editor.editorClear(),this.editor.edgeEditor(a)},a.prototype.addNodeStart=function(a){return d3.event.sourceEvent.stopPropagation(),this.sourceNode=a,alchemy.vis.select("#dragline").classed({hidden:!1}),this},a.prototype.addNodeDragging=function(){var a,b;return a=d3.event.x,b=d3.event.y,alchemy.vis.select("#dragline").attr("x1",this.sourceNode.x).attr("y1",this.sourceNode.y).attr("x2",a).attr("y2",b).attr("style","stroke: #FFF"),this},a.prototype.addNodeDragended=function(){var a,b,c;return this.click||(this.mouseUpNode||(a=alchemy.vis.select("#dragline"),b=a.attr("x2"),c=a.attr("y2"),this.targetNode={id:""+_.uniqueId("addedNode_"),x:parseFloat(b),y:parseFloat(c),caption:"node added"}),this.newEdge={id:""+this.sourceNode.id+"-"+this.targetNode.id,source:this.sourceNode.id,target:this.targetNode.id,caption:"edited"},alchemy.editor.update(this.targetNode,this.newEdge)),this.reset(),this},a.prototype.deleteSelected=function(){switch(d3.event.keyCode){case 8:case 46:if("INPUT"!==d3.select(d3.event.target).node().tagName)return d3.event.preventDefault(),alchemy.editor.remove()}},a.prototype.reset=function(){return this.mouseUpNode=null,this.sourceNode=null,this.targetNode=null,this.newEdge=null,this.click=null,alchemy.vis.select("#dragline").classed({hidden:!0}).attr("x1",0).attr("y1",0).attr("x2",0).attr("y2",0),this},a}(),alchemy.editor.Utils=function(){function a(){this.enableEditor=c(this.enableEditor,this),this.drawNodes=alchemy._drawNodes,this.drawEdges=alchemy._drawEdges}return a.prototype.enableEditor=function(){var a,b,c;return alchemy.set.state("interactions","editor"),a=alchemy.vis.append("line").attr("id","dragline"),this.drawNodes.updateNode(alchemy.node),this.drawEdges.updateEdge(alchemy.edge),c=alchemy.vis.selectAll(".selected"),b=new alchemy.editor.Editor,c.empty()||1!==c.length?c.classed({selected:!1}):c.classed("node")?(b.nodeEditor(c.datum()),alchemy.dash.select("#node-editor").attr("class","enabled").style("opacity",1)):c.classed("edge")?(b.edgeEditor(c.datum()),alchemy.dash.select("#edge-editor").attr("class","enabled").style("opacity",1)):void 0},a.prototype.disableEditor=function(){return alchemy.setState("interactions","default"),alchemy.vis.select("#dragline").remove(),alchemy.dash.select("#node-editor").transition().duration(300).style("opacity",0),alchemy.dash.select("#node-editor").transition().delay(300).attr("class","hidden"),this.drawNodes.updateNode(alchemy.node),alchemy.vis.selectAll(".node").classed({selected:!1})},a.prototype.remove=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(e=alchemy.vis.selectAll(".selected.node"),j=e[0],l=[],f=0,h=j.length;h>f;f++)if(b=j[f],c=alchemy.vis.select(b).data()[0].id,d=alchemy._nodes[c],null!=d){for(k=d.adjacentEdges,g=0,i=k.length;i>g;g++)a=k[g],alchemy._edges=_.omit(alchemy._edges,""+a),alchemy.edge=alchemy.edge.data(_.map(alchemy._edges,function(a){return a._d3}),function(a){return a.id}),alchemy.vis.select("#edge-"+a).remove();alchemy._nodes=_.omit(alchemy._nodes,""+c),alchemy.node=alchemy.node.data(_.map(alchemy._nodes,function(a){return a._d3}),function(a){return a.id}),alchemy.vis.select(b).remove(),l.push("editor"===alchemy.get.state("interactions")?alchemy.modifyElements.nodeEditorClear():void 0)}else l.push(void 0);return l},a.prototype.addNode=function(a){var b;return b=alchemy._nodes[a.id]=new alchemy.models.Node({id:""+a.id}),b.setProperty("caption",a.caption),b.setD3Property("x",a.x),b.setD3Property("y",a.y),alchemy.node=alchemy.node.data(_.map(alchemy._nodes,function(a){return a._d3}),function(a){return a.id})},a.prototype.addEdge=function(a){var b;return b=alchemy._edges[a.id]=new alchemy.models.Edge(a),alchemy.edge=alchemy.edge.data(_.map(alchemy._edges,function(a){return a._d3}),function(a){return a.id})},a.prototype.update=function(a,b){return this.mouseUpNode?(alchemy.editor.addEdge(b),this.drawEdges.createEdge(alchemy.edge)):(alchemy.editor.addNode(a),alchemy.editor.addEdge(b),this.drawEdges.createEdge(alchemy.edge),this.drawNodes.createNode(alchemy.node)),alchemy.layout.tick()},a}(),alchemy.models.Edge=function(){function a(a,b){var d,e;null==b&&(b=null),this.allNodesActive=c(this.allNodesActive,this),this.getStyles=c(this.getStyles,this),this.getProperties=c(this.getProperties,this),this.setProperties=c(this.setProperties,this),this._setCaption=c(this._setCaption,this),this._setID=c(this._setID,this),this._setD3Properties=c(this._setD3Properties,this),d=alchemy,e=d.conf,this.id=this._setID(a),this._index=b,this._state="active",this._properties=a,this._edgeType=this._setEdgeType(),this._style=null!=e.edgeStyle[this._edgeType]?_.merge(_.clone(e.edgeStyle.all),e.edgeStyle[this._edgeType]):_.clone(e.edgeStyle.all),this._d3=_.merge({id:this.id,pos:this._index,edgeType:this._edgeType,source:d._nodes[this._properties.source]._d3,target:d._nodes[this._properties.target]._d3},d.svgStyles.edge.populate(this)),this._setCaption(a,e),d._nodes[""+a.source]._addEdge(""+this.id+"-"+this._index),d._nodes[""+a.target]._addEdge(""+this.id+"-"+this._index)}return a.prototype._setD3Properties=function(a){return _.merge(this._d3,a)},a.prototype._setID=function(a){return null!=a.id?a.id:""+a.source+"-"+a.target},a.prototype._setCaption=function(a,b){var c,d;return c=b.edgeCaption,d=function(a){switch(typeof c){case"string":return a[c];case"function":return c(a)}}(a),d?this._d3.caption=d:void 0},a.prototype._setEdgeType=function(){var a,b,c;return a=alchemy.conf,a.edgeTypes&&(_.isPlainObject(a.edgeTypes)?(c=Object.keys(alchemy.conf.edgeTypes),b=this._properties[c]):_.isArray(a.edgeTypes)?b=this._properties.caption:"string"==typeof a.edgeTypes&&(b=this._properties[a.edgeTypes])),void 0===b&&(b="all"),this._setD3Properties("edgeType",b),b},a.prototype.setProperties=function(a,b){return null==b&&(b=null),_.isPlainObject(a)?(_.assign(this._properties,a),"source"in a&&this._setD3Properties({source:alchemy._nodes[a.source]._d3}),"target"in a&&this._setD3Properties({target:alchemy._nodes[a.target]._d3})):(this._properties[a]=b,("source"===a||"target"===a)&&this._setD3Properties({property:alchemy._nodes[b]._d3})),this},a.prototype.getProperties=function(){var a,b,c;return a=arguments[0],b=2<=arguments.length?d.call(arguments,1):[],null==a&&(a=null),null==a&&0===b.length?this._properties:0!==b.length?(c=_.union([a],b),_.pick(this._properties,c)):this._properties[a]},a.prototype.getStyles=function(a){return null==a&&(a=null),null!=a?this._style[a]:this._style},a.prototype.setStyles=function(a,b){return null==b&&(b=null),void 0===a&&(a=alchemy.svgStyles.edge.populate(this)),_.isPlainObject(a)?_.assign(this._style,a):"string"==typeof a&&(this._style[a]=b),this._setD3Properties(alchemy.svgStyles.edge.update(this)),alchemy._drawEdges.updateEdge(this._d3),this},a.prototype.toggleHidden=function(){return this._state="hidden"===this._state?"active":"hidden",this.setStyles()},a.prototype.allNodesActive=function(){var a,b;return a=alchemy.vis.select("#node-"+this.properties.source),b=alchemy.vis.select("#node-"+this.properties.target),!a.classed("inactive")&&!b.classed("inactive")},a}(),alchemy.models.Node=function(){function a(a){this.getStyles=c(this.getStyles,this),this.removeProperty=c(this.removeProperty,this),this.setProperty=c(this.setProperty,this),this.getProperties=c(this.getProperties,this),this._setD3Properties=c(this._setD3Properties,this),this._setNodeType=c(this._setNodeType,this);var b,d;b=alchemy,d=b.conf,this.id=a.id,this._properties=a,this._d3=_.merge({id:this.id,root:this._properties[d.rootNodes]},b.svgStyles.node.populate(this)),this._nodeType=this._setNodeType(),this._style=d.nodeStyle[this._nodeType]?d.nodeStyle[this._nodeType]:d.nodeStyle.all,this._state="active",this._adjacentEdges=[]}return a.prototype._setNodeType=function(){var a,b,c,d;return a=alchemy.conf,a.nodeTypes&&(_.isPlainObject(a.nodeTypes)?(b=Object.keys(alchemy.conf.nodeTypes),d=_.values(a.nodeTypes),c=this._properties[b]):"string"==typeof a.nodeTypes&&(c=this._properties[a.nodeTypes])),void 0===c&&(c="all"),this._setD3Properties("nodeType",c),c},a.prototype._setD3Properties=function(a){return _.merge(this._d3,a)},a.prototype._addEdge=function(a){return this._adjacentEdges=_.union(this._adjacentEdges,[a])},a.prototype.getProperties=function(){var a,b,c;return a=arguments[0],b=2<=arguments.length?d.call(arguments,1):[],null==a&&(a=null),null==a&&0===b.length?this._properties:0!==b.length?(c=_.union([a],b),_.pick(this._properties,c)):this._properties[a]},a.prototype.setProperty=function(a,b){return null==b&&(b=null),_.isPlainObject(a)?_.assign(this._properties,a):this._properties[a]=b,this},a.prototype.removeProperty=function(a){return null!=this._properties.property&&_.omit(this._properties,a),this},a.prototype.getStyles=function(a){return null==a&&(a=null),null!=a?this._style[a]:this._style},a.prototype.setStyles=function(a,b){return null==b&&(b=null),void 0===a?a=alchemy.svgStyles.node.populate(this):_.isPlainObject(a)?_.assign(this._style,a):this._style[a]=b,this._setD3Properties(alchemy.svgStyles.node.populate(this)),alchemy._drawNodes.updateNode(this._d3),this},a.prototype.toggleHidden=function(){return this._state="hidden"===this._state?"active":"hidden",this.setStyles(),_.each(this._adjacentEdges,function(a){var b,c,d,e,f,g,h;return h=a.split("-"),d=h[0],f=h[1],c=h[2],b=alchemy._edges[""+d+"-"+f][c],e=alchemy._nodes[""+d]._state,g=alchemy._nodes[""+f]._state,"hidden"===b._state&&"active"===e&&"active"===g?b.toggleHidden():"active"!==b._state||"hidden"!==e&&"hidden"!==g?void 0:b.toggleHidden()})},a.prototype.outDegree=function(){return this._adjacentEdges.length},a}(),alchemy.themes={"default":{backgroundColour:"#000000",nodeStyle:{all:{radius:function(){return 10},color:function(){return"#68B9FE"},borderColor:function(){return"#127DC1"},borderWidth:function(a,b){return b/3},captionColor:function(){return"#FFFFFF"},captionBackground:function(){return null},captionSize:12,selected:{color:function(){return"#FFFFFF"},borderColor:function(){return"#349FE3"}},highlighted:{color:function(){return"#EEEEFF"}},hidden:{color:function(){return"none"},borderColor:function(){return"none"}}}},edgeStyle:{all:{width:4,color:"#CCC",opacity:.2,directed:!0,curved:!0,selected:{opacity:1},highlighted:{opacity:1},hidden:{opacity:0}}}},white:{backgroundColour:"#FFFFFF",nodeStyle:{all:{radius:function(){return 10},color:function(){return"#68B9FE"},borderColor:function(){return"#127DC1"},borderWidth:function(a,b){return b/3},captionColor:function(){return"#FFFFFF"},captionBackground:function(){return null},captionSize:12,selected:{color:function(){return"#FFFFFF"},borderColor:function(){return"38DD38"}},highlighted:{color:function(){return"#EEEEFF"}},hidden:{color:function(){return"none"},borderColor:function(){return"none"}}}},edgeStyle:{all:{width:4,color:"#333",opacity:.4,directed:!1,curved:!1,selected:{color:"#38DD38",opacity:.9},highlighted:{color:"#383838",opacity:.7},hidden:{opacity:0}}}}},alchemy.utils.warnings={dataWarning:function(){var a;return alchemy.conf.dataWarning&&"function"==typeof alchemy.conf.dataWarning?alchemy.conf.dataWarning():"default"===alchemy.conf.dataWarning?(a='
\n
\n
\n
\n \n
Sorry!
\n
\n
\n
'+alchemy.conf.warningMessage+'
\n
\n \n
\n
\n
',$("body").append(a),$("#no-results").modal("show")):void 0
},divWarning:function(){return"create an element that matches the value for 'divSelector' in your conf.\nFor instance, if you are using the default 'divSelector' conf, simply provide\n."}}}).call(this);
\ No newline at end of file
diff --git a/site/app/docs/_documentation/Annotated-Source.md b/site/app/docs/_documentation/Annotated-Source.md
index e9dd19b..c90880f 100644
--- a/site/app/docs/_documentation/Annotated-Source.md
+++ b/site/app/docs/_documentation/Annotated-Source.md
@@ -59,10 +59,6 @@ title: Anotated Source
@_edges = {}
begin: (userConf) =>
- # Make sure current instance hasn't already begun
- d3.select userConf.divSelector
- .html ""
- console.log alchemy._nodes
# overide configuration with user inputs
@setConf(userConf)
@@ -253,6 +249,9 @@ title: Anotated Source
else
_.map alchemy._nodes, (n) -> n
+ activeNodes: () ->
+ _.filter alchemy._nodes, (node) -> node if node._state is "active"
+
allEdges: ->
_.flatten _.map(alchemy._edges, (edgeArray) -> e for e in edgeArray)
@@ -583,10 +582,10 @@ title: Anotated Source
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
- alchemy.filters =
- init: () ->
+ alchemy.filters =
+ init: () ->
alchemy.filters.show()
-
+
if alchemy.conf.edgeFilters then alchemy.filters.showEdgeFilters()
if alchemy.conf.nodeFilters then alchemy.filters.showNodeFilters()
#generate filter forms
@@ -612,7 +611,7 @@ title: Anotated Source
edgeTypes += "
#{caption}
"
alchemy.dash.select '#rel-dropdown'
.html edgeTypes
-
+
if alchemy.conf.captionsToggle then alchemy.filters.captionsToggle()
if alchemy.conf.edgesToggle then alchemy.filters.edgesToggle()
if alchemy.conf.nodesToggle then alchemy.filters.nodesToggle()
@@ -681,12 +680,12 @@ title: Anotated Source
.append "div"
.attr "id", "filter-nodes"
.html node_filter_html
- alchemy.dash.select "#filter-node-header"
+ alchemy.dash.select "#filter-node-header"
.on 'click', () ->
if alchemy.dash.select('#node-dropdown').classed "in"
alchemy.dash.select "#filter-node-header>span"
.attr "class", "fa fa-lg fa-caret-right"
- else
+ else
alchemy.dash.select "#filter-node-header>span"
.attr "class", "fa fa-lg fa-caret-down"
@@ -713,8 +712,16 @@ title: Anotated Source
.attr {"id":"toggle-edges","class":"list-group-item active-label toggle"}
.html "Toggle Edges"
.on "click", ->
- _.each _.values(alchemy._edges), (edges)->
- _.each edges, (e)-> e.toggleHidden()
+ if _.contains(_.pluck(_.flatten(_.values(alchemy._edges)), "_state"), "active")
+ _.each _.values(alchemy._edges), (edges)->
+ _.each edges, (e)-> if e._state is "active" then e.toggleHidden()
+ else
+ _.each _.values(alchemy._edges), (edges)->
+ _.each edges, (e)->
+ source = alchemy._nodes[e._properties.source]
+ target = alchemy._nodes[e._properties.target]
+ if source._state is "active" and target._state is "active"
+ e.toggleHidden()
#create nodes toggle
nodesToggle: () ->
@@ -723,9 +730,14 @@ title: Anotated Source
.attr {"id":"toggle-nodes","class":"list-group-item active-label toggle"}
.html "Toggle Nodes"
.on "click", ->
- _.each _.values(alchemy._nodes), (n)->
- if alchemy.conf.toggleRootNodes and n._d3.root then return
- n.toggleHidden()
+ if _.contains(_.pluck(_.values(alchemy._nodes), "_state"), "active")
+ _.each _.values(alchemy._nodes), (n)->
+ if alchemy.conf.toggleRootNodes and n._d3.root then return
+ if n._state is "active" then n.toggleHidden()
+ else
+ _.each _.values(alchemy._nodes), (n)->
+ if alchemy.conf.toggleRootNodes and n._d3.root then return
+ n.toggleHidden()
#update filters
update: () ->
@@ -734,13 +746,18 @@ title: Anotated Source
element = d3.select this
tag = element.attr "name"
alchemy.vis.selectAll ".#{tag}"
- .each (d)->
+ .each (d)->
if alchemy._nodes[d.id]?
node = alchemy._nodes[d.id]
node.toggleHidden()
else
edge = alchemy._edges[d.id][0]
- edge.toggleHidden()
+ source = alchemy._nodes[edge._properties.source]
+ target = alchemy._nodes[edge._properties.target]
+ if source._state is "active" and target._state is "active"
+ edge.toggleHidden()
+ alchemy.stats.nodeStats()
+
# Alchemy.js is a graph drawing application for the web.
# Copyright (C) 2014 GraphAlchemist, Inc.
@@ -928,12 +945,8 @@ title: Anotated Source
nodes = alchemy._nodes
@k = Math.sqrt Math.log(_.size(alchemy._nodes)) / (conf.graphWidth() * conf.graphHeight())
@_clustering = new alchemy.clustering
+ @d3NodeInternals = _.map alchemy._nodes, (v,k)-> v._d3
- # Set up quad tree
- if conf.collisionDetection
- @d3NodeInternals = _.map alchemy._nodes, (v,k)-> v._d3
- @q = d3.geom.quadtree @d3NodeInternals
-
if conf.cluster
@_charge = () -> @_clustering.layout.charge
@_linkStrength = (edge) -> @_clustering.layout.linkStrength(edge)
@@ -955,6 +968,8 @@ title: Anotated Source
else if typeof conf.linkDistancefn is 'function'
@_linkDistancefn = (edge) -> conf.linkDistancefn(edge)
+
+
gravity: () =>
if alchemy.conf.cluster
@_clustering.layout.gravity @k
@@ -964,10 +979,9 @@ title: Anotated Source
linkStrength: (edge) =>
@_linkStrength edge
- friction: () ->
- if alchemy.conf.cluster then 0.7 else 0.9
+ friction: () -> 0.9
- collide: (node) =>
+ collide: (node) ->
conf = alchemy.conf
r = 2 * (node.radius + node['stroke-width']) + conf.nodeOverlap
nx1 = node.x - r
@@ -992,9 +1006,10 @@ title: Anotated Source
y2 < ny1
tick: () =>
- if alchemy.conf.collisionDetection
+ if alchemy.conf.collisionDetectionls
+ q = d3.geom.quadtree @d3NodeInternals
for node in @d3NodeInternals
- @q.visit @collide(node)
+ q.visit @collide(node)
# alchemy.node
alchemy.vis
@@ -1216,7 +1231,10 @@ title: Anotated Source
if conf.curvedEdges
marker.attr "refX", arrowSize + 1
else
- marker.attr 'refX', 1
+ marker.attr 'refX', 1
+
+ if conf.nodeStats
+ alchemy.stats.nodeStats()
if conf.showEditor
editor = new alchemy.editor.Editor
@@ -1249,23 +1267,26 @@ title: Anotated Source
nodeStats: () ->
#general node stats
nodeStats = ''
- nodeNum = alchemy.vis.selectAll(".node")[0].length
- activeNodes = alchemy.vis.selectAll(".node.active")[0].length
- inactiveNodes = alchemy.vis.selectAll(".node.inactive")[0].length
- nodeStats += "
"
#add stats for all node types
if alchemy.conf.nodeTypes
- nodeKey = Object.keys(alchemy.conf.nodeTypes)
+ nodeKeys = Object.keys(alchemy.conf.nodeTypes)
nodeTypes = ''
- for nodeType in alchemy.conf.nodeTypes[nodeKey]
- # if not currentNodeTypes[t] then continue
+ for nodeType in alchemy.conf.nodeTypes[nodeKeys]
caption = nodeType.replace('_', ' ')
nodeNum = alchemy.vis.selectAll("g.node.#{nodeType}")[0].length
nodeTypes += "
- "
-
- alchemy.dash
- .select '#node-stats'
- .html nodeGraph
- alchemy.stats.insertSVG "node", nodeData
- return nodeData
-
insertSVG: (element, data) ->
if data is null
alchemy.dash
@@ -2813,13 +2808,13 @@ for the curve of the node.
constructor: (edge, index=null) ->
a = alchemy
conf = a.conf
-
+
@id = @_setID edge
@_index = index
@_state = "active"
@_properties = edge
@_edgeType = @_setEdgeType()
- @_style =
+ @_style =
if conf.edgeStyle[@_edgeType]?
_.merge _.clone(conf.edgeStyle["all"]), conf.edgeStyle[@_edgeType]
else
@@ -2841,7 +2836,7 @@ for the curve of the node.
_setCaption: (edge, conf) =>
cap = conf.edgeCaption
- edgeCaption = do (edge) ->
+ edgeCaption = do (edge) ->
switch typeof cap
when ('string' or 'number') then edge[cap]
when 'function' then cap(edge)
@@ -2853,6 +2848,8 @@ for the curve of the node.
if _.isPlainObject conf.edgeTypes
lookup = Object.keys alchemy.conf.edgeTypes
edgeType = @_properties[lookup]
+ else if _.isArray conf.edgeTypes
+ edgeType = @_properties["caption"]
else if typeof conf.edgeTypes is 'string'
edgeType = @_properties[conf.edgeTypes]
if edgeType is undefined then edgeType = "all"
@@ -2882,7 +2879,7 @@ for the curve of the node.
# Style methods
getStyles: (key=null) =>
if key?
- @_style[key]
+ @_style[key]
else
@_style