diff --git a/dist/vis.min.js b/dist/vis.min.js deleted file mode 100644 index 95acc029..00000000 --- a/dist/vis.min.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * vis.js - * https://github.com/almende/vis - * - * A dynamic, browser-based visualization library. - * - * @version 0.5.0-SNAPSHOT - * @date 2014-02-10 - * - * @license - * Copyright (C) 2011-2014 Almende B.V, http://almende.com - * - * 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. - */ -!function(t){if("object"==typeof exports)module.exports=t();else if("function"==typeof define&&define.amd)define(t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.vis=t()}}(function(){var define,module,exports;return function t(e,i,n){function s(r,a){if(!i[r]){if(!e[r]){var h="function"==typeof require&&require;if(!a&&h)return h(r,!0);if(o)return o(r,!0);throw new Error("Cannot find module '"+r+"'")}var l=i[r]={exports:{}};e[r][0].call(l.exports,function(t){var i=e[r][1][t];return s(i?i:t)},l,l.exports,t,e,i,n)}return i[r].exports}for(var o="function"==typeof require&&require,r=0;ri;++i)t.call(e||this,this[i],i,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){var i,n,s;if(null==this)throw new TypeError(" this is null or not defined");var o=Object(this),r=o.length>>>0;if("function"!=typeof t)throw new TypeError(t+" is not a function");for(e&&(i=e),n=new Array(r),s=0;r>s;){var a,h;s in o&&(a=o[s],h=t.call(i,a,s,o),n[s]=h),s++}return n}),Array.prototype.filter||(Array.prototype.filter=function(t){"use strict";if(null==this)throw new TypeError;var e=Object(this),i=e.length>>>0;if("function"!=typeof t)throw new TypeError;for(var n=[],s=arguments[1],o=0;i>o;o++)if(o in e){var r=e[o];t.call(s,r,o,e)&&n.push(r)}return n}),Object.keys||(Object.keys=function(){var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),i=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],n=i.length;return function(s){if("object"!=typeof s&&"function"!=typeof s||null===s)throw new TypeError("Object.keys called on non-object");var o=[];for(var r in s)t.call(s,r)&&o.push(r);if(e)for(var a=0;n>a;a++)t.call(s,i[a])&&o.push(i[a]);return o}}()),Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),Function.prototype.bind||(Function.prototype.bind=function(t){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var e=Array.prototype.slice.call(arguments,1),i=this,n=function(){},s=function(){return i.apply(this instanceof n&&t?this:t,e.concat(Array.prototype.slice.call(arguments)))};return n.prototype=this.prototype,s.prototype=new n,s}),Object.create||(Object.create=function(t){function e(){}if(arguments.length>1)throw new Error("Object.create implementation only accepts the first parameter.");return e.prototype=t,new e}),Function.prototype.bind||(Function.prototype.bind=function(t){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var e=Array.prototype.slice.call(arguments,1),i=this,n=function(){},s=function(){return i.apply(this instanceof n&&t?this:t,e.concat(Array.prototype.slice.call(arguments)))};return n.prototype=this.prototype,s.prototype=new n,s});var util={};util.isNumber=function(t){return t instanceof Number||"number"==typeof t},util.isString=function(t){return t instanceof String||"string"==typeof t},util.isDate=function(t){if(t instanceof Date)return!0;if(util.isString(t)){var e=ASPDateRegex.exec(t);if(e)return!0;if(!isNaN(Date.parse(t)))return!0}return!1},util.isDataTable=function(t){return"undefined"!=typeof google&&google.visualization&&google.visualization.DataTable&&t instanceof google.visualization.DataTable},util.randomUUID=function(){var t=function(){return Math.floor(65536*Math.random()).toString(16)};return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()},util.extend=function(t){for(var e=1,i=arguments.length;i>e;e++){var n=arguments[e];for(var s in n)n.hasOwnProperty(s)&&void 0!==n[s]&&(t[s]=n[s])}return t},util.convert=function(t,e){var i;if(void 0===t)return void 0;if(null===t)return null;if(!e)return t;if("string"!=typeof e&&!(e instanceof String))throw new Error("Type must be a string");switch(e){case"boolean":case"Boolean":return Boolean(t);case"number":case"Number":return Number(t.valueOf());case"string":case"String":return String(t);case"Date":if(util.isNumber(t))return new Date(t);if(t instanceof Date)return new Date(t.valueOf());if(moment.isMoment(t))return new Date(t.valueOf());if(util.isString(t))return i=ASPDateRegex.exec(t),i?new Date(Number(i[1])):moment(t).toDate();throw new Error("Cannot convert object of type "+util.getType(t)+" to type Date");case"Moment":if(util.isNumber(t))return moment(t);if(t instanceof Date)return moment(t.valueOf());if(moment.isMoment(t))return moment(t);if(util.isString(t))return i=ASPDateRegex.exec(t),moment(i?Number(i[1]):t);throw new Error("Cannot convert object of type "+util.getType(t)+" to type Date");case"ISODate":if(util.isNumber(t))return new Date(t);if(t instanceof Date)return t.toISOString();if(moment.isMoment(t))return t.toDate().toISOString();if(util.isString(t))return i=ASPDateRegex.exec(t),i?new Date(Number(i[1])).toISOString():new Date(t).toISOString();throw new Error("Cannot convert object of type "+util.getType(t)+" to type ISODate");case"ASPDate":if(util.isNumber(t))return"/Date("+t+")/";if(t instanceof Date)return"/Date("+t.valueOf()+")/";if(util.isString(t)){i=ASPDateRegex.exec(t);var n;return n=i?new Date(Number(i[1])).valueOf():new Date(t).valueOf(),"/Date("+n+")/"}throw new Error("Cannot convert object of type "+util.getType(t)+" to type ASPDate");default:throw new Error("Cannot convert object of type "+util.getType(t)+' to type "'+e+'"')}};var ASPDateRegex=/^\/?Date\((\-?\d+)/i;util.getType=function(t){var e=typeof t;return"object"==e?null==t?"null":t instanceof Boolean?"Boolean":t instanceof Number?"Number":t instanceof String?"String":t instanceof Array?"Array":t instanceof Date?"Date":"Object":"number"==e?"Number":"boolean"==e?"Boolean":"string"==e?"String":e},util.getAbsoluteLeft=function(t){for(var e=document.documentElement,i=document.body,n=t.offsetLeft,s=t.offsetParent;null!=s&&s!=i&&s!=e;)n+=s.offsetLeft,n-=s.scrollLeft,s=s.offsetParent;return n},util.getAbsoluteTop=function(t){for(var e=document.documentElement,i=document.body,n=t.offsetTop,s=t.offsetParent;null!=s&&s!=i&&s!=e;)n+=s.offsetTop,n-=s.scrollTop,s=s.offsetParent;return n},util.getPageY=function(t){if("pageY"in t)return t.pageY;var e;e="targetTouches"in t&&t.targetTouches.length?t.targetTouches[0].clientY:t.clientY;var i=document.documentElement,n=document.body;return e+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)},util.getPageX=function(t){if("pageY"in t)return t.pageX;var e;e="targetTouches"in t&&t.targetTouches.length?t.targetTouches[0].clientX:t.clientX;var i=document.documentElement,n=document.body;return e+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0)},util.addClassName=function(t,e){var i=t.className.split(" ");-1==i.indexOf(e)&&(i.push(e),t.className=i.join(" "))},util.removeClassName=function(t,e){var i=t.className.split(" "),n=i.indexOf(e);-1!=n&&(i.splice(n,1),t.className=i.join(" "))},util.forEach=function(t,e){var i,n;if(t instanceof Array)for(i=0,n=t.length;n>i;i++)e(t[i],i,t);else for(i in t)t.hasOwnProperty(i)&&e(t[i],i,t)},util.updateProperty=function(t,e,i){return t[e]!==i?(t[e]=i,!0):!1},util.addEventListener=function(t,e,i,n){t.addEventListener?(void 0===n&&(n=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.addEventListener(e,i,n)):t.attachEvent("on"+e,i)},util.removeEventListener=function(t,e,i,n){t.removeEventListener?(void 0===n&&(n=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.removeEventListener(e,i,n)):t.detachEvent("on"+e,i)},util.getTarget=function(t){t||(t=window.event);var e;return t.target?e=t.target:t.srcElement&&(e=t.srcElement),void 0!=e.nodeType&&3==e.nodeType&&(e=e.parentNode),e},util.stopPropagation=function(t){t||(t=window.event),t.stopPropagation?t.stopPropagation():t.cancelBubble=!0},util.fakeGesture=function(t,e){var i=null;return Hammer.event.collectEventData(this,i,e)},util.preventDefault=function(t){t||(t=window.event),t.preventDefault?t.preventDefault():t.returnValue=!1},util.option={},util.option.asBoolean=function(t,e){return"function"==typeof t&&(t=t()),null!=t?0!=t:e||null},util.option.asNumber=function(t,e){return"function"==typeof t&&(t=t()),null!=t?Number(t)||e||null:e||null},util.option.asString=function(t,e){return"function"==typeof t&&(t=t()),null!=t?String(t):e||null},util.option.asSize=function(t,e){return"function"==typeof t&&(t=t()),util.isString(t)?t:util.isNumber(t)?t+"px":e||null},util.option.asElement=function(t,e){return"function"==typeof t&&(t=t()),t||e||null},util.GiveDec=function GiveDec(Hex){return Value="A"==Hex?10:"B"==Hex?11:"C"==Hex?12:"D"==Hex?13:"E"==Hex?14:"F"==Hex?15:eval(Hex)},util.GiveHex=function(t){return Value=10==t?"A":11==t?"B":12==t?"C":13==t?"D":14==t?"E":15==t?"F":""+t},util.hexToRGB=function(t){t=t.replace("#","").toUpperCase();var e=util.GiveDec(t.substring(0,1)),i=util.GiveDec(t.substring(1,2)),n=util.GiveDec(t.substring(2,3)),s=util.GiveDec(t.substring(3,4)),o=util.GiveDec(t.substring(4,5)),r=util.GiveDec(t.substring(5,6)),a=16*e+i,h=16*n+s,i=16*o+r;return{r:a,g:h,b:i}},util.RGBToHex=function(t,e,i){var n=util.GiveHex(Math.floor(t/16)),s=util.GiveHex(t%16),o=util.GiveHex(Math.floor(e/16)),r=util.GiveHex(e%16),a=util.GiveHex(Math.floor(i/16)),h=util.GiveHex(i%16),l=n+s+o+r+a+h;return"#"+l},util.RGBToHSV=function(t,e,i){t/=255,e/=255,i/=255;var n=Math.min(t,Math.min(e,i)),s=Math.max(t,Math.max(e,i));if(n==s)return{h:0,s:0,v:n};var o=t==n?e-i:i==n?t-e:i-t,r=t==n?3:i==n?1:5,a=60*(r-o/(s-n))/360,h=(s-n)/s,l=s;return{h:a,s:h,v:l}},util.HSVToRGB=function(t,e,i){var n,s,o,r=Math.floor(6*t),a=6*t-r,h=i*(1-e),l=i*(1-a*e),c=i*(1-(1-a)*e);switch(r%6){case 0:n=i,s=c,o=h;break;case 1:n=l,s=i,o=h;break;case 2:n=h,s=i,o=c;break;case 3:n=h,s=l,o=i;break;case 4:n=c,s=h,o=i;break;case 5:n=i,s=h,o=l}return{r:Math.floor(255*n),g:Math.floor(255*s),b:Math.floor(255*o)}},util.HSVToHex=function(t,e,i){var n=util.HSVToRGB(t,e,i);return util.RGBToHex(n.r,n.g,n.b)},util.hexToHSV=function(t){var e=util.hexToRGB(t);return util.RGBToHSV(e.r,e.g,e.b)};var events={listeners:[],indexOf:function(t){for(var e=this.listeners,i=0,n=this.listeners.length;n>i;i++){var s=e[i];if(s&&s.object==t)return i}return-1},addListener:function(t,e,i){var n=this.indexOf(t),s=this.listeners[n];s||(s={object:t,events:{}},this.listeners.push(s));var o=s.events[e];o||(o=[],s.events[e]=o),-1==o.indexOf(i)&&o.push(i)},removeListener:function(t,e,i){var n=this.indexOf(t),s=this.listeners[n];if(s){var o=s.events[e];o&&(n=o.indexOf(i),-1!=n&&o.splice(n,1),0==o.length&&delete s.events[e]);var r=0,a=s.events;for(var h in a)a.hasOwnProperty(h)&&r++;0==r&&delete this.listeners[n]}},removeAllListeners:function(){this.listeners=[]},trigger:function(t,e,i){var n=this.indexOf(t),s=this.listeners[n];if(s){var o=s.events[e];if(o)for(var r=0,a=o.length;a>r;r++)o[r](i)}}};EventBus.prototype.on=function(t,e,i){var n=t instanceof RegExp?t:new RegExp(t.replace("*","\\w+")),s={id:util.randomUUID(),event:t,regexp:n,callback:"function"==typeof e?e:null,target:i};return this.subscriptions.push(s),s.id},EventBus.prototype.off=function(t){for(var e=0;eo;o++)i=s._addItem(t[o]),n.push(i);else if(util.isDataTable(t))for(var a=this._getColumnNames(t),h=0,l=t.getNumberOfRows();l>h;h++){for(var c={},d=0,u=a.length;u>d;d++){var p=a[d];c[p]=t.getValue(h,d)}i=s._addItem(c),n.push(i)}else{if(!(t instanceof Object))throw new Error("Unknown dataType");i=s._addItem(t),n.push(i)}return n.length&&this._trigger("add",{items:n},e),n},DataSet.prototype.update=function(t,e){var i=[],n=[],s=this,o=s.fieldId,r=function(t){var e=t[o];s.data[e]?(e=s._updateItem(t),n.push(e)):(e=s._addItem(t),i.push(e))};if(t instanceof Array)for(var a=0,h=t.length;h>a;a++)r(t[a]);else if(util.isDataTable(t))for(var l=this._getColumnNames(t),c=0,d=t.getNumberOfRows();d>c;c++){for(var u={},p=0,f=l.length;f>p;p++){var g=l[p];u[g]=t.getValue(c,p)}r(u)}else{if(!(t instanceof Object))throw new Error("Unknown dataType");r(t)}return i.length&&this._trigger("add",{items:i},e),n.length&&this._trigger("update",{items:n},e),i.concat(n)},DataSet.prototype.get=function(){var t,e,i,n,s=this,o=this.showInternalIds,r=util.getType(arguments[0]);"String"==r||"Number"==r?(t=arguments[0],i=arguments[1],n=arguments[2]):"Array"==r?(e=arguments[0],i=arguments[1],n=arguments[2]):(i=arguments[0],n=arguments[1]);var a;if(i&&i.type){if(a="DataTable"==i.type?"DataTable":"Array",n&&a!=util.getType(n))throw new Error('Type of parameter "data" ('+util.getType(n)+") does not correspond with specified options.type ("+i.type+")");if("DataTable"==a&&!util.isDataTable(n))throw new Error('Parameter "data" must be a DataTable when options.type is "DataTable"')}else a=n?"DataTable"==util.getType(n)?"DataTable":"Array":"Array";void 0!=i&&void 0!=i.showInternalIds&&(this.showInternalIds=i.showInternalIds);var h,l,c,d,u=i&&i.convert||this.options.convert,p=i&&i.filter,f=[];if(void 0!=t)h=s._getItem(t,u),p&&!p(h)&&(h=null);else if(void 0!=e)for(c=0,d=e.length;d>c;c++)h=s._getItem(e[c],u),(!p||p(h))&&f.push(h);else for(l in this.data)this.data.hasOwnProperty(l)&&(h=s._getItem(l,u),(!p||p(h))&&f.push(h));if(this.showInternalIds=o,i&&i.order&&void 0==t&&this._sort(f,i.order),i&&i.fields){var g=i.fields;if(void 0!=t)h=this._filterFields(h,g);else for(c=0,d=f.length;d>c;c++)f[c]=this._filterFields(f[c],g)}if("DataTable"==a){var m=this._getColumnNames(n);if(void 0!=t)s._appendRow(n,m,h);else for(c=0,d=f.length;d>c;c++)s._appendRow(n,m,f[c]);return n}if(void 0!=t)return h;if(n){for(c=0,d=f.length;d>c;c++)n.push(f[c]);return n}return f},DataSet.prototype.getIds=function(t){var e,i,n,s,o,r=this.data,a=t&&t.filter,h=t&&t.order,l=t&&t.convert||this.options.convert,c=[];if(a)if(h){o=[];for(n in r)r.hasOwnProperty(n)&&(s=this._getItem(n,l),a(s)&&o.push(s));for(this._sort(o,h),e=0,i=o.length;i>e;e++)c[e]=o[e][this.fieldId]}else for(n in r)r.hasOwnProperty(n)&&(s=this._getItem(n,l),a(s)&&c.push(s[this.fieldId]));else if(h){o=[];for(n in r)r.hasOwnProperty(n)&&o.push(r[n]);for(this._sort(o,h),e=0,i=o.length;i>e;e++)c[e]=o[e][this.fieldId]}else for(n in r)r.hasOwnProperty(n)&&(s=r[n],c.push(s[this.fieldId]));return c},DataSet.prototype.forEach=function(t,e){var i,n,s=e&&e.filter,o=e&&e.convert||this.options.convert,r=this.data;if(e&&e.order)for(var a=this.get(e),h=0,l=a.length;l>h;h++)i=a[h],n=i[this.fieldId],t(i,n);else for(n in r)r.hasOwnProperty(n)&&(i=this._getItem(n,o),(!s||s(i))&&t(i,n))},DataSet.prototype.map=function(t,e){var i,n=e&&e.filter,s=e&&e.convert||this.options.convert,o=[],r=this.data;for(var a in r)r.hasOwnProperty(a)&&(i=this._getItem(a,s),(!n||n(i))&&o.push(t(i,a)));return e&&e.order&&this._sort(o,e.order),o},DataSet.prototype._filterFields=function(t,e){var i={};for(var n in t)t.hasOwnProperty(n)&&-1!=e.indexOf(n)&&(i[n]=t[n]);return i},DataSet.prototype._sort=function(t,e){if(util.isString(e)){var i=e;t.sort(function(t,e){var n=t[i],s=e[i];return n>s?1:s>n?-1:0})}else{if("function"!=typeof e)throw new TypeError("Order must be a function or a string");t.sort(e)}},DataSet.prototype.remove=function(t,e){var i,n,s,o=[];if(t instanceof Array)for(i=0,n=t.length;n>i;i++)s=this._remove(t[i]),null!=s&&o.push(s);else s=this._remove(t),null!=s&&o.push(s);return o.length&&this._trigger("remove",{items:o},e),o},DataSet.prototype._remove=function(t){if(util.isNumber(t)||util.isString(t)){if(this.data[t])return delete this.data[t],delete this.internalIds[t],t}else if(t instanceof Object){var e=t[this.fieldId];if(e&&this.data[e])return delete this.data[e],delete this.internalIds[e],e}return null},DataSet.prototype.clear=function(t){var e=Object.keys(this.data);return this.data={},this.internalIds={},this._trigger("remove",{items:e},t),e},DataSet.prototype.max=function(t){var e=this.data,i=null,n=null;for(var s in e)if(e.hasOwnProperty(s)){var o=e[s],r=o[t];null!=r&&(!i||r>n)&&(i=o,n=r)}return i},DataSet.prototype.min=function(t){var e=this.data,i=null,n=null;for(var s in e)if(e.hasOwnProperty(s)){var o=e[s],r=o[t];null!=r&&(!i||n>r)&&(i=o,n=r)}return i},DataSet.prototype.distinct=function(t){var e=this.data,i=[],n=this.options.convert[t],s=0;for(var o in e)if(e.hasOwnProperty(o)){for(var r=e[o],a=util.convert(r[t],n),h=!1,l=0;s>l;l++)if(i[l]==a){h=!0;break}h||(i[s]=a,s++)}return i},DataSet.prototype._addItem=function(t){var e=t[this.fieldId];if(void 0!=e){if(this.data[e])throw new Error("Cannot add item: item with id "+e+" already exists")}else e=util.randomUUID(),t[this.fieldId]=e,this.internalIds[e]=t;var i={};for(var n in t)if(t.hasOwnProperty(n)){var s=this.convert[n];i[n]=util.convert(t[n],s)}return this.data[e]=i,e},DataSet.prototype._getItem=function(t,e){var i,n,s=this.data[t];if(!s)return null;var o={},r=this.fieldId,a=this.internalIds;if(e)for(i in s)s.hasOwnProperty(i)&&(n=s[i],i==r&&n in a&&!this.showInternalIds||(o[i]=util.convert(n,e[i])));else for(i in s)s.hasOwnProperty(i)&&(n=s[i],i==r&&n in a&&!this.showInternalIds||(o[i]=n));return o},DataSet.prototype._updateItem=function(t){var e=t[this.fieldId];if(void 0==e)throw new Error("Cannot update item: item has no id (item: "+JSON.stringify(t)+")");var i=this.data[e];if(!i)throw new Error("Cannot update item: no item with id "+e+" found");for(var n in t)if(t.hasOwnProperty(n)){var s=this.convert[n];i[n]=util.convert(t[n],s)}return e},DataSet.prototype.isInternalId=function(t){return t in this.internalIds},DataSet.prototype._getColumnNames=function(t){for(var e=[],i=0,n=t.getNumberOfColumns();n>i;i++)e[i]=t.getColumnId(i)||t.getColumnLabel(i);return e},DataSet.prototype._appendRow=function(t,e,i){for(var n=t.addRow(),s=0,o=e.length;o>s;s++){var r=e[s];t.setValue(n,s,i[r])}},DataView.prototype.setData=function(t){var e,i,n;if(this.data){this.data.unsubscribe&&this.data.unsubscribe("*",this.listener),e=[];for(var s in this.ids)this.ids.hasOwnProperty(s)&&e.push(s);this.ids={},this._trigger("remove",{items:e})}if(this.data=t,this.data){for(this.fieldId=this.options.fieldId||this.data&&this.data.options&&this.data.options.fieldId||"id",e=this.data.getIds({filter:this.options&&this.options.filter}),i=0,n=e.length;n>i;i++)s=e[i],this.ids[s]=!0;this._trigger("add",{items:e}),this.data.subscribe&&this.data.subscribe("*",this.listener)}},DataView.prototype.get=function(){var t,e,i,n=this,s=util.getType(arguments[0]);"String"==s||"Number"==s||"Array"==s?(t=arguments[0],e=arguments[1],i=arguments[2]):(e=arguments[0],i=arguments[1]);var o=util.extend({},this.options,e);this.options.filter&&e&&e.filter&&(o.filter=function(t){return n.options.filter(t)&&e.filter(t)});var r=[];return void 0!=t&&r.push(t),r.push(o),r.push(i),this.data&&this.data.get.apply(this.data,r)},DataView.prototype.getIds=function(t){var e;if(this.data){var i,n=this.options.filter; -i=t&&t.filter?n?function(e){return n(e)&&t.filter(e)}:t.filter:n,e=this.data.getIds({filter:i,order:t&&t.order})}else e=[];return e},DataView.prototype._onEvent=function(t,e,i){var n,s,o,r,a=e&&e.items,h=this.data,l=[],c=[],d=[];if(a&&h){switch(t){case"add":for(n=0,s=a.length;s>n;n++)o=a[n],r=this.get(o),r&&(this.ids[o]=!0,l.push(o));break;case"update":for(n=0,s=a.length;s>n;n++)o=a[n],r=this.get(o),r?this.ids[o]?c.push(o):(this.ids[o]=!0,l.push(o)):this.ids[o]&&(delete this.ids[o],d.push(o));break;case"remove":for(n=0,s=a.length;s>n;n++)o=a[n],this.ids[o]&&(delete this.ids[o],d.push(o))}l.length&&this._trigger("add",{items:l},i),c.length&&this._trigger("update",{items:c},i),d.length&&this._trigger("remove",{items:d},i)}},DataView.prototype.subscribe=DataSet.prototype.subscribe,DataView.prototype.unsubscribe=DataSet.prototype.unsubscribe,DataView.prototype._trigger=DataSet.prototype._trigger,TimeStep=function(t,e,i){this.current=new Date,this._start=new Date,this._end=new Date,this.autoScale=!0,this.scale=TimeStep.SCALE.DAY,this.step=1,this.setRange(t,e,i)},TimeStep.SCALE={MILLISECOND:1,SECOND:2,MINUTE:3,HOUR:4,DAY:5,WEEKDAY:6,MONTH:7,YEAR:8},TimeStep.prototype.setRange=function(t,e,i){if(!(t instanceof Date&&e instanceof Date))throw"No legal start or end date in method setRange";this._start=void 0!=t?new Date(t.valueOf()):new Date,this._end=void 0!=e?new Date(e.valueOf()):new Date,this.autoScale&&this.setMinimumStep(i)},TimeStep.prototype.first=function(){this.current=new Date(this._start.valueOf()),this.roundToMinor()},TimeStep.prototype.roundToMinor=function(){switch(this.scale){case TimeStep.SCALE.YEAR:this.current.setFullYear(this.step*Math.floor(this.current.getFullYear()/this.step)),this.current.setMonth(0);case TimeStep.SCALE.MONTH:this.current.setDate(1);case TimeStep.SCALE.DAY:case TimeStep.SCALE.WEEKDAY:this.current.setHours(0);case TimeStep.SCALE.HOUR:this.current.setMinutes(0);case TimeStep.SCALE.MINUTE:this.current.setSeconds(0);case TimeStep.SCALE.SECOND:this.current.setMilliseconds(0)}if(1!=this.step)switch(this.scale){case TimeStep.SCALE.MILLISECOND:this.current.setMilliseconds(this.current.getMilliseconds()-this.current.getMilliseconds()%this.step);break;case TimeStep.SCALE.SECOND:this.current.setSeconds(this.current.getSeconds()-this.current.getSeconds()%this.step);break;case TimeStep.SCALE.MINUTE:this.current.setMinutes(this.current.getMinutes()-this.current.getMinutes()%this.step);break;case TimeStep.SCALE.HOUR:this.current.setHours(this.current.getHours()-this.current.getHours()%this.step);break;case TimeStep.SCALE.WEEKDAY:case TimeStep.SCALE.DAY:this.current.setDate(this.current.getDate()-1-(this.current.getDate()-1)%this.step+1);break;case TimeStep.SCALE.MONTH:this.current.setMonth(this.current.getMonth()-this.current.getMonth()%this.step);break;case TimeStep.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()-this.current.getFullYear()%this.step)}},TimeStep.prototype.hasNext=function(){return this.current.valueOf()<=this._end.valueOf()},TimeStep.prototype.next=function(){var t=this.current.valueOf();if(this.current.getMonth()<6)switch(this.scale){case TimeStep.SCALE.MILLISECOND:this.current=new Date(this.current.valueOf()+this.step);break;case TimeStep.SCALE.SECOND:this.current=new Date(this.current.valueOf()+1e3*this.step);break;case TimeStep.SCALE.MINUTE:this.current=new Date(this.current.valueOf()+1e3*this.step*60);break;case TimeStep.SCALE.HOUR:this.current=new Date(this.current.valueOf()+1e3*this.step*60*60);var e=this.current.getHours();this.current.setHours(e-e%this.step);break;case TimeStep.SCALE.WEEKDAY:case TimeStep.SCALE.DAY:this.current.setDate(this.current.getDate()+this.step);break;case TimeStep.SCALE.MONTH:this.current.setMonth(this.current.getMonth()+this.step);break;case TimeStep.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()+this.step)}else switch(this.scale){case TimeStep.SCALE.MILLISECOND:this.current=new Date(this.current.valueOf()+this.step);break;case TimeStep.SCALE.SECOND:this.current.setSeconds(this.current.getSeconds()+this.step);break;case TimeStep.SCALE.MINUTE:this.current.setMinutes(this.current.getMinutes()+this.step);break;case TimeStep.SCALE.HOUR:this.current.setHours(this.current.getHours()+this.step);break;case TimeStep.SCALE.WEEKDAY:case TimeStep.SCALE.DAY:this.current.setDate(this.current.getDate()+this.step);break;case TimeStep.SCALE.MONTH:this.current.setMonth(this.current.getMonth()+this.step);break;case TimeStep.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()+this.step)}if(1!=this.step)switch(this.scale){case TimeStep.SCALE.MILLISECOND:this.current.getMilliseconds()0&&(this.step=e),this.autoScale=!1},TimeStep.prototype.setAutoScale=function(t){this.autoScale=t},TimeStep.prototype.setMinimumStep=function(t){if(void 0!=t){var e=31104e6,i=2592e6,n=864e5,s=36e5,o=6e4,r=1e3,a=1;1e3*e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=1e3),500*e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=500),100*e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=100),50*e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=50),10*e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=10),5*e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=5),e>t&&(this.scale=TimeStep.SCALE.YEAR,this.step=1),3*i>t&&(this.scale=TimeStep.SCALE.MONTH,this.step=3),i>t&&(this.scale=TimeStep.SCALE.MONTH,this.step=1),5*n>t&&(this.scale=TimeStep.SCALE.DAY,this.step=5),2*n>t&&(this.scale=TimeStep.SCALE.DAY,this.step=2),n>t&&(this.scale=TimeStep.SCALE.DAY,this.step=1),n/2>t&&(this.scale=TimeStep.SCALE.WEEKDAY,this.step=1),4*s>t&&(this.scale=TimeStep.SCALE.HOUR,this.step=4),s>t&&(this.scale=TimeStep.SCALE.HOUR,this.step=1),15*o>t&&(this.scale=TimeStep.SCALE.MINUTE,this.step=15),10*o>t&&(this.scale=TimeStep.SCALE.MINUTE,this.step=10),5*o>t&&(this.scale=TimeStep.SCALE.MINUTE,this.step=5),o>t&&(this.scale=TimeStep.SCALE.MINUTE,this.step=1),15*r>t&&(this.scale=TimeStep.SCALE.SECOND,this.step=15),10*r>t&&(this.scale=TimeStep.SCALE.SECOND,this.step=10),5*r>t&&(this.scale=TimeStep.SCALE.SECOND,this.step=5),r>t&&(this.scale=TimeStep.SCALE.SECOND,this.step=1),200*a>t&&(this.scale=TimeStep.SCALE.MILLISECOND,this.step=200),100*a>t&&(this.scale=TimeStep.SCALE.MILLISECOND,this.step=100),50*a>t&&(this.scale=TimeStep.SCALE.MILLISECOND,this.step=50),10*a>t&&(this.scale=TimeStep.SCALE.MILLISECOND,this.step=10),5*a>t&&(this.scale=TimeStep.SCALE.MILLISECOND,this.step=5),a>t&&(this.scale=TimeStep.SCALE.MILLISECOND,this.step=1)}},TimeStep.prototype.snap=function(t){if(this.scale==TimeStep.SCALE.YEAR){var e=t.getFullYear()+Math.round(t.getMonth()/12);t.setFullYear(Math.round(e/this.step)*this.step),t.setMonth(0),t.setDate(0),t.setHours(0),t.setMinutes(0),t.setSeconds(0),t.setMilliseconds(0)}else if(this.scale==TimeStep.SCALE.MONTH)t.getDate()>15?(t.setDate(1),t.setMonth(t.getMonth()+1)):t.setDate(1),t.setHours(0),t.setMinutes(0),t.setSeconds(0),t.setMilliseconds(0);else if(this.scale==TimeStep.SCALE.DAY||this.scale==TimeStep.SCALE.WEEKDAY){switch(this.step){case 5:case 2:t.setHours(24*Math.round(t.getHours()/24));break;default:t.setHours(12*Math.round(t.getHours()/12))}t.setMinutes(0),t.setSeconds(0),t.setMilliseconds(0)}else if(this.scale==TimeStep.SCALE.HOUR){switch(this.step){case 4:t.setMinutes(60*Math.round(t.getMinutes()/60));break;default:t.setMinutes(30*Math.round(t.getMinutes()/30))}t.setSeconds(0),t.setMilliseconds(0)}else if(this.scale==TimeStep.SCALE.MINUTE){switch(this.step){case 15:case 10:t.setMinutes(5*Math.round(t.getMinutes()/5)),t.setSeconds(0);break;case 5:t.setSeconds(60*Math.round(t.getSeconds()/60));break;default:t.setSeconds(30*Math.round(t.getSeconds()/30))}t.setMilliseconds(0)}else if(this.scale==TimeStep.SCALE.SECOND)switch(this.step){case 15:case 10:t.setSeconds(5*Math.round(t.getSeconds()/5)),t.setMilliseconds(0);break;case 5:t.setMilliseconds(1e3*Math.round(t.getMilliseconds()/1e3));break;default:t.setMilliseconds(500*Math.round(t.getMilliseconds()/500))}else if(this.scale==TimeStep.SCALE.MILLISECOND){var i=this.step>5?this.step/2:1;t.setMilliseconds(Math.round(t.getMilliseconds()/i)*i)}},TimeStep.prototype.isMajor=function(){switch(this.scale){case TimeStep.SCALE.MILLISECOND:return 0==this.current.getMilliseconds();case TimeStep.SCALE.SECOND:return 0==this.current.getSeconds();case TimeStep.SCALE.MINUTE:return 0==this.current.getHours()&&0==this.current.getMinutes();case TimeStep.SCALE.HOUR:return 0==this.current.getHours();case TimeStep.SCALE.WEEKDAY:case TimeStep.SCALE.DAY:return 1==this.current.getDate();case TimeStep.SCALE.MONTH:return 0==this.current.getMonth();case TimeStep.SCALE.YEAR:return!1;default:return!1}},TimeStep.prototype.getLabelMinor=function(t){switch(void 0==t&&(t=this.current),this.scale){case TimeStep.SCALE.MILLISECOND:return moment(t).format("SSS");case TimeStep.SCALE.SECOND:return moment(t).format("s");case TimeStep.SCALE.MINUTE:return moment(t).format("HH:mm");case TimeStep.SCALE.HOUR:return moment(t).format("HH:mm");case TimeStep.SCALE.WEEKDAY:return moment(t).format("ddd D");case TimeStep.SCALE.DAY:return moment(t).format("D");case TimeStep.SCALE.MONTH:return moment(t).format("MMM");case TimeStep.SCALE.YEAR:return moment(t).format("YYYY");default:return""}},TimeStep.prototype.getLabelMajor=function(t){switch(void 0==t&&(t=this.current),this.scale){case TimeStep.SCALE.MILLISECOND:return moment(t).format("HH:mm:ss");case TimeStep.SCALE.SECOND:return moment(t).format("D MMMM HH:mm");case TimeStep.SCALE.MINUTE:case TimeStep.SCALE.HOUR:return moment(t).format("ddd D MMMM");case TimeStep.SCALE.WEEKDAY:case TimeStep.SCALE.DAY:return moment(t).format("MMMM YYYY");case TimeStep.SCALE.MONTH:return moment(t).format("YYYY");case TimeStep.SCALE.YEAR:return"";default:return""}},Stack.prototype.setOptions=function(t){util.extend(this.options,t)},Stack.prototype.update=function(){this._order(),this._stack()},Stack.prototype._order=function(){var t=this.parent.items;if(!t)throw new Error("Cannot stack items: parent does not contain items");var e=[],i=0;util.forEach(t,function(t){t.visible&&(e[i]=t,i++)});var n=this.options.order||this.defaultOptions.order;if("function"!=typeof n)throw new Error("Option order must be a function");e.sort(n),this.ordered=e},Stack.prototype._stack=function(){var t,e,i,n=this.ordered,s=this.options,o=s.orientation||this.defaultOptions.orientation,r="top"==o;for(i=s.margin&&void 0!==s.margin.item?s.margin.item:this.defaultOptions.margin.item,t=0,e=n.length;e>t;t++){var a=n[t],h=null;do h=this.checkOverlap(n,t,0,t-1,i),null!=h&&(a.top=r?h.top+h.height+i:h.top-a.height-i);while(h)}},Stack.prototype.checkOverlap=function(t,e,i,n,s){for(var o=this.collision,r=t[e],a=n;a>=i;a--){var h=t[a];if(o(r,h,s)&&a!=e)return h}return null},Stack.prototype.collision=function(t,e,i){return t.left-ie.left&&t.top-ie.top},Range.prototype.setOptions=function(t){util.extend(this.options,t),null!==this.start&&null!==this.end&&this.setRange(this.start,this.end)},Range.prototype.subscribe=function(t,e,i){function n(e){s._onMouseWheel(e,t,i)}var s=this;if("move"==e)t.on("dragstart",function(e){s._onDragStart(e,t)}),t.on("drag",function(e){s._onDrag(e,t,i)}),t.on("dragend",function(e){s._onDragEnd(e,t)});else{if("zoom"!=e)throw new TypeError('Unknown event "'+e+'". Choose "move" or "zoom".');t.on("mousewheel",n),t.on("DOMMouseScroll",n),t.on("touch",function(){s._onTouch()}),t.on("pinch",function(e){s._onPinch(e,t,i)})}},Range.prototype.on=function(t,e){var i=["rangechange","rangechanged"];if(-1==i.indexOf(t))throw new Error('Unknown event "'+t+'". Choose from '+i.join());events.addListener(this,t,e)},Range.prototype.off=function(t,e){events.removeListener(this,t,e)},Range.prototype._trigger=function(t){events.trigger(this,t,{start:this.start,end:this.end})},Range.prototype.setRange=function(t,e){var i=this._applyRange(t,e);i&&(this._trigger("rangechange"),this._trigger("rangechanged"))},Range.prototype._applyRange=function(t,e){var i,n=null!=t?util.convert(t,"Date").valueOf():this.start,s=null!=e?util.convert(e,"Date").valueOf():this.end,o=null!=this.options.max?util.convert(this.options.max,"Date").valueOf():null,r=null!=this.options.min?util.convert(this.options.min,"Date").valueOf():null;if(isNaN(n)||null===n)throw new Error('Invalid start "'+t+'"');if(isNaN(s)||null===s)throw new Error('Invalid end "'+e+'"');if(n>s&&(s=n),null!==r&&r>n&&(i=r-n,n+=i,s+=i,null!=o&&s>o&&(s=o)),null!==o&&s>o&&(i=s-o,n-=i,s-=i,null!=r&&r>n&&(n=r)),null!==this.options.zoomMin){var a=parseFloat(this.options.zoomMin);0>a&&(a=0),a>s-n&&(this.end-this.start===a?(n=this.start,s=this.end):(i=a-(s-n),n-=i/2,s+=i/2))}if(null!==this.options.zoomMax){var h=parseFloat(this.options.zoomMax);0>h&&(h=0),s-n>h&&(this.end-this.start===h?(n=this.start,s=this.end):(i=s-n-h,n+=i/2,s-=i/2))}var l=this.start!=n||this.end!=s;return this.start=n,this.end=s,l},Range.prototype.getRange=function(){return{start:this.start,end:this.end}},Range.prototype.conversion=function(t){return Range.conversion(this.start,this.end,t)},Range.conversion=function(t,e,i){return 0!=i&&e-t!=0?{offset:t,scale:i/(e-t)}:{offset:0,scale:1}};var touchParams={};Range.prototype._onDragStart=function(t,e){if(!touchParams.pinching){touchParams.start=this.start,touchParams.end=this.end;var i=e.frame;i&&(i.style.cursor="move")}},Range.prototype._onDrag=function(t,e,i){if(validateDirection(i),!touchParams.pinching){var n="horizontal"==i?t.gesture.deltaX:t.gesture.deltaY,s=touchParams.end-touchParams.start,o="horizontal"==i?e.width:e.height,r=-n/o*s;this._applyRange(touchParams.start+r,touchParams.end+r),this._trigger("rangechange")}},Range.prototype._onDragEnd=function(t,e){touchParams.pinching||(e.frame&&(e.frame.style.cursor="auto"),this._trigger("rangechanged"))},Range.prototype._onMouseWheel=function(t,e,i){validateDirection(i);var n=0;if(t.wheelDelta?n=t.wheelDelta/120:t.detail&&(n=-t.detail/3),n){var s;s=0>n?1-n/5:1/(1+n/5);var o=util.fakeGesture(this,t),r=getPointer(o.touches[0],e.frame),a=this._pointerToDate(e,i,r);this.zoom(s,a)}util.preventDefault(t)},Range.prototype._onTouch=function(){touchParams.start=this.start,touchParams.end=this.end,touchParams.pinching=!1,touchParams.center=null},Range.prototype._onPinch=function(t,e,i){if(touchParams.pinching=!0,t.gesture.touches.length>1){touchParams.center||(touchParams.center=getPointer(t.gesture.center,e.frame));var n=1/t.gesture.scale,s=this._pointerToDate(e,i,touchParams.center),o=getPointer(t.gesture.center,e.frame),r=(this._pointerToDate(e,i,o),parseInt(s+(touchParams.start-s)*n)),a=parseInt(s+(touchParams.end-s)*n);this.setRange(r,a)}},Range.prototype._pointerToDate=function(t,e,i){var n;if("horizontal"==e){var s=t.width;return n=this.conversion(s),i.x/n.scale+n.offset}var o=t.height;return n=this.conversion(o),i.y/n.scale+n.offset},Range.prototype.zoom=function(t,e){null==e&&(e=(this.start+this.end)/2);var i=e+(this.start-e)*t,n=e+(this.end-e)*t;this.setRange(i,n)},Range.prototype.move=function(t){var e=this.end-this.start,i=this.start+e*t,n=this.end+e*t;this.start=i,this.end=n},Range.prototype.moveTo=function(t){var e=(this.start+this.end)/2,i=e-t,n=this.start-i,s=this.end-i;this.setRange(n,s)},Controller.prototype.add=function(t){if(void 0==t.id)throw new Error("Component has no field id");if(!(t instanceof Component||t instanceof Controller))throw new TypeError("Component must be an instance of prototype Component or Controller");t.controller=this,this.components[t.id]=t},Controller.prototype.remove=function(t){var e;for(e in this.components)if(this.components.hasOwnProperty(e)&&(e==t||this.components[e]==t))break;e&&delete this.components[e]},Controller.prototype.requestReflow=function(t){if(t)this.reflow();else if(!this.reflowTimer){var e=this;this.reflowTimer=setTimeout(function(){e.reflowTimer=void 0,e.reflow()},0)}},Controller.prototype.requestRepaint=function(t){if(t)this.repaint();else if(!this.repaintTimer){var e=this;this.repaintTimer=setTimeout(function(){e.repaintTimer=void 0,e.repaint()},0)}},Controller.prototype.repaint=function t(){function t(n,s){s in i||(n.depends&&n.depends.forEach(function(e){t(e,e.id)}),n.parent&&t(n.parent,n.parent.id),e=n.repaint()||e,i[s]=!0)}var e=!1;this.repaintTimer&&(clearTimeout(this.repaintTimer),this.repaintTimer=void 0);var i={};util.forEach(this.components,t),e&&this.reflow()},Controller.prototype.reflow=function e(){function e(n,s){s in i||(n.depends&&n.depends.forEach(function(t){e(t,t.id)}),n.parent&&e(n.parent,n.parent.id),t=n.reflow()||t,i[s]=!0)}var t=!1;this.reflowTimer&&(clearTimeout(this.reflowTimer),this.reflowTimer=void 0);var i={};util.forEach(this.components,e),t&&this.repaint()},Component.prototype.setOptions=function(t){t&&(util.extend(this.options,t),this.controller&&(this.requestRepaint(),this.requestReflow()))},Component.prototype.getOption=function(t){var e;return this.options&&(e=this.options[t]),void 0===e&&this.defaultOptions&&(e=this.defaultOptions[t]),e},Component.prototype.getContainer=function(){return null},Component.prototype.getFrame=function(){return this.frame},Component.prototype.repaint=function(){return!1},Component.prototype.reflow=function(){return!1},Component.prototype.hide=function(){return this.frame&&this.frame.parentNode?(this.frame.parentNode.removeChild(this.frame),!0):!1},Component.prototype.show=function(){return this.frame&&this.frame.parentNode?!1:this.repaint()},Component.prototype.requestRepaint=function(){if(!this.controller)throw new Error("Cannot request a repaint: no controller configured");this.controller.requestRepaint()},Component.prototype.requestReflow=function(){if(!this.controller)throw new Error("Cannot request a reflow: no controller configured");this.controller.requestReflow()},Panel.prototype=new Component,Panel.prototype.setOptions=Component.prototype.setOptions,Panel.prototype.getContainer=function(){return this.frame},Panel.prototype.repaint=function(){var t=0,e=util.updateProperty,i=util.option.asSize,n=this.options,s=this.frame;if(!s){s=document.createElement("div"),s.className="panel";var o=n.className;o&&("function"==typeof o?util.addClassName(s,String(o())):util.addClassName(s,String(o))),this.frame=s,t+=1}if(!s.parentNode){if(!this.parent)throw new Error("Cannot repaint panel: no parent attached");var r=this.parent.getContainer();if(!r)throw new Error("Cannot repaint panel: parent has no container element");r.appendChild(s),t+=1}return t+=e(s.style,"top",i(n.top,"0px")),t+=e(s.style,"left",i(n.left,"0px")),t+=e(s.style,"width",i(n.width,"100%")),t+=e(s.style,"height",i(n.height,"100%")),t>0},Panel.prototype.reflow=function(){var t=0,e=util.updateProperty,i=this.frame;return i?(t+=e(this,"top",i.offsetTop),t+=e(this,"left",i.offsetLeft),t+=e(this,"width",i.offsetWidth),t+=e(this,"height",i.offsetHeight)):t+=1,t>0},RootPanel.prototype=new Panel,RootPanel.prototype.setOptions=Component.prototype.setOptions,RootPanel.prototype.repaint=function(){var t=0,e=util.updateProperty,i=util.option.asSize,n=this.options,s=this.frame;if(s||(s=document.createElement("div"),this.frame=s,t+=1),!s.parentNode){if(!this.container)throw new Error("Cannot repaint root panel: no container attached");this.container.appendChild(s),t+=1}s.className="vis timeline rootpanel "+n.orientation;var o=n.className;return o&&util.addClassName(s,util.option.asString(o)),t+=e(s.style,"top",i(n.top,"0px")),t+=e(s.style,"left",i(n.left,"0px")),t+=e(s.style,"width",i(n.width,"100%")),t+=e(s.style,"height",i(n.height,"100%")),this._updateEventEmitters(),this._updateWatch(),t>0},RootPanel.prototype.reflow=function(){var t=0,e=util.updateProperty,i=this.frame;return i?(t+=e(this,"top",i.offsetTop),t+=e(this,"left",i.offsetLeft),t+=e(this,"width",i.offsetWidth),t+=e(this,"height",i.offsetHeight)):t+=1,t>0},RootPanel.prototype._updateWatch=function(){var t=this.getOption("autoResize");t?this._watch():this._unwatch()},RootPanel.prototype._watch=function(){var t=this;this._unwatch();var e=function(){var e=t.getOption("autoResize");return e?void(t.frame&&(t.frame.clientWidth!=t.width||t.frame.clientHeight!=t.height)&&t.requestReflow()):void t._unwatch()};util.addEventListener(window,"resize",e),this.watchTimer=setInterval(e,1e3)},RootPanel.prototype._unwatch=function(){this.watchTimer&&(clearInterval(this.watchTimer),this.watchTimer=void 0)},RootPanel.prototype.on=function(t,e){var i=this.listeners[t];i||(i=[],this.listeners[t]=i),i.push(e),this._updateEventEmitters()},RootPanel.prototype._updateEventEmitters=function(){if(this.listeners){var t=this;util.forEach(this.listeners,function(e,i){if(t.emitters||(t.emitters={}),!(i in t.emitters)){var n=t.frame;if(n){var s=function(t){e.forEach(function(e){e(t)})};t.emitters[i]=s,t.hammer||(t.hammer=Hammer(n,{prevent_default:!0})),t.hammer.on(i,s)}}})}},TimeAxis.prototype=new Component,TimeAxis.prototype.setOptions=Component.prototype.setOptions,TimeAxis.prototype.setRange=function(t){if(!(t instanceof Range||t&&t.start&&t.end))throw new TypeError("Range must be an instance of Range, or an object containing start and end.");this.range=t},TimeAxis.prototype.toTime=function(t){var e=this.conversion;return new Date(t/e.scale+e.offset)},TimeAxis.prototype.toScreen=function(t){var e=this.conversion;return(t.valueOf()-e.offset)*e.scale},TimeAxis.prototype.repaint=function(){var t=0,e=util.updateProperty,i=util.option.asSize,n=this.options,s=this.getOption("orientation"),o=this.props,r=this.step,a=this.frame;if(a||(a=document.createElement("div"),this.frame=a,t+=1),a.className="axis",!a.parentNode){if(!this.parent)throw new Error("Cannot repaint time axis: no parent attached");var h=this.parent.getContainer();if(!h)throw new Error("Cannot repaint time axis: parent has no container element");h.appendChild(a),t+=1}var l=a.parentNode;if(l){var c=a.nextSibling;l.removeChild(a);var d="bottom"==s&&this.props.parentHeight&&this.height?this.props.parentHeight-this.height+"px":"0px";if(t+=e(a.style,"top",i(n.top,d)),t+=e(a.style,"left",i(n.left,"0px")),t+=e(a.style,"width",i(n.width,"100%")),t+=e(a.style,"height",i(n.height,this.height+"px")),this._repaintMeasureChars(),this.step){this._repaintStart(),r.first();for(var u=void 0,p=0;r.hasNext()&&1e3>p;){p++;var f=r.getCurrent(),g=this.toScreen(f),m=r.isMajor();this.getOption("showMinorLabels")&&this._repaintMinorText(g,r.getLabelMinor()),m&&this.getOption("showMajorLabels")?(g>0&&(void 0==u&&(u=g),this._repaintMajorText(g,r.getLabelMajor())),this._repaintMajorLine(g)):this._repaintMinorLine(g),r.next()}if(this.getOption("showMajorLabels")){var v=this.toTime(0),y=r.getLabelMajor(v),_=y.length*(o.majorCharWidth||10)+10;(void 0==u||u>_)&&this._repaintMajorText(0,y)}this._repaintEnd()}this._repaintLine(),c?l.insertBefore(a,c):l.appendChild(a)}return t>0},TimeAxis.prototype._repaintStart=function(){var t=this.dom,e=t.redundant;e.majorLines=t.majorLines,e.majorTexts=t.majorTexts,e.minorLines=t.minorLines,e.minorTexts=t.minorTexts,t.majorLines=[],t.majorTexts=[],t.minorLines=[],t.minorTexts=[]},TimeAxis.prototype._repaintEnd=function(){util.forEach(this.dom.redundant,function(t){for(;t.length;){var e=t.pop();e&&e.parentNode&&e.parentNode.removeChild(e)}})},TimeAxis.prototype._repaintMinorText=function(t,e){var i=this.dom.redundant.minorTexts.shift();if(!i){var n=document.createTextNode("");i=document.createElement("div"),i.appendChild(n),i.className="text minor",this.frame.appendChild(i)}this.dom.minorTexts.push(i),i.childNodes[0].nodeValue=e,i.style.left=t+"px",i.style.top=this.props.minorLabelTop+"px"},TimeAxis.prototype._repaintMajorText=function(t,e){var i=this.dom.redundant.majorTexts.shift();if(!i){var n=document.createTextNode(e);i=document.createElement("div"),i.className="text major",i.appendChild(n),this.frame.appendChild(i)}this.dom.majorTexts.push(i),i.childNodes[0].nodeValue=e,i.style.top=this.props.majorLabelTop+"px",i.style.left=t+"px"},TimeAxis.prototype._repaintMinorLine=function(t){var e=this.dom.redundant.minorLines.shift();e||(e=document.createElement("div"),e.className="grid vertical minor",this.frame.appendChild(e)),this.dom.minorLines.push(e);var i=this.props;e.style.top=i.minorLineTop+"px",e.style.height=i.minorLineHeight+"px",e.style.left=t-i.minorLineWidth/2+"px"},TimeAxis.prototype._repaintMajorLine=function(t){var e=this.dom.redundant.majorLines.shift();e||(e=document.createElement("DIV"),e.className="grid vertical major",this.frame.appendChild(e)),this.dom.majorLines.push(e);var i=this.props;e.style.top=i.majorLineTop+"px",e.style.left=t-i.majorLineWidth/2+"px",e.style.height=i.majorLineHeight+"px"},TimeAxis.prototype._repaintLine=function(){{var t=this.dom.line,e=this.frame;this.options}this.getOption("showMinorLabels")||this.getOption("showMajorLabels")?(t?(e.removeChild(t),e.appendChild(t)):(t=document.createElement("div"),t.className="grid horizontal major",e.appendChild(t),this.dom.line=t),t.style.top=this.props.lineTop+"px"):t&&t.parentElement&&(e.removeChild(t.line),delete this.dom.line)},TimeAxis.prototype._repaintMeasureChars=function(){var t,e=this.dom;if(!e.measureCharMinor){t=document.createTextNode("0");var i=document.createElement("DIV");i.className="text minor measure",i.appendChild(t),this.frame.appendChild(i),e.measureCharMinor=i}if(!e.measureCharMajor){t=document.createTextNode("0");var n=document.createElement("DIV");n.className="text major measure",n.appendChild(t),this.frame.appendChild(n),e.measureCharMajor=n}},TimeAxis.prototype.reflow=function(){var t=0,e=util.updateProperty,i=this.frame,n=this.range;if(!n)throw new Error("Cannot repaint time axis: no range configured");if(i){t+=e(this,"top",i.offsetTop),t+=e(this,"left",i.offsetLeft);var s=this.props,o=this.getOption("showMinorLabels"),r=this.getOption("showMajorLabels"),a=this.dom.measureCharMinor,h=this.dom.measureCharMajor;a&&(s.minorCharHeight=a.clientHeight,s.minorCharWidth=a.clientWidth),h&&(s.majorCharHeight=h.clientHeight,s.majorCharWidth=h.clientWidth);var l=i.parentNode?i.parentNode.offsetHeight:0;switch(l!=s.parentHeight&&(s.parentHeight=l,t+=1),this.getOption("orientation")){case"bottom":s.minorLabelHeight=o?s.minorCharHeight:0,s.majorLabelHeight=r?s.majorCharHeight:0,s.minorLabelTop=0,s.majorLabelTop=s.minorLabelTop+s.minorLabelHeight,s.minorLineTop=-this.top,s.minorLineHeight=Math.max(this.top+s.majorLabelHeight,0),s.minorLineWidth=1,s.majorLineTop=-this.top,s.majorLineHeight=Math.max(this.top+s.minorLabelHeight+s.majorLabelHeight,0),s.majorLineWidth=1,s.lineTop=0;break;case"top":s.minorLabelHeight=o?s.minorCharHeight:0,s.majorLabelHeight=r?s.majorCharHeight:0,s.majorLabelTop=0,s.minorLabelTop=s.majorLabelTop+s.majorLabelHeight,s.minorLineTop=s.minorLabelTop,s.minorLineHeight=Math.max(l-s.majorLabelHeight-this.top),s.minorLineWidth=1,s.majorLineTop=0,s.majorLineHeight=Math.max(l-this.top),s.majorLineWidth=1,s.lineTop=s.majorLabelHeight+s.minorLabelHeight;break;default:throw new Error('Unkown orientation "'+this.getOption("orientation")+'"')}var c=s.minorLabelHeight+s.majorLabelHeight;t+=e(this,"width",i.offsetWidth),t+=e(this,"height",c),this._updateConversion();var d=util.convert(n.start,"Number"),u=util.convert(n.end,"Number"),p=this.toTime(5*(s.minorCharWidth||10)).valueOf()-this.toTime(0).valueOf();this.step=new TimeStep(new Date(d),new Date(u),p),t+=e(s.range,"start",d),t+=e(s.range,"end",u),t+=e(s.range,"minimumStep",p.valueOf())}return t>0},TimeAxis.prototype._updateConversion=function(){var t=this.range;if(!t)throw new Error("No range configured");this.conversion=t.conversion?t.conversion(this.width):Range.conversion(t.start,t.end,this.width)},CurrentTime.prototype=new Component,CurrentTime.prototype.setOptions=Component.prototype.setOptions,CurrentTime.prototype.getContainer=function(){return this.frame},CurrentTime.prototype.repaint=function(){var t=this.frame,e=this.parent,i=e.parent.getContainer();if(!e)throw new Error("Cannot repaint bar: no parent attached");if(!i)throw new Error("Cannot repaint bar: parent has no container element");if(!this.getOption("showCurrentTime"))return void(t&&(i.removeChild(t),delete this.frame));t||(t=document.createElement("div"),t.className="currenttime",t.style.position="absolute",t.style.top="0px",t.style.height="100%",i.appendChild(t),this.frame=t),e.conversion||e._updateConversion();var n=new Date,s=e.toScreen(n);t.style.left=s+"px",t.title="Current time: "+n,void 0!==this.currentTimeTimer&&(clearTimeout(this.currentTimeTimer),delete this.currentTimeTimer);var o=this,r=1/e.conversion.scale/2;return 30>r&&(r=30),this.currentTimeTimer=setTimeout(function(){o.repaint()},r),!1},CustomTime.prototype=new Component,CustomTime.prototype.setOptions=Component.prototype.setOptions,CustomTime.prototype.getContainer=function(){return this.frame},CustomTime.prototype.repaint=function(){var t=this.frame,e=this.parent,i=e.parent.getContainer();if(!e)throw new Error("Cannot repaint bar: no parent attached");if(!i)throw new Error("Cannot repaint bar: parent has no container element");if(!this.getOption("showCustomTime"))return void(t&&(i.removeChild(t),delete this.frame));if(!t){t=document.createElement("div"),t.className="customtime",t.style.position="absolute",t.style.top="0px",t.style.height="100%",i.appendChild(t);var n=document.createElement("div");n.style.position="relative",n.style.top="0px",n.style.left="-10px",n.style.height="100%",n.style.width="20px",t.appendChild(n),this.frame=t,this.subscribe(this,"movetime")}e.conversion||e._updateConversion();var s=e.toScreen(this.customTime);return t.style.left=s+"px",t.title="Time: "+this.customTime,!1},CustomTime.prototype._setCustomTime=function(t){this.customTime=new Date(t.valueOf()),this.repaint()},CustomTime.prototype._getCustomTime=function(){return new Date(this.customTime.valueOf())},CustomTime.prototype.subscribe=function(t,e){var i=this,n={component:t,event:e,callback:function(t){i._onMouseDown(t,n)},params:{}};t.on("mousedown",n.callback),i.listeners.push(n)},CustomTime.prototype.on=function(t,e){var i=this.frame;if(!i)throw new Error("Cannot add event listener: no parent attached");events.addListener(this,t,e),util.addEventListener(i,t,e)},CustomTime.prototype._onMouseDown=function(t,e){t=t||window.event;var i=e.params,n=t.which?1==t.which:1==t.button;if(n){i.mouseX=util.getPageX(t),i.moved=!1,i.customTime=this.customTime;var s=this;i.onMouseMove||(i.onMouseMove=function(t){s._onMouseMove(t,e)},util.addEventListener(document,"mousemove",i.onMouseMove)),i.onMouseUp||(i.onMouseUp=function(t){s._onMouseUp(t,e)},util.addEventListener(document,"mouseup",i.onMouseUp)),util.stopPropagation(t),util.preventDefault(t)}},CustomTime.prototype._onMouseMove=function(t,e){t=t||window.event;var i=e.params,n=this.parent,s=util.getPageX(t);void 0===i.mouseX&&(i.mouseX=s);var o=s-i.mouseX;Math.abs(o)>=1&&(i.moved=!0);var r=n.toScreen(i.customTime),a=r+o,h=n.toTime(a);this._setCustomTime(h),events.trigger(this,"timechange",{customTime:this.customTime}),util.preventDefault(t)},CustomTime.prototype._onMouseUp=function(t,e){t=t||window.event;var i=e.params;i.onMouseMove&&(util.removeEventListener(document,"mousemove",i.onMouseMove),i.onMouseMove=null),i.onMouseUp&&(util.removeEventListener(document,"mouseup",i.onMouseUp),i.onMouseUp=null),i.moved&&events.trigger(this,"timechanged",{customTime:this.customTime}) -},ItemSet.prototype=new Panel,ItemSet.types={box:ItemBox,range:ItemRange,rangeoverflow:ItemRangeOverflow,point:ItemPoint},ItemSet.prototype.setOptions=Component.prototype.setOptions,ItemSet.prototype.setRange=function(t){if(!(t instanceof Range||t&&t.start&&t.end))throw new TypeError("Range must be an instance of Range, or an object containing start and end.");this.range=t},ItemSet.prototype.setSelection=function(t){var e,i,n,s,o;if(t){if(!Array.isArray(t))throw new TypeError("Array expected");for(e=0,i=this.selection.length;i>e;e++)n=this.selection[e],s=this.items[n],s&&s.unselect();for(this.selection=[],e=0,i=t.length;i>e;e++)n=t[e],s=this.items[n],s&&(this.selection.push(n),s.select());o=this.selection.concat([]),events.trigger(this,"select",{ids:o}),this.controller&&this.requestRepaint()}},ItemSet.prototype.getSelection=function(){return this.selection.concat([])},ItemSet.prototype._deselect=function(t){for(var e=this.selection,i=0,n=e.length;n>i;i++)if(e[i]==t){e.splice(i,1);break}},ItemSet.prototype.repaint=function(){var t=0,e=util.updateProperty,i=util.option.asSize,n=this.options,s=this.getOption("orientation"),o=this.defaultOptions,r=this.frame;if(!r){r=document.createElement("div"),r.className="itemset";var a=n.className;a&&util.addClassName(r,util.option.asString(a));var h=document.createElement("div");h.className="background",r.appendChild(h),this.dom.background=h;var l=document.createElement("div");l.className="foreground",r.appendChild(l),this.dom.foreground=l;var c=document.createElement("div");c.className="itemset-axis",this.dom.axis=c,this.frame=r,t+=1}if(!this.parent)throw new Error("Cannot repaint itemset: no parent attached");var d=this.parent.getContainer();if(!d)throw new Error("Cannot repaint itemset: parent has no container element");r.parentNode||(d.appendChild(r),t+=1),this.dom.axis.parentNode||(d.appendChild(this.dom.axis),t+=1),t+=e(r.style,"left",i(n.left,"0px")),t+=e(r.style,"top",i(n.top,"0px")),t+=e(r.style,"width",i(n.width,"100%")),t+=e(r.style,"height",i(n.height,this.height+"px")),t+=e(this.dom.axis.style,"left",i(n.left,"0px")),t+=e(this.dom.axis.style,"width",i(n.width,"100%")),t+="bottom"==s?e(this.dom.axis.style,"top",this.height+this.top+"px"):e(this.dom.axis.style,"top",this.top+"px"),this._updateConversion();var u=this,p=this.queue,f=this.itemsData,g=this.items,m={};for(var v in p)if(p.hasOwnProperty(v)){var y=p[v],_=g[v],b=y.action;switch(b){case"add":case"update":var w=f&&f.get(v,m);if(w){var S=w.type||w.start&&w.end&&"range"||n.type||"box",T=ItemSet.types[S];if(_&&(T&&_ instanceof T?(_.data=w,t++):(t+=_.hide(),_=null)),!_){if(!T)throw new TypeError('Unknown item type "'+S+'"');_=new T(u,w,n,o),_.id=y.id,t++}_.repaint(),g[v]=_}delete p[v];break;case"remove":_&&(_.selected&&u._deselect(v),t+=_.hide()),delete g[v],delete p[v];break;default:console.log('Error: unknown action "'+b+'"')}}return util.forEach(this.items,function(e){e.visible?(t+=e.show(),e.reposition()):t+=e.hide()}),t>0},ItemSet.prototype.getForeground=function(){return this.dom.foreground},ItemSet.prototype.getBackground=function(){return this.dom.background},ItemSet.prototype.getAxis=function(){return this.dom.axis},ItemSet.prototype.reflow=function(){var t=0,e=this.options,i=e.margin&&e.margin.axis||this.defaultOptions.margin.axis,n=e.margin&&e.margin.item||this.defaultOptions.margin.item,s=util.updateProperty,o=util.option.asNumber,r=util.option.asSize,a=this.frame;if(a){this._updateConversion(),util.forEach(this.items,function(e){t+=e.reflow()}),this.stack.update();var h,l=o(e.maxHeight),c=null!=r(e.height);if(c)h=a.offsetHeight;else{var d=this.stack.ordered;if(d.length){var u=d[0].top,p=d[0].top+d[0].height;util.forEach(d,function(t){u=Math.min(u,t.top),p=Math.max(p,t.top+t.height)}),h=p-u+i+n}else h=i+n}null!=l&&(h=Math.min(h,l)),t+=s(this,"height",h),t+=s(this,"top",a.offsetTop),t+=s(this,"left",a.offsetLeft),t+=s(this,"width",a.offsetWidth)}else t+=1;return t>0},ItemSet.prototype.hide=function(){var t=!1;return this.frame&&this.frame.parentNode&&(this.frame.parentNode.removeChild(this.frame),t=!0),this.dom.axis&&this.dom.axis.parentNode&&(this.dom.axis.parentNode.removeChild(this.dom.axis),t=!0),t},ItemSet.prototype.setItems=function(t){var e,i=this,n=this.itemsData;if(t){if(!(t instanceof DataSet||t instanceof DataView))throw new TypeError("Data must be an instance of DataSet");this.itemsData=t}else this.itemsData=null;if(n&&(util.forEach(this.listeners,function(t,e){n.unsubscribe(e,t)}),e=n.getIds(),this._onRemove(e)),this.itemsData){var s=this.id;util.forEach(this.listeners,function(t,e){i.itemsData.subscribe(e,t,s)}),e=this.itemsData.getIds(),this._onAdd(e)}},ItemSet.prototype.getItems=function(){return this.itemsData},ItemSet.prototype._onUpdate=function(t){this._toQueue("update",t)},ItemSet.prototype._onAdd=function(t){this._toQueue("add",t)},ItemSet.prototype._onRemove=function(t){this._toQueue("remove",t)},ItemSet.prototype._toQueue=function(t,e){var i=this.queue;e.forEach(function(e){i[e]={id:e,action:t}}),this.controller&&this.requestRepaint()},ItemSet.prototype._updateConversion=function(){var t=this.range;if(!t)throw new Error("No range configured");this.conversion=t.conversion?t.conversion(this.width):Range.conversion(t.start,t.end,this.width)},ItemSet.prototype.toTime=function(t){var e=this.conversion;return new Date(t/e.scale+e.offset)},ItemSet.prototype.toScreen=function(t){var e=this.conversion;return(t.valueOf()-e.offset)*e.scale},Item.prototype.select=function(){this.selected=!0,this.visible&&this.repaint()},Item.prototype.unselect=function(){this.selected=!1,this.visible&&this.repaint()},Item.prototype.show=function(){return!1},Item.prototype.hide=function(){return!1},Item.prototype.repaint=function(){return!1},Item.prototype.reflow=function(){return!1},Item.prototype.getWidth=function(){return this.width},ItemBox.prototype=new Item(null,null),ItemBox.prototype.repaint=function(){var t=!1,e=this.dom;if(e||(this._create(),e=this.dom,t=!0),e){if(!this.parent)throw new Error("Cannot repaint item: no parent attached");if(!e.box.parentNode){var i=this.parent.getForeground();if(!i)throw new Error("Cannot repaint time axis: parent has no foreground container element");i.appendChild(e.box),t=!0}if(!e.line.parentNode){var n=this.parent.getBackground();if(!n)throw new Error("Cannot repaint time axis: parent has no background container element");n.appendChild(e.line),t=!0}if(!e.dot.parentNode){var s=this.parent.getAxis();if(!n)throw new Error("Cannot repaint time axis: parent has no axis container element");s.appendChild(e.dot),t=!0}if(this.data.content!=this.content){if(this.content=this.data.content,this.content instanceof Element)e.content.innerHTML="",e.content.appendChild(this.content);else{if(void 0==this.data.content)throw new Error('Property "content" missing in item '+this.data.id);e.content.innerHTML=this.content}t=!0}var o=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");this.className!=o&&(this.className=o,e.box.className="item box"+o,e.line.className="item line"+o,e.dot.className="item dot"+o,t=!0)}return t},ItemBox.prototype.show=function(){return this.dom&&this.dom.box.parentNode?!1:this.repaint()},ItemBox.prototype.hide=function(){var t=!1,e=this.dom;return e&&(e.box.parentNode&&(e.box.parentNode.removeChild(e.box),t=!0),e.line.parentNode&&e.line.parentNode.removeChild(e.line),e.dot.parentNode&&e.dot.parentNode.removeChild(e.dot)),t},ItemBox.prototype.reflow=function(){var t,e,i,n,s,o,r,a,h,l,c,d,u=0;if(void 0==this.data.start)throw new Error('Property "start" missing in item '+this.data.id);if(c=this.data,d=this.parent&&this.parent.range,c&&d){var p=d.end-d.start;this.visible=c.start>d.start-p&&c.start0},ItemBox.prototype._create=function(){var t=this.dom;t||(this.dom=t={},t.box=document.createElement("DIV"),t.content=document.createElement("DIV"),t.content.className="content",t.box.appendChild(t.content),t.line=document.createElement("DIV"),t.line.className="line",t.dot=document.createElement("DIV"),t.dot.className="dot",t.box["timeline-item"]=this)},ItemBox.prototype.reposition=function(){var t=this.dom,e=this.props,i=this.options.orientation||this.defaultOptions.orientation;if(t){var n=t.box,s=t.line,o=t.dot;n.style.left=this.left+"px",n.style.top=this.top+"px",s.style.left=e.line.left+"px","top"==i?(s.style.top="0px",s.style.height=this.top+"px"):(s.style.top=this.top+this.height+"px",s.style.height=Math.max(this.parent.height-this.top-this.height+this.props.dot.height/2,0)+"px"),o.style.left=e.dot.left+"px",o.style.top=e.dot.top+"px"}},ItemPoint.prototype=new Item(null,null),ItemPoint.prototype.repaint=function(){var t=!1,e=this.dom;if(e||(this._create(),e=this.dom,t=!0),e){if(!this.parent)throw new Error("Cannot repaint item: no parent attached");var i=this.parent.getForeground();if(!i)throw new Error("Cannot repaint time axis: parent has no foreground container element");if(e.point.parentNode||(i.appendChild(e.point),i.appendChild(e.point),t=!0),this.data.content!=this.content){if(this.content=this.data.content,this.content instanceof Element)e.content.innerHTML="",e.content.appendChild(this.content);else{if(void 0==this.data.content)throw new Error('Property "content" missing in item '+this.data.id);e.content.innerHTML=this.content}t=!0}var n=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");this.className!=n&&(this.className=n,e.point.className="item point"+n,t=!0)}return t},ItemPoint.prototype.show=function(){return this.dom&&this.dom.point.parentNode?!1:this.repaint()},ItemPoint.prototype.hide=function(){var t=!1,e=this.dom;return e&&e.point.parentNode&&(e.point.parentNode.removeChild(e.point),t=!0),t},ItemPoint.prototype.reflow=function(){var t,e,i,n,s,o,r,a,h,l,c=0;if(void 0==this.data.start)throw new Error('Property "start" missing in item '+this.data.id);if(h=this.data,l=this.parent&&this.parent.range,h&&l){var d=l.end-l.start;this.visible=h.start>l.start-d&&h.start0},ItemPoint.prototype._create=function(){var t=this.dom;t||(this.dom=t={},t.point=document.createElement("div"),t.content=document.createElement("div"),t.content.className="content",t.point.appendChild(t.content),t.dot=document.createElement("div"),t.dot.className="dot",t.point.appendChild(t.dot),t.point["timeline-item"]=this)},ItemPoint.prototype.reposition=function(){var t=this.dom,e=this.props;t&&(t.point.style.top=this.top+"px",t.point.style.left=this.left+"px",t.content.style.marginLeft=e.content.marginLeft+"px",t.dot.style.top=e.dot.top+"px")},ItemRange.prototype=new Item(null,null),ItemRange.prototype.repaint=function(){var t=!1,e=this.dom;if(e||(this._create(),e=this.dom,t=!0),e){if(!this.parent)throw new Error("Cannot repaint item: no parent attached");var i=this.parent.getForeground();if(!i)throw new Error("Cannot repaint time axis: parent has no foreground container element");if(e.box.parentNode||(i.appendChild(e.box),t=!0),this.data.content!=this.content){if(this.content=this.data.content,this.content instanceof Element)e.content.innerHTML="",e.content.appendChild(this.content);else{if(void 0==this.data.content)throw new Error('Property "content" missing in item '+this.data.id);e.content.innerHTML=this.content}t=!0}var n=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");this.className!=n&&(this.className=n,e.box.className="item range"+n,t=!0)}return t},ItemRange.prototype.show=function(){return this.dom&&this.dom.box.parentNode?!1:this.repaint()},ItemRange.prototype.hide=function(){var t=!1,e=this.dom;return e&&e.box.parentNode&&(e.box.parentNode.removeChild(e.box),t=!0),t},ItemRange.prototype.reflow=function(){var t,e,i,n,s,o,r,a,h,l,c,d,u,p,f,g,m=0;if(void 0==this.data.start)throw new Error('Property "start" missing in item '+this.data.id);if(void 0==this.data.end)throw new Error('Property "end" missing in item '+this.data.id);return h=this.data,l=this.parent&&this.parent.range,this.visible=h&&l?h.startl.start:!1,this.visible&&(t=this.dom,t?(e=this.props,i=this.options,o=this.parent,r=o.toScreen(this.data.start),a=o.toScreen(this.data.end),c=util.updateProperty,d=t.box,u=o.width,f=i.orientation||this.defaultOptions.orientation,n=i.margin&&i.margin.axis||this.defaultOptions.margin.axis,s=i.padding||this.defaultOptions.padding,m+=c(e.content,"width",t.content.offsetWidth),m+=c(this,"height",d.offsetHeight),-u>r&&(r=-u),a>2*u&&(a=2*u),p=0>r?Math.min(-r,a-r-e.content.width-2*s):0,m+=c(e.content,"left",p),"top"==f?(g=n,m+=c(this,"top",g)):(g=o.height-this.height-n,m+=c(this,"top",g)),m+=c(this,"left",r),m+=c(this,"width",Math.max(a-r,1))):m+=1),m>0},ItemRange.prototype._create=function(){var t=this.dom;t||(this.dom=t={},t.box=document.createElement("div"),t.content=document.createElement("div"),t.content.className="content",t.box.appendChild(t.content),t.box["timeline-item"]=this)},ItemRange.prototype.reposition=function(){var t=this.dom,e=this.props;t&&(t.box.style.top=this.top+"px",t.box.style.left=this.left+"px",t.box.style.width=this.width+"px",t.content.style.left=e.content.left+"px")},ItemRangeOverflow.prototype=new ItemRange(null,null),ItemRangeOverflow.prototype.repaint=function(){var t=!1,e=this.dom;if(e||(this._create(),e=this.dom,t=!0),e){if(!this.parent)throw new Error("Cannot repaint item: no parent attached");var i=this.parent.getForeground();if(!i)throw new Error("Cannot repaint time axis: parent has no foreground container element");if(e.box.parentNode||(i.appendChild(e.box),t=!0),this.data.content!=this.content){if(this.content=this.data.content,this.content instanceof Element)e.content.innerHTML="",e.content.appendChild(this.content);else{if(void 0==this.data.content)throw new Error('Property "content" missing in item '+this.data.id);e.content.innerHTML=this.content}t=!0}var n=this.data.className?" "+this.data.className:"";this.className!=n&&(this.className=n,e.box.className="item rangeoverflow"+n,t=!0)}return t},ItemRangeOverflow.prototype.getWidth=function(){return void 0!==this.props.content&&this.width0},GroupSet.prototype=new Panel,GroupSet.prototype.setOptions=Component.prototype.setOptions,GroupSet.prototype.setRange=function(){},GroupSet.prototype.setItems=function(t){this.itemsData=t;for(var e in this.groups)if(this.groups.hasOwnProperty(e)){var i=this.groups[e];i.setItems(t)}},GroupSet.prototype.getItems=function(){return this.itemsData},GroupSet.prototype.setRange=function(t){this.range=t},GroupSet.prototype.setGroups=function(t){var e,i=this;if(this.groupsData&&(util.forEach(this.listeners,function(t,e){i.groupsData.unsubscribe(e,t)}),e=this.groupsData.getIds(),this._onRemove(e)),t?t instanceof DataSet?this.groupsData=t:(this.groupsData=new DataSet({convert:{start:"Date",end:"Date"}}),this.groupsData.add(t)):this.groupsData=null,this.groupsData){var n=this.id;util.forEach(this.listeners,function(t,e){i.groupsData.subscribe(e,t,n)}),e=this.groupsData.getIds(),this._onAdd(e)}},GroupSet.prototype.getGroups=function(){return this.groupsData},GroupSet.prototype.setSelection=function(t){var e=[],i=this.groups;for(var n in i)if(i.hasOwnProperty(n)){var s=i[n];s.setSelection(t)}return e},GroupSet.prototype.getSelection=function(){var t=[],e=this.groups;for(var i in e)if(e.hasOwnProperty(i)){var n=e[i];t=t.concat(n.getSelection())}return t},GroupSet.prototype.repaint=function(){var t,e,i,n,s=0,o=util.updateProperty,r=util.option.asSize,a=util.option.asElement,h=this.options,l=this.dom.frame,c=this.dom.labels,d=this.dom.labelSet;if(!this.parent)throw new Error("Cannot repaint groupset: no parent attached");var u=this.parent.getContainer();if(!u)throw new Error("Cannot repaint groupset: parent has no container element");if(!l){l=document.createElement("div"),l.className="groupset",this.dom.frame=l;var p=h.className;p&&util.addClassName(l,util.option.asString(p)),s+=1}l.parentNode||(u.appendChild(l),s+=1);var f=a(h.labelContainer);if(!f)throw new Error('Cannot repaint groupset: option "labelContainer" not defined');c||(c=document.createElement("div"),c.className="labels",this.dom.labels=c),d||(d=document.createElement("div"),d.className="label-set",c.appendChild(d),this.dom.labelSet=d),c.parentNode&&c.parentNode==f||(c.parentNode&&c.parentNode.removeChild(c.parentNode),f.appendChild(c)),s+=o(l.style,"height",r(h.height,this.height+"px")),s+=o(l.style,"top",r(h.top,"0px")),s+=o(l.style,"left",r(h.left,"0px")),s+=o(l.style,"width",r(h.width,"100%")),s+=o(d.style,"top",r(h.top,"0px")),s+=o(d.style,"height",r(h.height,this.height+"px"));var g=this,m=this.queue,v=this.groups,y=this.groupsData,_=Object.keys(m);if(_.length){_.forEach(function(t){var e=m[t],i=v[t];switch(e){case"add":case"update":if(!i){var n=Object.create(g.options);util.extend(n,{height:null,maxHeight:null}),i=new Group(g,t,n),i.setItems(g.itemsData),v[t]=i,g.controller.add(i)}i.data=y.get(t),delete m[t];break;case"remove":i&&(i.setItems(),delete v[t],g.controller.remove(i)),delete m[t];break;default:console.log('Error: unknown action "'+e+'"')}});var b=this.groupsData.getIds({order:this.options.groupOrder});for(t=0;t0},GroupSet.prototype._createLabel=function(t){var e=this.groups[t],i=document.createElement("div");i.className="label";var n=document.createElement("div");n.className="inner",i.appendChild(n);var s=e.data&&e.data.content;s instanceof Element?n.appendChild(s):void 0!=s&&(n.innerHTML=s);var o=e.data&&e.data.className;return o&&util.addClassName(i,o),e.label=i,i},GroupSet.prototype.getContainer=function(){return this.dom.frame},GroupSet.prototype.getLabelsWidth=function(){return this.props.labels.width},GroupSet.prototype.reflow=function(){var t,e,i=0,n=this.options,s=util.updateProperty,o=util.option.asNumber,r=util.option.asSize,a=this.dom.frame;if(a){var h,l=o(n.maxHeight),c=null!=r(n.height);if(c)h=a.offsetHeight;else{h=0;for(t in this.groups)this.groups.hasOwnProperty(t)&&(e=this.groups[t],h+=e.height)}null!=l&&(h=Math.min(h,l)),i+=s(this,"height",h),i+=s(this,"top",a.offsetTop),i+=s(this,"left",a.offsetLeft),i+=s(this,"width",a.offsetWidth)}var d=0;for(t in this.groups)if(this.groups.hasOwnProperty(t)){e=this.groups[t];var u=e.props&&e.props.label&&e.props.label.width||0;d=Math.max(d,u)}return i+=s(this.props.labels,"width",d),i>0},GroupSet.prototype.hide=function(){return this.dom.frame&&this.dom.frame.parentNode?(this.dom.frame.parentNode.removeChild(this.dom.frame),!0):!1},GroupSet.prototype.show=function(){return this.dom.frame&&this.dom.frame.parentNode?!1:this.repaint()},GroupSet.prototype._onUpdate=function(t){this._toQueue(t,"update")},GroupSet.prototype._onAdd=function(t){this._toQueue(t,"add")},GroupSet.prototype._onRemove=function(t){this._toQueue(t,"remove")},GroupSet.prototype._toQueue=function(t,e){var i=this.queue;t.forEach(function(t){i[t]=e}),this.controller&&this.requestRepaint()},Timeline.prototype.setOptions=function(t){util.extend(this.options,t),this.range.setRange(t.start,t.end),this.controller.reflow(),this.controller.repaint()},Timeline.prototype.setCustomTime=function(t){this.customtime._setCustomTime(t)},Timeline.prototype.getCustomTime=function(){return new Date(this.customtime.customTime.valueOf())},Timeline.prototype.setItems=function(t){var e,i=null==this.itemsData;if(t?t instanceof DataSet&&(e=t):e=null,t instanceof DataSet||(e=new DataSet({convert:{start:"Date",end:"Date"}}),e.add(t)),this.itemsData=e,this.content.setItems(e),i&&(void 0==this.options.start||void 0==this.options.end)){var n=this.getItemRange(),s=n.min,o=n.max;if(null!=s&&null!=o){var r=o.valueOf()-s.valueOf();0>=r&&(r=864e5),s=new Date(s.valueOf()-.05*r),o=new Date(o.valueOf()+.05*r)}void 0!=this.options.start&&(s=util.convert(this.options.start,"Date")),void 0!=this.options.end&&(o=util.convert(this.options.end,"Date")),(null!=s||null!=o)&&this.range.setRange(s,o)}},Timeline.prototype.setGroups=function(t){var e=this;this.groupsData=t;var i=this.groupsData?GroupSet:ItemSet;if(!(this.content instanceof i)){this.content&&(this.content.hide(),this.content.setItems&&this.content.setItems(),this.content.setGroups&&this.content.setGroups(),this.controller.remove(this.content));var n=Object.create(this.options);util.extend(n,{top:function(){return"top"==e.options.orientation?e.timeaxis.height:e.itemPanel.height-e.timeaxis.height-e.content.height},left:null,width:"100%",height:function(){return e.options.height?e.itemPanel.height-e.timeaxis.height:null},maxHeight:function(){if(e.options.maxHeight){if(!util.isNumber(e.options.maxHeight))throw new TypeError("Number expected for property maxHeight");return e.options.maxHeight-e.timeaxis.height}return null},labelContainer:function(){return e.labelPanel.getContainer()}}),this.content=new i(this.itemPanel,[this.timeaxis],n),this.content.setRange&&this.content.setRange(this.range),this.content.setItems&&this.content.setItems(this.itemsData),this.content.setGroups&&this.content.setGroups(this.groupsData),this.controller.add(this.content)}},Timeline.prototype.getItemRange=function(){var t=this.itemsData,e=null,i=null;if(t){var n=t.min("start");e=n?n.start.valueOf():null;var s=t.max("start");s&&(i=s.start.valueOf());var o=t.max("end");o&&(i=null==i?o.end.valueOf():Math.max(i,o.end.valueOf()))}return{min:null!=e?new Date(e):null,max:null!=i?new Date(i):null}},Timeline.prototype.setSelection=function(t){this.content&&this.content.setSelection(t)},Timeline.prototype.getSelection=function(){return this.content?this.content.getSelection():[]},Timeline.prototype.on=function(t,e){var i=["rangechange","rangechanged","select"];if(-1==i.indexOf(t))throw new Error('Unknown event "'+t+'". Choose from '+i.join());events.addListener(this,t,e)},Timeline.prototype.off=function(t,e){events.removeListener(this,t,e)},Timeline.prototype._trigger=function(t,e){events.trigger(this,t,e||{})},Timeline.prototype._onSelectItem=function(t){var e=this._itemFromTarget(t),i=e?[e.id]:[];this.setSelection(i),this._trigger("select",{items:this.getSelection()}),t.stopPropagation()},Timeline.prototype._onMultiSelectItem=function(t){var e,i=this._itemFromTarget(t);if(i){e=this.getSelection();var n=e.indexOf(i.id);-1==n?e.push(i.id):e.splice(n,1),this.setSelection(e),this._trigger("select",{items:this.getSelection()}),t.stopPropagation()}},Timeline.prototype._itemFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-item"))return e["timeline-item"];e=e.parentNode}return null},function(t){function e(t){return C=t,u()}function i(){M=0,D=C.charAt(0)}function n(){M++,D=C.charAt(M)}function s(){return C.charAt(M+1)}function o(t){return O.test(t)}function r(t,e){if(t||(t={}),e)for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}function a(t,e,i){for(var n=e.split("."),s=t;n.length;){var o=n.shift();n.length?(s[o]||(s[o]={}),s=s[o]):s[o]=i}}function h(t,e){for(var i,n,s=null,o=[t],a=t;a.parent;)o.push(a.parent),a=a.parent;if(a.nodes)for(i=0,n=a.nodes.length;n>i;i++)if(e.id===a.nodes[i].id){s=a.nodes[i];break}for(s||(s={id:e.id},t.node&&(s.attr=r(s.attr,t.node))),i=o.length-1;i>=0;i--){var h=o[i];h.nodes||(h.nodes=[]),-1==h.nodes.indexOf(s)&&h.nodes.push(s)}e.attr&&(s.attr=r(s.attr,e.attr))}function l(t,e){if(t.edges||(t.edges=[]),t.edges.push(e),t.edge){var i=r({},t.edge);e.attr=r(i,e.attr)}}function c(t,e,i,n,s){var o={from:e,to:i,type:n};return t.edge&&(o.attr=r({},t.edge)),o.attr=r(o.attr||{},s),o}function d(){for(N=E.NULL,I="";" "==D||" "==D||"\n"==D||"\r"==D;)n();do{var t=!1;if("#"==D){for(var e=M-1;" "==C.charAt(e)||" "==C.charAt(e);)e--;if("\n"==C.charAt(e)||""==C.charAt(e)){for(;""!=D&&"\n"!=D;)n();t=!0}}if("/"==D&&"/"==s()){for(;""!=D&&"\n"!=D;)n();t=!0}if("/"==D&&"*"==s()){for(;""!=D;){if("*"==D&&"/"==s()){n(),n();break}n()}t=!0}for(;" "==D||" "==D||"\n"==D||"\r"==D;)n()}while(t);if(""==D)return void(N=E.DELIMITER);var i=D+s();if(x[i])return N=E.DELIMITER,I=i,n(),void n();if(x[D])return N=E.DELIMITER,I=D,void n();if(o(D)||"-"==D){for(I+=D,n();o(D);)I+=D,n();return"false"==I?I=!1:"true"==I?I=!0:isNaN(Number(I))||(I=Number(I)),void(N=E.IDENTIFIER)}if('"'==D){for(n();""!=D&&('"'!=D||'"'==D&&'"'==s());)I+=D,'"'==D&&n(),n();if('"'!=D)throw b('End of string " expected');return n(),void(N=E.IDENTIFIER)}for(N=E.UNKNOWN;""!=D;)I+=D,n();throw new SyntaxError('Syntax error in part "'+w(I,30)+'"')}function u(){var t={};if(i(),d(),"strict"==I&&(t.strict=!0,d()),("graph"==I||"digraph"==I)&&(t.type=I,d()),N==E.IDENTIFIER&&(t.id=I,d()),"{"!=I)throw b("Angle bracket { expected");if(d(),p(t),"}"!=I)throw b("Angle bracket } expected");if(d(),""!==I)throw b("End of file expected");return d(),delete t.node,delete t.edge,delete t.graph,t}function p(t){for(;""!==I&&"}"!=I;)f(t),";"==I&&d()}function f(t){var e=g(t);if(e)return void y(t,e);var i=m(t);if(!i){if(N!=E.IDENTIFIER)throw b("Identifier expected");var n=I;if(d(),"="==I){if(d(),N!=E.IDENTIFIER)throw b("Identifier expected");t[n]=I,d()}else v(t,n)}}function g(t){var e=null;if("subgraph"==I&&(e={},e.type="subgraph",d(),N==E.IDENTIFIER&&(e.id=I,d())),"{"==I){if(d(),e||(e={}),e.parent=t,e.node=t.node,e.edge=t.edge,e.graph=t.graph,p(e),"}"!=I)throw b("Angle bracket } expected");d(),delete e.node,delete e.edge,delete e.graph,delete e.parent,t.subgraphs||(t.subgraphs=[]),t.subgraphs.push(e)}return e}function m(t){return"node"==I?(d(),t.node=_(),"node"):"edge"==I?(d(),t.edge=_(),"edge"):"graph"==I?(d(),t.graph=_(),"graph"):null}function v(t,e){var i={id:e},n=_();n&&(i.attr=n),h(t,i),y(t,e)}function y(t,e){for(;"->"==I||"--"==I;){var i,n=I;d();var s=g(t);if(s)i=s;else{if(N!=E.IDENTIFIER)throw b("Identifier or subgraph expected");i=I,h(t,{id:i}),d()}var o=_(),r=c(t,e,i,n,o);l(t,r),e=i}}function _(){for(var t=null;"["==I;){for(d(),t={};""!==I&&"]"!=I;){if(N!=E.IDENTIFIER)throw b("Attribute name expected");var e=I;if(d(),"="!=I)throw b("Equal sign = expected");if(d(),N!=E.IDENTIFIER)throw b("Attribute value expected");var i=I;a(t,e,i),d(),","==I&&d()}if("]"!=I)throw b("Bracket ] expected");d()}return t}function b(t){return new SyntaxError(t+', got "'+w(I,30)+'" (char '+M+")")}function w(t,e){return t.length<=e?t:t.substr(0,27)+"..."}function S(t,e,i){t instanceof Array?t.forEach(function(t){e instanceof Array?e.forEach(function(e){i(t,e)}):i(t,e)}):e instanceof Array?e.forEach(function(e){i(t,e)}):i(t,e)}function T(t){function i(t){var e={from:t.from,to:t.to};return r(e,t.attr),e.style="->"==t.type?"arrow":"line",e}var n=e(t),s={nodes:[],edges:[],options:{}};return n.nodes&&n.nodes.forEach(function(t){var e={id:t.id,label:String(t.label||t.id)};r(e,t.attr),e.image&&(e.shape="image"),s.nodes.push(e)}),n.edges&&n.edges.forEach(function(t){var e,n;e=t.from instanceof Object?t.from.nodes:{id:t.from},n=t.to instanceof Object?t.to.nodes:{id:t.to},t.from instanceof Object&&t.from.edges&&t.from.edges.forEach(function(t){var e=i(t);s.edges.push(e)}),S(e,n,function(e,n){var o=c(s,e.id,n.id,t.type,t.attr),r=i(o);s.edges.push(r)}),t.to instanceof Object&&t.to.edges&&t.to.edges.forEach(function(t){var e=i(t);s.edges.push(e)})}),n.attr&&(s.options=n.attr),s}var E={NULL:0,DELIMITER:1,IDENTIFIER:2,UNKNOWN:3},x={"{":!0,"}":!0,"[":!0,"]":!0,";":!0,"=":!0,",":!0,"->":!0,"--":!0},C="",M=0,D="",I="",N=E.NULL,O=/[a-zA-Z_0-9.:#]/;t.parseDOT=e,t.DOTToGraph=T}("undefined"!=typeof util?util:exports),"undefined"!=typeof CanvasRenderingContext2D&&(CanvasRenderingContext2D.prototype.circle=function(t,e,i){this.beginPath(),this.arc(t,e,i,0,2*Math.PI,!1)},CanvasRenderingContext2D.prototype.square=function(t,e,i){this.beginPath(),this.rect(t-i,e-i,2*i,2*i)},CanvasRenderingContext2D.prototype.triangle=function(t,e,i){this.beginPath();var n=2*i,s=n/2,o=Math.sqrt(3)/6*n,r=Math.sqrt(n*n-s*s);this.moveTo(t,e-(r-o)),this.lineTo(t+s,e+o),this.lineTo(t-s,e+o),this.lineTo(t,e-(r-o)),this.closePath()},CanvasRenderingContext2D.prototype.triangleDown=function(t,e,i){this.beginPath();var n=2*i,s=n/2,o=Math.sqrt(3)/6*n,r=Math.sqrt(n*n-s*s);this.moveTo(t,e+(r-o)),this.lineTo(t+s,e-o),this.lineTo(t-s,e-o),this.lineTo(t,e+(r-o)),this.closePath()},CanvasRenderingContext2D.prototype.star=function(t,e,i){this.beginPath();for(var n=0;10>n;n++){var s=n%2===0?1.3*i:.5*i;this.lineTo(t+s*Math.sin(2*n*Math.PI/10),e-s*Math.cos(2*n*Math.PI/10))}this.closePath()},CanvasRenderingContext2D.prototype.roundRect=function(t,e,i,n,s){var o=Math.PI/180;0>i-2*s&&(s=i/2),0>n-2*s&&(s=n/2),this.beginPath(),this.moveTo(t+s,e),this.lineTo(t+i-s,e),this.arc(t+i-s,e+s,s,270*o,360*o,!1),this.lineTo(t+i,e+n-s),this.arc(t+i-s,e+n-s,s,0,90*o,!1),this.lineTo(t+s,e+n),this.arc(t+s,e+n-s,s,90*o,180*o,!1),this.lineTo(t,e+s),this.arc(t+s,e+s,s,180*o,270*o,!1)},CanvasRenderingContext2D.prototype.ellipse=function(t,e,i,n){var s=.5522848,o=i/2*s,r=n/2*s,a=t+i,h=e+n,l=t+i/2,c=e+n/2;this.beginPath(),this.moveTo(t,c),this.bezierCurveTo(t,c-r,l-o,e,l,e),this.bezierCurveTo(l+o,e,a,c-r,a,c),this.bezierCurveTo(a,c+r,l+o,h,l,h),this.bezierCurveTo(l-o,h,t,c+r,t,c)},CanvasRenderingContext2D.prototype.database=function(t,e,i,n){var s=1/3,o=i,r=n*s,a=.5522848,h=o/2*a,l=r/2*a,c=t+o,d=e+r,u=t+o/2,p=e+r/2,f=e+(n-r/2),g=e+n; -this.beginPath(),this.moveTo(c,p),this.bezierCurveTo(c,p+l,u+h,d,u,d),this.bezierCurveTo(u-h,d,t,p+l,t,p),this.bezierCurveTo(t,p-l,u-h,e,u,e),this.bezierCurveTo(u+h,e,c,p-l,c,p),this.lineTo(c,f),this.bezierCurveTo(c,f+l,u+h,g,u,g),this.bezierCurveTo(u-h,g,t,f+l,t,f),this.lineTo(t,p)},CanvasRenderingContext2D.prototype.arrow=function(t,e,i,n){var s=t-n*Math.cos(i),o=e-n*Math.sin(i),r=t-.9*n*Math.cos(i),a=e-.9*n*Math.sin(i),h=s+n/3*Math.cos(i+.5*Math.PI),l=o+n/3*Math.sin(i+.5*Math.PI),c=s+n/3*Math.cos(i-.5*Math.PI),d=o+n/3*Math.sin(i-.5*Math.PI);this.beginPath(),this.moveTo(t,e),this.lineTo(h,l),this.lineTo(r,a),this.lineTo(c,d),this.closePath()},CanvasRenderingContext2D.prototype.dashedLine=function(t,e,i,n,s){s||(s=[10,5]),0==u&&(u=.001);var o=s.length;this.moveTo(t,e);for(var r=i-t,a=n-e,h=a/r,l=Math.sqrt(r*r+a*a),c=0,d=!0;l>=.1;){var u=s[c++%o];u>l&&(u=l);var p=Math.sqrt(u*u/(1+h*h));0>r&&(p=-p),t+=p,e+=h*p,this[d?"lineTo":"moveTo"](t,e),l-=u,d=!d}}),Node.prototype.resetCluster=function(){this.formationScale=void 0,this.clusterSize=1,this.containedNodes={},this.containedEdges={},this.clusterSessions=[]},Node.prototype.attachEdge=function(t){-1==this.edges.indexOf(t)&&this.edges.push(t),-1==this.dynamicEdges.indexOf(t)&&this.dynamicEdges.push(t),this.dynamicEdgesLength=this.dynamicEdges.length},Node.prototype.detachEdge=function(t){var e=this.edges.indexOf(t);-1!=e&&(this.edges.splice(e,1),this.dynamicEdges.splice(e,1)),this.dynamicEdgesLength=this.dynamicEdges.length},Node.prototype.setProperties=function(t,e){if(t){if(this.originalLabel=void 0,void 0!==t.id&&(this.id=t.id),void 0!==t.label&&(this.label=t.label,this.originalLabel=t.label),void 0!==t.title&&(this.title=t.title),void 0!==t.group&&(this.group=t.group),void 0!==t.x&&(this.x=t.x),void 0!==t.y&&(this.y=t.y),void 0!==t.value&&(this.value=t.value),void 0!==t.internalMultiplier&&(this.internalMultiplier=t.value),void 0!==t.horizontalAlignLeft&&(this.horizontalAlignLeft=t.horizontalAlignLeft),void 0!==t.verticalAlignTop&&(this.verticalAlignTop=t.verticalAlignTop),void 0!==t.triggerFunction&&(this.triggerFunction=t.triggerFunction),void 0===this.id)throw"Node must have an id";if(this.group){var i=this.grouplist.get(this.group);for(var n in i)i.hasOwnProperty(n)&&(this[n]=i[n])}if(void 0!==t.shape&&(this.shape=t.shape),void 0!==t.image&&(this.image=t.image),void 0!==t.radius&&(this.radius=t.radius),void 0!==t.color&&(this.color=Node.parseColor(t.color)),void 0!==t.fontColor&&(this.fontColor=t.fontColor),void 0!==t.fontSize&&(this.fontSize=t.fontSize),void 0!==t.fontFace&&(this.fontFace=t.fontFace),void 0!==this.image){if(!this.imagelist)throw"No imagelist provided";this.imageObj=this.imagelist.load(this.image)}switch(this.xFixed=this.xFixed||void 0!==t.x&&t.fixed,this.yFixed=this.yFixed||void 0!==t.y&&t.fixed,this.radiusFixed=this.radiusFixed||void 0!==t.radius,"image"==this.shape&&(this.radiusMin=e.nodes.widthMin,this.radiusMax=e.nodes.widthMax),this.shape){case"database":this.draw=this._drawDatabase,this.resize=this._resizeDatabase;break;case"box":this.draw=this._drawBox,this.resize=this._resizeBox;break;case"circle":this.draw=this._drawCircle,this.resize=this._resizeCircle;break;case"ellipse":this.draw=this._drawEllipse,this.resize=this._resizeEllipse;break;case"image":this.draw=this._drawImage,this.resize=this._resizeImage;break;case"text":this.draw=this._drawText,this.resize=this._resizeText;break;case"dot":this.draw=this._drawDot,this.resize=this._resizeShape;break;case"square":this.draw=this._drawSquare,this.resize=this._resizeShape;break;case"triangle":this.draw=this._drawTriangle,this.resize=this._resizeShape;break;case"triangleDown":this.draw=this._drawTriangleDown,this.resize=this._resizeShape;break;case"star":this.draw=this._drawStar,this.resize=this._resizeShape;break;default:this.draw=this._drawEllipse,this.resize=this._resizeEllipse}this._reset()}},Node.parseColor=function(t){var e;return util.isString(t)?e={border:t,background:t,highlight:{border:t,background:t}}:(e={},e.background=t.background||"white",e.border=t.border||e.background,util.isString(t.highlight)?e.highlight={border:t.highlight,background:t.highlight}:(e.highlight={},e.highlight.background=t.highlight&&t.highlight.background||e.background,e.highlight.border=t.highlight&&t.highlight.border||e.border)),e},Node.prototype.select=function(){this.selected=!0,this._reset()},Node.prototype.unselect=function(){this.selected=!1,this._reset()},Node.prototype.clearSizeCache=function(){this._reset()},Node.prototype._reset=function(){this.width=void 0,this.height=void 0},Node.prototype.getTitle=function(){return this.title},Node.prototype.distanceToBorder=function(t,e){var i=1;switch(this.width||this.resize(t),this.shape){case"circle":case"dot":return this.radius+i;case"ellipse":var n=this.width/2,s=this.height/2,o=Math.sin(e)*n,r=Math.cos(e)*s;return n*s/Math.sqrt(o*o+r*r);case"box":case"image":case"text":default:return this.width?Math.min(Math.abs(this.width/2/Math.cos(e)),Math.abs(this.height/2/Math.sin(e)))+i:0}},Node.prototype._setForce=function(t,e){this.fx=t,this.fy=e},Node.prototype._addForce=function(t,e){this.fx+=t,this.fy+=e},Node.prototype.discreteStep=function(t){if(!this.xFixed){var e=-this.damping*this.vx,i=(this.fx+e)/this.mass;this.vx+=i*t,this.x+=this.vx*t}if(!this.yFixed){var n=-this.damping*this.vy,s=(this.fy+n)/this.mass;this.vy+=s*t,this.y+=this.vy*t}},Node.prototype.discreteStepLimited=function(t,e){if(!this.xFixed){var i=-this.damping*this.vx,n=(this.fx+i)/this.mass;this.vx+=n*t,this.vx=Math.abs(this.vx)>e?this.vx>0?e:-e:this.vx,this.x+=this.vx*t}if(!this.yFixed){var s=-this.damping*this.vy,o=(this.fy+s)/this.mass;this.vy+=o*t,this.vy=Math.abs(this.vy)>e?this.vy>0?e:-e:this.vy,this.y+=this.vy*t}},Node.prototype.isFixed=function(){return this.xFixed&&this.yFixed},Node.prototype.isMoving=function(t){return Math.abs(this.vx)>t||Math.abs(this.vy)>t?!0:(this.vx=0,this.vy=0,!1)},Node.prototype.isSelected=function(){return this.selected},Node.prototype.getValue=function(){return this.value},Node.prototype.getDistance=function(t,e){var i=this.x-t,n=this.y-e;return Math.sqrt(i*i+n*n)},Node.prototype.setValueRange=function(t,e){if(!this.radiusFixed&&void 0!==this.value)if(e==t)this.radius=(this.radiusMin+this.radiusMax)/2;else{var i=(this.radiusMax-this.radiusMin)/(e-t);this.radius=(this.value-t)*i+this.radiusMin}this.baseRadiusValue=this.radius},Node.prototype.draw=function(){throw"Draw method not initialized for node"},Node.prototype.resize=function(){throw"Resize method not initialized for node"},Node.prototype.isOverlappingWith=function(t){return this.leftt.left&&this.topt.top},Node.prototype._resizeImage=function(){if(!this.width||!this.height){var t,e;if(this.value){this.radius=this.baseRadiusValue;var i=this.imageObj.height/this.imageObj.width;void 0!==i?(t=this.radius||this.imageObj.width,e=this.radius*i||this.imageObj.height):(t=0,e=0)}else t=this.imageObj.width,e=this.imageObj.height;this.width=t,this.height=e,this.width>0&&this.height>0&&(this.width+=(this.clusterSize-1)*this.clusterSizeWidthFactor,this.height+=(this.clusterSize-1)*this.clusterSizeHeightFactor,this.radius+=(this.clusterSize-1)*this.clusterSizeRadiusFactor)}},Node.prototype._drawImage=function(t){this._resizeImage(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e;if(0!=this.imageObj.width){if(this.clusterSize>1){var i=this.clusterSize>1?10:0;i*=this.graphScaleInv,i=Math.min(.2*this.width,i),t.globalAlpha=.5,t.drawImage(this.imageObj,this.left-i,this.top-i,this.width+2*i,this.height+2*i)}t.globalAlpha=1,t.drawImage(this.imageObj,this.left,this.top,this.width,this.height),e=this.y+this.height/2}else e=this.y;this._label(t,this.label,this.x,e,void 0,"top")},Node.prototype._resizeBox=function(t){if(!this.width){var e=5,i=this.getTextSize(t);this.width=i.width+2*e,this.height=i.height+2*e,this.width+=.5*(this.clusterSize-1)*this.clusterSizeWidthFactor,this.height+=.5*(this.clusterSize-1)*this.clusterSizeHeightFactor}},Node.prototype._drawBox=function(t){this._resizeBox(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=2;t.strokeStyle=this.selected?this.color.highlight.border:this.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.roundRect(this.left-2*t.lineWidth,this.top-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth,this.radius),t.stroke()),t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.fillStyle=this.selected?this.color.highlight.background:this.color.background,t.roundRect(this.left,this.top,this.width,this.height,this.radius),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},Node.prototype._resizeDatabase=function(t){if(!this.width){var e=5,i=this.getTextSize(t),n=i.width+2*e;this.width=n,this.height=n,this.width+=(this.clusterSize-1)*this.clusterSizeWidthFactor,this.height+=(this.clusterSize-1)*this.clusterSizeHeightFactor,this.radius+=(this.clusterSize-1)*this.clusterSizeRadiusFactor}},Node.prototype._drawDatabase=function(t){this._resizeDatabase(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=2;t.strokeStyle=this.selected?this.color.highlight.border:this.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.database(this.x-this.width/2-2*t.lineWidth,this.y-.5*this.height-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.fillStyle=this.selected?this.color.highlight.background:this.color.background,t.database(this.x-this.width/2,this.y-.5*this.height,this.width,this.height),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},Node.prototype._resizeCircle=function(t){if(!this.width){var e=5,i=this.getTextSize(t),n=Math.max(i.width,i.height)+2*e;this.radius=n/2,this.width=n,this.height=n,this.radius+=.5*(this.clusterSize-1)*this.clusterSizeRadiusFactor}},Node.prototype._drawCircle=function(t){this._resizeCircle(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=2;t.strokeStyle=this.selected?this.color.highlight.border:this.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.circle(this.x,this.y,this.radius+2*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.fillStyle=this.selected?this.color.highlight.background:this.color.background,t.circle(this.x,this.y,this.radius),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},Node.prototype._resizeEllipse=function(t){if(!this.width){var e=this.getTextSize(t);this.width=1.5*e.width,this.height=2*e.height,this.width1&&(t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.ellipse(this.left-2*t.lineWidth,this.top-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?i:1)+(this.clusterSize>1?e:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.fillStyle=this.selected?this.color.highlight.background:this.color.background,t.ellipse(this.left,this.top,this.width,this.height),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},Node.prototype._drawDot=function(t){this._drawShape(t,"circle")},Node.prototype._drawTriangle=function(t){this._drawShape(t,"triangle")},Node.prototype._drawTriangleDown=function(t){this._drawShape(t,"triangleDown")},Node.prototype._drawSquare=function(t){this._drawShape(t,"square")},Node.prototype._drawStar=function(t){this._drawShape(t,"star")},Node.prototype._resizeShape=function(){if(!this.width){this.radius=this.baseRadiusValue;var t=2*this.radius;this.width=t,this.height=t,this.width+=(this.clusterSize-1)*this.clusterSizeWidthFactor,this.height+=(this.clusterSize-1)*this.clusterSizeHeightFactor,this.radius+=.5*(this.clusterSize-1)*this.clusterSizeRadiusFactor}},Node.prototype._drawShape=function(t,e){this._resizeShape(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var i=2.5,n=2,s=2;switch(e){case"dot":s=2;break;case"square":s=2;break;case"triangle":s=3;break;case"triangleDown":s=3;break;case"star":s=4}t.strokeStyle=this.selected?this.color.highlight.border:this.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?n:1)+(this.clusterSize>1?i:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t[e](this.x,this.y,this.radius+s*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?n:1)+(this.clusterSize>1?i:0),t.lineWidth*=this.graphScaleInv,t.lineWidth=Math.min(.1*this.width,t.lineWidth),t.fillStyle=this.selected?this.color.highlight.background:this.color.background,t[e](this.x,this.y,this.radius),t.fill(),t.stroke(),this.label&&this._label(t,this.label,this.x,this.y+this.height/2,void 0,"top")},Node.prototype._resizeText=function(t){if(!this.width){var e=5,i=this.getTextSize(t);this.width=i.width+2*e,this.height=i.height+2*e,this.width+=(this.clusterSize-1)*this.clusterSizeWidthFactor,this.height+=(this.clusterSize-1)*this.clusterSizeHeightFactor,this.radius+=(this.clusterSize-1)*this.clusterSizeRadiusFactor}},Node.prototype._drawText=function(t){this._resizeText(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2,this._label(t,this.label,this.x,this.y)},Node.prototype._label=function(t,e,i,n,s,o){if(e){t.font=(this.selected?"bold ":"")+this.fontSize+"px "+this.fontFace,t.fillStyle=this.fontColor||"black",t.textAlign=s||"center",t.textBaseline=o||"middle";for(var r=e.split("\n"),a=r.length,h=this.fontSize+4,l=n+(1-a)/2*h,c=0;a>c;c++)t.fillText(r[c],i,l),l+=h}},Node.prototype.getTextSize=function(t){if(void 0!==this.label){t.font=(this.selected?"bold ":"")+this.fontSize+"px "+this.fontFace;for(var e=this.label.split("\n"),i=(this.fontSize+4)*e.length,n=0,s=0,o=e.length;o>s;s++)n=Math.max(n,t.measureText(e[s]).width);return{width:n,height:i}}return{width:0,height:0}},Node.prototype.inArea=function(){return void 0!==this.width?this.x+this.width*this.graphScaleInv>=this.canvasTopLeft.x&&this.x-this.width*this.graphScaleInv=this.canvasTopLeft.y&&this.y-this.height*this.graphScaleInv=this.canvasTopLeft.x&&this.x=this.canvasTopLeft.y&&this.yh},Edge.prototype._drawLine=function(t){t.strokeStyle=this.color,t.lineWidth=this._getLineWidth();var e;if(this.from!=this.to)this._line(t),this.label&&(e=this._pointOnLine(.5),this._label(t,this.label,e.x,e.y));else{var i,n,s=this.length/4,o=this.from;o.width||o.resize(t),o.width>o.height?(i=o.x+o.width/2,n=o.y-s):(i=o.x+s,n=o.y-o.height/2),this._circle(t,i,n,s),e=this._pointOnCircle(i,n,s,.5),this._label(t,this.label,e.x,e.y)}},Edge.prototype._getLineWidth=function(){return 1==this.selected?Math.min(2*this.width,this.widthMax)*this.graphScaleInv:this.width*this.graphScaleInv},Edge.prototype._line=function(t){t.beginPath(),t.moveTo(this.from.x,this.from.y),t.lineTo(this.to.x,this.to.y),t.stroke()},Edge.prototype._circle=function(t,e,i,n){t.beginPath(),t.arc(e,i,n,0,2*Math.PI,!1),t.stroke()},Edge.prototype._label=function(t,e,i,n){if(e){t.font=(this.from.selected||this.to.selected?"bold ":"")+this.fontSize+"px "+this.fontFace,t.fillStyle="white";var s=t.measureText(e).width,o=this.fontSize,r=i-s/2,a=n-o/2;t.fillRect(r,a,s,o),t.fillStyle=this.fontColor||"black",t.textAlign="left",t.textBaseline="top",t.fillText(e,r,a)}},Edge.prototype._drawDashLine=function(t){if(t.strokeStyle=this.color,t.lineWidth=this._getLineWidth(),t.beginPath(),t.lineCap="round",void 0!==this.dash.altLength?t.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,[this.dash.length,this.dash.gap,this.dash.altLength,this.dash.gap]):void 0!==this.dash.length&&void 0!==this.dash.gap?t.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,[this.dash.length,this.dash.gap]):(t.moveTo(this.from.x,this.from.y),t.lineTo(this.to.x,this.to.y)),t.stroke(),this.label){var e=this._pointOnLine(.5);this._label(t,this.label,e.x,e.y)}},Edge.prototype._pointOnLine=function(t){return{x:(1-t)*this.from.x+t*this.to.x,y:(1-t)*this.from.y+t*this.to.y}},Edge.prototype._pointOnCircle=function(t,e,i,n){var s=2*(n-3/8)*Math.PI;return{x:t+i*Math.cos(s),y:e-i*Math.sin(s)}},Edge.prototype._drawArrowCenter=function(t){var e;if(t.strokeStyle=this.color,t.fillStyle=this.color,t.lineWidth=this._getLineWidth(),this.from!=this.to){this._line(t);var i=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x),n=10+5*this.width;e=this._pointOnLine(.5),t.arrow(e.x,e.y,i,n),t.fill(),t.stroke(),this.label&&(e=this._pointOnLine(.5),this._label(t,this.label,e.x,e.y))}else{var s,o,r=this.length/4,a=this.from;a.width||a.resize(t),a.width>a.height?(s=a.x+a.width/2,o=a.y-r):(s=a.x+r,o=a.y-a.height/2),this._circle(t,s,o,r);var i=.2*Math.PI,n=10+5*this.width;e=this._pointOnCircle(s,o,r,.5),t.arrow(e.x,e.y,i,n),t.fill(),t.stroke(),this.label&&(e=this._pointOnCircle(s,o,r,.5),this._label(t,this.label,e.x,e.y))}},Edge.prototype._drawArrow=function(t){t.strokeStyle=this.color,t.fillStyle=this.color,t.lineWidth=this._getLineWidth();var e,i;if(this.from!=this.to){e=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x);var n=this.to.x-this.from.x,s=this.to.y-this.from.y,o=Math.sqrt(n*n+s*s),r=this.from.distanceToBorder(t,e+Math.PI),a=(o-r)/o,h=a*this.from.x+(1-a)*this.to.x,l=a*this.from.y+(1-a)*this.to.y,c=this.to.distanceToBorder(t,e),d=(o-c)/o,u=(1-d)*this.from.x+d*this.to.x,p=(1-d)*this.from.y+d*this.to.y;if(t.beginPath(),t.moveTo(h,l),t.lineTo(u,p),t.stroke(),i=10+5*this.width,t.arrow(u,p,e,i),t.fill(),t.stroke(),this.label){var f=this._pointOnLine(.5);this._label(t,this.label,f.x,f.y)}}else{var g,m,v,y=this.from,_=this.length/4;y.width||y.resize(t),y.width>y.height?(g=y.x+y.width/2,m=y.y-_,v={x:g,y:y.y,angle:.9*Math.PI}):(g=y.x+_,m=y.y-y.height/2,v={x:y.x,y:m,angle:.6*Math.PI}),t.beginPath(),t.arc(g,m,_,0,2*Math.PI,!1),t.stroke(),i=10+5*this.width,t.arrow(v.x,v.y,v.angle,i),t.fill(),t.stroke(),this.label&&(f=this._pointOnCircle(g,m,_,.5),this._label(t,this.label,f.x,f.y))}},Edge._dist=function(t,e,i,n,s,o){var r=i-t,a=n-e,h=r*r+a*a,l=((s-t)*r+(o-e)*a)/h;l>1?l=1:0>l&&(l=0);var c=t+l*r,d=e+l*a,u=c-s,p=d-o;return Math.sqrt(u*u+p*p)},Edge.prototype.setScale=function(t){this.graphScaleInv=1/t},Edge.prototype.select=function(){this.selected=!0},Edge.prototype.unselect=function(){this.selected=!1},Popup.prototype.setPosition=function(t,e){this.x=parseInt(t),this.y=parseInt(e)},Popup.prototype.setText=function(t){this.frame.innerHTML=t},Popup.prototype.show=function(t){if(void 0===t&&(t=!0),t){var e=this.frame.clientHeight,i=this.frame.clientWidth,n=this.frame.parentNode.clientHeight,s=this.frame.parentNode.clientWidth,o=this.y-e;o+e+this.padding>n&&(o=n-e-this.padding),os&&(r=s-i-this.padding),rthis.constants.clustering.clusterThreshold&&1==this.constants.clustering.enabled&&this.clusterToFit(this.constants.clustering.reduceToNodes,!1),this._calculateForces())},_calculateForces:function(){this.barnesHutTree=void 0,this._calculateGravitationalForces(),this._calculateNodeForces(),this._calculateSpringForces()},_calculateGravitationalForces:function(){var t,e,i,n,s,o,r,a=this.nodes,h=this.constants.physics.centralGravity;for(r=0;ro;o++)t=e[i[o]],this._getForceContribution(s.root.children.NW,t),this._getForceContribution(s.root.children.NE,t),this._getForceContribution(s.root.children.SW,t),this._getForceContribution(s.root.children.SE,t)},_getForceContribution:function(t,e){if(t.childrenCount>0){var i,n,s;i=t.CenterOfMass.x-e.x,n=t.CenterOfMass.y-e.y,s=Math.sqrt(i*i+n*n),s>0&&(s*t.calcSizeh;h++){var l=e[i[h]].x,c=e[i[h]].y;s>l&&(s=l),l>r&&(r=l),o>c&&(o=c),c>a&&(a=c)}var d=Math.abs(r-s)-Math.abs(a-o);d>0?(o-=.5*d,a+=.5*d):(s+=.5*d,r-=.5*d);var u={root:{CenterOfMass:{x:0,y:0},mass:0,range:{minX:s,maxX:r,minY:o,maxY:a},size:Math.abs(r-s),calcSize:1/Math.abs(r-s),children:{data:null},maxWidth:0,level:0,childrenCount:4}};for(this._splitBranch(u.root),h=0;n>h;h++)t=e[i[h]],this._placeInTree(u.root,t);this.barnesHutTree=u},_updateBranchMass:function(t,e){var i=t.mass+e.mass,n=1/i;t.CenterOfMass.x=t.CenterOfMass.x*t.mass+e.x*e.mass,t.CenterOfMass.x*=n,t.CenterOfMass.y=t.CenterOfMass.y*t.mass+e.y*e.mass,t.CenterOfMass.y*=n,t.mass=i;var s=Math.max(Math.max(e.height,e.radius),e.width);t.maxWidth=t.maxWidthe.x?t.children.NW.range.maxY>e.y?this._placeInRegion(t,e,"NW"):this._placeInRegion(t,e,"SW"):t.children.NE.range.maxY>e.y?this._placeInRegion(t,e,"NE"):this._placeInRegion(t,e,"SE")},_placeInRegion:function(t,e,i){switch(t.children[i].childrenCount){case 0:t.children[i].children.data=e,t.children[i].childrenCount=1,this._updateBranchMass(t.children[i],e);break;case 1:this._splitBranch(t.children[i]),this._placeInTree(t.children[i],e);break;case 4:this._placeInTree(t.children[i],e)}},_splitBranch:function(t){var e=null;1==t.childrenCount&&(e=t.children.data,t.mass=0,t.CenterOfMass.x=0,t.CenterOfMass.y=0),t.childrenCount=4,t.children.data=null,this._insertRegion(t,"NW"),this._insertRegion(t,"NE"),this._insertRegion(t,"SW"),this._insertRegion(t,"SE"),null!=e&&this._placeInTree(t,e)},_insertRegion:function(t,e){var i,n,s,o;switch(e){case"NW":i=t.range.minX,n=t.range.minX+t.size,s=t.range.minY,o=t.range.minY+t.size;break;case"NE":i=t.range.minX+t.size,n=t.range.maxX,s=t.range.minY,o=t.range.minY+t.size;break;case"SW":i=t.range.minX,n=t.range.minX+t.size,s=t.range.minY+t.size,o=t.range.maxY;break;case"SE":i=t.range.minX+t.size,n=t.range.maxX,s=t.range.minY+t.size,o=t.range.maxY}t.children[e]={CenterOfMass:{x:0,y:0},mass:0,range:{minX:i,maxX:n,minY:s,maxY:o},size:.5*t.size,calcSize:2*t.calcSize,children:{data:null},maxWidth:0,level:t.level+1,childrenCount:0}},_drawTree:function(t,e){void 0!==this.barnesHutTree&&(t.lineWidth=1,this._drawBranch(this.barnesHutTree.root,t,e))},_drawBranch:function(t,e,i){void 0===i&&(i="#FF0000"),4==t.childrenCount&&(this._drawBranch(t.children.NW,e),this._drawBranch(t.children.NE,e),this._drawBranch(t.children.SE,e),this._drawBranch(t.children.SW,e)),e.strokeStyle=i,e.beginPath(),e.moveTo(t.range.minX,t.range.minY),e.lineTo(t.range.maxX,t.range.minY),e.stroke(),e.beginPath(),e.moveTo(t.range.maxX,t.range.minY),e.lineTo(t.range.maxX,t.range.maxY),e.stroke(),e.beginPath(),e.moveTo(t.range.maxX,t.range.maxY),e.lineTo(t.range.minX,t.range.maxY),e.stroke(),e.beginPath(),e.moveTo(t.range.minX,t.range.maxY),e.lineTo(t.range.minX,t.range.minY),e.stroke()}},repulsionMixin={_calculateNodeForces:function(){var t,e,i,n,s,o,r,a,h,l,c,d,u=this.nodes,p=-2/3,f=4/3,g=this.constants.nodes.distance;for(c=0;cn&&(i=Math.atan2(e,t),a=.5*g>n?1:m*n+f,a*=0==r?1:1+r*this.constants.clustering.forceAmplification,a*=h.internalMultiplier*l.internalMultiplier,s=Math.cos(i)*a,o=Math.sin(i)*a,h._addForce(-s,-o),l._addForce(s,o))}}},manipulationMixin={_clearManipulatorBar:function(){for(;this.manipulationDiv.hasChildNodes();)this.manipulationDiv.removeChild(this.manipulationDiv.firstChild)},_createManipulatorBar:function(){for(this.off("select",this.boundFunction),this.blockConnectingEdgeSelection=!1,this.forceAppendSelection=!1;this.manipulationDiv.hasChildNodes();)this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);this.manipulationDiv.innerHTML="Add Node
Edit Selected
Connect Node
Delete selected";var t=document.getElementById("manipulate-addNode");t.onclick=this._createAddToolbar.bind(this); -var e=document.getElementById("manipulate-editNode");e.onclick=this._createEditToolbar.bind(this);var i=document.getElementById("manipulate-connectNode");i.onclick=this._createConnectToolbar.bind(this);var n=document.getElementById("manipulate-delete");n.onclick=this._createDeletionToolbar.bind(this)},_createAddToolbar:function(){this._clearManipulatorBar(),this.off("select",this.boundFunction),this.manipulationDiv.innerHTML="Back
Click in an empty space to place a new node";var t=document.getElementById("manipulate-back");t.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._addNode.bind(this),this.on("select",this.boundFunction)},_createEditToolbar:function(){this.blockConnectingEdgeSelection=!1,this._clearManipulatorBar(),this.off("select",this.boundFunction);var t="";if(this._selectionIsEmpty()?t="Select a node or edge to edit.":this._getSelectedObjectCount()>1?(t="Select a single node or edge to edit.",this._unselectAll(!0)):this._clusterInSelection()?(t="You cannot edit a cluster.",this._unselectAll(!0)):this._getSelectedNodeCount()>0?this._createEditNodeToolbar():this._createEditEdgeToolbar(),""!=t){this.blockConnectingEdgeSelection=!0,this.manipulationDiv.innerHTML="Back
"+t+"";var e=document.getElementById("manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._createEditToolbar.bind(this),this.on("select",this.boundFunction)}},_createEditNodeToolbar:function(){this.blockConnectingEdgeSelection=!1,this._clearManipulatorBar(),this.off("select",this.boundFunction);var t=this._getEditObject();this.manipulationDiv.innerHTML="Cancel
label:
color:
";var e=document.getElementById("manipulate-back");e.onclick=this._createManipulatorBar.bind(this);var i=document.getElementById("manipulator-obj-save");i.onclick=this._saveNodeData.bind(this),this.boundFunction=this._createManipulatorBar.bind(this),this.on("select",this.boundFunction)},_saveNodeData:function(){var t=this._getEditObject().id,e=document.getElementById("manipulator-obj-label").value,i=document.getElementById("manipulator-obj-color").value,n=util.hexToHSV(i),s={h:n.h,s:.45*n.s,v:Math.min(1,1.05*n.v)},o={h:n.h,s:Math.min(1,1.25*n.v),v:.6*n.v},r=util.HSVToHex(o.h,o.h,o.v),a=util.HSVToHex(s.h,s.s,s.v),h={id:t,label:e,color:{background:i,border:r,highlight:{background:a,border:r}}};this.nodesData.update(h),this._createManipulatorBar()},_createEditEdgeToolbar:function(){this.blockConnectingEdgeSelection=!1,this._clearManipulatorBar(),this.off("select",this.boundFunction),this.manipulationDiv.innerHTML="Back
Currently only nodes can be edited.";var t=document.getElementById("manipulate-back");t.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._createManipulatorBar.bind(this),this.on("select",this.boundFunction)},_createConnectToolbar:function(){this._clearManipulatorBar(),this.off("select",this.boundFunction),this._unselectAll(),this.forceAppendSelection=!1,this.blockConnectingEdgeSelection=!0,this.manipulationDiv.innerHTML="Back
Select the node you want to connect to other nodes.";var t=document.getElementById("manipulate-back");t.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._handleConnect.bind(this),this.on("select",this.boundFunction)},_createDeletionToolbar:function(){if(this._clearManipulatorBar(),this.off("select",this.boundFunction),this._selectionIsEmpty()){this.manipulationDiv.innerHTML="Cannot delete an empty selection.";var t=this;window.setTimeout(function(){t._createManipulatorBar()},1500)}else{this.manipulationDiv.innerHTML="Back
Are you sure? This cannot be undone.
Yes.";var e=document.getElementById("manipulate-back");e.onclick=this._createManipulatorBar.bind(this);var i=document.getElementById("manipulate-acceptDelete");i.onclick=this._deleteSelected.bind(this),this.boundFunction=this._createManipulatorBar.bind(this),this.on("select",this.boundFunction)}},_handleConnect:function(){this.forceAppendSelection=!1,this._clusterInSelection()?(this._unselectClusters(!0),this._selectionIsEmpty()?this._setManipulationMessage("You cannot connect anything to a cluster."):(this._setManipulationMessage("You cannot connect a node to a cluster."),this.forceAppendSelection=!0)):this._selectionIsEmpty()?this._setManipulationMessage("Select the node you want to connect to other nodes."):2==this._getSelectedNodeCount()?(this._connectNodes(),this._restoreSourceNode(),this._setManipulationMessage("Click on another node you want to connect this node to or go back.")):(this._setManipulationMessage("Click on the node you want to connect this node."),this._setSourceNode(),this.forceAppendSelection=!0)},_getEditObject:function(){for(var t in this.selectionObj)if(this.selectionObj.hasOwnProperty(t))return this.selectionObj[t];return null},_setSourceNode:function(){for(var t in this.selectionObj)this.selectionObj.hasOwnProperty(t)&&this.selectionObj[t]instanceof Node&&(this.manipulationSourceNode=this.selectionObj[t])},_getTargetNode:function(){for(var t in this.selectionObj)if(this.selectionObj.hasOwnProperty(t)&&this.selectionObj[t]instanceof Node&&this.manipulationSourceNode.id!=this.selectionObj[t].id)return this.selectionObj[t];return null},_restoreSourceNode:function(){this._unselectAll(!0),this._selectObject(this.manipulationSourceNode)},_setManipulationMessage:function(t){var e=document.getElementById("manipulatorLabel");e.innerHTML=t},_addNode:function(){if(this._selectionIsEmpty()){var t=this._pointerToPositionObject(this.pointerPosition);this.createNodeOnClick=!0,this.nodesData.add({id:util.randomUUID(),x:t.left,y:t.top,label:"new",fixed:!1}),this.createNodeOnClick=!1,this.moving=!0,this.start()}},_connectNodes:function(){var t=this._getTargetNode(),e=this.manipulationSourceNode;this.edgesData.add({from:e.id,to:t.id}),this.moving=!0,this.start()},_deleteSelected:function(){if(this._clusterInSelection())alert("Clusters cannot be deleted.");else{var t=this.getSelectedNodes(),e=this.getSelectedEdges();this._removeEdges(e),this._removeNodes(t),this.moving=!0,this.start()}}},SectorMixin={_putDataInSector:function(){this.sectors.active[this._sector()].nodes=this.nodes,this.sectors.active[this._sector()].edges=this.edges,this.sectors.active[this._sector()].nodeIndices=this.nodeIndices},_switchToSector:function(t,e){void 0===e||"active"==e?this._switchToActiveSector(t):this._switchToFrozenSector(t)},_switchToActiveSector:function(t){this.nodeIndices=this.sectors.active[t].nodeIndices,this.nodes=this.sectors.active[t].nodes,this.edges=this.sectors.active[t].edges},_switchToFrozenSector:function(t){this.nodeIndices=this.sectors.frozen[t].nodeIndices,this.nodes=this.sectors.frozen[t].nodes,this.edges=this.sectors.frozen[t].edges},_switchToNavigationSector:function(){this.nodeIndices=this.sectors.navigation.nodeIndices,this.nodes=this.sectors.navigation.nodes,this.edges=this.sectors.navigation.edges},_loadLatestSector:function(){this._switchToSector(this._sector())},_sector:function(){return this.activeSector[this.activeSector.length-1]},_previousSector:function(){if(this.activeSector.length>1)return this.activeSector[this.activeSector.length-2];throw new TypeError("there are not enough sectors in the this.activeSector array.")},_setActiveSector:function(t){this.activeSector.push(t)},_forgetLastSector:function(){this.activeSector.pop()},_createNewSector:function(t){this.sectors.active[t]={nodes:{},edges:{},nodeIndices:[],formationScale:this.scale,drawingNode:void 0},this.sectors.active[t].drawingNode=new Node({id:t,color:{background:"#eaefef",border:"495c5e"}},{},{},this.constants),this.sectors.active[t].drawingNode.clusterSize=2},_deleteActiveSector:function(t){delete this.sectors.active[t]},_deleteFrozenSector:function(t){delete this.sectors.frozen[t]},_freezeSector:function(t){this.sectors.frozen[t]=this.sectors.active[t],this._deleteActiveSector(t)},_activateSector:function(t){this.sectors.active[t]=this.sectors.frozen[t],this._deleteFrozenSector(t)},_mergeThisWithFrozen:function(t){for(var e in this.nodes)this.nodes.hasOwnProperty(e)&&(this.sectors.frozen[t].nodes[e]=this.nodes[e]);for(var i in this.edges)this.edges.hasOwnProperty(i)&&(this.sectors.frozen[t].edges[i]=this.edges[i]);for(var n=0;n1?this[t](n[0],n[1]):this[t](e)}this._loadLatestSector()},_doInAllFrozenSectors:function(t,e){if(void 0===e)for(var i in this.sectors.frozen)this.sectors.frozen.hasOwnProperty(i)&&(this._switchToFrozenSector(i),this[t]());else for(var i in this.sectors.frozen)if(this.sectors.frozen.hasOwnProperty(i)){this._switchToFrozenSector(i);var n=Array.prototype.splice.call(arguments,1);n.length>1?this[t](n[0],n[1]):this[t](e)}this._loadLatestSector()},_doInNavigationSector:function(t,e){if(this._switchToNavigationSector(),void 0===e)this[t]();else{var i=Array.prototype.splice.call(arguments,1);i.length>1?this[t](i[0],i[1]):this[t](e)}this._loadLatestSector()},_doInAllSectors:function(t,e){var i=Array.prototype.splice.call(arguments,1);void 0===e?(this._doInAllActiveSectors(t),this._doInAllFrozenSectors(t)):i.length>1?(this._doInAllActiveSectors(t,i[0],i[1]),this._doInAllFrozenSectors(t,i[0],i[1])):(this._doInAllActiveSectors(t,e),this._doInAllFrozenSectors(t,e))},_clearNodeIndexList:function(){var t=this._sector();this.sectors.active[t].nodeIndices=[],this.nodeIndices=this.sectors.active[t].nodeIndices},_drawSectorNodes:function(t,e){var i,n=1e9,s=-1e9,o=1e9,r=-1e9;for(var a in this.sectors[e])if(this.sectors[e].hasOwnProperty(a)&&void 0!==this.sectors[e][a].drawingNode){this._switchToSector(a,e),n=1e9,s=-1e9,o=1e9,r=-1e9;for(var h in this.nodes)this.nodes.hasOwnProperty(h)&&(i=this.nodes[h],i.resize(t),o>i.x-.5*i.width&&(o=i.x-.5*i.width),ri.y-.5*i.height&&(n=i.y-.5*i.height),st&&n>s;)s%3==0?this.forceAggregateHubs():this.increaseClusterLevel(),i=this.nodeIndices.length,s+=1;s>1&&1==e&&this.repositionNodes()},openCluster:function(t){var e=this.moving;if(t.clusterSize>this.constants.clustering.sectorThreshold&&this._nodeInActiveArea(t)&&("default"!=this._sector()||1!=this.nodeIndices.length)){this._addSector(t);for(var i=0;this.nodeIndices.lengthi;)this.decreaseClusterLevel(),i+=1}else this._expandClusterNode(t,!1,!0),this._updateNodeIndexList(),this._updateDynamicEdges(),this.updateLabels();this.moving!=e&&this.start()},updateClustersDefault:function(){1==this.constants.clustering.enabled&&this.updateClusters(0,!1,!1)},increaseClusterLevel:function(){this.updateClusters(-1,!1,!0)},decreaseClusterLevel:function(){this.updateClusters(1,!1,!0)},updateClusters:function(t,e,i){var n=this.moving,s=this.nodeIndices.length;this.previousScale>this.scale&&0==t&&this._collapseSector(),this.previousScale>this.scale||-1==t?this._formClusters(i):(this.previousScalethis.scale||-1==t)&&(this._aggregateHubs(i),this._updateNodeIndexList()),(this.previousScale>this.scale||-1==t)&&(this.handleChains(),this._updateNodeIndexList()),this.previousScale=this.scale,this._updateDynamicEdges(),this.updateLabels(),this.nodeIndices.lengththis.constants.clustering.chainThreshold&&this._reduceAmountOfChains(1-this.constants.clustering.chainThreshold/t)},_aggregateHubs:function(t){this._getHubSize(),this._formClustersByHub(t,!1)},forceAggregateHubs:function(){var t=this.moving,e=this.nodeIndices.length;this._aggregateHubs(!0),this._updateNodeIndexList(),this._updateDynamicEdges(),this.updateLabels(),this.nodeIndices.length!=e&&(this.clusterSession+=1),this.moving!=t&&this.start()},_openClustersBySize:function(){for(var t in this.nodes)if(this.nodes.hasOwnProperty(t)){var e=this.nodes[t];1==e.inView()&&(e.width*this.scale>this.constants.clustering.screenSizeThreshold*this.frame.canvas.clientWidth||e.height*this.scale>this.constants.clustering.screenSizeThreshold*this.frame.canvas.clientHeight)&&this.openCluster(e)}},_openClusters:function(t,e){for(var i=0;i1&&(t.clusterSizei)){var r=o.from,a=o.to;o.to.mass>o.from.mass&&(r=o.to,a=o.from),1==a.dynamicEdgesLength?this._addToCluster(r,a,!1):1==r.dynamicEdgesLength&&this._addToCluster(a,r,!1)}}},_forceClustersByZoom:function(){for(var t in this.nodes)if(this.nodes.hasOwnProperty(t)){var e=this.nodes[t];if(1==e.dynamicEdgesLength&&0!=e.dynamicEdges.length){var i=e.dynamicEdges[0],n=i.toId==e.id?this.nodes[i.fromId]:this.nodes[i.toId];e.id!=n.id&&(n.mass>e.mass?this._addToCluster(n,e,!0):this._addToCluster(e,n,!0))}}},_formClustersByHub:function(t,e){for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&this._formClusterFromHub(this.nodes[i],t,e)},_formClusterFromHub:function(t,e,i,n){if(void 0===n&&(n=0),t.dynamicEdgesLength>=this.hubThreshold&&0==i||t.dynamicEdgesLength==this.hubThreshold&&1==i){for(var s,o,r,a=this.constants.clustering.clusterEdgeThreshold/this.scale,h=!1,l=[],c=t.dynamicEdges.length,d=0;c>d;d++)l.push(t.dynamicEdges[d].id);if(0==e)for(h=!1,d=0;c>d;d++){var u=this.edges[l[d]];if(void 0!==u&&u.connected&&u.toId!=u.fromId&&(s=u.to.x-u.from.x,o=u.to.y-u.from.y,r=Math.sqrt(s*s+o*o),a>r)){h=!0;break}}if(!e&&h||e)for(d=0;c>d;d++)if(u=this.edges[l[d]],void 0!==u){var p=this.nodes[u.fromId==t.id?u.toId:u.fromId];p.dynamicEdges.length<=this.hubThreshold+n&&p.id!=t.id&&this._addToCluster(t,p,e)}}},_addToCluster:function(t,e,i){t.containedNodes[e.id]=e;for(var n=0;n1)for(var n=0;n1&&(e.label="[".concat(String(e.clusterSize),"]"))}for(t in this.nodes)this.nodes.hasOwnProperty(t)&&(e=this.nodes[t],1==e.clusterSize&&(e.label=void 0!==e.originalLabel?e.originalLabel:String(e.id)))},_nodeInActiveArea:function(t){return Math.abs(t.x-this.areaCenter.x)<=this.constants.clustering.activeAreaBoxSize/this.scale&&Math.abs(t.y-this.areaCenter.y)<=this.constants.clustering.activeAreaBoxSize/this.scale},repositionNodes:function(){for(var t=0;tn&&(n=o.dynamicEdgesLength),t+=o.dynamicEdgesLength,e+=Math.pow(o.dynamicEdgesLength,2),i+=1}t/=i,e/=i;var r=e-Math.pow(t,2),a=Math.sqrt(r);this.hubThreshold=Math.floor(t+2*a),this.hubThreshold>n&&(this.hubThreshold=n)},_reduceAmountOfChains:function(t){this.hubThreshold=2;var e=Math.floor(this.nodeIndices.length*t);for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&2==this.nodes[i].dynamicEdgesLength&&this.nodes[i].dynamicEdges.length>=2&&e>0&&(this._formClusterFromHub(this.nodes[i],!0,!0,1),e-=1)},_getChainFraction:function(){var t=0,e=0;for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&(2==this.nodes[i].dynamicEdgesLength&&this.nodes[i].dynamicEdges.length>=2&&(t+=1),e+=1);return t/e}},SelectionMixin={_getNodesOverlappingWith:function(t,e){var i=this.nodes;for(var n in i)i.hasOwnProperty(n)&&i[n].isOverlappingWith(t)&&e.push(n)},_getAllNodesOverlappingWith:function(t){var e=[];return this._doInAllActiveSectors("_getNodesOverlappingWith",t,e),e},_getAllNavigationNodesOverlappingWith:function(t){var e=[];return this._doInNavigationSector("_getNodesOverlappingWith",t,e),e},_pointerToPositionObject:function(t){var e=this._canvasToX(t.x),i=this._canvasToY(t.y);return{left:e,top:i,right:e,bottom:i}},_pointerToScreenPositionObject:function(t){var e=t.x,i=t.y;return{left:e,top:i,right:e,bottom:i}},_getNavigationNodeAt:function(t){var e=this._pointerToScreenPositionObject(t),i=this._getAllNavigationNodesOverlappingWith(e);return i.length>0?this.sectors.navigation.nodes[i[i.length-1]]:null},_getNodeAt:function(t){var e=this._pointerToPositionObject(t),i=this._getAllNodesOverlappingWith(e);return i.length>0?this.nodes[i[i.length-1]]:null},_getEdgesOverlappingWith:function(t,e){var i=this.edges;for(var n in i)i.hasOwnProperty(n)&&i[n].isOverlappingWith(t)&&e.push(n)},_getAllEdgesOverlappingWith:function(t){var e=[];return this._doInAllActiveSectors("_getEdgesOverlappingWith",t,e),e},_getEdgeAt:function(t){var e=this._pointerToPositionObject(t),i=this._getAllEdgesOverlappingWith(e);return i.length>0?this.edges[i[i.length-1]]:null},_addToSelection:function(t){this.selectionObj[t.id]=t},_removeFromSelection:function(t){delete this.selectionObj[t.id]},_unselectAll:function(t){void 0===t&&(t=!1);for(var e in this.selectionObj)this.selectionObj.hasOwnProperty(e)&&this.selectionObj[e].unselect();this.selectionObj={},0==t&&this._trigger("select",this.getSelection())},_unselectClusters:function(t){void 0===t&&(t=!1);for(var e in this.selectionObj)this.selectionObj.hasOwnProperty(e)&&this.selectionObj[e]instanceof Node&&this.selectionObj[e].clusterSize>1&&(this.selectionObj[e].unselect(),this._removeFromSelection(this.selectionObj[e]));0==t&&this._trigger("select",this.getSelection())},_getSelectedNodeCount:function(){var t=0;for(var e in this.selectionObj)this.selectionObj.hasOwnProperty(e)&&this.selectionObj[e]instanceof Node&&(t+=1);return t},_getSelectedEdgeCount:function(){var t=0;for(var e in this.selectionObj)this.selectionObj.hasOwnProperty(e)&&this.selectionObj[e]instanceof Edge&&(t+=1);return t},_getSelectedObjectCount:function(){var t=0;for(var e in this.selectionObj)this.selectionObj.hasOwnProperty(e)&&(t+=1);return t},_selectionIsEmpty:function(){for(var t in this.selectionObj)if(this.selectionObj.hasOwnProperty(t))return!1;return!0},_clusterInSelection:function(){for(var t in this.selectionObj)if(this.selectionObj.hasOwnProperty(t)&&this.selectionObj[t]instanceof Node&&this.selectionObj[t].clusterSize>1)return!0;return!1},_selectConnectedEdges:function(t){for(var e=0;ee;e++){n=t[e];var s=this.nodes[n];if(!s)throw new RangeError('Node with id "'+n+'" not found');this._selectObject(s,!0,!0)}this.redraw()},_updateSelection:function(){for(var t in this.selectionObj)this.selectionObj.hasOwnProperty(t)&&(this.selectionObj[t]instanceof Node?this.nodes.hasOwnProperty(t)||delete this.selectionObj[t]:this.edges.hasOwnProperty(t)||delete this.selectionObj[t])}},NavigationMixin={_relocateNavigation:function(){if(void 0!==this.sectors){var t=this.navigationClientWidth-this.frame.canvas.clientWidth,e=this.navigationClientHeight-this.frame.canvas.clientHeight;this.navigationClientWidth=this.frame.canvas.clientWidth,this.navigationClientHeight=this.frame.canvas.clientHeight;var i=null;for(var n in this.sectors.navigation.nodes)this.sectors.navigation.nodes.hasOwnProperty(n)&&(i=this.sectors.navigation.nodes[n],i.horizontalAlignLeft||(i.x-=t),i.verticalAlignTop||(i.y-=e))}},_loadNavigationElements:function(){var t=this.constants.navigation.iconPath;this.navigationClientWidth=this.frame.canvas.clientWidth,this.navigationClientHeight=this.frame.canvas.clientHeight,void 0===this.navigationClientWidth&&(this.navigationClientWidth=0,this.navigationClientHeight=0);for(var e=15,i=7,n=[{id:"navigation_up",shape:"image",image:t+"/uparrow.png",triggerFunction:"_moveUp",verticalAlignTop:!1,x:45+e+i,y:this.navigationClientHeight-45-e-i},{id:"navigation_down",shape:"image",image:t+"/downarrow.png",triggerFunction:"_moveDown",verticalAlignTop:!1,x:45+e+i,y:this.navigationClientHeight-15-e},{id:"navigation_left",shape:"image",image:t+"/leftarrow.png",triggerFunction:"_moveLeft",verticalAlignTop:!1,x:15+e,y:this.navigationClientHeight-15-e},{id:"navigation_right",shape:"image",image:t+"/rightarrow.png",triggerFunction:"_moveRight",verticalAlignTop:!1,x:75+e+2*i,y:this.navigationClientHeight-15-e},{id:"navigation_plus",shape:"image",image:t+"/plus.png",triggerFunction:"_zoomIn",verticalAlignTop:!1,horizontalAlignLeft:!1,x:this.navigationClientWidth-45-e-i,y:this.navigationClientHeight-15-e},{id:"navigation_min",shape:"image",image:t+"/minus.png",triggerFunction:"_zoomOut",verticalAlignTop:!1,horizontalAlignLeft:!1,x:this.navigationClientWidth-15-e,y:this.navigationClientHeight-15-e},{id:"navigation_zoomExtends",shape:"image",image:t+"/zoomExtends.png",triggerFunction:"zoomToFit",verticalAlignTop:!1,horizontalAlignLeft:!1,x:this.navigationClientWidth-15-e,y:this.navigationClientHeight-45-e-i}],s=null,o=0;ot.x-t.width&&(n=t.x-t.width),st.y-t.height&&(e=t.y-t.height),i=this.constants.clustering.initialMaxNodes)var n=38.8467/(e-14.50184)+.0116;else var n=42.54117319/(e+39.31966387)+.1944405;else{var s=1.1*(Math.abs(i.minX)+Math.abs(i.maxX)),o=1.1*(Math.abs(i.minY)+Math.abs(i.maxY)),r=this.frame.canvas.clientWidth/s,a=this.frame.canvas.clientHeight/o;n=a>=r?r:a}n>1&&(n=1),this.pinch.mousewheelScale=n,this._setScale(n),this._centerGraph(i),this.start()},Graph.prototype._updateNodeIndexList=function(){this._clearNodeIndexList();for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&this.nodeIndices.push(t)},Graph.prototype.setData=function(t,e){if(void 0===e&&(e=!1),t&&t.dot&&(t.nodes||t.edges))throw new SyntaxError('Data must contain either parameter "dot" or parameter pair "nodes" and "edges", but not both.');if(this.setOptions(t&&t.options),t&&t.dot){if(t&&t.dot){var i=vis.util.DOTToGraph(t.dot);return void this.setData(i)}}else this._setNodes(t&&t.nodes),this._setEdges(t&&t.edges);this._putDataInSector(),e||(this.stabilize&&this._doStabilize(),this.moving=!0,this.start())},Graph.prototype.setOptions=function(t){if(t){if(void 0!==t.width&&(this.width=t.width),void 0!==t.height&&(this.height=t.height),void 0!==t.stabilize&&(this.stabilize=t.stabilize),void 0!==t.selectable&&(this.selectable=t.selectable),t.clustering){this.constants.clustering.enabled=!0;for(var e in t.clustering)t.clustering.hasOwnProperty(e)&&(this.constants.clustering[e]=t.clustering[e])}else void 0!==t.clustering&&(this.constants.clustering.enabled=!1);if(t.navigation){this.constants.navigation.enabled=!0;for(var e in t.navigation)t.navigation.hasOwnProperty(e)&&(this.constants.navigation[e]=t.navigation[e])}else void 0!==t.navigation&&(this.constants.navigation.enabled=!1);if(t.keyboard){this.constants.keyboard.enabled=!0;for(var e in t.keyboard)t.keyboard.hasOwnProperty(e)&&(this.constants.keyboard[e]=t.keyboard[e])}else void 0!==t.keyboard&&(this.constants.keyboard.enabled=!1);if(t.dataManipulationToolbar){this.constants.dataManipulationToolbar.enabled=!0;for(var e in t.dataManipulationToolbar)t.dataManipulationToolbar.hasOwnProperty(e)&&(this.constants.dataManipulationToolbar[e]=t.dataManipulationToolbar[e])}else void 0!==t.dataManipulationToolbar&&(this.constants.dataManipulationToolbar.enabled=!1);if(t.edges){for(e in t.edges)t.edges.hasOwnProperty(e)&&(this.constants.edges[e]=t.edges[e]);void 0!==t.edges.length&&t.nodes&&void 0===t.nodes.distance&&(this.constants.edges.length=t.edges.length,this.constants.nodes.distance=1.25*t.edges.length),t.edges.fontColor||(this.constants.edges.fontColor=t.edges.color),t.edges.dash&&(void 0!==t.edges.dash.length&&(this.constants.edges.dash.length=t.edges.dash.length),void 0!==t.edges.dash.gap&&(this.constants.edges.dash.gap=t.edges.dash.gap),void 0!==t.edges.dash.altLength&&(this.constants.edges.dash.altLength=t.edges.dash.altLength))}if(t.nodes){for(e in t.nodes)t.nodes.hasOwnProperty(e)&&(this.constants.nodes[e]=t.nodes[e]);t.nodes.color&&(this.constants.nodes.color=Node.parseColor(t.nodes.color))}if(t.groups)for(var i in t.groups)if(t.groups.hasOwnProperty(i)){var n=t.groups[i];this.groups.add(i,n)}}this._loadPhysicsSystem(),this._loadNavigationControls(),this._loadManipulationSystem(),this._createKeyBinds(),this.setSize(this.width,this.height),this._setTranslation(this.frame.clientWidth/2,this.frame.clientHeight/2),this._setScale(1),this._redraw()},Graph.prototype.on=function(t,e){var i=["select"];if(-1==i.indexOf(t))throw new Error('Unknown event "'+t+'". Choose from '+i.join());events.addListener(this,t,e)},Graph.prototype.off=function(t,e){events.removeListener(this,t,e)},Graph.prototype._trigger=function(t,e){events.trigger(this,t,e)},Graph.prototype._create=function(){for(;this.containerElement.hasChildNodes();)this.containerElement.removeChild(this.containerElement.firstChild);if(this.frame=document.createElement("div"),this.frame.className="graph-frame",this.frame.style.position="relative",this.frame.style.overflow="hidden",this.frame.style.zIndex="1",this.frame.canvas=document.createElement("canvas"),this.frame.canvas.style.position="relative",this.frame.appendChild(this.frame.canvas),!this.frame.canvas.getContext){var t=document.createElement("DIV");t.style.color="red",t.style.fontWeight="bold",t.style.padding="10px",t.innerHTML="Error: your browser does not support HTML canvas",this.frame.canvas.appendChild(t)}var e=this;this.drag={},this.pinch={},this.hammer=Hammer(this.frame.canvas,{prevent_default:!0}),this.hammer.on("tap",e._onTap.bind(e)),this.hammer.on("doubletap",e._onDoubleTap.bind(e)),this.hammer.on("hold",e._onHold.bind(e)),this.hammer.on("pinch",e._onPinch.bind(e)),this.hammer.on("touch",e._onTouch.bind(e)),this.hammer.on("dragstart",e._onDragStart.bind(e)),this.hammer.on("drag",e._onDrag.bind(e)),this.hammer.on("dragend",e._onDragEnd.bind(e)),this.hammer.on("release",e._onRelease.bind(e)),this.hammer.on("mousewheel",e._onMouseWheel.bind(e)),this.hammer.on("DOMMouseScroll",e._onMouseWheel.bind(e)),this.hammer.on("mousemove",e._onMouseMoveTitle.bind(e)),this.containerElement.appendChild(this.frame)},Graph.prototype._createKeyBinds=function(){var t=this;this.mousetrap=mousetrap,this.mousetrap.reset(),1==this.constants.keyboard.enabled&&(this.mousetrap.bind("up",this._moveUp.bind(t),"keydown"),this.mousetrap.bind("up",this._yStopMoving.bind(t),"keyup"),this.mousetrap.bind("down",this._moveDown.bind(t),"keydown"),this.mousetrap.bind("down",this._yStopMoving.bind(t),"keyup"),this.mousetrap.bind("left",this._moveLeft.bind(t),"keydown"),this.mousetrap.bind("left",this._xStopMoving.bind(t),"keyup"),this.mousetrap.bind("right",this._moveRight.bind(t),"keydown"),this.mousetrap.bind("right",this._xStopMoving.bind(t),"keyup"),this.mousetrap.bind("=",this._zoomIn.bind(t),"keydown"),this.mousetrap.bind("=",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("-",this._zoomOut.bind(t),"keydown"),this.mousetrap.bind("-",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("[",this._zoomIn.bind(t),"keydown"),this.mousetrap.bind("[",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("]",this._zoomOut.bind(t),"keydown"),this.mousetrap.bind("]",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("pageup",this._zoomIn.bind(t),"keydown"),this.mousetrap.bind("pageup",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("pagedown",this._zoomOut.bind(t),"keydown"),this.mousetrap.bind("pagedown",this._stopZoom.bind(t),"keyup")),this.mousetrap.bind("b",this._toggleBarnesHut.bind(t)),1==this.constants.dataManipulationToolbar.enabled&&this.mousetrap.bind("escape",this._createManipulatorBar.bind(t))},Graph.prototype._getPointer=function(t){return{x:t.pageX-vis.util.getAbsoluteLeft(this.frame.canvas),y:t.pageY-vis.util.getAbsoluteTop(this.frame.canvas)}},Graph.prototype._onTouch=function(t){this.drag.pointer=this._getPointer(t.gesture.touches[0]),this.drag.pinched=!1,this.pinch.scale=this._getScale(),this._handleTouch(this.drag.pointer)},Graph.prototype._onDragStart=function(){var t=this.drag,e=this._getNodeAt(t.pointer);if(t.dragging=!0,t.selection=[],t.translation=this._getTranslation(),t.nodeId=null,null!=e){t.nodeId=e.id,e.isSelected()||this._selectObject(e,!1);for(var i in this.selectionObj)if(this.selectionObj.hasOwnProperty(i)){var n=this.selectionObj[i];if(n instanceof Node){var s={id:n.id,node:n,x:n.x,y:n.y,xFixed:n.xFixed,yFixed:n.yFixed};n.xFixed=!0,n.yFixed=!0,t.selection.push(s)}}}},Graph.prototype._onDrag=function(t){if(!this.drag.pinched){var e=this._getPointer(t.gesture.touches[0]),i=this,n=this.drag,s=n.selection;if(s&&s.length){var o=e.x-n.pointer.x,r=e.y-n.pointer.y;s.forEach(function(t){var e=t.node;t.xFixed||(e.x=i._canvasToX(i._xToCanvas(t.x)+o)),t.yFixed||(e.y=i._canvasToY(i._yToCanvas(t.y)+r))}),this.moving||(this.moving=!0,this.start())}else{var a=e.x-this.drag.pointer.x,h=e.y-this.drag.pointer.y;this._setTranslation(this.drag.translation.x+a,this.drag.translation.y+h),this._redraw(),this.moved=!0}}},Graph.prototype._onDragEnd=function(){this.drag.dragging=!1;var t=this.drag.selection;t&&t.forEach(function(t){t.node.xFixed=t.xFixed,t.node.yFixed=t.yFixed})},Graph.prototype._onTap=function(t){var e=this._getPointer(t.gesture.touches[0]);this.pointerPosition=e,this._handleTap(e)},Graph.prototype._onDoubleTap=function(t){var e=this._getPointer(t.gesture.touches[0]);this._handleDoubleTap(e)},Graph.prototype._onHold=function(t){var e=this._getPointer(t.gesture.touches[0]);this.pointerPosition=e,this._handleOnHold(e)},Graph.prototype._onRelease=function(){this._handleOnRelease()},Graph.prototype._onPinch=function(t){var e=this._getPointer(t.gesture.center);this.drag.pinched=!0,"scale"in this.pinch||(this.pinch.scale=1);var i=this.pinch.scale*t.gesture.scale;this._zoom(i,e)},Graph.prototype._zoom=function(t,e){var i=this._getScale();1e-5>t&&(t=1e-5),t>10&&(t=10);var n=this._getTranslation(),s=t/i,o=(1-s)*e.x+n.x*s,r=(1-s)*e.y+n.y*s;return this.areaCenter={x:this._canvasToX(e.x),y:this._canvasToY(e.y)},this.pinch.mousewheelScale=t,this._setScale(t),this._setTranslation(o,r),this.updateClustersDefault(),this._redraw(),t},Graph.prototype._onMouseWheel=function(t){var e=0;if(t.wheelDelta?e=t.wheelDelta/120:t.detail&&(e=-t.detail/3),e){"mousewheelScale"in this.pinch||(this.pinch.mousewheelScale=1);var i=this.pinch.mousewheelScale,n=e/10;0>e&&(n/=1-n),i*=1+n;var s=util.fakeGesture(this,t),o=this._getPointer(s.center);i=this._zoom(i,o)}t.preventDefault()},Graph.prototype._onMouseMoveTitle=function(t){var e=util.fakeGesture(this,t),i=this._getPointer(e.center);this.popupNode&&this._checkHidePopup(i);var n=this,s=function(){n._checkShowPopup(i)};this.popupTimer&&clearInterval(this.popupTimer),this.drag.dragging||(this.popupTimer=setTimeout(s,300))},Graph.prototype._checkShowPopup=function(t){var e,i={left:this._canvasToX(t.x),top:this._canvasToY(t.y),right:this._canvasToX(t.x),bottom:this._canvasToY(t.y)},n=this.popupNode;if(void 0==this.popupNode){var s=this.nodes;for(e in s)if(s.hasOwnProperty(e)){var o=s[e];if(void 0!==o.getTitle()&&o.isOverlappingWith(i)){this.popupNode=o;break}}}if(void 0===this.popupNode){var r=this.edges;for(e in r)if(r.hasOwnProperty(e)){var a=r[e];if(a.connected&&void 0!==a.getTitle()&&a.isOverlappingWith(i)){this.popupNode=a;break}}}if(this.popupNode){if(this.popupNode!=n){var h=this;h.popup||(h.popup=new Popup(h.frame)),h.popup.setPosition(t.x-3,t.y-3),h.popup.setText(h.popupNode.getTitle()),h.popup.show()}}else this.popup&&this.popup.hide()},Graph.prototype._checkHidePopup=function(t){this.popupNode&&this._getNodeAt(t)||(this.popupNode=void 0,this.popup&&this.popup.hide())},Graph.prototype._getConnectionCount=function(t){function e(t){for(var e=[],i=0,n=t.length;n>i;i++)for(var s=t[i],o=s.edges,r=0,a=o.length;a>r;r++){var h=o[r],l=null;h.from==s?l=h.to:h.to==s&&(l=h.from);var c,d;if(l)for(c=0,d=t.length;d>c;c++)if(t[c]==l){l=null;break}if(l)for(c=0,d=e.length;d>c;c++)if(e[c]==l){l=null;break}l&&e.push(l)}return e}void 0==t&&(t=1);var i=[],n=this.nodes;for(var s in n)if(n.hasOwnProperty(s)){for(var o=[n[s]],r=0;t>r;r++)o=o.concat(e(o));i.push(o)}for(var a=[],h=0,l=i.length;l>h;h++)a.push(i[h].length);return a},Graph.prototype.setSize=function(t,e){this.frame.style.width=t,this.frame.style.height=e,this.frame.canvas.style.width="100%",this.frame.canvas.style.height="100%",this.frame.canvas.width=this.frame.canvas.clientWidth,this.frame.canvas.height=this.frame.canvas.clientHeight,void 0!==this.manipulationDiv&&(this.manipulationDiv.style.width=this.frame.canvas.clientWidth),1==this.constants.navigation.enabled&&this._relocateNavigation()},Graph.prototype._setNodes=function(t){var e=this.nodesData;if(t instanceof DataSet||t instanceof DataView)this.nodesData=t;else if(t instanceof Array)this.nodesData=new DataSet,this.nodesData.add(t);else{if(t)throw new TypeError("Array or DataSet expected");this.nodesData=new DataSet}if(e&&util.forEach(this.nodesListeners,function(t,i){e.unsubscribe(i,t)}),this.nodes={},this.nodesData){var i=this;util.forEach(this.nodesListeners,function(t,e){i.nodesData.subscribe(e,t)});var n=this.nodesData.getIds();this._addNodes(n)}this._updateSelection()},Graph.prototype._addNodes=function(t){for(var e,i=0,n=t.length;n>i;i++){e=t[i];var s=this.nodesData.get(e),o=new Node(s,this.images,this.groups,this.constants);if(this.nodes[e]=o,!o.isFixed()&&1!=this.createNodeOnClick){var r=this.constants.edges.length,a=t.length,h=2*Math.PI*(i/a);o.x=r*Math.cos(h),o.y=r*Math.sin(h),this.moving=!0}}this._updateNodeIndexList(),this._reconnectEdges(),this._updateValueRange(this.nodes),this.updateLabels()},Graph.prototype._updateNodes=function(t){for(var e=this.nodes,i=this.nodesData,n=0,s=t.length;s>n;n++){var o=t[n],r=e[o],a=i.get(o);r?r.setProperties(a,this.constants):(r=new Node(properties,this.images,this.groups,this.constants),e[o]=r,r.isFixed()||(this.moving=!0))}this._updateNodeIndexList(),this._reconnectEdges(),this._updateValueRange(e)},Graph.prototype._removeNodes=function(t){for(var e=this.nodes,i=0,n=t.length;n>i;i++){var s=t[i];delete e[s]}this._updateNodeIndexList(),this._reconnectEdges(),this._updateSelection(),this._updateValueRange(e)},Graph.prototype._setEdges=function(t){var e=this.edgesData;if(t instanceof DataSet||t instanceof DataView)this.edgesData=t;else if(t instanceof Array)this.edgesData=new DataSet,this.edgesData.add(t);else{if(t)throw new TypeError("Array or DataSet expected");this.edgesData=new DataSet}if(e&&util.forEach(this.edgesListeners,function(t,i){e.unsubscribe(i,t)}),this.edges={},this.edgesData){var i=this;util.forEach(this.edgesListeners,function(t,e){i.edgesData.subscribe(e,t)});var n=this.edgesData.getIds();this._addEdges(n)}this._reconnectEdges()},Graph.prototype._addEdges=function(t){for(var e=this.edges,i=this.edgesData,n=0,s=t.length;s>n;n++){var o=t[n],r=e[o];r&&r.disconnect();var a=i.get(o,{showInternalIds:!0});e[o]=new Edge(a,this,this.constants)}this.moving=!0,this._updateValueRange(e)},Graph.prototype._updateEdges=function(t){for(var e=this.edges,i=this.edgesData,n=0,s=t.length;s>n;n++){var o=t[n],r=i.get(o),a=e[o];a?(a.disconnect(),a.setProperties(r,this.constants),a.connect()):(a=new Edge(r,this,this.constants),this.edges[o]=a)}this.moving=!0,this._updateValueRange(e)},Graph.prototype._removeEdges=function(t){for(var e=this.edges,i=0,n=t.length;n>i;i++){var s=t[i],o=e[s];o&&(o.disconnect(),delete e[s])}this.moving=!0,this._updateValueRange(e)},Graph.prototype._reconnectEdges=function(){var t,e=this.nodes,i=this.edges;for(t in e)e.hasOwnProperty(t)&&(e[t].edges=[]);for(t in i)if(i.hasOwnProperty(t)){var n=i[t];n.from=null,n.to=null,n.connect()}},Graph.prototype._updateValueRange=function(t){var e,i=void 0,n=void 0;for(e in t)if(t.hasOwnProperty(e)){var s=t[e].getValue();void 0!==s&&(i=void 0===i?s:Math.min(s,i),n=void 0===n?s:Math.max(s,n))}if(void 0!==i&&void 0!==n)for(e in t)t.hasOwnProperty(e)&&t[e].setValueRange(i,n)},Graph.prototype.redraw=function(){this.setSize(this.width,this.height),this._redraw()},Graph.prototype._redraw=function(){var t=this.frame.canvas.getContext("2d"),e=this.frame.canvas.width,i=this.frame.canvas.height;t.clearRect(0,0,e,i),t.save(),t.translate(this.translation.x,this.translation.y),t.scale(this.scale,this.scale),this.canvasTopLeft={x:this._canvasToX(0),y:this._canvasToY(0)},this.canvasBottomRight={x:this._canvasToX(this.frame.canvas.clientWidth),y:this._canvasToY(this.frame.canvas.clientHeight)},this._doInAllSectors("_drawAllSectorNodes",t),this._doInAllSectors("_drawEdges",t),this._doInAllSectors("_drawNodes",t,!0),t.restore(),1==this.constants.navigation.enabled&&this._doInNavigationSector("_drawNodes",t,!0)},Graph.prototype._setTranslation=function(t,e){void 0===this.translation&&(this.translation={x:0,y:0}),void 0!==t&&(this.translation.x=t),void 0!==e&&(this.translation.y=e)},Graph.prototype._getTranslation=function(){return{x:this.translation.x,y:this.translation.y}},Graph.prototype._setScale=function(t){this.scale=t},Graph.prototype._getScale=function(){return this.scale},Graph.prototype._canvasToX=function(t){return(t-this.translation.x)/this.scale},Graph.prototype._xToCanvas=function(t){return t*this.scale+this.translation.x},Graph.prototype._canvasToY=function(t){return(t-this.translation.y)/this.scale},Graph.prototype._yToCanvas=function(t){return t*this.scale+this.translation.y},Graph.prototype._drawNodes=function(t,e){void 0===e&&(e=!1);var i=this.nodes,n=[];for(var s in i)i.hasOwnProperty(s)&&(i[s].setScaleAndPos(this.scale,this.canvasTopLeft,this.canvasBottomRight),i[s].isSelected()?n.push(s):(i[s].inArea()||e)&&i[s].draw(t));for(var o=0,r=n.length;r>o;o++)(i[n[o]].inArea()||e)&&i[n[o]].draw(t)},Graph.prototype._drawEdges=function(t){var e=this.edges;for(var i in e)if(e.hasOwnProperty(i)){var n=e[i];n.setScale(this.scale),n.connected&&e[i].draw(t)}},Graph.prototype._doStabilize=function(){for(var t=0,e=this.constants.minVelocity,i=!1;!i&&t0)for(var i in e)e.hasOwnProperty(i)&&e[i].discreteStepLimited(t,this.constants.maxVelocity);else for(var i in e)e.hasOwnProperty(i)&&e[i].discreteStep(t);var n=this.constants.minVelocity;this.moving=this._isMoving(n)},Graph.prototype.start=function(){if(!this.freezeSimulation)if(this.moving&&(this._doInAllActiveSectors("_initializeForceCalculation"),this._doInAllActiveSectors("_discreteStepNodes"),this._findCenter(this._getRange())),this.moving||0!=this.xIncrement||0!=this.yIncrement||0!=this.zoomIncrement){if(!this.timer){var t=this;this.timer=window.setTimeout(function(){if(t.timer=void 0,0!=t.xIncrement||0!=t.yIncrement){var e=t._getTranslation();t._setTranslation(e.x+t.xIncrement,e.y+t.yIncrement)}if(0!=t.zoomIncrement){var i={x:t.frame.canvas.clientWidth/2,y:t.frame.canvas.clientHeight/2};t._zoom(t.scale*(1+t.zoomIncrement),i)}var n=Date.now();t.start(),t.start();var s=(Date.now()-n,Date.now());t._redraw();Date.now()-s},this.renderTimestep)}}else this._redraw()},Graph.prototype.singleStep=function(){if(this.moving){this._initializeForceCalculation(),this._discreteStepNodes();var t=this.constants.minVelocity;this.moving=this._isMoving(t),this._redraw()}},Graph.prototype.toggleFreeze=function(){0==this.freezeSimulation?this.freezeSimulation=!0:(this.freezeSimulation=!1,this.start())},Graph.prototype._initializeMixinLoaders=function(){for(var t in graphMixinLoaders)graphMixinLoaders.hasOwnProperty(t)&&(Graph.prototype[t]=graphMixinLoaders[t])};var vis={util:util,events:events,Controller:Controller,DataSet:DataSet,DataView:DataView,Range:Range,Stack:Stack,TimeStep:TimeStep,EventBus:EventBus,components:{items:{Item:Item,ItemBox:ItemBox,ItemPoint:ItemPoint,ItemRange:ItemRange},Component:Component,Panel:Panel,RootPanel:RootPanel,ItemSet:ItemSet,TimeAxis:TimeAxis},graph:{Node:Node,Edge:Edge,Popup:Popup,Groups:Groups,Images:Images},Timeline:Timeline,Graph:Graph};"undefined"!=typeof exports&&(exports=vis),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=vis),"function"==typeof define&&define(function(){return vis}),"undefined"!=typeof window&&(window.vis=vis)},{hammerjs:2,moment:3,mousetrap:4}],2:[function(t,e){!function(t,i){"use strict";function n(){if(!s.READY){s.event.determineEventTypes();for(var t in s.gestures)s.gestures.hasOwnProperty(t)&&s.detection.register(s.gestures[t]);s.event.onTouch(s.DOCUMENT,s.EVENT_MOVE,s.detection.detect),s.event.onTouch(s.DOCUMENT,s.EVENT_END,s.detection.detect),s.READY=!0}}var s=function(t,e){return new s.Instance(t,e||{})};s.defaults={stop_browser_behavior:{userSelect:"none",touchAction:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},s.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,s.HAS_TOUCHEVENTS="ontouchstart"in t,s.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android/i,s.NO_MOUSEEVENTS=s.HAS_TOUCHEVENTS&&navigator.userAgent.match(s.MOBILE_REGEX),s.EVENT_TYPES={},s.DIRECTION_DOWN="down",s.DIRECTION_LEFT="left",s.DIRECTION_UP="up",s.DIRECTION_RIGHT="right",s.POINTER_MOUSE="mouse",s.POINTER_TOUCH="touch",s.POINTER_PEN="pen",s.EVENT_START="start",s.EVENT_MOVE="move",s.EVENT_END="end",s.DOCUMENT=document,s.plugins={},s.READY=!1,s.Instance=function(t,e){var i=this;return n(),this.element=t,this.enabled=!0,this.options=s.utils.extend(s.utils.extend({},s.defaults),e||{}),this.options.stop_browser_behavior&&s.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),s.event.onTouch(t,s.EVENT_START,function(t){i.enabled&&s.detection.startDetect(i,t)}),this},s.Instance.prototype={on:function(t,e){for(var i=t.split(" "),n=0;n0&&e==s.EVENT_END?e=s.EVENT_MOVE:c||(e=s.EVENT_END),c||null===o?o=h:h=o,i.call(s.detection,n.collectEventData(t,e,h)),s.HAS_POINTEREVENTS&&e==s.EVENT_END&&(c=s.PointerEvent.updatePointer(e,h))),c||(o=null,r=!1,a=!1,s.PointerEvent.reset())}})},determineEventTypes:function(){var t;t=s.HAS_POINTEREVENTS?s.PointerEvent.getEvents():s.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],s.EVENT_TYPES[s.EVENT_START]=t[0],s.EVENT_TYPES[s.EVENT_MOVE]=t[1],s.EVENT_TYPES[s.EVENT_END]=t[2]},getTouchList:function(t){return s.HAS_POINTEREVENTS?s.PointerEvent.getTouchList():t.touches?t.touches:[{identifier:1,pageX:t.pageX,pageY:t.pageY,target:t.target}]},collectEventData:function(t,e,i){var n=this.getTouchList(i,e),o=s.POINTER_TOUCH;return(i.type.match(/mouse/)||s.PointerEvent.matchType(s.POINTER_MOUSE,i))&&(o=s.POINTER_MOUSE),{center:s.utils.getCenter(n),timeStamp:(new Date).getTime(),target:i.target,touches:n,eventType:e,pointerType:o,srcEvent:i,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault&&this.srcEvent.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return s.detection.stopDetect()}}}},s.PointerEvent={pointers:{},getTouchList:function(){var t=this,e=[];return Object.keys(t.pointers).sort().forEach(function(i){e.push(t.pointers[i])}),e},updatePointer:function(t,e){return t==s.EVENT_END?this.pointers={}:(e.identifier=e.pointerId,this.pointers[e.pointerId]=e),Object.keys(this.pointers).length},matchType:function(t,e){if(!e.pointerType)return!1;var i={};return i[s.POINTER_MOUSE]=e.pointerType==e.MSPOINTER_TYPE_MOUSE||e.pointerType==s.POINTER_MOUSE,i[s.POINTER_TOUCH]=e.pointerType==e.MSPOINTER_TYPE_TOUCH||e.pointerType==s.POINTER_TOUCH,i[s.POINTER_PEN]=e.pointerType==e.MSPOINTER_TYPE_PEN||e.pointerType==s.POINTER_PEN,i[t]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},s.utils={extend:function(t,e,n){for(var s in e)t[s]!==i&&n||(t[s]=e[s]);return t},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){for(var e=[],i=[],n=0,s=t.length;s>n;n++)e.push(t[n].pageX),i.push(t[n].pageY);return{pageX:(Math.min.apply(Math,e)+Math.max.apply(Math,e))/2,pageY:(Math.min.apply(Math,i)+Math.max.apply(Math,i))/2}},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.pageY-t.pageY,n=e.pageX-t.pageX;return 180*Math.atan2(i,n)/Math.PI},getDirection:function(t,e){var i=Math.abs(t.pageX-e.pageX),n=Math.abs(t.pageY-e.pageY);return i>=n?t.pageX-e.pageX>0?s.DIRECTION_LEFT:s.DIRECTION_RIGHT:t.pageY-e.pageY>0?s.DIRECTION_UP:s.DIRECTION_DOWN},getDistance:function(t,e){var i=e.pageX-t.pageX,n=e.pageY-t.pageY;return Math.sqrt(i*i+n*n)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(t){return t==s.DIRECTION_UP||t==s.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,e){var i,n=["webkit","khtml","moz","ms","o",""];if(e&&t.style){for(var s=0;si;i++){var o=this.gestures[i];if(!this.stopped&&e[o.name]!==!1&&o.handler.call(o,t,this.current.inst)===!1){this.stopDetect();break}}return this.current&&(this.current.lastEvent=t),t.eventType==s.EVENT_END&&!t.touches.length-1&&this.stopDetect(),t}},stopDetect:function(){this.previous=s.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(t){var e=this.current.startEvent;if(e&&(t.touches.length!=e.touches.length||t.touches===e.touches)){e.touches=[];for(var i=0,n=t.touches.length;n>i;i++)e.touches.push(s.utils.extend({},t.touches[i]))}var o=t.timeStamp-e.timeStamp,r=t.center.pageX-e.center.pageX,a=t.center.pageY-e.center.pageY,h=s.utils.getVelocity(o,r,a);return s.utils.extend(t,{deltaTime:o,deltaX:r,deltaY:a,velocityX:h.x,velocityY:h.y,distance:s.utils.getDistance(e.center,t.center),angle:s.utils.getAngle(e.center,t.center),direction:s.utils.getDirection(e.center,t.center),scale:s.utils.getScale(e.touches,t.touches),rotation:s.utils.getRotation(e.touches,t.touches),startEvent:e}),t},register:function(t){var e=t.defaults||{};return e[t.name]===i&&(e[t.name]=!0),s.utils.extend(s.defaults,e,!0),t.index=t.index||1e3,this.gestures.push(t),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},s.gestures=s.gestures||{},s.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(t,e){switch(t.eventType){case s.EVENT_START:clearTimeout(this.timer),s.detection.current.name=this.name,this.timer=setTimeout(function(){"hold"==s.detection.current.name&&e.trigger("hold",t)},e.options.hold_timeout);break;case s.EVENT_MOVE:t.distance>e.options.hold_threshold&&clearTimeout(this.timer); -break;case s.EVENT_END:clearTimeout(this.timer)}}},s.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(t,e){if(t.eventType==s.EVENT_END){var i=s.detection.previous,n=!1;if(t.deltaTime>e.options.tap_max_touchtime||t.distance>e.options.tap_max_distance)return;i&&"tap"==i.name&&t.timeStamp-i.lastEvent.timeStamp0&&t.touches.length>e.options.swipe_max_touches)return;(t.velocityX>e.options.swipe_velocity||t.velocityY>e.options.swipe_velocity)&&(e.trigger(this.name,t),e.trigger(this.name+t.direction,t))}}},s.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,drag_max_touches:1,drag_block_horizontal:!1,drag_block_vertical:!1,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(t,e){if(s.detection.current.name!=this.name&&this.triggered)return e.trigger(this.name+"end",t),void(this.triggered=!1);if(!(e.options.drag_max_touches>0&&t.touches.length>e.options.drag_max_touches))switch(t.eventType){case s.EVENT_START:this.triggered=!1;break;case s.EVENT_MOVE:if(t.distancee.options.transform_min_rotation&&e.trigger("rotate",t),i>e.options.transform_min_scale&&(e.trigger("pinch",t),e.trigger("pinch"+(t.scale<1?"in":"out"),t));break;case s.EVENT_END:this.triggered&&e.trigger(this.name+"end",t),this.triggered=!1}}},s.gestures.Touch={name:"touch",index:-1/0,defaults:{prevent_default:!1,prevent_mouseevents:!1},handler:function(t,e){return e.options.prevent_mouseevents&&t.pointerType==s.POINTER_MOUSE?void t.stopDetect():(e.options.prevent_default&&t.preventDefault(),void(t.eventType==s.EVENT_START&&e.trigger(this.name,t)))}},s.gestures.Release={name:"release",index:1/0,handler:function(t,e){t.eventType==s.EVENT_END&&e.trigger(this.name,t)}},"object"==typeof e&&"object"==typeof e.exports?e.exports=s:(t.Hammer=s,"function"==typeof t.define&&t.define.amd&&t.define("hammer",[],function(){return s}))}(this)},{}],3:[function(t,e){(function(i){function n(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function s(t,e){return function(i){return u(t.call(this,i),e)}}function o(t,e){return function(i){return this.lang().ordinal(t.call(this,i),e)}}function r(){}function a(t){E(t),l(this,t)}function h(t){var e=y(t),i=e.year||0,n=e.month||0,s=e.week||0,o=e.day||0,r=e.hour||0,a=e.minute||0,h=e.second||0,l=e.millisecond||0;this._milliseconds=+l+1e3*h+6e4*a+36e5*r,this._days=+o+7*s,this._months=+n+12*i,this._data={},this._bubble()}function l(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return e.hasOwnProperty("toString")&&(t.toString=e.toString),e.hasOwnProperty("valueOf")&&(t.valueOf=e.valueOf),t}function c(t){var e,i={};for(e in t)t.hasOwnProperty(e)&&ye.hasOwnProperty(e)&&(i[e]=t[e]);return i}function d(t){return 0>t?Math.ceil(t):Math.floor(t)}function u(t,e,i){for(var n=""+Math.abs(t),s=t>=0;n.lengthn;n++)(i&&t[n]!==e[n]||!i&&b(t[n])!==b(e[n]))&&r++;return r+o}function v(t){if(t){var e=t.toLowerCase().replace(/(.)s$/,"$1");t=Xe[t]||qe[e]||e}return t}function y(t){var e,i,n={};for(i in t)t.hasOwnProperty(i)&&(e=v(i),e&&(n[e]=t[i]));return n}function _(t){var e,n;if(0===t.indexOf("week"))e=7,n="day";else{if(0!==t.indexOf("month"))return;e=12,n="month"}oe[t]=function(s,o){var r,a,h=oe.fn._lang[t],l=[];if("number"==typeof s&&(o=s,s=i),a=function(t){var e=oe().utc().set(n,t);return h.call(oe.fn._lang,e,s||"")},null!=o)return a(o);for(r=0;e>r;r++)l.push(a(r));return l}}function b(t){var e=+t,i=0;return 0!==e&&isFinite(e)&&(i=e>=0?Math.floor(e):Math.ceil(e)),i}function w(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function S(t){return T(t)?366:365}function T(t){return t%4===0&&t%100!==0||t%400===0}function E(t){var e;t._a&&-2===t._pf.overflow&&(e=t._a[de]<0||t._a[de]>11?de:t._a[ue]<1||t._a[ue]>w(t._a[ce],t._a[de])?ue:t._a[pe]<0||t._a[pe]>23?pe:t._a[fe]<0||t._a[fe]>59?fe:t._a[ge]<0||t._a[ge]>59?ge:t._a[me]<0||t._a[me]>999?me:-1,t._pf._overflowDayOfYear&&(ce>e||e>ue)&&(e=ue),t._pf.overflow=e)}function x(t){return null==t._isValid&&(t._isValid=!isNaN(t._d.getTime())&&t._pf.overflow<0&&!t._pf.empty&&!t._pf.invalidMonth&&!t._pf.nullInput&&!t._pf.invalidFormat&&!t._pf.userInvalidated,t._strict&&(t._isValid=t._isValid&&0===t._pf.charsLeftOver&&0===t._pf.unusedTokens.length)),t._isValid}function C(t){return t?t.toLowerCase().replace("_","-"):t}function M(t,e){return e._isUTC?oe(t).zone(e._offset||0):oe(t).local()}function D(t,e){return e.abbr=t,ve[t]||(ve[t]=new r),ve[t].set(e),ve[t]}function I(t){delete ve[t]}function N(e){var i,n,s,o,r=0,a=function(e){if(!ve[e]&&_e)try{t("./lang/"+e)}catch(i){}return ve[e]};if(!e)return oe.fn._lang;if(!f(e)){if(n=a(e))return n;e=[e]}for(;r0;){if(n=a(o.slice(0,i).join("-")))return n;if(s&&s.length>=i&&m(o,s,!0)>=i-1)break;i--}r++}return oe.fn._lang}function O(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function L(t){var e,i,n=t.match(Te);for(e=0,i=n.length;i>e;e++)n[e]=Qe[n[e]]?Qe[n[e]]:O(n[e]);return function(s){var o="";for(e=0;i>e;e++)o+=n[e]instanceof Function?n[e].call(s,t):n[e];return o}}function k(t,e){return t.isValid()?(e=A(e,t.lang()),Ze[e]||(Ze[e]=L(e)),Ze[e](t)):t.lang().invalidDate()}function A(t,e){function i(t){return e.longDateFormat(t)||t}var n=5;for(Ee.lastIndex=0;n>=0&&Ee.test(t);)t=t.replace(Ee,i),Ee.lastIndex=0,n-=1;return t}function P(t,e){var i,n=e._strict;switch(t){case"DDDD":return ze;case"YYYY":case"GGGG":case"gggg":return n?Fe:Me;case"Y":case"G":case"g":return Ye;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return n?Re:De;case"S":if(n)return Ae;case"SS":if(n)return Pe;case"SSS":if(n)return ze;case"DDD":return Ce;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Ne;case"a":case"A":return N(e._l)._meridiemParse;case"X":return ke;case"Z":case"ZZ":return Oe;case"T":return Le;case"SSSS":return Ie;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return n?Pe:xe;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return xe;default:return i=new RegExp(j(G(t.replace("\\","")),"i"))}}function z(t){t=t||"";var e=t.match(Oe)||[],i=e[e.length-1]||[],n=(i+"").match(Ue)||["-",0,0],s=+(60*n[1])+b(n[2]);return"+"===n[0]?-s:s}function F(t,e,i){var n,s=i._a;switch(t){case"M":case"MM":null!=e&&(s[de]=b(e)-1);break;case"MMM":case"MMMM":n=N(i._l).monthsParse(e),null!=n?s[de]=n:i._pf.invalidMonth=e;break;case"D":case"DD":null!=e&&(s[ue]=b(e));break;case"DDD":case"DDDD":null!=e&&(i._dayOfYear=b(e));break;case"YY":s[ce]=b(e)+(b(e)>68?1900:2e3);break;case"YYYY":case"YYYYY":case"YYYYYY":s[ce]=b(e);break;case"a":case"A":i._isPm=N(i._l).isPM(e);break;case"H":case"HH":case"h":case"hh":s[pe]=b(e);break;case"m":case"mm":s[fe]=b(e);break;case"s":case"ss":s[ge]=b(e);break;case"S":case"SS":case"SSS":case"SSSS":s[me]=b(1e3*("0."+e));break;case"X":i._d=new Date(1e3*parseFloat(e));break;case"Z":case"ZZ":i._useUTC=!0,i._tzm=z(e);break;case"w":case"ww":case"W":case"WW":case"d":case"dd":case"ddd":case"dddd":case"e":case"E":t=t.substr(0,1);case"gg":case"gggg":case"GG":case"GGGG":case"GGGGG":t=t.substr(0,2),e&&(i._w=i._w||{},i._w[t]=e)}}function R(t){var e,i,n,s,o,r,a,h,l,c,d=[];if(!t._d){for(n=H(t),t._w&&null==t._a[ue]&&null==t._a[de]&&(o=function(e){var i=parseInt(e,10);return e?e.length<3?i>68?1900+i:2e3+i:i:null==t._a[ce]?oe().weekYear():t._a[ce]},r=t._w,null!=r.GG||null!=r.W||null!=r.E?a=J(o(r.GG),r.W||1,r.E,4,1):(h=N(t._l),l=null!=r.d?Z(r.d,h):null!=r.e?parseInt(r.e,10)+h._week.dow:0,c=parseInt(r.w,10)||1,null!=r.d&&lS(s)&&(t._pf._overflowDayOfYear=!0),i=q(s,0,t._dayOfYear),t._a[de]=i.getUTCMonth(),t._a[ue]=i.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=d[e]=n[e];for(;7>e;e++)t._a[e]=d[e]=null==t._a[e]?2===e?1:0:t._a[e];d[pe]+=b((t._tzm||0)/60),d[fe]+=b((t._tzm||0)%60),t._d=(t._useUTC?q:X).apply(null,d)}}function Y(t){var e;t._d||(e=y(t._i),t._a=[e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond],R(t))}function H(t){var e=new Date;return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function W(t){t._a=[],t._pf.empty=!0;var e,i,n,s,o,r=N(t._l),a=""+t._i,h=a.length,l=0;for(n=A(t._f,r).match(Te)||[],e=0;e0&&t._pf.unusedInput.push(o),a=a.slice(a.indexOf(i)+i.length),l+=i.length),Qe[s]?(i?t._pf.empty=!1:t._pf.unusedTokens.push(s),F(s,i,t)):t._strict&&!i&&t._pf.unusedTokens.push(s);t._pf.charsLeftOver=h-l,a.length>0&&t._pf.unusedInput.push(a),t._isPm&&t._a[pe]<12&&(t._a[pe]+=12),t._isPm===!1&&12===t._a[pe]&&(t._a[pe]=0),R(t),E(t)}function G(t){return t.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,i,n,s){return e||i||n||s})}function j(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function U(t){var e,i,s,o,r;if(0===t._f.length)return t._pf.invalidFormat=!0,void(t._d=new Date(0/0));for(o=0;or)&&(s=r,i=e));l(t,i||e)}function B(t){var e,i,n=t._i,s=He.exec(n);if(s){for(t._pf.iso=!0,e=0,i=Ge.length;i>e;e++)if(Ge[e][1].exec(n)){t._f=Ge[e][0]+(s[6]||" ");break}for(e=0,i=je.length;i>e;e++)if(je[e][1].exec(n)){t._f+=je[e][0];break}n.match(Oe)&&(t._f+="Z"),W(t)}else t._d=new Date(n)}function V(t){var e=t._i,n=be.exec(e);e===i?t._d=new Date:n?t._d=new Date(+n[1]):"string"==typeof e?B(t):f(e)?(t._a=e.slice(0),R(t)):g(e)?t._d=new Date(+e):"object"==typeof e?Y(t):t._d=new Date(e)}function X(t,e,i,n,s,o,r){var a=new Date(t,e,i,n,s,o,r);return 1970>t&&a.setFullYear(t),a}function q(t){var e=new Date(Date.UTC.apply(null,arguments));return 1970>t&&e.setUTCFullYear(t),e}function Z(t,e){if("string"==typeof t)if(isNaN(t)){if(t=e.weekdaysParse(t),"number"!=typeof t)return null}else t=parseInt(t,10);return t}function K(t,e,i,n,s){return s.relativeTime(e||1,!!i,t,n)}function $(t,e,i){var n=le(Math.abs(t)/1e3),s=le(n/60),o=le(s/60),r=le(o/24),a=le(r/365),h=45>n&&["s",n]||1===s&&["m"]||45>s&&["mm",s]||1===o&&["h"]||22>o&&["hh",o]||1===r&&["d"]||25>=r&&["dd",r]||45>=r&&["M"]||345>r&&["MM",le(r/30)]||1===a&&["y"]||["yy",a];return h[2]=e,h[3]=t>0,h[4]=i,K.apply({},h)}function Q(t,e,i){var n,s=i-e,o=i-t.day();return o>s&&(o-=7),s-7>o&&(o+=7),n=oe(t).add("d",o),{week:Math.ceil(n.dayOfYear()/7),year:n.year()}}function J(t,e,i,n,s){var o,r,a=q(t,0,1).getUTCDay();return i=null!=i?i:s,o=s-a+(a>n?7:0)-(s>a?7:0),r=7*(e-1)+(i-s)+o+1,{year:r>0?t:t-1,dayOfYear:r>0?r:S(t-1)+r}}function te(t){var e=t._i,i=t._f;return null===e?oe.invalid({nullInput:!0}):("string"==typeof e&&(t._i=e=N().preparse(e)),oe.isMoment(e)?(t=c(e),t._d=new Date(+e._d)):i?f(i)?U(t):W(t):V(t),new a(t))}function ee(t,e){oe.fn[t]=oe.fn[t+"s"]=function(t){var i=this._isUTC?"UTC":"";return null!=t?(this._d["set"+i+e](t),oe.updateOffset(this),this):this._d["get"+i+e]()}}function ie(t){oe.duration.fn[t]=function(){return this._data[t]}}function ne(t,e){oe.duration.fn["as"+t]=function(){return+this/e}}function se(t){var e=!1,i=oe;"undefined"==typeof ender&&(t?(he.moment=function(){return!e&&console&&console.warn&&(e=!0,console.warn("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.")),i.apply(null,arguments)},l(he.moment,i)):he.moment=oe)}for(var oe,re,ae="2.5.1",he=this,le=Math.round,ce=0,de=1,ue=2,pe=3,fe=4,ge=5,me=6,ve={},ye={_isAMomentObject:null,_i:null,_f:null,_l:null,_strict:null,_isUTC:null,_offset:null,_pf:null,_lang:null},_e="undefined"!=typeof e&&e.exports&&"undefined"!=typeof t,be=/^\/?Date\((\-?\d+)/i,we=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Se=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,Te=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,Ee=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,xe=/\d\d?/,Ce=/\d{1,3}/,Me=/\d{1,4}/,De=/[+\-]?\d{1,6}/,Ie=/\d+/,Ne=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Oe=/Z|[\+\-]\d\d:?\d\d/gi,Le=/T/i,ke=/[\+\-]?\d+(\.\d{1,3})?/,Ae=/\d/,Pe=/\d\d/,ze=/\d{3}/,Fe=/\d{4}/,Re=/[+-]?\d{6}/,Ye=/[+-]?\d+/,He=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,We="YYYY-MM-DDTHH:mm:ssZ",Ge=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],je=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],Ue=/([\+\-]|\d\d)/gi,Be="Date|Hours|Minutes|Seconds|Milliseconds".split("|"),Ve={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},Xe={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},qe={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},Ze={},Ke="DDD w W M D d".split(" "),$e="M D H h m s w W".split(" "),Qe={M:function(){return this.month()+1},MMM:function(t){return this.lang().monthsShort(this,t)},MMMM:function(t){return this.lang().months(this,t)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(t){return this.lang().weekdaysMin(this,t)},ddd:function(t){return this.lang().weekdaysShort(this,t)},dddd:function(t){return this.lang().weekdays(this,t)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return u(this.year()%100,2)},YYYY:function(){return u(this.year(),4)},YYYYY:function(){return u(this.year(),5)},YYYYYY:function(){var t=this.year(),e=t>=0?"+":"-";return e+u(Math.abs(t),6)},gg:function(){return u(this.weekYear()%100,2)},gggg:function(){return u(this.weekYear(),4)},ggggg:function(){return u(this.weekYear(),5)},GG:function(){return u(this.isoWeekYear()%100,2)},GGGG:function(){return u(this.isoWeekYear(),4)},GGGGG:function(){return u(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return b(this.milliseconds()/100)},SS:function(){return u(b(this.milliseconds()/10),2)},SSS:function(){return u(this.milliseconds(),3)},SSSS:function(){return u(this.milliseconds(),3)},Z:function(){var t=-this.zone(),e="+";return 0>t&&(t=-t,e="-"),e+u(b(t/60),2)+":"+u(b(t)%60,2)},ZZ:function(){var t=-this.zone(),e="+";return 0>t&&(t=-t,e="-"),e+u(b(t/60),2)+u(b(t)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},Je=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];Ke.length;)re=Ke.pop(),Qe[re+"o"]=o(Qe[re],re);for(;$e.length;)re=$e.pop(),Qe[re+re]=s(Qe[re],2);for(Qe.DDDD=s(Qe.DDD,3),l(r.prototype,{set:function(t){var e,i;for(i in t)e=t[i],"function"==typeof e?this[i]=e:this["_"+i]=e},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(t){return this._months[t.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(t){return this._monthsShort[t.month()]},monthsParse:function(t){var e,i,n;for(this._monthsParse||(this._monthsParse=[]),e=0;12>e;e++)if(this._monthsParse[e]||(i=oe.utc([2e3,e]),n="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[e]=new RegExp(n.replace(".",""),"i")),this._monthsParse[e].test(t))return e},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(t){return this._weekdays[t.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(t){return this._weekdaysShort[t.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(t){return this._weekdaysMin[t.day()]},weekdaysParse:function(t){var e,i,n;for(this._weekdaysParse||(this._weekdaysParse=[]),e=0;7>e;e++)if(this._weekdaysParse[e]||(i=oe([2e3,1]).day(e),n="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[e]=new RegExp(n.replace(".",""),"i")),this._weekdaysParse[e].test(t))return e},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(t){var e=this._longDateFormat[t];return!e&&this._longDateFormat[t.toUpperCase()]&&(e=this._longDateFormat[t.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t]=e),e},isPM:function(t){return"p"===(t+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(t,e,i){return t>11?i?"pm":"PM":i?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(t,e){var i=this._calendar[t];return"function"==typeof i?i.apply(e):i},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(t,e,i,n){var s=this._relativeTime[i];return"function"==typeof s?s(t,e,i,n):s.replace(/%d/i,t)},pastFuture:function(t,e){var i=this._relativeTime[t>0?"future":"past"];return"function"==typeof i?i(e):i.replace(/%s/i,e)},ordinal:function(t){return this._ordinal.replace("%d",t)},_ordinal:"%d",preparse:function(t){return t},postformat:function(t){return t},week:function(t){return Q(t,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),oe=function(t,e,s,o){var r;return"boolean"==typeof s&&(o=s,s=i),r={},r._isAMomentObject=!0,r._i=t,r._f=e,r._l=s,r._strict=o,r._isUTC=!1,r._pf=n(),te(r)},oe.utc=function(t,e,s,o){var r;return"boolean"==typeof s&&(o=s,s=i),r={},r._isAMomentObject=!0,r._useUTC=!0,r._isUTC=!0,r._l=s,r._i=t,r._f=e,r._strict=o,r._pf=n(),te(r).utc()},oe.unix=function(t){return oe(1e3*t)},oe.duration=function(t,e){var i,n,s,o=t,r=null;return oe.isDuration(t)?o={ms:t._milliseconds,d:t._days,M:t._months}:"number"==typeof t?(o={},e?o[e]=t:o.milliseconds=t):(r=we.exec(t))?(i="-"===r[1]?-1:1,o={y:0,d:b(r[ue])*i,h:b(r[pe])*i,m:b(r[fe])*i,s:b(r[ge])*i,ms:b(r[me])*i}):(r=Se.exec(t))&&(i="-"===r[1]?-1:1,s=function(t){var e=t&&parseFloat(t.replace(",","."));return(isNaN(e)?0:e)*i},o={y:s(r[2]),M:s(r[3]),d:s(r[4]),h:s(r[5]),m:s(r[6]),s:s(r[7]),w:s(r[8])}),n=new h(o),oe.isDuration(t)&&t.hasOwnProperty("_lang")&&(n._lang=t._lang),n},oe.version=ae,oe.defaultFormat=We,oe.updateOffset=function(){},oe.lang=function(t,e){var i;return t?(e?D(C(t),e):null===e?(I(t),t="en"):ve[t]||N(t),i=oe.duration.fn._lang=oe.fn._lang=N(t),i._abbr):oe.fn._lang._abbr},oe.langData=function(t){return t&&t._lang&&t._lang._abbr&&(t=t._lang._abbr),N(t)},oe.isMoment=function(t){return t instanceof a||null!=t&&t.hasOwnProperty("_isAMomentObject")},oe.isDuration=function(t){return t instanceof h},re=Je.length-1;re>=0;--re)_(Je[re]);for(oe.normalizeUnits=function(t){return v(t)},oe.invalid=function(t){var e=oe.utc(0/0);return null!=t?l(e._pf,t):e._pf.userInvalidated=!0,e},oe.parseZone=function(t){return oe(t).parseZone()},l(oe.fn=a.prototype,{clone:function(){return oe(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var t=oe(this).utc();return 00:!1},parsingFlags:function(){return l({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(t){var e=k(this,t||oe.defaultFormat);return this.lang().postformat(e)},add:function(t,e){var i;return i="string"==typeof t?oe.duration(+e,t):oe.duration(t,e),p(this,i,1),this},subtract:function(t,e){var i;return i="string"==typeof t?oe.duration(+e,t):oe.duration(t,e),p(this,i,-1),this},diff:function(t,e,i){var n,s,o=M(t,this),r=6e4*(this.zone()-o.zone());return e=v(e),"year"===e||"month"===e?(n=432e5*(this.daysInMonth()+o.daysInMonth()),s=12*(this.year()-o.year())+(this.month()-o.month()),s+=(this-oe(this).startOf("month")-(o-oe(o).startOf("month")))/n,s-=6e4*(this.zone()-oe(this).startOf("month").zone()-(o.zone()-oe(o).startOf("month").zone()))/n,"year"===e&&(s/=12)):(n=this-o,s="second"===e?n/1e3:"minute"===e?n/6e4:"hour"===e?n/36e5:"day"===e?(n-r)/864e5:"week"===e?(n-r)/6048e5:n),i?s:d(s)},from:function(t,e){return oe.duration(this.diff(t)).lang(this.lang()._abbr).humanize(!e)},fromNow:function(t){return this.from(oe(),t)},calendar:function(){var t=M(oe(),this).startOf("day"),e=this.diff(t,"days",!0),i=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse";return this.format(this.lang().calendar(i,this))},isLeapYear:function(){return T(this.year())},isDST:function(){return this.zone()+oe(t).startOf(e)},isBefore:function(t,e){return e="undefined"!=typeof e?e:"millisecond",+this.clone().startOf(e)<+oe(t).startOf(e)},isSame:function(t,e){return e=e||"ms",+this.clone().startOf(e)===+M(t,this).startOf(e)},min:function(t){return t=oe.apply(null,arguments),this>t?this:t},max:function(t){return t=oe.apply(null,arguments),t>this?this:t},zone:function(t){var e=this._offset||0;return null==t?this._isUTC?e:this._d.getTimezoneOffset():("string"==typeof t&&(t=z(t)),Math.abs(t)<16&&(t=60*t),this._offset=t,this._isUTC=!0,e!==t&&p(this,oe.duration(e-t,"m"),1,!0),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(t){return t=t?oe(t).zone():0,(this.zone()-t)%60===0},daysInMonth:function(){return w(this.year(),this.month())},dayOfYear:function(t){var e=le((oe(this).startOf("day")-oe(this).startOf("year"))/864e5)+1;return null==t?e:this.add("d",t-e)},quarter:function(){return Math.ceil((this.month()+1)/3)},weekYear:function(t){var e=Q(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==t?e:this.add("y",t-e)},isoWeekYear:function(t){var e=Q(this,1,4).year;return null==t?e:this.add("y",t-e)},week:function(t){var e=this.lang().week(this);return null==t?e:this.add("d",7*(t-e))},isoWeek:function(t){var e=Q(this,1,4).week;return null==t?e:this.add("d",7*(t-e))},weekday:function(t){var e=(this.day()+7-this.lang()._week.dow)%7;return null==t?e:this.add("d",t-e)},isoWeekday:function(t){return null==t?this.day()||7:this.day(this.day()%7?t:t-7)},get:function(t){return t=v(t),this[t]()},set:function(t,e){return t=v(t),"function"==typeof this[t]&&this[t](e),this},lang:function(t){return t===i?this._lang:(this._lang=N(t),this)}}),re=0;re-1?!1:"INPUT"==i||"SELECT"==i||"TEXTAREA"==i||e.contentEditable&&"true"==e.contentEditable}function o(t,e){return t.sort().join(",")===e.sort().join(",")}function r(t){t=t||{};var e,i=!1;for(e in M)t[e]?i=!0:M[e]=0;i||(I=!1)}function a(t,e,i,n,s){var r,a,h=[];if(!x[t])return[];for("keyup"==i&&u(t)&&(e=[t]),r=0;r95&&112>t||w.hasOwnProperty(t)&&(_[w[t]]=t)}return _}function g(t,e,i){return i||(i=f()[t]?"keydown":"keypress"),"keypress"==i&&e.length&&(i="keydown"),i}function m(t,e,i,s){M[t]=0,s||(s=g(e[0],[]));var o,a=function(){I=s,++M[t],p()},h=function(t){l(i,t),"keyup"!==s&&(D=n(t)),setTimeout(r,10)};for(o=0;o1)return m(t,l,e,i);for(h="+"===t?["+"]:t.split("+"),o=0;o":".","?":"/","|":"\\"},E={option:"alt",command:"meta","return":"enter",escape:"esc"},x={},C={},M={},D=!1,I=!1,N=1;20>N;++N)w[111+N]="f"+N;for(N=0;9>=N;++N)w[N+96]=N;i(document,"keypress",d),i(document,"keydown",d),i(document,"keyup",d);var O={bind:function(t,e,i){return y(t instanceof Array?t:[t],e,i),C[t+":"+i]=e,this},unbind:function(t,e){return C[t+":"+e]&&(delete C[t+":"+e],this.bind(t,function(){},e)),this},trigger:function(t,e){return C[t+":"+e](),this},reset:function(){return x={},C={},this}};e.exports=O},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/examples/graph/19_scale_free_graph_clustering.html b/examples/graph/19_scale_free_graph_clustering.html index cced805b..640e2207 100644 --- a/examples/graph/19_scale_free_graph_clustering.html +++ b/examples/graph/19_scale_free_graph_clustering.html @@ -88,9 +88,6 @@ }; */ var options = { - edges: { - length: 50 - }, clustering: { enabled: clusteringOn, clusterEdgeThreshold: clusterEdgeThreshold diff --git a/src/graph/Graph.js b/src/graph/Graph.js index 6801ed85..c61ad086 100644 --- a/src/graph/Graph.js +++ b/src/graph/Graph.js @@ -70,16 +70,16 @@ function Graph (container, data, options) { }, physics: { barnesHut: { - enabled: false, - theta: 1 / 0.3, // inverted to save time during calculation - gravitationalConstant: -10000, - centralGravity: 0.08, - springLength: 100, - springConstant: 0.02 + enabled: true, + theta: 1 / 0.4, // inverted to save time during calculation + gravitationalConstant: -7500, + centralGravity: 0.9, + springLength: 20, + springConstant: 0.06 }, repulsion: { centralGravity: 0.01, - springLength: 100, + springLength: 60, springConstant: 0.05 }, centralGravity: null, @@ -98,11 +98,11 @@ function Graph (container, data, options) { fontSizeMultiplier: 4.0, // (px PNiC) | how much the cluster font size grows per node in cluster (in px). forceAmplification: 0.1, // (multiplier PNiC) | factor of increase fo the repulsion force of a cluster (per node in cluster). maxFontSize: 1000, - distanceAmplification: 0.03, // (multiplier PNiC) | factor how much the repulsion distance of a cluster increases (per node in cluster). + distanceAmplification: 0.1, // (multiplier PNiC) | factor how much the repulsion distance of a cluster increases (per node in cluster). edgeGrowth: 1, // (px PNiC) | amount of clusterSize connected to the edge is multiplied with this and added to edgeLength. - nodeScaling: {width: 5, // (px PNiC) | growth of the width per node in cluster. - height: 5, // (px PNiC) | growth of the height per node in cluster. - radius: 5}, // (px PNiC) | growth of the radius per node in cluster. + nodeScaling: {width: 1, // (px PNiC) | growth of the width per node in cluster. + height: 1, // (px PNiC) | growth of the height per node in cluster. + radius: 1}, // (px PNiC) | growth of the radius per node in cluster. maxNodeSizeIncrements: 600, // (# increments) | max growth of the width per node in cluster. activeAreaBoxSize: 80, // (px) | box area around the curser where clusters are popped open. clusterLevelDifference: 2 @@ -417,7 +417,6 @@ Graph.prototype.setOptions = function (options) { if (options.stabilize !== undefined) {this.stabilize = options.stabilize;} if (options.selectable !== undefined) {this.selectable = options.selectable;} -/* if (options.physics) { if (options.physics.barnesHut) { this.constants.physics.barnesHut.enabled = true; @@ -437,7 +436,7 @@ Graph.prototype.setOptions = function (options) { } } } -*/ + if (options.clustering) { this.constants.clustering.enabled = true; for (var prop in options.clustering) { @@ -1264,13 +1263,11 @@ Graph.prototype._addNodes = function(ids) { var node = new Node(data, this.images, this.groups, this.constants); this.nodes[id] = node; // note: this may replace an existing node - if (!node.isFixed() && this.createNodeOnClick != true) { - // TODO: position new nodes in a smarter way! - var radius = this.constants.edges.length; - var count = ids.length; - var angle = 2 * Math.PI * (i / count); - node.x = radius * Math.cos(angle); - node.y = radius * Math.sin(angle); + if ((node.xFixed == false || node.yFixed == false) && this.createNodeOnClick != true) { + var radius = this.constants.physics.springLength * 0.1*ids.length; + var angle = 2 * Math.PI * Math.random(); + if (node.xFixed == false) {node.x = radius * Math.cos(angle);} + if (node.yFixed == false) {node.y = radius * Math.sin(angle);} // note: no not use node.isMoving() here, as that gives the current // velocity of the node, which is zero after creation of the node. @@ -1431,6 +1428,7 @@ Graph.prototype._updateEdges = function (ids) { } } + this._createBezierNodes(); this.moving = true; this._updateValueRange(edges); }; @@ -1446,6 +1444,9 @@ Graph.prototype._removeEdges = function (ids) { var id = ids[i]; var edge = edges[id]; if (edge) { + if (edge.via != null) { + delete this.sectors['support']['nodes'][edge.via.id]; + } edge.disconnect(); delete edges[id]; } @@ -1453,6 +1454,7 @@ Graph.prototype._removeEdges = function (ids) { this.moving = true; this._updateValueRange(edges); + this._setCalculationNodes(); }; /** @@ -1741,10 +1743,9 @@ Graph.prototype._doStabilize = function() { * @private */ Graph.prototype._isMoving = function(vmin) { - var vminCorrected = vmin / Math.max(this.scale,0.05); var nodes = this.nodes; for (var id in nodes) { - if (nodes.hasOwnProperty(id) && nodes[id].isMoving(vminCorrected)) { + if (nodes.hasOwnProperty(id) && nodes[id].isMoving(vmin)) { return true; } } @@ -1760,7 +1761,7 @@ Graph.prototype._isMoving = function(vmin) { * @private */ Graph.prototype._discreteStepNodes = function() { - var interval = 1.2; + var interval = 1.0; var nodes = this.nodes; if (this.constants.maxVelocity > 0) { @@ -1777,8 +1778,13 @@ Graph.prototype._discreteStepNodes = function() { } } } - var vmin = this.constants.minVelocity; - this.moving = this._isMoving(vmin); + var vminCorrected = this.constants.minVelocity / Math.max(this.scale,0.05); + if (vminCorrected > 0.5*this.constants.maxVelocity) { + this.moving = true; + } + else { + this.moving = this._isMoving(vminCorrected); + } }; @@ -1820,15 +1826,15 @@ Graph.prototype.start = function() { graph._zoom(graph.scale*(1 + graph.zoomIncrement), center); } - var calctimeStart = Date.now(); +// var calctimeStart = Date.now(); graph.start(); graph.start(); - var calctime = Date.now() - calctimeStart; - var rendertimeStart = Date.now(); +// var calctime = Date.now() - calctimeStart; +// var rendertimeStart = Date.now(); graph._redraw(); - var rendertime = Date.now() - rendertimeStart; +// var rendertime = Date.now() - rendertimeStart; //this.end = window.performance.now(); //this.time = this.end - this.startTime; @@ -1882,25 +1888,27 @@ Graph.prototype.toggleFreeze = function() { Graph.prototype._createBezierNodes = function() { - for (var edgeId in this.edges) { - if (this.edges.hasOwnProperty(edgeId)) { - var edge = this.edges[edgeId]; - if (edge.smooth == true) { - if (edge.via == null) { - this.sectors['support']['nodes'][edge.id] = new Node( - {id:edge.id, - mass:1, - shape:'circle', - internalMultiplier:1, - damping: 0.9},{},{},this.constants); - edge.via = this.sectors['support']['nodes'][edge.id]; - edge.via.parentEdgeId = edge.id; - edge.positionBezierNode(); + if (this.constants.smoothCurves == true) { + for (var edgeId in this.edges) { + if (this.edges.hasOwnProperty(edgeId)) { + var edge = this.edges[edgeId]; + if (edge.smooth == true) { + if (edge.via == null) { + var nodeId = "edgeId:".concat(edge.id); + this.sectors['support']['nodes'][nodeId] = new Node( + {id:nodeId, + mass:1, + shape:'circle', + internalMultiplier:1, + damping: 1},{},{},this.constants); + edge.via = this.sectors['support']['nodes'][nodeId]; + edge.via.parentEdgeId = edge.id; + edge.positionBezierNode(); + } } } } } - }; diff --git a/src/graph/Node.js b/src/graph/Node.js index c9f96466..764db270 100644 --- a/src/graph/Node.js +++ b/src/graph/Node.js @@ -60,6 +60,7 @@ function Node(properties, imagelist, grouplist, constants) { this.dampingBase = 0.9; this.damping = 0.9; // this is manipulated in the updateDamping function + this.mass = 1; // kg this.setProperties(properties, constants); @@ -74,7 +75,7 @@ function Node(properties, imagelist, grouplist, constants) { this.growthIndicator = 0; // mass, force, velocity - this.mass = 1; // kg + this.fx = 0.0; // external force x this.fy = 0.0; // external force y this.vx = 0.0; // velocity x @@ -150,6 +151,8 @@ Node.prototype.setProperties = function(properties, constants) { // physics if (properties.internalMultiplier !== undefined) {this.internalMultiplier = properties.internalMultiplier;} if (properties.damping !== undefined) {this.dampingBase = properties.damping;} + if (properties.mass !== undefined) {this.mass = properties.mass;} + // navigation controls properties if (properties.horizontalAlignLeft !== undefined) {this.horizontalAlignLeft = properties.horizontalAlignLeft;} if (properties.verticalAlignTop !== undefined) {this.verticalAlignTop = properties.verticalAlignTop;} @@ -984,7 +987,7 @@ Node.prototype.setScale = function(scale) { * @param {Number} numberOfNodes */ Node.prototype.updateDamping = function() { - this.damping = Math.min(Math.max(1.5,this.dampingBase),this.dampingBase + 0.01*this.growthIndicator); + this.damping = Math.min(Math.max(1.2,this.dampingBase),this.dampingBase + 0.01*this.growthIndicator); }; diff --git a/src/graph/graphMixins/ClusterMixin.js b/src/graph/graphMixins/ClusterMixin.js index ccc8fbba..74f825b3 100644 --- a/src/graph/graphMixins/ClusterMixin.js +++ b/src/graph/graphMixins/ClusterMixin.js @@ -8,23 +8,24 @@ */ var ClusterMixin = { -/** - * This is only called in the constructor of the graph object - * */ + /** + * This is only called in the constructor of the graph object + * + */ startWithClustering : function() { - // cluster if the data set is big - this.clusterToFit(this.constants.clustering.initialMaxNodes, true); + // cluster if the data set is big + this.clusterToFit(this.constants.clustering.initialMaxNodes, true); - // updates the lables after clustering - this.updateLabels(); + // updates the lables after clustering + this.updateLabels(); - // this is called here because if clusterin is disabled, the start and stabilize are called in - // the setData function. - if (this.stabilize) { - this._doStabilize(); - } - this.start(); - }, + // this is called here because if clusterin is disabled, the start and stabilize are called in + // the setData function. + if (this.stabilize) { + this._doStabilize(); + } + this.start(); + }, /** * This function clusters until the initialMaxNodes has been reached @@ -56,7 +57,7 @@ var ClusterMixin = { if (level > 0 && reposition == true) { this.repositionNodes(); } - }, + }, /** * This function can be called to open up a specific cluster. It is only called by @@ -68,12 +69,16 @@ var ClusterMixin = { var isMovingBeforeClustering = this.moving; if (node.clusterSize > this.constants.clustering.sectorThreshold && this._nodeInActiveArea(node) && !(this._sector() == "default" && this.nodeIndices.length == 1)) { + // this loads a new sector, loads the nodes and edges and nodeIndices of it. this._addSector(node); var level = 0; + + // we decluster until we reach a decent number of nodes while ((this.nodeIndices.length < this.constants.clustering.initialMaxNodes) && (level < 10)) { this.decreaseClusterLevel(); level += 1; } + } else { this._expandClusterNode(node,false,true); @@ -89,7 +94,7 @@ var ClusterMixin = { if (this.moving != isMovingBeforeClustering) { this.start(); } - }, + }, /** @@ -109,7 +114,7 @@ var ClusterMixin = { */ increaseClusterLevel : function() { this.updateClusters(-1,false,true); - }, + }, /** @@ -119,7 +124,7 @@ var ClusterMixin = { */ decreaseClusterLevel : function() { this.updateClusters(1,false,true); - }, + }, /** @@ -192,7 +197,9 @@ var ClusterMixin = { this.start(); } } - }, + + this._setCalculationNodes(); + }, /** * This function handles the chains. It is called on every updateClusters(). @@ -204,7 +211,7 @@ var ClusterMixin = { this._reduceAmountOfChains(1 - this.constants.clustering.chainThreshold / chainPercentage) } - }, + }, /** * this functions starts clustering by hubs @@ -215,7 +222,7 @@ var ClusterMixin = { _aggregateHubs : function(force) { this._getHubSize(); this._formClustersByHub(force,false); - }, + }, /** @@ -244,7 +251,7 @@ var ClusterMixin = { this.start(); } } - }, + }, /** * If a cluster takes up more than a set percentage of the screen, open the cluster @@ -263,7 +270,7 @@ var ClusterMixin = { } } } - }, + }, /** @@ -278,7 +285,7 @@ var ClusterMixin = { this._expandClusterNode(node,recursive,force); this._setCalculationNodes(); } - }, + }, /** * This function checks if a node has to be opened. This is done by checking the zoom level. @@ -324,8 +331,7 @@ var ClusterMixin = { } } } - - }, + }, /** * ONLY CALLED FROM _expandClusterNode @@ -342,14 +348,13 @@ var ClusterMixin = { * @param {Boolean} openAll | This will recursively force all nodes in the parent to be released * @private */ - _expelChildFromParent : function(parentNode, containedNodeId, recursive, force, openAll) { + _expelChildFromParent : function(parentNode, containedNodeId, recursive, force, openAll) { var childNode = parentNode.containedNodes[containedNodeId]; // if child node has been added on smaller scale than current, kick out if (childNode.formationScale < this.scale || force == true) { - // remove the selection, first remove the selection from the connected edges - this._unselectConnectedEdges(parentNode); - parentNode.unselect(); + // unselect all selected items + this._unselectAll(); // put the child node back in the global nodes object this.nodes[containedNodeId] = childNode; @@ -370,8 +375,8 @@ var ClusterMixin = { parentNode.dynamicEdgesLength = parentNode.dynamicEdges.length; // place the child node near the parent, not at the exact same location to avoid chaos in the system - childNode.x = parentNode.x + parentNode.growthIndicator * (0.5 - Math.random()) * childNode.clusterSize; - childNode.y = parentNode.y + parentNode.growthIndicator * (0.5 - Math.random()) * childNode.clusterSize; + childNode.x = parentNode.x + parentNode.growthIndicator * (0.5 - Math.random()); + childNode.y = parentNode.y + parentNode.growthIndicator * (0.5 - Math.random()); // remove node from the list delete parentNode.containedNodes[containedNodeId]; @@ -391,24 +396,37 @@ var ClusterMixin = { parentNode.clusterSessions.pop(); } + this._repositionBezierNodes(childNode); +// this._repositionBezierNodes(parentNode); + // remove the clusterSession from the child node childNode.clusterSession = 0; - // restart the simulation to reorganise all nodes - this.moving = true; - // recalculate the size of the node on the next time the node is rendered parentNode.clearSizeCache(); - // this unselects the rest of the edges - this._unselectConnectedEdges(parentNode); + // restart the simulation to reorganise all nodes + this.moving = true; } // check if a further expansion step is possible if recursivity is enabled if (recursive == true) { this._expandClusterNode(childNode,recursive,force,openAll); } - }, + }, + + + /** + * position the bezier nodes at the center of the edges + * + * @param node + * @private + */ + _repositionBezierNodes : function(node) { + for (var i = 0; i < node.dynamicEdges.length; i++) { + node.dynamicEdges[i].positionBezierNode(); + } + }, /** @@ -427,7 +445,8 @@ var ClusterMixin = { else { this._forceClustersByZoom(); } - }, + }, + /** * This function handles the clustering by zooming out, this is based on a minimum edge distance @@ -470,7 +489,7 @@ var ClusterMixin = { } } } - }, + }, /** * This function forces the graph to cluster all nodes with only one connecting edge to their @@ -501,9 +520,16 @@ var ClusterMixin = { } } } - }, + }, + /** + * To keep the nodes of roughly equal size we normalize the cluster levels. + * This function clusters a node to its smallest connected neighbour. + * + * @param node + * @private + */ _clusterToSmallestNeighbour : function(node) { var smallestNeighbour = -1; var smallestNeighbourNode = null; @@ -546,7 +572,7 @@ var ClusterMixin = { this._formClusterFromHub(this.nodes[nodeId],force,onlyEqual); } } - }, + }, /** * This function forms a cluster from a specific preselected hub node @@ -616,7 +642,7 @@ var ClusterMixin = { } } } - }, + }, @@ -687,7 +713,7 @@ var ClusterMixin = { // restart the simulation to reorganise all nodes this.moving = true; - }, + }, /** @@ -717,7 +743,7 @@ var ClusterMixin = { } node.dynamicEdgesLength -= correction; } - }, + }, /** @@ -746,7 +772,7 @@ var ClusterMixin = { break; } } - }, + }, /** * This function connects an edge that was connected to a child node to the parent node. @@ -777,9 +803,17 @@ var ClusterMixin = { this._addToReroutedEdges(parentNode,childNode,edge); } - }, + }, + /** + * If a node is connected to itself, a circular edge is drawn. When clustering we want to contain + * these edges inside of the cluster. + * + * @param parentNode + * @param childNode + * @private + */ _containCircularEdgesFromNode : function(parentNode, childNode) { // manage all the edges connected to the child and parent nodes for (var i = 0; i < parentNode.dynamicEdges.length; i++) { @@ -850,7 +884,7 @@ var ClusterMixin = { // remove the entry from the rerouted edges delete parentNode.reroutedEdges[childNode.id]; } - }, + }, /** @@ -868,7 +902,7 @@ var ClusterMixin = { parentNode.dynamicEdges.splice(i,1); } } - }, + }, /** @@ -893,7 +927,7 @@ var ClusterMixin = { // remove the entry from the contained edges delete parentNode.containedEdges[childNode.id]; - }, + }, @@ -939,9 +973,15 @@ var ClusterMixin = { // } // } - }, + }, + /** + * We want to keep the cluster level distribution rather small. This means we do not want unclustered nodes + * if the rest of the nodes are already a few cluster levels in. + * To fix this we use this function. It determines the min and max cluster level and sends nodes that have not + * clustered enough to the clusterToSmallestNeighbours function. + */ normalizeClusterLevels : function() { var maxLevel = 0; var minLevel = 1e9; @@ -992,7 +1032,7 @@ var ClusterMixin = { && Math.abs(node.y - this.areaCenter.y) <= this.constants.clustering.activeAreaBoxSize/this.scale ) - }, + }, /** @@ -1003,17 +1043,14 @@ var ClusterMixin = { repositionNodes : function() { for (var i = 0; i < this.nodeIndices.length; i++) { var node = this.nodes[this.nodeIndices[i]]; - if (!node.isFixed()) { + if ((node.xFixed == false || node.yFixed == false) && this.createNodeOnClick != true) { var radius = this.constants.physics.springLength * (1 + 0.1*node.mass); var angle = 2 * Math.PI * Math.random(); - node.x = radius * Math.cos(angle); - node.y = radius * Math.sin(angle); + if (node.xFixed == false) {node.x = radius * Math.cos(angle);} + if (node.yFixed == false) {node.y = radius * Math.sin(angle);} } } - }, - - - + }, /** @@ -1054,7 +1091,7 @@ var ClusterMixin = { // console.log("average",average,"averageSQ",averageSquared,"var",variance,"std",standardDeviation); // console.log("hubThreshold:",this.hubThreshold); - }, + }, /** @@ -1077,7 +1114,7 @@ var ClusterMixin = { } } } - }, + }, /** * We get the amount of "extension nodes" or chains. These are not quickly clustered with the outliers and hubs methods @@ -1097,5 +1134,6 @@ var ClusterMixin = { } } return chains/total; - } + } + }; diff --git a/src/graph/graphMixins/physics/PhysicsMixin.js b/src/graph/graphMixins/physics/PhysicsMixin.js index 1f7dc85c..3608ab20 100644 --- a/src/graph/graphMixins/physics/PhysicsMixin.js +++ b/src/graph/graphMixins/physics/PhysicsMixin.js @@ -5,12 +5,19 @@ var physicsMixin = { + /** + * Toggling barnes Hut calculation on and off. + * + * @private + */ _toggleBarnesHut : function() { this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled; this._loadSelectedForceSolver(); this.moving = true; this.start(); }, + + /** * Before calculating the forces, we check if we need to cluster to keep up performance and we check * if there is more than one node. If it is just one node, we dont calculate anything. @@ -51,13 +58,22 @@ var physicsMixin = { if (this.constants.smoothCurves == true) { - this._calculateSpringForcesOnSupport(); + this._calculateSpringForcesWithSupport(); } else { this._calculateSpringForces(); } }, + + /** + * Smooth curves are created by adding invisible nodes in the center of the edges. These nodes are also + * handled in the calculateForces function. We then use a quadratic curve with the center node as control. + * This function joins the datanodes and invisible (called support) nodes into one object. + * We do this so we do not contaminate this.nodes with the support nodes. + * + * @private + */ _setCalculationNodes : function() { if (this.constants.smoothCurves == true) { this.calculationNodes = {}; @@ -74,6 +90,9 @@ var physicsMixin = { if (this.edges.hasOwnProperty(supportNodes[supportNodeId].parentEdgeId)) { this.calculationNodes[supportNodeId] = supportNodes[supportNodeId]; } + else { + supportNodes[supportNodeId]._setForce(0,0); + } } } @@ -90,17 +109,11 @@ var physicsMixin = { }, - _clearForces : function() { - var node, i; - var nodes = this.nodes; - - for (i = 0; i < this.nodeIndices.length; i++) { - node = nodes[this.nodeIndices[i]]; - node._setForce(0, 0); - node.updateDamping(this.nodeIndices.length); - } - }, - + /** + * this function applies the central gravity effect to keep groups from floating off + * + * @private + */ _calculateGravitationalForces : function() { var dx, dy, angle, fx, fy, node, i; var nodes = this.calculationNodes; @@ -110,8 +123,8 @@ var physicsMixin = { node = nodes[this.calculationNodeIndices[i]]; // gravity does not apply when we are in a pocket sector if (this._sector() == "default") { - dx = -node.x;// + screenCenterPos.x; - dy = -node.y;// + screenCenterPos.y; + dx = -node.x; + dy = -node.y; angle = Math.atan2(dy, dx); fx = Math.cos(angle) * gravity; @@ -126,8 +139,14 @@ var physicsMixin = { } }, + + /** + * this function calculates the effects of the springs in the case of unsmooth curves. + * + * @private + */ _calculateSpringForces : function() { - var dx, dy, angle, fx, fy, springForce, length, edgeLength, edge, edgeId; + var edgeLength, edge, edgeId; var edges = this.edges; // forces caused by the edges, modelled as springs @@ -137,30 +156,23 @@ var physicsMixin = { if (edge.connected) { // only calculate forces if nodes are in the same sector if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) { - dx = (edge.to.x - edge.from.x); - dy = (edge.to.y - edge.from.y); - edgeLength = edge.length; - // this implies that the edges between big clusters are longer edgeLength += (edge.to.growthIndicator + edge.from.growthIndicator) * this.constants.clustering.edgeGrowth; - length = Math.sqrt(dx * dx + dy * dy); - angle = Math.atan2(dy, dx); - - springForce = this.constants.physics.springConstant * (edgeLength - length); - - fx = Math.cos(angle) * springForce; - fy = Math.sin(angle) * springForce; - - edge.from._addForce(-fx, -fy); - edge.to._addForce(fx, fy); + this._calculateSpringForce(edge.from,edge.to,edgeLength); } } } } }, - _calculateSpringForcesOnSupport : function() { + + /** + * This function calculates the springforces on the nodes, accounting for the support nodes. + * + * @private + */ + _calculateSpringForcesWithSupport : function() { var edgeLength, edge, edgeId, growthIndicator; var edges = this.edges; @@ -177,11 +189,11 @@ var physicsMixin = { var node3 = edge.from; edgeLength = 0.5*edge.length; + growthIndicator = 0.5*(node1.growthIndicator + node3.growthIndicator); // this implies that the edges between big clusters are longer edgeLength += growthIndicator * this.constants.clustering.edgeGrowth; - this._calculateSpringForce(node1,node2,edgeLength); this._calculateSpringForce(node2,node3,edgeLength); } @@ -191,6 +203,15 @@ var physicsMixin = { } }, + + /** + * This is the code actually performing the calculation for the function above. It is split out to avoid repetition. + * + * @param node1 + * @param node2 + * @param edgeLength + * @private + */ _calculateSpringForce : function(node1,node2,edgeLength) { var dx, dy, angle, fx, fy, springForce, length; @@ -198,6 +219,7 @@ var physicsMixin = { dy = (node1.y - node2.y); length = Math.sqrt(dx * dx + dy * dy); angle = Math.atan2(dy, dx); + springForce = this.constants.physics.springConstant * (edgeLength - length); fx = Math.cos(angle) * springForce; diff --git a/src/graph/graphMixins/physics/barnesHut.js b/src/graph/graphMixins/physics/barnesHut.js index 2321320b..a7646213 100644 --- a/src/graph/graphMixins/physics/barnesHut.js +++ b/src/graph/graphMixins/physics/barnesHut.js @@ -4,7 +4,12 @@ var barnesHutMixin = { - + /** + * This function calculates the forces the nodes apply on eachother based on a gravitational model. + * The Barnes Hut method is used to speed up this N-body simulation. + * + * @private + */ _calculateNodeForces : function() { var node; var nodes = this.calculationNodes; @@ -13,7 +18,6 @@ var barnesHutMixin = { this._formBarnesHutTree(nodes,nodeIndices); - var barnesHutTree = this.barnesHutTree; // place the nodes one by one recursively @@ -27,14 +31,23 @@ var barnesHutMixin = { } }, + + /** + * This function traverses the barnesHutTree. It checks when it can approximate distant nodes with their center of mass. + * If a region contains a single node, we check if it is not itself, then we apply the force. + * + * @param parentBranch + * @param node + * @private + */ _getForceContribution : function(parentBranch,node) { // we get no force contribution from an empty region if (parentBranch.childrenCount > 0) { var dx,dy,distance; // get the distance from the center of mass to the node. - dx = parentBranch.CenterOfMass.x - node.x; - dy = parentBranch.CenterOfMass.y - node.y; + dx = parentBranch.centerOfMass.x - node.x; + dy = parentBranch.centerOfMass.y - node.y; distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { // distance is 0 if it looks to apply a force on itself. @@ -60,8 +73,17 @@ var barnesHutMixin = { } }, + /** + * The gravitational force applied on the node by the mass of the branch. + * + * @param parentBranch + * @param node + * @param dx + * @param dy + * @param distance + * @private + */ _getForceOnNode : function(parentBranch, node, dx ,dy, distance) { - //console.log(Math.max(Math.max(node.height,node.radius),node.width),parentBranch.maxWidth,distance); // even if the parentBranch only has one node, its Center of Mass is at the right place (the node in this case). var gravityForce = this.constants.physics.barnesHut.gravitationalConstant * parentBranch.mass * node.mass / (distance * distance); var angle = Math.atan2(dy, dx); @@ -71,6 +93,13 @@ var barnesHutMixin = { }, + /** + * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes. + * + * @param nodes + * @param nodeIndices + * @private + */ _formBarnesHutTree : function(nodes,nodeIndices) { var node; var nodeCount = nodeIndices.length; @@ -95,13 +124,19 @@ var barnesHutMixin = { else {minX += 0.5 * sizeDiff; maxX -= 0.5 * sizeDiff;} // xSize < ySize + var minimumTreeSize = 1e-5; + var rootSize = Math.max(minimumTreeSize,Math.abs(maxX - minX)); + var halfRootSize = 0.5 * rootSize; + var centerX = 0.5 * (minX + maxX), centerY = 0.5 * (minY + maxY); + // construct the barnesHutTree var barnesHutTree = {root:{ - CenterOfMass:{x:0,y:0}, // Center of Mass + centerOfMass:{x:0,y:0}, // Center of Mass mass:0, - range:{minX:minX,maxX:maxX,minY:minY,maxY:maxY}, - size: Math.abs(maxX - minX), - calcSize: 1 / Math.abs(maxX - minX), + range: {minX:centerX-halfRootSize,maxX:centerX+halfRootSize, + minY:centerY-halfRootSize,maxY:centerY+halfRootSize}, + size: rootSize, + calcSize: 1 / rootSize, children: {data:null}, maxWidth: 0, level: 0, @@ -124,11 +159,11 @@ var barnesHutMixin = { var totalMass = parentBranch.mass + node.mass; var totalMassInv = 1/totalMass; - parentBranch.CenterOfMass.x = parentBranch.CenterOfMass.x * parentBranch.mass + node.x * node.mass; - parentBranch.CenterOfMass.x *= totalMassInv; + parentBranch.centerOfMass.x = parentBranch.centerOfMass.x * parentBranch.mass + node.x * node.mass; + parentBranch.centerOfMass.x *= totalMassInv; - parentBranch.CenterOfMass.y = parentBranch.CenterOfMass.y * parentBranch.mass + node.y * node.mass; - parentBranch.CenterOfMass.y *= totalMassInv; + parentBranch.centerOfMass.y = parentBranch.centerOfMass.y * parentBranch.mass + node.y * node.mass; + parentBranch.centerOfMass.y *= totalMassInv; parentBranch.mass = totalMass; var biggestSize = Math.max(Math.max(node.height,node.radius),node.width); @@ -137,10 +172,12 @@ var barnesHutMixin = { }, - _placeInTree : function(parentBranch,node) { - // update the mass of the branch. - this._updateBranchMass(parentBranch,node); - + _placeInTree : function(parentBranch,node,skipMassUpdate) { + if (skipMassUpdate != true || skipMassUpdate === undefined) { + // update the mass of the branch. + this._updateBranchMass(parentBranch,node); + } + //console.log(parentBranch.children.NW.range.maxX,parentBranch.children.NW.range.maxY, node.x,node.y); if (parentBranch.children.NW.range.maxX > node.x) { // in NW or SW if (parentBranch.children.NW.range.maxY > node.y) { // in NW this._placeInRegion(parentBranch,node,"NW"); @@ -150,7 +187,7 @@ var barnesHutMixin = { } } else { // in NE or SE - if (parentBranch.children.NE.range.maxY > node.y) { // in NE + if (parentBranch.children.NW.range.maxY > node.y) { // in NE this._placeInRegion(parentBranch,node,"NE"); } else { // in SE @@ -168,8 +205,16 @@ var barnesHutMixin = { this._updateBranchMass(parentBranch.children[region],node); break; case 1: // convert into children - this._splitBranch(parentBranch.children[region]); - this._placeInTree(parentBranch.children[region],node); + // if there are two nodes exactly overlapping (on init, on opening of cluster etc.) + // we move one node a pixel and we do not put it in the tree. + if (parentBranch.children[region].children.data.x == node.x && + parentBranch.children[region].children.data.y == node.y) { + node.x += 0.1; + } + else { + this._splitBranch(parentBranch.children[region]); + this._placeInTree(parentBranch.children[region],node); + } break; case 4: // place in branch this._placeInTree(parentBranch.children[region],node); @@ -178,12 +223,19 @@ var barnesHutMixin = { }, + /** + * this function splits a branch into 4 sub branches. If the branch contained a node, we place it in the subbranch + * after the split is complete. + * + * @param parentBranch + * @private + */ _splitBranch : function(parentBranch) { // if the branch is filled with a node, replace the node in the new subset. var containedNode = null; if (parentBranch.childrenCount == 1) { containedNode = parentBranch.children.data; - parentBranch.mass = 0; parentBranch.CenterOfMass.x = 0; parentBranch.CenterOfMass.y = 0; + parentBranch.mass = 0; parentBranch.centerOfMass.x = 0; parentBranch.centerOfMass.y = 0; } parentBranch.childrenCount = 4; parentBranch.children.data = null; @@ -210,47 +262,56 @@ var barnesHutMixin = { */ _insertRegion : function(parentBranch, region) { var minX,maxX,minY,maxY; + var childSize = 0.5 * parentBranch.size; switch (region) { case "NW": minX = parentBranch.range.minX; - maxX = parentBranch.range.minX + parentBranch.size; + maxX = parentBranch.range.minX + childSize; minY = parentBranch.range.minY; - maxY = parentBranch.range.minY + parentBranch.size; + maxY = parentBranch.range.minY + childSize; break; case "NE": - minX = parentBranch.range.minX + parentBranch.size; + minX = parentBranch.range.minX + childSize; maxX = parentBranch.range.maxX; minY = parentBranch.range.minY; - maxY = parentBranch.range.minY + parentBranch.size; + maxY = parentBranch.range.minY + childSize; break; case "SW": minX = parentBranch.range.minX; - maxX = parentBranch.range.minX + parentBranch.size; - minY = parentBranch.range.minY + parentBranch.size; + maxX = parentBranch.range.minX + childSize; + minY = parentBranch.range.minY + childSize; maxY = parentBranch.range.maxY; break; case "SE": - minX = parentBranch.range.minX + parentBranch.size; + minX = parentBranch.range.minX + childSize; maxX = parentBranch.range.maxX; - minY = parentBranch.range.minY + parentBranch.size; + minY = parentBranch.range.minY + childSize; maxY = parentBranch.range.maxY; break; } parentBranch.children[region] = { - CenterOfMass:{x:0,y:0}, + centerOfMass:{x:0,y:0}, mass:0, range:{minX:minX,maxX:maxX,minY:minY,maxY:maxY}, size: 0.5 * parentBranch.size, calcSize: 2 * parentBranch.calcSize, children: {data:null}, maxWidth: 0, - level: parentBranch.level +1, + level: parentBranch.level+1, childrenCount: 0 }; }, + + /** + * This function is for debugging purposed, it draws the tree. + * + * @param ctx + * @param color + * @private + */ _drawTree : function(ctx,color) { if (this.barnesHutTree !== undefined) { @@ -260,6 +321,15 @@ var barnesHutMixin = { } }, + + /** + * This function is for debugging purposes. It draws the branches recursively. + * + * @param branch + * @param ctx + * @param color + * @private + */ _drawBranch : function(branch,ctx,color) { if (color === undefined) { color = "#FF0000"; @@ -294,7 +364,7 @@ var barnesHutMixin = { /* if (branch.mass > 0) { - ctx.circle(branch.CenterOfMass.x, branch.CenterOfMass.y, 3*branch.mass); + ctx.circle(branch.centerOfMass.x, branch.centerOfMass.y, 3*branch.mass); ctx.stroke(); } */ diff --git a/src/graph/graphMixins/physics/repulsion.js b/src/graph/graphMixins/physics/repulsion.js index 3c01932f..8bc9895e 100644 --- a/src/graph/graphMixins/physics/repulsion.js +++ b/src/graph/graphMixins/physics/repulsion.js @@ -30,7 +30,7 @@ var repulsionMixin = { node1 = nodes[nodeIndices[i]]; for (j = i+1; j < nodeIndices.length; j++) { node2 = nodes[nodeIndices[j]]; - combinedClusterSize = (node1.growthIndicator + node2.growthIndicator); + combinedClusterSize = node1.clusterSize + node2.clusterSize - 2; dx = node2.x - node1.x; dy = node2.y - node1.y;