(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["labella"] = factory(); else root["labella"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; /* Copyright 2015 Twitter, Inc. Licensed under the Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0 */ module.exports = { Node: __webpack_require__(1), Force: __webpack_require__(2), Distributor: __webpack_require__(3), Renderer: __webpack_require__(10) }; /***/ }, /* 1 */ /***/ function(module, exports) { 'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Node = function () { function Node(idealPos, width, data) { _classCallCheck(this, Node); this.idealPos = idealPos; this.currentPos = idealPos; this.width = width; this.data = data; this.layerIndex = 0; } // return negative if overlap _createClass(Node, [{ key: 'distanceFrom', value: function distanceFrom(node) { var halfWidth = this.width / 2; var nodeHalfWidth = node.width / 2; // max(a[0], b[0]) - min(a[1], b[1]) return Math.max(this.currentPos - halfWidth, node.currentPos - nodeHalfWidth) - Math.min(this.currentPos + halfWidth, node.currentPos + nodeHalfWidth); } }, { key: 'moveToIdealPosition', value: function moveToIdealPosition() { this.currentPos = this.idealPos; return this; } }, { key: 'displacement', value: function displacement() { return this.idealPos - this.currentPos; } }, { key: 'overlapWithNode', value: function overlapWithNode(node) { var buffer = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; return this.distanceFrom(node) - buffer < 0; } }, { key: 'overlapWithPoint', value: function overlapWithPoint(pos) { var halfWidth = this.width / 2; return pos >= this.currentPos - halfWidth && pos <= this.currentPos + halfWidth; } }, { key: 'positionBefore', value: function positionBefore(node) { var buffer = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; return node.currentLeft() - this.width / 2 - buffer; } }, { key: 'positionAfter', value: function positionAfter(node) { var buffer = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; return node.currentRight() + this.width / 2 + buffer; } }, { key: 'currentRight', value: function currentRight() { return this.currentPos + this.width / 2; } }, { key: 'currentLeft', value: function currentLeft() { return this.currentPos - this.width / 2; } }, { key: 'idealRight', value: function idealRight() { return this.idealPos + this.width / 2; } }, { key: 'idealLeft', value: function idealLeft() { return this.idealPos - this.width / 2; } }, { key: 'createStub', value: function createStub(width) { var stub = new Node(this.idealPos, width, this.data); stub.currentPos = this.currentPos; stub.child = this; this.parent = stub; return stub; } }, { key: 'removeStub', value: function removeStub() { if (this.parent) { this.parent.child = null; this.parent = null; } return this; } }, { key: 'isStub', value: function isStub() { return !!this.child; } }, { key: 'getPathToRoot', value: function getPathToRoot() { var path = []; var current = this; while (current) { path.push(current); current = current.parent; } return path; } }, { key: 'getPathFromRoot', value: function getPathFromRoot() { return this.getPathToRoot().reverse(); } }, { key: 'getPathToRootLength', value: function getPathToRootLength() { var length = 0; var current = this; while (current) { var targetPos = current.parent ? current.parent.currentPos : current.idealPos; length += Math.abs(current.currentPos - targetPos); current = current.parent; } return length; } // Trace back to the node without parent }, { key: 'getRoot', value: function getRoot() { var previous = this; var current = this; while (current) { previous = current; current = current.parent; } return previous; } }, { key: 'getLayerIndex', value: function getLayerIndex() { return this.layerIndex; } }, { key: 'clone', value: function clone() { var node = new Node(this.idealPos, this.width, this.data); node.currentPos = this.currentPos; node.layerIndex = this.layerIndex; return node; } }]); return Node; }(); module.exports = Node; /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var Distributor = __webpack_require__(3); var helper = __webpack_require__(4); var removeOverlap = __webpack_require__(8); var DEFAULT_OPTIONS = { nodeSpacing: 3, minPos: 0, maxPos: null, algorithm: 'overlap', removeOverlap: true, density: 0.85, stubWidth: 1 }; var Force = function Force(_options) { var force = {}; var options = helper.extend({}, DEFAULT_OPTIONS); var distributor = new Distributor(); var nodes = []; var layers = null; force.nodes = function (x) { if (!arguments.length) return nodes; nodes = x; layers = [x]; return force; }; force.getLayers = function () { return layers; }; force.options = function (x) { if (!arguments.length) return options; options = helper.extend(options, x); var disOptions = helper.pick(options, Object.keys(Distributor.DEFAULT_OPTIONS)); if (helper.isDefined(options.minPos) && helper.isDefined(options.maxPos)) { disOptions.layerWidth = options.maxPos - options.minPos; } else { disOptions.layerWidth = null; } distributor.options(disOptions); return force; }; force.options(_options); force.compute = function () { var overlapOptions = helper.pick(options, Object.keys(removeOverlap.DEFAULT_OPTIONS)); nodes.forEach(function (node) { node.removeStub(); }); layers = distributor.distribute(nodes); layers.map(function (nodes, layerIndex) { nodes.forEach(function (node) { node.layerIndex = layerIndex; }); if (options.removeOverlap) { removeOverlap(nodes, overlapOptions); } }); return force; }; force.start = function () { console.log('[warning] force.start() is deprecated. Please use force.compute() instead.'); }; return force; }; Force.DEFAULT_OPTIONS = DEFAULT_OPTIONS; module.exports = Force; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var helper = __webpack_require__(4); var IntervalTree = __webpack_require__(6); var DEFAULT_OPTIONS = { algorithm: 'overlap', layerWidth: 1000, density: 0.75, nodeSpacing: 3, stubWidth: 1 }; var Distributor = function Distributor(options) { var distributor = {}; options = helper.extend({}, DEFAULT_OPTIONS, options); distributor.options = function (x) { if (!arguments.length) return options; options = helper.extend(options, x); return distributor; }; distributor.computeRequiredWidth = function (nodes) { return helper.sum(nodes, function (d) { return d.width + options.nodeSpacing; }) - options.nodeSpacing; }; distributor.maxWidthPerLayer = function () { return options.density * options.layerWidth; }; distributor.needToSplit = function (nodes) { return distributor.estimateRequiredLayers(nodes) > 1; }; distributor.estimateRequiredLayers = function (nodes) { return options.layerWidth ? Math.ceil(distributor.computeRequiredWidth(nodes) / distributor.maxWidthPerLayer()) : 1; }; var algorithms = { simple: function simple(nodes) { var numLayers = distributor.estimateRequiredLayers(nodes); var layers = []; for (var i = 0; i < numLayers; i++) { layers.push([]); } nodes.forEach(function (node, i) { var mod = i % numLayers; layers[mod].push(node); var stub = node; for (var j = mod - 1; j >= 0; j--) { stub = stub.createStub(options.stubWidth); layers[j].push(stub); } }); return layers; }, roundRobin: function roundRobin(nodes) { var layers = []; return layers; }, overlap: function overlap(nodes) { var layers = []; var maxWidth = distributor.maxWidthPerLayer(); var puntedNodes = nodes.concat(); var puntedWidth = distributor.computeRequiredWidth(puntedNodes); while (puntedWidth > maxWidth) { distributor.countIdealOverlaps(puntedNodes); var nodesInCurrentLayer = puntedNodes.concat(); var currentlayerWidth = puntedWidth; puntedNodes = []; while (nodesInCurrentLayer.length > 2 && currentlayerWidth > maxWidth) { // Sort by overlaps nodesInCurrentLayer.sort(function (a, b) { return b.overlapCount - a.overlapCount; }); // Remove the node with most overlap var first = nodesInCurrentLayer.shift(); // Update width currentlayerWidth -= first.width; currentlayerWidth += options.stubWidth; // Update overlap count for the remaining nodes first.overlaps.forEach(function (node) { node.overlapCount--; }); // Add removed node to the next layer puntedNodes.push(first); } layers.push(nodesInCurrentLayer); puntedWidth = distributor.computeRequiredWidth(puntedNodes); } if (puntedNodes.length > 0) { layers.push(puntedNodes); } // Create stubs // From last layer for (var i = layers.length - 1; i >= 1; i--) { var layer = layers[i]; // For each node in the layer for (var k = 0; k < layer.length; k++) { var node = layer[k]; // If it is not a stub if (node.isStub()) continue; // Create one stub for each layer above it var stub = node; for (var j = i - 1; j >= 0; j--) { stub = stub.createStub(options.stubWidth); layers[j].push(stub); } } } return layers; } }; distributor.countIdealOverlaps = function (nodes) { var iTree = new IntervalTree(options.layerWidth / 2); nodes.forEach(function (node) { iTree.add([node.idealLeft(), node.idealRight(), node]); }); nodes.forEach(function (node) { var overlaps = iTree.search(node.idealLeft(), node.idealRight()); node.overlaps = overlaps.map(function (x) { return x.data[2]; }); node.overlapCount = overlaps.length; }); return nodes; }; distributor.distribute = function (nodes) { if (!nodes || nodes.length === 0) return []; if (options.algorithm == 'none' || !helper.isDefined(options.algorithm)) { return [nodes]; } if (!distributor.needToSplit(nodes)) { return [nodes]; } nodes = nodes.concat().sort(function (a, b) { return a.idealPos - b.idealPos; }); if (typeof options.algorithm == 'function') { return options.algorithm(nodes, options); } else if (algorithms.hasOwnProperty(options.algorithm)) { return algorithms[options.algorithm](nodes); } else { throw 'Unknown algorithm: ' + options.algorithm; } }; return distributor; }; Distributor.DEFAULT_OPTIONS = DEFAULT_OPTIONS; // return module module.exports = Distributor; /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var helper = { isDefined: function isDefined(x) { return x !== null && x !== undefined; }, last: function last(array) { return array.length > 0 ? array[array.length - 1] : null; }, pick: function pick(object, keys) { return keys.reduce(function (prev, key) { prev[key] = object[key]; return prev; }, {}); }, sum: function sum(array, accessor) { return array.map(accessor).reduce(function (prev, current) { return prev + current; }, 0); } }; helper.extend = __webpack_require__(5); module.exports = helper; /***/ }, /* 5 */ /***/ function(module, exports) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /* This file is modified from https://github.com/justmoon/node-extend The MIT License (MIT) Copyright (c) 2014 Stefan Thomas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var hasOwn = Object.prototype.hasOwnProperty; var toStr = Object.prototype.toString; var isArray = function isArray(arr) { if (typeof Array.isArray === 'function') { return Array.isArray(arr); } return toStr.call(arr) === '[object Array]'; }; var isPlainObject = function isPlainObject(obj) { 'use strict'; if (!obj || toStr.call(obj) !== '[object Object]') { return false; } var has_own_constructor = hasOwn.call(obj, 'constructor'); var has_is_property_of_method = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); // Not own constructor property must be Object if (obj.constructor && !has_own_constructor && !has_is_property_of_method) { return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for (key in obj) {} return key === undefined || hasOwn.call(obj, key); }; module.exports = function extend() { 'use strict'; var options, name, src, copy, copyIsArray, clone, target = arguments[0], i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if (typeof target === 'boolean') { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } else if ((typeof target === 'undefined' ? 'undefined' : _typeof(target)) !== 'object' && typeof target !== 'function' || target == null) { target = {}; } for (; i < length; ++i) { options = arguments[i]; // Only deal with non-null/undefined values if (options != null) { // Extend the base object for (name in options) { src = target[name]; copy = options[name]; // Prevent never-ending loop if (target === copy) { continue; } // Recurse if we're merging plain objects or arrays if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { if (copyIsArray) { copyIsArray = false; clone = src && isArray(src) ? src : []; } else { clone = src && isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[name] = extend(deep, clone, copy); // Don't bring in undefined values } else if (copy !== undefined) { target[name] = copy; } } } } // Return the modified object return target; }; /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; /* This file is modified from https://github.com/shinout/interval-tree (The MIT License) Copyright (c) 2012 SHIN Suzuki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var SortedList = __webpack_require__(7); /** * IntervalTree * * @param (object) data: * @param (number) center: * @param (object) options: * center: * **/ function IntervalTree(center, options) { options || (options = {}); this.startKey = options.startKey || 0; // start key this.endKey = options.endKey || 1; // end key this.intervalHash = {}; // id => interval object this.pointTree = new SortedList({ // b-tree of start, end points compare: function compare(a, b) { if (a == null) return -1; if (b == null) return 1; var c = a[0] - b[0]; return c > 0 ? 1 : c == 0 ? 0 : -1; } }); this._autoIncrement = 0; // index of the root node if (!center || typeof center != 'number') { throw new Error('you must specify center index as the 2nd argument.'); } this.root = new Node(center, this); } /** * publid methods **/ /** * add new range **/ IntervalTree.prototype.add = function (data, id) { if (this.intervalHash[id]) { throw new Error('id ' + id + ' is already registered.'); } if (id == undefined) { while (this.intervalHash[this._autoIncrement]) { this._autoIncrement++; } id = this._autoIncrement; } var itvl = new Interval(data, id, this.startKey, this.endKey); this.pointTree.insert([itvl.start, id]); this.pointTree.insert([itvl.end, id]); this.intervalHash[id] = itvl; this._autoIncrement++; _insert.call(this, this.root, itvl); }; /** * search * * @param (integer) val: * @return (array) **/ IntervalTree.prototype.search = function (val1, val2) { var ret = []; if (typeof val1 != 'number') { throw new Error(val1 + ': invalid input'); } if (val2 == undefined) { _pointSearch.call(this, this.root, val1, ret); } else if (typeof val2 == 'number') { _rangeSearch.call(this, val1, val2, ret); } else { throw new Error(val1 + ',' + val2 + ': invalid input'); } return ret; }; /** * remove: **/ IntervalTree.prototype.remove = function (interval_id) {}; /** * private methods **/ /** * _insert **/ function _insert(node, itvl) { if (itvl.end < node.idx) { if (!node.left) { node.left = new Node(itvl.start + itvl.end >> 1, this); } return _insert.call(this, node.left, itvl); } if (node.idx < itvl.start) { if (!node.right) { node.right = new Node(itvl.start + itvl.end >> 1, this); } return _insert.call(this, node.right, itvl); } return node.insert(itvl); } /** * _pointSearch * @param (Node) node * @param (integer) idx * @param (Array) arr **/ function _pointSearch(node, idx, arr) { if (!node) return; if (idx < node.idx) { node.starts.every(function (itvl) { var bool = itvl.start <= idx; if (bool) arr.push(itvl.result()); return bool; }); return _pointSearch.call(this, node.left, idx, arr); } else if (idx > node.idx) { node.ends.every(function (itvl) { var bool = itvl.end >= idx; if (bool) arr.push(itvl.result()); return bool; }); return _pointSearch.call(this, node.right, idx, arr); } // exact equal else { node.starts.map(function (itvl) { arr.push(itvl.result()); }); } } /** * _rangeSearch * @param (integer) start * @param (integer) end * @param (Array) arr **/ function _rangeSearch(start, end, arr) { if (end - start <= 0) { throw new Error('end must be greater than start. start: ' + start + ', end: ' + end); } var resultHash = {}; var wholeWraps = []; _pointSearch.call(this, this.root, start + end >> 1, wholeWraps, true); wholeWraps.forEach(function (result) { resultHash[result.id] = true; }); var idx1 = this.pointTree.bsearch([start, null]); var pointTreeArray = this.pointTree; while (idx1 >= 0 && pointTreeArray[idx1][0] == start) { idx1--; } var idx2 = this.pointTree.bsearch([end, null]); if (idx2 >= 0) { var len = pointTreeArray.length - 1; while (idx2 <= len && pointTreeArray[idx2][0] <= end) { idx2++; } pointTreeArray.slice(idx1 + 1, idx2).forEach(function (point) { var id = point[1]; resultHash[id] = true; }, this); Object.keys(resultHash).forEach(function (id) { var itvl = this.intervalHash[id]; arr.push(itvl.result(start, end)); }, this); } } /** * subclasses * **/ /** * Node : prototype of each node in a interval tree * **/ function Node(idx) { this.idx = idx; this.starts = new SortedList({ compare: function compare(a, b) { if (a == null) return -1; if (b == null) return 1; var c = a.start - b.start; return c > 0 ? 1 : c == 0 ? 0 : -1; } }); this.ends = new SortedList({ compare: function compare(a, b) { if (a == null) return -1; if (b == null) return 1; var c = a.end - b.end; return c < 0 ? 1 : c == 0 ? 0 : -1; } }); } /** * insert an Interval object to this node **/ Node.prototype.insert = function (interval) { this.starts.insert(interval); this.ends.insert(interval); }; /** * Interval : prototype of interval info **/ function Interval(data, id, s, e) { this.id = id; this.start = data[s]; this.end = data[e]; this.data = data; if (typeof this.start != 'number' || typeof this.end != 'number') { throw new Error('start, end must be number. start: ' + this.start + ', end: ' + this.end); } if (this.start >= this.end) { throw new Error('start must be smaller than end. start: ' + this.start + ', end: ' + this.end); } } /** * get result object **/ Interval.prototype.result = function (start, end) { var ret = { id: this.id, data: this.data }; if (typeof start == 'number' && typeof end == 'number') { /** * calc overlapping rate **/ var left = Math.max(this.start, start); var right = Math.min(this.end, end); var lapLn = right - left; ret.rate1 = lapLn / (end - start); ret.rate2 = lapLn / (this.end - this.start); } return ret; }; module.exports = IntervalTree; /***/ }, /* 7 */ /***/ function(module, exports) { "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /* This file is modified from https://github.com/shinout/SortedList (The MIT License) Copyright (c) 2012 SHIN Suzuki Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var SortedList = function SortedList() { var arr = null, options = {}, args = arguments; ["0", "1"].forEach(function (n) { var val = args[n]; if (Array.isArray(val)) { arr = val; } else if (val && (typeof val === "undefined" ? "undefined" : _typeof(val)) == "object") { options = val; } }); if (typeof options.filter == 'function') { this._filter = options.filter; } if (typeof options.compare == 'function') { this._compare = options.compare; } else if (typeof options.compare == 'string' && SortedList.compares[options.compare]) { this._compare = SortedList.compares[options.compare]; } this._unique = !!options.unique; if (options.resume && arr) { arr.forEach(function (v, i) { this.push(v); }, this); } else if (arr) this.insert.apply(this, arr); }; /** * SortedList.create(val1, val2) * creates an instance **/ SortedList.create = function (val1, val2) { return new SortedList(val1, val2); }; SortedList.prototype = new Array(); SortedList.prototype.constructor = Array.prototype.constructor; /** * sorted.insertOne(val) * insert one value * returns false if failed, inserted position if succeed **/ SortedList.prototype.insertOne = function (val) { var pos = this.bsearch(val); if (this._unique && this.key(val, pos) != null) return false; if (!this._filter(val, pos)) return false; this.splice(pos + 1, 0, val); return pos + 1; }; /** * sorted.insert(val1, val2, ...) * insert multi values * returns the list of the results of insertOne() **/ SortedList.prototype.insert = function () { return Array.prototype.map.call(arguments, function (val) { return this.insertOne(val); }, this); }; /** * sorted.remove(pos) * remove the value in the given position **/ SortedList.prototype.remove = function (pos) { this.splice(pos, 1); return this; }; /** * sorted.bsearch(val) * @returns position of the value **/ SortedList.prototype.bsearch = function (val) { if (!this.length) return -1; var mpos, spos = 0, epos = this.length; while (epos - spos > 1) { mpos = Math.floor((spos + epos) / 2); var mval = this[mpos]; var comp = this._compare(val, mval); if (comp == 0) return mpos; if (comp > 0) spos = mpos;else epos = mpos; } return spos == 0 && this._compare(this[0], val) > 0 ? -1 : spos; }; /** * sorted.key(val) * @returns first index if exists, null if not **/ SortedList.prototype.key = function (val, bsResult) { if (bsResult == null) bsResult = this.bsearch(val); var pos = bsResult; if (pos == -1 || this._compare(this[pos], val) < 0) return pos + 1 < this.length && this._compare(this[pos + 1], val) == 0 ? pos + 1 : null; while (pos >= 1 && this._compare(this[pos - 1], val) == 0) { pos--; }return pos; }; /** * sorted.key(val) * @returns indexes if exists, null if not **/ SortedList.prototype.keys = function (val, bsResult) { var ret = []; if (bsResult == null) bsResult = this.bsearch(val); var pos = bsResult; while (pos >= 0 && this._compare(this[pos], val) == 0) { ret.push(pos); pos--; } var len = this.length; pos = bsResult + 1; while (pos < len && this._compare(this[pos], val) == 0) { ret.push(pos); pos++; } return ret.length ? ret : null; }; /** * sorted.unique() * @param createNew : create new instance * @returns first index if exists, null if not **/ SortedList.prototype.unique = function (createNew) { if (createNew) return this.filter(function (v, k) { return k == 0 || this._compare(this[k - 1], v) != 0; }, this); var total = 0; this.map(function (v, k) { if (k == 0 || this._compare(this[k - 1], v) != 0) return null; return k - total++; }, this).forEach(function (k) { if (k != null) this.remove(k); }, this); return this; }; /** * sorted.toArray() * get raw array **/ SortedList.prototype.toArray = function () { return this.slice(); }; /** * default filtration function **/ SortedList.prototype._filter = function (val, pos) { return true; }; /** * comparison functions **/ SortedList.compares = { "number": function number(a, b) { var c = a - b; return c > 0 ? 1 : c == 0 ? 0 : -1; }, "string": function string(a, b) { return a > b ? 1 : a == b ? 0 : -1; } }; /** * sorted.compare(a, b) * default comparison function **/ SortedList.prototype._compare = SortedList.compares["string"]; module.exports = SortedList; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var helper = __webpack_require__(4); var vpsc = __webpack_require__(9); var DEFAULT_OPTIONS = { lineSpacing: 2, nodeSpacing: 3, minPos: 0, maxPos: null }; function nodeToVariable(node) { var v = new vpsc.Variable(node.targetPos); v.node = node; return v; } function removeOverlap(nodes, options) { if (nodes.length > 0) { options = helper.extend(DEFAULT_OPTIONS, options); // For nodes with stub, set target position to stub's current position nodes.forEach(function (node, index) { node.targetPos = node.parent ? node.parent.currentPos : node.idealPos; node.index = index; }); nodes.sort(function (a, b) { var diff = a.targetPos - b.targetPos; if (diff !== 0) return diff; var diff2 = a.isStub() - b.isStub(); if (diff2 !== 0) return diff2; // If same position, use original order return a.index - b.index; }); var variables = nodes.map(nodeToVariable); var constraints = []; for (var i = 1; i < variables.length; i++) { var v1 = variables[i - 1]; var v2 = variables[i]; var gap; if (v1.node.isStub() && v2.node.isStub()) { gap = (v1.node.width + v2.node.width) / 2 + options.lineSpacing; } else { gap = (v1.node.width + v2.node.width) / 2 + options.nodeSpacing; } constraints.push(new vpsc.Constraint(v1, v2, gap)); } if (helper.isDefined(options.minPos)) { var leftWall = new vpsc.Variable(options.minPos, 1e10); var v = variables[0]; constraints.push(new vpsc.Constraint(leftWall, v, v.node.width / 2)); variables.unshift(leftWall); } if (helper.isDefined(options.maxPos)) { var rightWall = new vpsc.Variable(options.maxPos, 1e10); var lastv = helper.last(variables); constraints.push(new vpsc.Constraint(lastv, rightWall, lastv.node.width / 2)); variables.push(rightWall); } new vpsc.Solver(variables, constraints).solve(); variables.filter(function (v) { return v.node; }).map(function (v) { v.node.currentPos = Math.round(v.position()); return v; }); } return nodes; } removeOverlap.DEFAULT_OPTIONS = DEFAULT_OPTIONS; module.exports = removeOverlap; /***/ }, /* 9 */ /***/ function(module, exports) { "use strict"; /* This file is compiled from https://github.com/tgdwyer/WebCola/blob/master/WebCola/src/vpsc.ts and modified slightly. The MIT License (MIT) Copyright (c) 2013 Tim Dwyer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var vpsc = {}; var PositionStats = function () { function PositionStats(scale) { this.scale = scale; this.AB = 0; this.AD = 0; this.A2 = 0; } PositionStats.prototype.addVariable = function (v) { var ai = this.scale / v.scale; var bi = v.offset / v.scale; var wi = v.weight; this.AB += wi * ai * bi; this.AD += wi * ai * v.desiredPosition; this.A2 += wi * ai * ai; }; PositionStats.prototype.getPosn = function () { return (this.AD - this.AB) / this.A2; }; return PositionStats; }(); vpsc.PositionStats = PositionStats; var Constraint = function () { function Constraint(left, right, gap, equality) { if (equality === void 0) { equality = false; } this.left = left; this.right = right; this.gap = gap; this.equality = equality; this.active = false; this.unsatisfiable = false; this.left = left; this.right = right; this.gap = gap; this.equality = equality; } Constraint.prototype.slack = function () { return this.unsatisfiable ? Number.MAX_VALUE : this.right.scale * this.right.position() - this.gap - this.left.scale * this.left.position(); }; return Constraint; }(); vpsc.Constraint = Constraint; var Variable = function () { function Variable(desiredPosition, weight, scale) { if (weight === void 0) { weight = 1; } if (scale === void 0) { scale = 1; } this.desiredPosition = desiredPosition; this.weight = weight; this.scale = scale; this.offset = 0; } Variable.prototype.dfdv = function () { return 2.0 * this.weight * (this.position() - this.desiredPosition); }; Variable.prototype.position = function () { return (this.block.ps.scale * this.block.posn + this.offset) / this.scale; }; // visit neighbours by active constraints within the same block Variable.prototype.visitNeighbours = function (prev, f) { var ff = function ff(c, next) { return c.active && prev !== next && f(c, next); }; this.cOut.forEach(function (c) { return ff(c, c.right); }); this.cIn.forEach(function (c) { return ff(c, c.left); }); }; return Variable; }(); vpsc.Variable = Variable; var Block = function () { function Block(v) { this.vars = []; v.offset = 0; this.ps = new PositionStats(v.scale); this.addVariable(v); } Block.prototype.addVariable = function (v) { v.block = this; this.vars.push(v); this.ps.addVariable(v); this.posn = this.ps.getPosn(); }; // move the block where it needs to be to minimize cost Block.prototype.updateWeightedPosition = function () { this.ps.AB = this.ps.AD = this.ps.A2 = 0; for (var i = 0, n = this.vars.length; i < n; ++i) { this.ps.addVariable(this.vars[i]); }this.posn = this.ps.getPosn(); }; Block.prototype.compute_lm = function (v, u, postAction) { var _this = this; var dfdv = v.dfdv(); v.visitNeighbours(u, function (c, next) { var _dfdv = _this.compute_lm(next, v, postAction); if (next === c.right) { dfdv += _dfdv * c.left.scale; c.lm = _dfdv; } else { dfdv += _dfdv * c.right.scale; c.lm = -_dfdv; } postAction(c); }); return dfdv / v.scale; }; Block.prototype.populateSplitBlock = function (v, prev) { var _this = this; v.visitNeighbours(prev, function (c, next) { next.offset = v.offset + (next === c.right ? c.gap : -c.gap); _this.addVariable(next); _this.populateSplitBlock(next, v); }); }; // traverse the active constraint tree applying visit to each active constraint Block.prototype.traverse = function (visit, acc, v, prev) { var _this = this; if (v === void 0) { v = this.vars[0]; } if (prev === void 0) { prev = null; } v.visitNeighbours(prev, function (c, next) { acc.push(visit(c)); _this.traverse(visit, acc, next, v); }); }; // calculate lagrangian multipliers on constraints and // find the active constraint in this block with the smallest lagrangian. // if the lagrangian is negative, then the constraint is a split candidate. Block.prototype.findMinLM = function () { var m = null; this.compute_lm(this.vars[0], null, function (c) { if (!c.equality && (m === null || c.lm < m.lm)) m = c; }); return m; }; Block.prototype.findMinLMBetween = function (lv, rv) { this.compute_lm(lv, null, function () {}); var m = null; this.findPath(lv, null, rv, function (c, next) { if (!c.equality && c.right === next && (m === null || c.lm < m.lm)) m = c; }); return m; }; Block.prototype.findPath = function (v, prev, to, visit) { var _this = this; var endFound = false; v.visitNeighbours(prev, function (c, next) { if (!endFound && (next === to || _this.findPath(next, v, to, visit))) { endFound = true; visit(c, next); } }); return endFound; }; // Search active constraint tree from u to see if there is a directed path to v. // Returns true if path is found. Block.prototype.isActiveDirectedPathBetween = function (u, v) { if (u === v) return true; var i = u.cOut.length; while (i--) { var c = u.cOut[i]; if (c.active && this.isActiveDirectedPathBetween(c.right, v)) return true; } return false; }; // split the block into two by deactivating the specified constraint Block.split = function (c) { /* DEBUG console.log("split on " + c); console.assert(c.active, "attempt to split on inactive constraint"); DEBUG */ c.active = false; return [Block.createSplitBlock(c.left), Block.createSplitBlock(c.right)]; }; Block.createSplitBlock = function (startVar) { var b = new Block(startVar); b.populateSplitBlock(startVar, null); return b; }; // find a split point somewhere between the specified variables Block.prototype.splitBetween = function (vl, vr) { /* DEBUG console.assert(vl.block === this); console.assert(vr.block === this); DEBUG */ var c = this.findMinLMBetween(vl, vr); if (c !== null) { var bs = Block.split(c); return { constraint: c, lb: bs[0], rb: bs[1] }; } // couldn't find a split point - for example the active path is all equality constraints return null; }; Block.prototype.mergeAcross = function (b, c, dist) { c.active = true; for (var i = 0, n = b.vars.length; i < n; ++i) { var v = b.vars[i]; v.offset += dist; this.addVariable(v); } this.posn = this.ps.getPosn(); }; Block.prototype.cost = function () { var sum = 0, i = this.vars.length; while (i--) { var v = this.vars[i], d = v.position() - v.desiredPosition; sum += d * d * v.weight; } return sum; }; return Block; }(); vpsc.Block = Block; var Blocks = function () { function Blocks(vs) { this.vs = vs; var n = vs.length; this.list = new Array(n); while (n--) { var b = new Block(vs[n]); this.list[n] = b; b.blockInd = n; } } Blocks.prototype.cost = function () { var sum = 0, i = this.list.length; while (i--) { sum += this.list[i].cost(); }return sum; }; Blocks.prototype.insert = function (b) { /* DEBUG console.assert(!this.contains(b), "blocks error: tried to reinsert block " + b.blockInd) DEBUG */ b.blockInd = this.list.length; this.list.push(b); /* DEBUG console.log("insert block: " + b.blockInd); this.contains(b); DEBUG */ }; Blocks.prototype.remove = function (b) { /* DEBUG console.log("remove block: " + b.blockInd); console.assert(this.contains(b)); DEBUG */ var last = this.list.length - 1; var swapBlock = this.list[last]; this.list.length = last; if (b !== swapBlock) { this.list[b.blockInd] = swapBlock; swapBlock.blockInd = b.blockInd; } }; // merge the blocks on either side of the specified constraint, by copying the smaller block into the larger // and deleting the smaller. Blocks.prototype.merge = function (c) { var l = c.left.block, r = c.right.block; /* DEBUG console.assert(l!==r, "attempt to merge within the same block"); DEBUG */ var dist = c.right.offset - c.left.offset - c.gap; if (l.vars.length < r.vars.length) { r.mergeAcross(l, c, dist); this.remove(l); } else { l.mergeAcross(r, c, -dist); this.remove(r); } /* DEBUG console.assert(Math.abs(c.slack()) < 1e-6, "Error: Constraint should be at equality after merge!"); console.log("merged on " + c); DEBUG */ }; Blocks.prototype.forEach = function (f) { this.list.forEach(f); }; // useful, for example, after variable desired positions change. Blocks.prototype.updateBlockPositions = function () { this.list.forEach(function (b) { return b.updateWeightedPosition(); }); }; // split each block across its constraint with the minimum lagrangian Blocks.prototype.split = function (inactive) { var _this = this; this.updateBlockPositions(); this.list.forEach(function (b) { var v = b.findMinLM(); if (v !== null && v.lm < Solver.LAGRANGIAN_TOLERANCE) { b = v.left.block; Block.split(v).forEach(function (nb) { return _this.insert(nb); }); _this.remove(b); inactive.push(v); } }); }; return Blocks; }(); vpsc.Blocks = Blocks; var Solver = function () { function Solver(vs, cs) { this.vs = vs; this.cs = cs; this.vs = vs; vs.forEach(function (v) { v.cIn = [], v.cOut = []; /* DEBUG v.toString = () => "v" + vs.indexOf(v); DEBUG */ }); this.cs = cs; cs.forEach(function (c) { c.left.cOut.push(c); c.right.cIn.push(c); /* DEBUG c.toString = () => c.left + "+" + c.gap + "<=" + c.right + " slack=" + c.slack() + " active=" + c.active; DEBUG */ }); this.inactive = cs.map(function (c) { c.active = false;return c; }); this.bs = null; } Solver.prototype.cost = function () { return this.bs.cost(); }; // set starting positions without changing desired positions. // Note: it throws away any previous block structure. Solver.prototype.setStartingPositions = function (ps) { this.inactive = this.cs.map(function (c) { c.active = false;return c; }); this.bs = new Blocks(this.vs); this.bs.forEach(function (b, i) { return b.posn = ps[i]; }); }; Solver.prototype.setDesiredPositions = function (ps) { this.vs.forEach(function (v, i) { return v.desiredPosition = ps[i]; }); }; /* DEBUG private getId(v: Variable): number { return this.vs.indexOf(v); } // sanity check of the index integrity of the inactive list checkInactive(): void { var inactiveCount = 0; this.cs.forEach(c=> { var i = this.inactive.indexOf(c); console.assert(!c.active && i >= 0 || c.active && i < 0, "constraint should be in the inactive list if it is not active: " + c); if (i >= 0) { inactiveCount++; } else { console.assert(c.active, "inactive constraint not found in inactive list: " + c); } }); console.assert(inactiveCount === this.inactive.length, inactiveCount + " inactive constraints found, " + this.inactive.length + "in inactive list"); } // after every call to satisfy the following should check should pass checkSatisfied(): void { this.cs.forEach(c=>console.assert(c.slack() >= vpsc.Solver.ZERO_UPPERBOUND, "Error: Unsatisfied constraint! "+c)); } DEBUG */ Solver.prototype.mostViolated = function () { var minSlack = Number.MAX_VALUE, v = null, l = this.inactive, n = l.length, deletePoint = n; for (var i = 0; i < n; ++i) { var c = l[i]; if (c.unsatisfiable) continue; var slack = c.slack(); if (c.equality || slack < minSlack) { minSlack = slack; v = c; deletePoint = i; if (c.equality) break; } } if (deletePoint !== n && (minSlack < Solver.ZERO_UPPERBOUND && !v.active || v.equality)) { l[deletePoint] = l[n - 1]; l.length = n - 1; } return v; }; // satisfy constraints by building block structure over violated constraints // and moving the blocks to their desired positions Solver.prototype.satisfy = function () { if (this.bs == null) { this.bs = new Blocks(this.vs); } /* DEBUG console.log("satisfy: " + this.bs); DEBUG */ this.bs.split(this.inactive); var v = null; while ((v = this.mostViolated()) && (v.equality || v.slack() < Solver.ZERO_UPPERBOUND && !v.active)) { var lb = v.left.block, rb = v.right.block; /* DEBUG console.log("most violated is: " + v); this.bs.contains(lb); this.bs.contains(rb); DEBUG */ if (lb !== rb) { this.bs.merge(v); } else { if (lb.isActiveDirectedPathBetween(v.right, v.left)) { // cycle found! v.unsatisfiable = true; continue; } // constraint is within block, need to split first var split = lb.splitBetween(v.left, v.right); if (split !== null) { this.bs.insert(split.lb); this.bs.insert(split.rb); this.bs.remove(lb); this.inactive.push(split.constraint); } else { /* DEBUG console.log("unsatisfiable constraint found"); DEBUG */ v.unsatisfiable = true; continue; } if (v.slack() >= 0) { /* DEBUG console.log("violated constraint indirectly satisfied: " + v); DEBUG */ // v was satisfied by the above split! this.inactive.push(v); } else { /* DEBUG console.log("merge after split:"); DEBUG */ this.bs.merge(v); } } } /* DEBUG this.checkSatisfied(); DEBUG */ }; // repeatedly build and split block structure until we converge to an optimal solution Solver.prototype.solve = function () { this.satisfy(); var lastcost = Number.MAX_VALUE, cost = this.bs.cost(); while (Math.abs(lastcost - cost) > 0.0001) { this.satisfy(); lastcost = cost; cost = this.bs.cost(); } return cost; }; Solver.LAGRANGIAN_TOLERANCE = -1e-4; Solver.ZERO_UPPERBOUND = -1e-10; return Solver; }(); vpsc.Solver = Solver; module.exports = vpsc; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var helper = __webpack_require__(4); function Renderer(options) { this.options = helper.extend({ layerGap: 60, nodeHeight: 10, direction: 'down' }, options); } function lineTo(point) { return 'L ' + point.join(' '); } function moveTo(point) { return 'M ' + point.join(' '); } function curveTo(c1, c2, point2) { return 'C ' + c1.join(' ') + ' ' + c2.join(' ') + ' ' + point2.join(' '); } function vCurveBetween(point1, point2) { var midY = (point1[1] + point2[1]) / 2; return curveTo([point1[0], midY], [point2[0], midY], point2); } function hCurveBetween(point1, point2) { var midX = (point1[0] + point2[0]) / 2; return curveTo([midX, point1[1]], [midX, point2[1]], point2); } Renderer.lineTo = lineTo; Renderer.moveTo = moveTo; Renderer.curveTo = curveTo; Renderer.vCurveBetween = vCurveBetween; Renderer.hCurveBetween = hCurveBetween; Renderer.prototype.getWaypoints = function (node) { var options = this.options; var direction = options.direction; var hops = node.getPathFromRoot(); var gap = options.nodeHeight + options.layerGap; if (direction === 'left') { return [[[0, hops[0].idealPos]]].concat(hops.map(function (hop, level) { var xPos = gap * (level + 1) * -1; return [[xPos + options.nodeHeight, hop.currentPos], [xPos, hop.currentPos]]; })); } else if (direction === 'right') { return [[[0, hops[0].idealPos]]].concat(hops.map(function (hop, level) { var xPos = gap * (level + 1); return [[xPos - options.nodeHeight, hop.currentPos], [xPos, hop.currentPos]]; })); } else if (direction === 'up') { return [[[hops[0].idealPos, 0]]].concat(hops.map(function (hop, level) { var yPos = gap * (level + 1) * -1; return [[hop.currentPos, yPos + options.nodeHeight], [hop.currentPos, yPos]]; })); } else { return [[[hops[0].idealPos, 0]]].concat(hops.map(function (hop, level) { var yPos = gap * (level + 1); return [[hop.currentPos, yPos - options.nodeHeight], [hop.currentPos, yPos]]; })); } }; Renderer.prototype.layout = function (nodes) { var options = this.options; var gap = options.layerGap + options.nodeHeight; switch (options.direction) { case 'left': nodes.forEach(function (node) { var pos = node.getLayerIndex() * gap + options.layerGap; node.x = -pos - options.nodeHeight; node.y = node.currentPos; node.dx = options.nodeHeight; node.dy = node.width; }); break; case 'right': nodes.forEach(function (node) { var pos = node.getLayerIndex() * gap + options.layerGap; node.x = pos; node.y = node.currentPos; node.dx = options.nodeHeight; node.dy = node.width; }); break; case 'up': nodes.forEach(function (node) { var pos = node.getLayerIndex() * gap + options.layerGap; node.x = node.currentPos; node.y = -pos - options.nodeHeight; node.dx = node.width; node.dy = options.nodeHeight; }); break; default: case 'down': nodes.forEach(function (node) { var pos = node.getLayerIndex() * gap + options.layerGap; node.x = node.currentPos; node.y = pos; node.dx = node.width; node.dy = options.nodeHeight; }); break; } return nodes; }; Renderer.prototype.generatePath = function (node) { var options = this.options; var direction = options.direction; var waypoints = this.getWaypoints(node, direction); var steps = [moveTo(waypoints[0][0])]; if (direction === 'left' || direction === 'right') { waypoints.reduce(function (prev, current, level) { steps.push(hCurveBetween(prev[prev.length - 1], current[0])); if (level < waypoints.length - 1) { steps.push(lineTo(current[1])); } return current; }); } else { waypoints.reduce(function (prev, current, level) { steps.push(vCurveBetween(prev[prev.length - 1], current[0])); if (level < waypoints.length - 1) { steps.push(lineTo(current[1])); } return current; }); } return steps.join(' '); }; // return module module.exports = Renderer; /***/ } /******/ ]) }); ;