apextree 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -62
- package/apextree.es.min.js +7127 -0
- package/apextree.min.js +1 -0
- package/demo/bottom_to_top_view.html +9 -7
- package/demo/custom_font_options.html +3 -6
- package/demo/dynamic_view_change.html +3 -6
- package/demo/expand_collapse_nodes.html +2 -2
- package/demo/left_to_right_view.html +2 -2
- package/demo/per_node_options.html +3 -6
- package/demo/right_to_left_view.html +2 -2
- package/demo/top_to_bottom_view.html +2 -2
- package/index.d.ts +1 -0
- package/lib/ApexTree.d.ts +9 -0
- package/lib/models/Export.d.ts +9 -0
- package/lib/models/Graph.d.ts +35 -0
- package/lib/models/Paper.d.ts +32 -0
- package/lib/models/Toolbar.d.ts +15 -0
- package/lib/models/index.d.ts +2 -0
- package/lib/settings/DirectionConfig.d.ts +47 -0
- package/lib/settings/Options.d.ts +49 -0
- package/lib/utils/EdgeUtils.d.ts +2 -0
- package/lib/utils/GraphUtils.d.ts +10 -0
- package/package.json +19 -27
- package/.editorconfig +0 -7
- package/.eslintignore +0 -2
- package/.eslintrc +0 -9
- package/.prettierrc +0 -5
- package/.vscode/settings.json +0 -5
- package/LICENSE +0 -674
- package/dist/ApexTree.js +0 -608
- package/dist/ApexTree.min.js +0 -2
- package/dist/ApexTree.min.js.LICENSE.txt +0 -10
- package/globals.d.ts +0 -4
- package/src/ApexTree.ts +0 -34
- package/src/icons/add-circle.svg +0 -3
- package/src/icons/export-icon.svg +0 -2
- package/src/icons/fit-screen-icon.svg +0 -9
- package/src/icons/minus-circle.svg +0 -3
- package/src/icons/zoom-in-icon.svg +0 -8
- package/src/icons/zoom-out-icon.svg +0 -8
- package/src/models/Export.ts +0 -39
- package/src/models/Graph.ts +0 -284
- package/src/models/Paper.ts +0 -117
- package/src/models/Toolbar.ts +0 -71
- package/src/models/index.ts +0 -2
- package/src/settings/DirectionConfig.ts +0 -227
- package/src/settings/Options.ts +0 -98
- package/src/utils/EdgeUtils.ts +0 -30
- package/src/utils/GraphUtils.ts +0 -135
- package/tsconfig.json +0 -28
- package/webpack.common.ts +0 -68
- package/webpack.config.ts +0 -7
- package/webpack.dev.ts +0 -12
- package/webpack.prod.ts +0 -9
- /package/{src/utils/index.ts → lib/utils/index.d.ts} +0 -0
package/dist/ApexTree.js
DELETED
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
3
|
-
* This devtool is neither made for production nor for readable output files.
|
|
4
|
-
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
|
5
|
-
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
|
6
|
-
* or disable the default devtool with "devtool: false".
|
|
7
|
-
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
|
8
|
-
*/
|
|
9
|
-
(function webpackUniversalModuleDefinition(root, factory) {
|
|
10
|
-
if (typeof exports === 'object' && typeof module === 'object')
|
|
11
|
-
module.exports = factory();
|
|
12
|
-
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
13
|
-
else if (typeof exports === 'object') exports['ApexTree'] = factory();
|
|
14
|
-
else root['ApexTree'] = factory();
|
|
15
|
-
})(self, () => {
|
|
16
|
-
return /******/ (() => {
|
|
17
|
-
// webpackBootstrap
|
|
18
|
-
/******/ 'use strict';
|
|
19
|
-
/******/ var __webpack_modules__ = {
|
|
20
|
-
/***/ './node_modules/@svgdotjs/svg.js/dist/svg.esm.js':
|
|
21
|
-
/*!*******************************************************!*\
|
|
22
|
-
!*** ./node_modules/@svgdotjs/svg.js/dist/svg.esm.js ***!
|
|
23
|
-
\*******************************************************/
|
|
24
|
-
/***/ (
|
|
25
|
-
__unused_webpack_module,
|
|
26
|
-
__webpack_exports__,
|
|
27
|
-
__webpack_require__,
|
|
28
|
-
) => {
|
|
29
|
-
eval(
|
|
30
|
-
"__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (/* binding */ A),\n/* harmony export */ Animator: () => (/* binding */ Animator),\n/* harmony export */ Array: () => (/* binding */ SVGArray),\n/* harmony export */ Box: () => (/* binding */ Box),\n/* harmony export */ Circle: () => (/* binding */ Circle),\n/* harmony export */ ClipPath: () => (/* binding */ ClipPath),\n/* harmony export */ Color: () => (/* binding */ Color),\n/* harmony export */ Container: () => (/* binding */ Container),\n/* harmony export */ Controller: () => (/* binding */ Controller),\n/* harmony export */ Defs: () => (/* binding */ Defs),\n/* harmony export */ Dom: () => (/* binding */ Dom),\n/* harmony export */ Ease: () => (/* binding */ Ease),\n/* harmony export */ Element: () => (/* binding */ Element),\n/* harmony export */ Ellipse: () => (/* binding */ Ellipse),\n/* harmony export */ EventTarget: () => (/* binding */ EventTarget),\n/* harmony export */ ForeignObject: () => (/* binding */ ForeignObject),\n/* harmony export */ Fragment: () => (/* binding */ Fragment),\n/* harmony export */ G: () => (/* binding */ G),\n/* harmony export */ Gradient: () => (/* binding */ Gradient),\n/* harmony export */ Image: () => (/* binding */ Image),\n/* harmony export */ Line: () => (/* binding */ Line),\n/* harmony export */ List: () => (/* binding */ List),\n/* harmony export */ Marker: () => (/* binding */ Marker),\n/* harmony export */ Mask: () => (/* binding */ Mask),\n/* harmony export */ Matrix: () => (/* binding */ Matrix),\n/* harmony export */ Morphable: () => (/* binding */ Morphable),\n/* harmony export */ NonMorphable: () => (/* binding */ NonMorphable),\n/* harmony export */ Number: () => (/* binding */ SVGNumber),\n/* harmony export */ ObjectBag: () => (/* binding */ ObjectBag),\n/* harmony export */ PID: () => (/* binding */ PID),\n/* harmony export */ Path: () => (/* binding */ Path),\n/* harmony export */ PathArray: () => (/* binding */ PathArray),\n/* harmony export */ Pattern: () => (/* binding */ Pattern),\n/* harmony export */ Point: () => (/* binding */ Point),\n/* harmony export */ PointArray: () => (/* binding */ PointArray),\n/* harmony export */ Polygon: () => (/* binding */ Polygon),\n/* harmony export */ Polyline: () => (/* binding */ Polyline),\n/* harmony export */ Queue: () => (/* binding */ Queue),\n/* harmony export */ Rect: () => (/* binding */ Rect),\n/* harmony export */ Runner: () => (/* binding */ Runner),\n/* harmony export */ SVG: () => (/* binding */ SVG),\n/* harmony export */ Shape: () => (/* binding */ Shape),\n/* harmony export */ Spring: () => (/* binding */ Spring),\n/* harmony export */ Stop: () => (/* binding */ Stop),\n/* harmony export */ Style: () => (/* binding */ Style),\n/* harmony export */ Svg: () => (/* binding */ Svg),\n/* harmony export */ Symbol: () => (/* binding */ Symbol),\n/* harmony export */ Text: () => (/* binding */ Text),\n/* harmony export */ TextPath: () => (/* binding */ TextPath),\n/* harmony export */ Timeline: () => (/* binding */ Timeline),\n/* harmony export */ TransformBag: () => (/* binding */ TransformBag),\n/* harmony export */ Tspan: () => (/* binding */ Tspan),\n/* harmony export */ Use: () => (/* binding */ Use),\n/* harmony export */ adopt: () => (/* binding */ adopt),\n/* harmony export */ assignNewId: () => (/* binding */ assignNewId),\n/* harmony export */ clearEvents: () => (/* binding */ clearEvents),\n/* harmony export */ create: () => (/* binding */ create),\n/* harmony export */ defaults: () => (/* binding */ defaults),\n/* harmony export */ dispatch: () => (/* binding */ dispatch),\n/* harmony export */ easing: () => (/* binding */ easing),\n/* harmony export */ eid: () => (/* binding */ eid),\n/* harmony export */ extend: () => (/* binding */ extend),\n/* harmony export */ find: () => (/* binding */ baseFind),\n/* harmony export */ getClass: () => (/* binding */ getClass),\n/* harmony export */ getEventTarget: () => (/* binding */ getEventTarget),\n/* harmony export */ getEvents: () => (/* binding */ getEvents),\n/* harmony export */ getWindow: () => (/* binding */ getWindow),\n/* harmony export */ makeInstance: () => (/* binding */ makeInstance),\n/* harmony export */ makeMorphable: () => (/* binding */ makeMorphable),\n/* harmony export */ mockAdopt: () => (/* binding */ mockAdopt),\n/* harmony export */ namespaces: () => (/* binding */ namespaces),\n/* harmony export */ nodeOrNew: () => (/* binding */ nodeOrNew),\n/* harmony export */ off: () => (/* binding */ off),\n/* harmony export */ on: () => (/* binding */ on),\n/* harmony export */ parser: () => (/* binding */ parser),\n/* harmony export */ regex: () => (/* binding */ regex),\n/* harmony export */ register: () => (/* binding */ register),\n/* harmony export */ registerMorphableType: () => (/* binding */ registerMorphableType),\n/* harmony export */ registerWindow: () => (/* binding */ registerWindow),\n/* harmony export */ restoreWindow: () => (/* binding */ restoreWindow),\n/* harmony export */ root: () => (/* binding */ root),\n/* harmony export */ saveWindow: () => (/* binding */ saveWindow),\n/* harmony export */ utils: () => (/* binding */ utils),\n/* harmony export */ windowEvents: () => (/* binding */ windowEvents),\n/* harmony export */ withWindow: () => (/* binding */ withWindow),\n/* harmony export */ wrapWithAttrCheck: () => (/* binding */ wrapWithAttrCheck)\n/* harmony export */ });\n/*!\n* @svgdotjs/svg.js - A lightweight library for manipulating and animating SVG.\n* @version 3.2.0\n* https://svgjs.dev/\n*\n* @copyright Wout Fierens <wout@mick-wout.com>\n* @license MIT\n*\n* BUILT: Mon Jun 12 2023 10:34:51 GMT+0200 (Central European Summer Time)\n*/;\nconst methods$1 = {};\nconst names = [];\nfunction registerMethods(name, m) {\n if (Array.isArray(name)) {\n for (const _name of name) {\n registerMethods(_name, m);\n }\n\n return;\n }\n\n if (typeof name === 'object') {\n for (const _name in name) {\n registerMethods(_name, name[_name]);\n }\n\n return;\n }\n\n addMethodNames(Object.getOwnPropertyNames(m));\n methods$1[name] = Object.assign(methods$1[name] || {}, m);\n}\nfunction getMethodsFor(name) {\n return methods$1[name] || {};\n}\nfunction getMethodNames() {\n return [...new Set(names)];\n}\nfunction addMethodNames(_names) {\n names.push(..._names);\n}\n\n// Map function\nfunction map(array, block) {\n let i;\n const il = array.length;\n const result = [];\n\n for (i = 0; i < il; i++) {\n result.push(block(array[i]));\n }\n\n return result;\n} // Filter function\n\nfunction filter(array, block) {\n let i;\n const il = array.length;\n const result = [];\n\n for (i = 0; i < il; i++) {\n if (block(array[i])) {\n result.push(array[i]);\n }\n }\n\n return result;\n} // Degrees to radians\n\nfunction radians(d) {\n return d % 360 * Math.PI / 180;\n} // Radians to degrees\n\nfunction degrees(r) {\n return r * 180 / Math.PI % 360;\n} // Convert dash-separated-string to camelCase\n\nfunction camelCase(s) {\n return s.toLowerCase().replace(/-(.)/g, function (m, g) {\n return g.toUpperCase();\n });\n} // Convert camel cased string to dash separated\n\nfunction unCamelCase(s) {\n return s.replace(/([A-Z])/g, function (m, g) {\n return '-' + g.toLowerCase();\n });\n} // Capitalize first letter of a string\n\nfunction capitalize(s) {\n return s.charAt(0).toUpperCase() + s.slice(1);\n} // Calculate proportional width and height values when necessary\n\nfunction proportionalSize(element, width, height, box) {\n if (width == null || height == null) {\n box = box || element.bbox();\n\n if (width == null) {\n width = box.width / box.height * height;\n } else if (height == null) {\n height = box.height / box.width * width;\n }\n }\n\n return {\n width: width,\n height: height\n };\n}\n/**\n * This function adds support for string origins.\n * It searches for an origin in o.origin o.ox and o.originX.\n * This way, origin: {x: 'center', y: 50} can be passed as well as ox: 'center', oy: 50\n**/\n\nfunction getOrigin(o, element) {\n const origin = o.origin; // First check if origin is in ox or originX\n\n let ox = o.ox != null ? o.ox : o.originX != null ? o.originX : 'center';\n let oy = o.oy != null ? o.oy : o.originY != null ? o.originY : 'center'; // Then check if origin was used and overwrite in that case\n\n if (origin != null) {\n [ox, oy] = Array.isArray(origin) ? origin : typeof origin === 'object' ? [origin.x, origin.y] : [origin, origin];\n } // Make sure to only call bbox when actually needed\n\n\n const condX = typeof ox === 'string';\n const condY = typeof oy === 'string';\n\n if (condX || condY) {\n const {\n height,\n width,\n x,\n y\n } = element.bbox(); // And only overwrite if string was passed for this specific axis\n\n if (condX) {\n ox = ox.includes('left') ? x : ox.includes('right') ? x + width : x + width / 2;\n }\n\n if (condY) {\n oy = oy.includes('top') ? y : oy.includes('bottom') ? y + height : y + height / 2;\n }\n } // Return the origin as it is if it wasn't a string\n\n\n return [ox, oy];\n}\n\nvar utils = {\n __proto__: null,\n map: map,\n filter: filter,\n radians: radians,\n degrees: degrees,\n camelCase: camelCase,\n unCamelCase: unCamelCase,\n capitalize: capitalize,\n proportionalSize: proportionalSize,\n getOrigin: getOrigin\n};\n\n// Default namespaces\nconst svg = 'http://www.w3.org/2000/svg';\nconst html = 'http://www.w3.org/1999/xhtml';\nconst xmlns = 'http://www.w3.org/2000/xmlns/';\nconst xlink = 'http://www.w3.org/1999/xlink';\nconst svgjs = 'http://svgjs.dev/svgjs';\n\nvar namespaces = {\n __proto__: null,\n svg: svg,\n html: html,\n xmlns: xmlns,\n xlink: xlink,\n svgjs: svgjs\n};\n\nconst globals = {\n window: typeof window === 'undefined' ? null : window,\n document: typeof document === 'undefined' ? null : document\n};\nfunction registerWindow(win = null, doc = null) {\n globals.window = win;\n globals.document = doc;\n}\nconst save = {};\nfunction saveWindow() {\n save.window = globals.window;\n save.document = globals.document;\n}\nfunction restoreWindow() {\n globals.window = save.window;\n globals.document = save.document;\n}\nfunction withWindow(win, fn) {\n saveWindow();\n registerWindow(win, win.document);\n fn(win, win.document);\n restoreWindow();\n}\nfunction getWindow() {\n return globals.window;\n}\n\nclass Base {// constructor (node/*, {extensions = []} */) {\n // // this.tags = []\n // //\n // // for (let extension of extensions) {\n // // extension.setup.call(this, node)\n // // this.tags.push(extension.name)\n // // }\n // }\n}\n\nconst elements = {};\nconst root = '___SYMBOL___ROOT___'; // Method for element creation\n\nfunction create(name, ns = svg) {\n // create element\n return globals.document.createElementNS(ns, name);\n}\nfunction makeInstance(element, isHTML = false) {\n if (element instanceof Base) return element;\n\n if (typeof element === 'object') {\n return adopter(element);\n }\n\n if (element == null) {\n return new elements[root]();\n }\n\n if (typeof element === 'string' && element.charAt(0) !== '<') {\n return adopter(globals.document.querySelector(element));\n } // Make sure, that HTML elements are created with the correct namespace\n\n\n const wrapper = isHTML ? globals.document.createElement('div') : create('svg');\n wrapper.innerHTML = element; // We can use firstChild here because we know,\n // that the first char is < and thus an element\n\n element = adopter(wrapper.firstChild); // make sure, that element doesn't have its wrapper attached\n\n wrapper.removeChild(wrapper.firstChild);\n return element;\n}\nfunction nodeOrNew(name, node) {\n return node && node.ownerDocument && node instanceof node.ownerDocument.defaultView.Node ? node : create(name);\n} // Adopt existing svg elements\n\nfunction adopt(node) {\n // check for presence of node\n if (!node) return null; // make sure a node isn't already adopted\n\n if (node.instance instanceof Base) return node.instance;\n\n if (node.nodeName === '#document-fragment') {\n return new elements.Fragment(node);\n } // initialize variables\n\n\n let className = capitalize(node.nodeName || 'Dom'); // Make sure that gradients are adopted correctly\n\n if (className === 'LinearGradient' || className === 'RadialGradient') {\n className = 'Gradient'; // Fallback to Dom if element is not known\n } else if (!elements[className]) {\n className = 'Dom';\n }\n\n return new elements[className](node);\n}\nlet adopter = adopt;\nfunction mockAdopt(mock = adopt) {\n adopter = mock;\n}\nfunction register(element, name = element.name, asRoot = false) {\n elements[name] = element;\n if (asRoot) elements[root] = element;\n addMethodNames(Object.getOwnPropertyNames(element.prototype));\n return element;\n}\nfunction getClass(name) {\n return elements[name];\n} // Element id sequence\n\nlet did = 1000; // Get next named element id\n\nfunction eid(name) {\n return 'Svgjs' + capitalize(name) + did++;\n} // Deep new id assignment\n\nfunction assignNewId(node) {\n // do the same for SVG child nodes as well\n for (let i = node.children.length - 1; i >= 0; i--) {\n assignNewId(node.children[i]);\n }\n\n if (node.id) {\n node.id = eid(node.nodeName);\n return node;\n }\n\n return node;\n} // Method for extending objects\n\nfunction extend(modules, methods) {\n let key, i;\n modules = Array.isArray(modules) ? modules : [modules];\n\n for (i = modules.length - 1; i >= 0; i--) {\n for (key in methods) {\n modules[i].prototype[key] = methods[key];\n }\n }\n}\nfunction wrapWithAttrCheck(fn) {\n return function (...args) {\n const o = args[args.length - 1];\n\n if (o && o.constructor === Object && !(o instanceof Array)) {\n return fn.apply(this, args.slice(0, -1)).attr(o);\n } else {\n return fn.apply(this, args);\n }\n };\n}\n\nfunction siblings() {\n return this.parent().children();\n} // Get the current position siblings\n\nfunction position() {\n return this.parent().index(this);\n} // Get the next element (will return null if there is none)\n\nfunction next() {\n return this.siblings()[this.position() + 1];\n} // Get the next element (will return null if there is none)\n\nfunction prev() {\n return this.siblings()[this.position() - 1];\n} // Send given element one step forward\n\nfunction forward() {\n const i = this.position();\n const p = this.parent(); // move node one step forward\n\n p.add(this.remove(), i + 1);\n return this;\n} // Send given element one step backward\n\nfunction backward() {\n const i = this.position();\n const p = this.parent();\n p.add(this.remove(), i ? i - 1 : 0);\n return this;\n} // Send given element all the way to the front\n\nfunction front() {\n const p = this.parent(); // Move node forward\n\n p.add(this.remove());\n return this;\n} // Send given element all the way to the back\n\nfunction back() {\n const p = this.parent(); // Move node back\n\n p.add(this.remove(), 0);\n return this;\n} // Inserts a given element before the targeted element\n\nfunction before(element) {\n element = makeInstance(element);\n element.remove();\n const i = this.position();\n this.parent().add(element, i);\n return this;\n} // Inserts a given element after the targeted element\n\nfunction after(element) {\n element = makeInstance(element);\n element.remove();\n const i = this.position();\n this.parent().add(element, i + 1);\n return this;\n}\nfunction insertBefore(element) {\n element = makeInstance(element);\n element.before(this);\n return this;\n}\nfunction insertAfter(element) {\n element = makeInstance(element);\n element.after(this);\n return this;\n}\nregisterMethods('Dom', {\n siblings,\n position,\n next,\n prev,\n forward,\n backward,\n front,\n back,\n before,\n after,\n insertBefore,\n insertAfter\n});\n\n// Parse unit value\nconst numberAndUnit = /^([+-]?(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?)([a-z%]*)$/i; // Parse hex value\n\nconst hex = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i; // Parse rgb value\n\nconst rgb = /rgb\\((\\d+),(\\d+),(\\d+)\\)/; // Parse reference id\n\nconst reference = /(#[a-z_][a-z0-9\\-_]*)/i; // splits a transformation chain\n\nconst transforms = /\\)\\s*,?\\s*/; // Whitespace\n\nconst whitespace = /\\s/g; // Test hex value\n\nconst isHex = /^#[a-f0-9]{3}$|^#[a-f0-9]{6}$/i; // Test rgb value\n\nconst isRgb = /^rgb\\(/; // Test for blank string\n\nconst isBlank = /^(\\s+)?$/; // Test for numeric string\n\nconst isNumber = /^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?$/i; // Test for image url\n\nconst isImage = /\\.(jpg|jpeg|png|gif|svg)(\\?[^=]+.*)?/i; // split at whitespace and comma\n\nconst delimiter = /[\\s,]+/; // Test for path letter\n\nconst isPathLetter = /[MLHVCSQTAZ]/i;\n\nvar regex = {\n __proto__: null,\n numberAndUnit: numberAndUnit,\n hex: hex,\n rgb: rgb,\n reference: reference,\n transforms: transforms,\n whitespace: whitespace,\n isHex: isHex,\n isRgb: isRgb,\n isBlank: isBlank,\n isNumber: isNumber,\n isImage: isImage,\n delimiter: delimiter,\n isPathLetter: isPathLetter\n};\n\nfunction classes() {\n const attr = this.attr('class');\n return attr == null ? [] : attr.trim().split(delimiter);\n} // Return true if class exists on the node, false otherwise\n\nfunction hasClass(name) {\n return this.classes().indexOf(name) !== -1;\n} // Add class to the node\n\nfunction addClass(name) {\n if (!this.hasClass(name)) {\n const array = this.classes();\n array.push(name);\n this.attr('class', array.join(' '));\n }\n\n return this;\n} // Remove class from the node\n\nfunction removeClass(name) {\n if (this.hasClass(name)) {\n this.attr('class', this.classes().filter(function (c) {\n return c !== name;\n }).join(' '));\n }\n\n return this;\n} // Toggle the presence of a class on the node\n\nfunction toggleClass(name) {\n return this.hasClass(name) ? this.removeClass(name) : this.addClass(name);\n}\nregisterMethods('Dom', {\n classes,\n hasClass,\n addClass,\n removeClass,\n toggleClass\n});\n\nfunction css(style, val) {\n const ret = {};\n\n if (arguments.length === 0) {\n // get full style as object\n this.node.style.cssText.split(/\\s*;\\s*/).filter(function (el) {\n return !!el.length;\n }).forEach(function (el) {\n const t = el.split(/\\s*:\\s*/);\n ret[t[0]] = t[1];\n });\n return ret;\n }\n\n if (arguments.length < 2) {\n // get style properties as array\n if (Array.isArray(style)) {\n for (const name of style) {\n const cased = camelCase(name);\n ret[name] = this.node.style[cased];\n }\n\n return ret;\n } // get style for property\n\n\n if (typeof style === 'string') {\n return this.node.style[camelCase(style)];\n } // set styles in object\n\n\n if (typeof style === 'object') {\n for (const name in style) {\n // set empty string if null/undefined/'' was given\n this.node.style[camelCase(name)] = style[name] == null || isBlank.test(style[name]) ? '' : style[name];\n }\n }\n } // set style for property\n\n\n if (arguments.length === 2) {\n this.node.style[camelCase(style)] = val == null || isBlank.test(val) ? '' : val;\n }\n\n return this;\n} // Show element\n\nfunction show() {\n return this.css('display', '');\n} // Hide element\n\nfunction hide() {\n return this.css('display', 'none');\n} // Is element visible?\n\nfunction visible() {\n return this.css('display') !== 'none';\n}\nregisterMethods('Dom', {\n css,\n show,\n hide,\n visible\n});\n\nfunction data(a, v, r) {\n if (a == null) {\n // get an object of attributes\n return this.data(map(filter(this.node.attributes, el => el.nodeName.indexOf('data-') === 0), el => el.nodeName.slice(5)));\n } else if (a instanceof Array) {\n const data = {};\n\n for (const key of a) {\n data[key] = this.data(key);\n }\n\n return data;\n } else if (typeof a === 'object') {\n for (v in a) {\n this.data(v, a[v]);\n }\n } else if (arguments.length < 2) {\n try {\n return JSON.parse(this.attr('data-' + a));\n } catch (e) {\n return this.attr('data-' + a);\n }\n } else {\n this.attr('data-' + a, v === null ? null : r === true || typeof v === 'string' || typeof v === 'number' ? v : JSON.stringify(v));\n }\n\n return this;\n}\nregisterMethods('Dom', {\n data\n});\n\nfunction remember(k, v) {\n // remember every item in an object individually\n if (typeof arguments[0] === 'object') {\n for (const key in k) {\n this.remember(key, k[key]);\n }\n } else if (arguments.length === 1) {\n // retrieve memory\n return this.memory()[k];\n } else {\n // store memory\n this.memory()[k] = v;\n }\n\n return this;\n} // Erase a given memory\n\nfunction forget() {\n if (arguments.length === 0) {\n this._memory = {};\n } else {\n for (let i = arguments.length - 1; i >= 0; i--) {\n delete this.memory()[arguments[i]];\n }\n }\n\n return this;\n} // This triggers creation of a new hidden class which is not performant\n// However, this function is not rarely used so it will not happen frequently\n// Return local memory object\n\nfunction memory() {\n return this._memory = this._memory || {};\n}\nregisterMethods('Dom', {\n remember,\n forget,\n memory\n});\n\nfunction sixDigitHex(hex) {\n return hex.length === 4 ? ['#', hex.substring(1, 2), hex.substring(1, 2), hex.substring(2, 3), hex.substring(2, 3), hex.substring(3, 4), hex.substring(3, 4)].join('') : hex;\n}\n\nfunction componentHex(component) {\n const integer = Math.round(component);\n const bounded = Math.max(0, Math.min(255, integer));\n const hex = bounded.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n}\n\nfunction is(object, space) {\n for (let i = space.length; i--;) {\n if (object[space[i]] == null) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction getParameters(a, b) {\n const params = is(a, 'rgb') ? {\n _a: a.r,\n _b: a.g,\n _c: a.b,\n _d: 0,\n space: 'rgb'\n } : is(a, 'xyz') ? {\n _a: a.x,\n _b: a.y,\n _c: a.z,\n _d: 0,\n space: 'xyz'\n } : is(a, 'hsl') ? {\n _a: a.h,\n _b: a.s,\n _c: a.l,\n _d: 0,\n space: 'hsl'\n } : is(a, 'lab') ? {\n _a: a.l,\n _b: a.a,\n _c: a.b,\n _d: 0,\n space: 'lab'\n } : is(a, 'lch') ? {\n _a: a.l,\n _b: a.c,\n _c: a.h,\n _d: 0,\n space: 'lch'\n } : is(a, 'cmyk') ? {\n _a: a.c,\n _b: a.m,\n _c: a.y,\n _d: a.k,\n space: 'cmyk'\n } : {\n _a: 0,\n _b: 0,\n _c: 0,\n space: 'rgb'\n };\n params.space = b || params.space;\n return params;\n}\n\nfunction cieSpace(space) {\n if (space === 'lab' || space === 'xyz' || space === 'lch') {\n return true;\n } else {\n return false;\n }\n}\n\nfunction hueToRgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n}\n\nclass Color {\n constructor(...inputs) {\n this.init(...inputs);\n } // Test if given value is a color\n\n\n static isColor(color) {\n return color && (color instanceof Color || this.isRgb(color) || this.test(color));\n } // Test if given value is an rgb object\n\n\n static isRgb(color) {\n return color && typeof color.r === 'number' && typeof color.g === 'number' && typeof color.b === 'number';\n }\n /*\n Generating random colors\n */\n\n\n static random(mode = 'vibrant', t, u) {\n // Get the math modules\n const {\n random,\n round,\n sin,\n PI: pi\n } = Math; // Run the correct generator\n\n if (mode === 'vibrant') {\n const l = (81 - 57) * random() + 57;\n const c = (83 - 45) * random() + 45;\n const h = 360 * random();\n const color = new Color(l, c, h, 'lch');\n return color;\n } else if (mode === 'sine') {\n t = t == null ? random() : t;\n const r = round(80 * sin(2 * pi * t / 0.5 + 0.01) + 150);\n const g = round(50 * sin(2 * pi * t / 0.5 + 4.6) + 200);\n const b = round(100 * sin(2 * pi * t / 0.5 + 2.3) + 150);\n const color = new Color(r, g, b);\n return color;\n } else if (mode === 'pastel') {\n const l = (94 - 86) * random() + 86;\n const c = (26 - 9) * random() + 9;\n const h = 360 * random();\n const color = new Color(l, c, h, 'lch');\n return color;\n } else if (mode === 'dark') {\n const l = 10 + 10 * random();\n const c = (125 - 75) * random() + 86;\n const h = 360 * random();\n const color = new Color(l, c, h, 'lch');\n return color;\n } else if (mode === 'rgb') {\n const r = 255 * random();\n const g = 255 * random();\n const b = 255 * random();\n const color = new Color(r, g, b);\n return color;\n } else if (mode === 'lab') {\n const l = 100 * random();\n const a = 256 * random() - 128;\n const b = 256 * random() - 128;\n const color = new Color(l, a, b, 'lab');\n return color;\n } else if (mode === 'grey') {\n const grey = 255 * random();\n const color = new Color(grey, grey, grey);\n return color;\n } else {\n throw new Error('Unsupported random color mode');\n }\n } // Test if given value is a color string\n\n\n static test(color) {\n return typeof color === 'string' && (isHex.test(color) || isRgb.test(color));\n }\n\n cmyk() {\n // Get the rgb values for the current color\n const {\n _a,\n _b,\n _c\n } = this.rgb();\n const [r, g, b] = [_a, _b, _c].map(v => v / 255); // Get the cmyk values in an unbounded format\n\n const k = Math.min(1 - r, 1 - g, 1 - b);\n\n if (k === 1) {\n // Catch the black case\n return new Color(0, 0, 0, 1, 'cmyk');\n }\n\n const c = (1 - r - k) / (1 - k);\n const m = (1 - g - k) / (1 - k);\n const y = (1 - b - k) / (1 - k); // Construct the new color\n\n const color = new Color(c, m, y, k, 'cmyk');\n return color;\n }\n\n hsl() {\n // Get the rgb values\n const {\n _a,\n _b,\n _c\n } = this.rgb();\n const [r, g, b] = [_a, _b, _c].map(v => v / 255); // Find the maximum and minimum values to get the lightness\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2; // If the r, g, v values are identical then we are grey\n\n const isGrey = max === min; // Calculate the hue and saturation\n\n const delta = max - min;\n const s = isGrey ? 0 : l > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n const h = isGrey ? 0 : max === r ? ((g - b) / delta + (g < b ? 6 : 0)) / 6 : max === g ? ((b - r) / delta + 2) / 6 : max === b ? ((r - g) / delta + 4) / 6 : 0; // Construct and return the new color\n\n const color = new Color(360 * h, 100 * s, 100 * l, 'hsl');\n return color;\n }\n\n init(a = 0, b = 0, c = 0, d = 0, space = 'rgb') {\n // This catches the case when a falsy value is passed like ''\n a = !a ? 0 : a; // Reset all values in case the init function is rerun with new color space\n\n if (this.space) {\n for (const component in this.space) {\n delete this[this.space[component]];\n }\n }\n\n if (typeof a === 'number') {\n // Allow for the case that we don't need d...\n space = typeof d === 'string' ? d : space;\n d = typeof d === 'string' ? 0 : d; // Assign the values straight to the color\n\n Object.assign(this, {\n _a: a,\n _b: b,\n _c: c,\n _d: d,\n space\n }); // If the user gave us an array, make the color from it\n } else if (a instanceof Array) {\n this.space = b || (typeof a[3] === 'string' ? a[3] : a[4]) || 'rgb';\n Object.assign(this, {\n _a: a[0],\n _b: a[1],\n _c: a[2],\n _d: a[3] || 0\n });\n } else if (a instanceof Object) {\n // Set the object up and assign its values directly\n const values = getParameters(a, b);\n Object.assign(this, values);\n } else if (typeof a === 'string') {\n if (isRgb.test(a)) {\n const noWhitespace = a.replace(whitespace, '');\n const [_a, _b, _c] = rgb.exec(noWhitespace).slice(1, 4).map(v => parseInt(v));\n Object.assign(this, {\n _a,\n _b,\n _c,\n _d: 0,\n space: 'rgb'\n });\n } else if (isHex.test(a)) {\n const hexParse = v => parseInt(v, 16);\n\n const [, _a, _b, _c] = hex.exec(sixDigitHex(a)).map(hexParse);\n Object.assign(this, {\n _a,\n _b,\n _c,\n _d: 0,\n space: 'rgb'\n });\n } else throw Error('Unsupported string format, can\\'t construct Color');\n } // Now add the components as a convenience\n\n\n const {\n _a,\n _b,\n _c,\n _d\n } = this;\n const components = this.space === 'rgb' ? {\n r: _a,\n g: _b,\n b: _c\n } : this.space === 'xyz' ? {\n x: _a,\n y: _b,\n z: _c\n } : this.space === 'hsl' ? {\n h: _a,\n s: _b,\n l: _c\n } : this.space === 'lab' ? {\n l: _a,\n a: _b,\n b: _c\n } : this.space === 'lch' ? {\n l: _a,\n c: _b,\n h: _c\n } : this.space === 'cmyk' ? {\n c: _a,\n m: _b,\n y: _c,\n k: _d\n } : {};\n Object.assign(this, components);\n }\n\n lab() {\n // Get the xyz color\n const {\n x,\n y,\n z\n } = this.xyz(); // Get the lab components\n\n const l = 116 * y - 16;\n const a = 500 * (x - y);\n const b = 200 * (y - z); // Construct and return a new color\n\n const color = new Color(l, a, b, 'lab');\n return color;\n }\n\n lch() {\n // Get the lab color directly\n const {\n l,\n a,\n b\n } = this.lab(); // Get the chromaticity and the hue using polar coordinates\n\n const c = Math.sqrt(a ** 2 + b ** 2);\n let h = 180 * Math.atan2(b, a) / Math.PI;\n\n if (h < 0) {\n h *= -1;\n h = 360 - h;\n } // Make a new color and return it\n\n\n const color = new Color(l, c, h, 'lch');\n return color;\n }\n /*\n Conversion Methods\n */\n\n\n rgb() {\n if (this.space === 'rgb') {\n return this;\n } else if (cieSpace(this.space)) {\n // Convert to the xyz color space\n let {\n x,\n y,\n z\n } = this;\n\n if (this.space === 'lab' || this.space === 'lch') {\n // Get the values in the lab space\n let {\n l,\n a,\n b\n } = this;\n\n if (this.space === 'lch') {\n const {\n c,\n h\n } = this;\n const dToR = Math.PI / 180;\n a = c * Math.cos(dToR * h);\n b = c * Math.sin(dToR * h);\n } // Undo the nonlinear function\n\n\n const yL = (l + 16) / 116;\n const xL = a / 500 + yL;\n const zL = yL - b / 200; // Get the xyz values\n\n const ct = 16 / 116;\n const mx = 0.008856;\n const nm = 7.787;\n x = 0.95047 * (xL ** 3 > mx ? xL ** 3 : (xL - ct) / nm);\n y = 1.00000 * (yL ** 3 > mx ? yL ** 3 : (yL - ct) / nm);\n z = 1.08883 * (zL ** 3 > mx ? zL ** 3 : (zL - ct) / nm);\n } // Convert xyz to unbounded rgb values\n\n\n const rU = x * 3.2406 + y * -1.5372 + z * -0.4986;\n const gU = x * -0.9689 + y * 1.8758 + z * 0.0415;\n const bU = x * 0.0557 + y * -0.2040 + z * 1.0570; // Convert the values to true rgb values\n\n const pow = Math.pow;\n const bd = 0.0031308;\n const r = rU > bd ? 1.055 * pow(rU, 1 / 2.4) - 0.055 : 12.92 * rU;\n const g = gU > bd ? 1.055 * pow(gU, 1 / 2.4) - 0.055 : 12.92 * gU;\n const b = bU > bd ? 1.055 * pow(bU, 1 / 2.4) - 0.055 : 12.92 * bU; // Make and return the color\n\n const color = new Color(255 * r, 255 * g, 255 * b);\n return color;\n } else if (this.space === 'hsl') {\n // https://bgrins.github.io/TinyColor/docs/tinycolor.html\n // Get the current hsl values\n let {\n h,\n s,\n l\n } = this;\n h /= 360;\n s /= 100;\n l /= 100; // If we are grey, then just make the color directly\n\n if (s === 0) {\n l *= 255;\n const color = new Color(l, l, l);\n return color;\n } // TODO I have no idea what this does :D If you figure it out, tell me!\n\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q; // Get the rgb values\n\n const r = 255 * hueToRgb(p, q, h + 1 / 3);\n const g = 255 * hueToRgb(p, q, h);\n const b = 255 * hueToRgb(p, q, h - 1 / 3); // Make a new color\n\n const color = new Color(r, g, b);\n return color;\n } else if (this.space === 'cmyk') {\n // https://gist.github.com/felipesabino/5066336\n // Get the normalised cmyk values\n const {\n c,\n m,\n y,\n k\n } = this; // Get the rgb values\n\n const r = 255 * (1 - Math.min(1, c * (1 - k) + k));\n const g = 255 * (1 - Math.min(1, m * (1 - k) + k));\n const b = 255 * (1 - Math.min(1, y * (1 - k) + k)); // Form the color and return it\n\n const color = new Color(r, g, b);\n return color;\n } else {\n return this;\n }\n }\n\n toArray() {\n const {\n _a,\n _b,\n _c,\n _d,\n space\n } = this;\n return [_a, _b, _c, _d, space];\n }\n\n toHex() {\n const [r, g, b] = this._clamped().map(componentHex);\n\n return `#${r}${g}${b}`;\n }\n\n toRgb() {\n const [rV, gV, bV] = this._clamped();\n\n const string = `rgb(${rV},${gV},${bV})`;\n return string;\n }\n\n toString() {\n return this.toHex();\n }\n\n xyz() {\n // Normalise the red, green and blue values\n const {\n _a: r255,\n _b: g255,\n _c: b255\n } = this.rgb();\n const [r, g, b] = [r255, g255, b255].map(v => v / 255); // Convert to the lab rgb space\n\n const rL = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;\n const gL = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;\n const bL = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92; // Convert to the xyz color space without bounding the values\n\n const xU = (rL * 0.4124 + gL * 0.3576 + bL * 0.1805) / 0.95047;\n const yU = (rL * 0.2126 + gL * 0.7152 + bL * 0.0722) / 1.00000;\n const zU = (rL * 0.0193 + gL * 0.1192 + bL * 0.9505) / 1.08883; // Get the proper xyz values by applying the bounding\n\n const x = xU > 0.008856 ? Math.pow(xU, 1 / 3) : 7.787 * xU + 16 / 116;\n const y = yU > 0.008856 ? Math.pow(yU, 1 / 3) : 7.787 * yU + 16 / 116;\n const z = zU > 0.008856 ? Math.pow(zU, 1 / 3) : 7.787 * zU + 16 / 116; // Make and return the color\n\n const color = new Color(x, y, z, 'xyz');\n return color;\n }\n /*\n Input and Output methods\n */\n\n\n _clamped() {\n const {\n _a,\n _b,\n _c\n } = this.rgb();\n const {\n max,\n min,\n round\n } = Math;\n\n const format = v => max(0, min(round(v), 255));\n\n return [_a, _b, _c].map(format);\n }\n /*\n Constructing colors\n */\n\n\n}\n\nclass Point {\n // Initialize\n constructor(...args) {\n this.init(...args);\n } // Clone point\n\n\n clone() {\n return new Point(this);\n }\n\n init(x, y) {\n const base = {\n x: 0,\n y: 0\n }; // ensure source as object\n\n const source = Array.isArray(x) ? {\n x: x[0],\n y: x[1]\n } : typeof x === 'object' ? {\n x: x.x,\n y: x.y\n } : {\n x: x,\n y: y\n }; // merge source\n\n this.x = source.x == null ? base.x : source.x;\n this.y = source.y == null ? base.y : source.y;\n return this;\n }\n\n toArray() {\n return [this.x, this.y];\n }\n\n transform(m) {\n return this.clone().transformO(m);\n } // Transform point with matrix\n\n\n transformO(m) {\n if (!Matrix.isMatrixLike(m)) {\n m = new Matrix(m);\n }\n\n const {\n x,\n y\n } = this; // Perform the matrix multiplication\n\n this.x = m.a * x + m.c * y + m.e;\n this.y = m.b * x + m.d * y + m.f;\n return this;\n }\n\n}\nfunction point(x, y) {\n return new Point(x, y).transformO(this.screenCTM().inverseO());\n}\n\nfunction closeEnough(a, b, threshold) {\n return Math.abs(b - a) < (threshold || 1e-6);\n}\n\nclass Matrix {\n constructor(...args) {\n this.init(...args);\n }\n\n static formatTransforms(o) {\n // Get all of the parameters required to form the matrix\n const flipBoth = o.flip === 'both' || o.flip === true;\n const flipX = o.flip && (flipBoth || o.flip === 'x') ? -1 : 1;\n const flipY = o.flip && (flipBoth || o.flip === 'y') ? -1 : 1;\n const skewX = o.skew && o.skew.length ? o.skew[0] : isFinite(o.skew) ? o.skew : isFinite(o.skewX) ? o.skewX : 0;\n const skewY = o.skew && o.skew.length ? o.skew[1] : isFinite(o.skew) ? o.skew : isFinite(o.skewY) ? o.skewY : 0;\n const scaleX = o.scale && o.scale.length ? o.scale[0] * flipX : isFinite(o.scale) ? o.scale * flipX : isFinite(o.scaleX) ? o.scaleX * flipX : flipX;\n const scaleY = o.scale && o.scale.length ? o.scale[1] * flipY : isFinite(o.scale) ? o.scale * flipY : isFinite(o.scaleY) ? o.scaleY * flipY : flipY;\n const shear = o.shear || 0;\n const theta = o.rotate || o.theta || 0;\n const origin = new Point(o.origin || o.around || o.ox || o.originX, o.oy || o.originY);\n const ox = origin.x;\n const oy = origin.y; // We need Point to be invalid if nothing was passed because we cannot default to 0 here. That is why NaN\n\n const position = new Point(o.position || o.px || o.positionX || NaN, o.py || o.positionY || NaN);\n const px = position.x;\n const py = position.y;\n const translate = new Point(o.translate || o.tx || o.translateX, o.ty || o.translateY);\n const tx = translate.x;\n const ty = translate.y;\n const relative = new Point(o.relative || o.rx || o.relativeX, o.ry || o.relativeY);\n const rx = relative.x;\n const ry = relative.y; // Populate all of the values\n\n return {\n scaleX,\n scaleY,\n skewX,\n skewY,\n shear,\n theta,\n rx,\n ry,\n tx,\n ty,\n ox,\n oy,\n px,\n py\n };\n }\n\n static fromArray(a) {\n return {\n a: a[0],\n b: a[1],\n c: a[2],\n d: a[3],\n e: a[4],\n f: a[5]\n };\n }\n\n static isMatrixLike(o) {\n return o.a != null || o.b != null || o.c != null || o.d != null || o.e != null || o.f != null;\n } // left matrix, right matrix, target matrix which is overwritten\n\n\n static matrixMultiply(l, r, o) {\n // Work out the product directly\n const a = l.a * r.a + l.c * r.b;\n const b = l.b * r.a + l.d * r.b;\n const c = l.a * r.c + l.c * r.d;\n const d = l.b * r.c + l.d * r.d;\n const e = l.e + l.a * r.e + l.c * r.f;\n const f = l.f + l.b * r.e + l.d * r.f; // make sure to use local variables because l/r and o could be the same\n\n o.a = a;\n o.b = b;\n o.c = c;\n o.d = d;\n o.e = e;\n o.f = f;\n return o;\n }\n\n around(cx, cy, matrix) {\n return this.clone().aroundO(cx, cy, matrix);\n } // Transform around a center point\n\n\n aroundO(cx, cy, matrix) {\n const dx = cx || 0;\n const dy = cy || 0;\n return this.translateO(-dx, -dy).lmultiplyO(matrix).translateO(dx, dy);\n } // Clones this matrix\n\n\n clone() {\n return new Matrix(this);\n } // Decomposes this matrix into its affine parameters\n\n\n decompose(cx = 0, cy = 0) {\n // Get the parameters from the matrix\n const a = this.a;\n const b = this.b;\n const c = this.c;\n const d = this.d;\n const e = this.e;\n const f = this.f; // Figure out if the winding direction is clockwise or counterclockwise\n\n const determinant = a * d - b * c;\n const ccw = determinant > 0 ? 1 : -1; // Since we only shear in x, we can use the x basis to get the x scale\n // and the rotation of the resulting matrix\n\n const sx = ccw * Math.sqrt(a * a + b * b);\n const thetaRad = Math.atan2(ccw * b, ccw * a);\n const theta = 180 / Math.PI * thetaRad;\n const ct = Math.cos(thetaRad);\n const st = Math.sin(thetaRad); // We can then solve the y basis vector simultaneously to get the other\n // two affine parameters directly from these parameters\n\n const lam = (a * c + b * d) / determinant;\n const sy = c * sx / (lam * a - b) || d * sx / (lam * b + a); // Use the translations\n\n const tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy);\n const ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy); // Construct the decomposition and return it\n\n return {\n // Return the affine parameters\n scaleX: sx,\n scaleY: sy,\n shear: lam,\n rotate: theta,\n translateX: tx,\n translateY: ty,\n originX: cx,\n originY: cy,\n // Return the matrix parameters\n a: this.a,\n b: this.b,\n c: this.c,\n d: this.d,\n e: this.e,\n f: this.f\n };\n } // Check if two matrices are equal\n\n\n equals(other) {\n if (other === this) return true;\n const comp = new Matrix(other);\n return closeEnough(this.a, comp.a) && closeEnough(this.b, comp.b) && closeEnough(this.c, comp.c) && closeEnough(this.d, comp.d) && closeEnough(this.e, comp.e) && closeEnough(this.f, comp.f);\n } // Flip matrix on x or y, at a given offset\n\n\n flip(axis, around) {\n return this.clone().flipO(axis, around);\n }\n\n flipO(axis, around) {\n return axis === 'x' ? this.scaleO(-1, 1, around, 0) : axis === 'y' ? this.scaleO(1, -1, 0, around) : this.scaleO(-1, -1, axis, around || axis); // Define an x, y flip point\n } // Initialize\n\n\n init(source) {\n const base = Matrix.fromArray([1, 0, 0, 1, 0, 0]); // ensure source as object\n\n source = source instanceof Element ? source.matrixify() : typeof source === 'string' ? Matrix.fromArray(source.split(delimiter).map(parseFloat)) : Array.isArray(source) ? Matrix.fromArray(source) : typeof source === 'object' && Matrix.isMatrixLike(source) ? source : typeof source === 'object' ? new Matrix().transform(source) : arguments.length === 6 ? Matrix.fromArray([].slice.call(arguments)) : base; // Merge the source matrix with the base matrix\n\n this.a = source.a != null ? source.a : base.a;\n this.b = source.b != null ? source.b : base.b;\n this.c = source.c != null ? source.c : base.c;\n this.d = source.d != null ? source.d : base.d;\n this.e = source.e != null ? source.e : base.e;\n this.f = source.f != null ? source.f : base.f;\n return this;\n }\n\n inverse() {\n return this.clone().inverseO();\n } // Inverses matrix\n\n\n inverseO() {\n // Get the current parameters out of the matrix\n const a = this.a;\n const b = this.b;\n const c = this.c;\n const d = this.d;\n const e = this.e;\n const f = this.f; // Invert the 2x2 matrix in the top left\n\n const det = a * d - b * c;\n if (!det) throw new Error('Cannot invert ' + this); // Calculate the top 2x2 matrix\n\n const na = d / det;\n const nb = -b / det;\n const nc = -c / det;\n const nd = a / det; // Apply the inverted matrix to the top right\n\n const ne = -(na * e + nc * f);\n const nf = -(nb * e + nd * f); // Construct the inverted matrix\n\n this.a = na;\n this.b = nb;\n this.c = nc;\n this.d = nd;\n this.e = ne;\n this.f = nf;\n return this;\n }\n\n lmultiply(matrix) {\n return this.clone().lmultiplyO(matrix);\n }\n\n lmultiplyO(matrix) {\n const r = this;\n const l = matrix instanceof Matrix ? matrix : new Matrix(matrix);\n return Matrix.matrixMultiply(l, r, this);\n } // Left multiplies by the given matrix\n\n\n multiply(matrix) {\n return this.clone().multiplyO(matrix);\n }\n\n multiplyO(matrix) {\n // Get the matrices\n const l = this;\n const r = matrix instanceof Matrix ? matrix : new Matrix(matrix);\n return Matrix.matrixMultiply(l, r, this);\n } // Rotate matrix\n\n\n rotate(r, cx, cy) {\n return this.clone().rotateO(r, cx, cy);\n }\n\n rotateO(r, cx = 0, cy = 0) {\n // Convert degrees to radians\n r = radians(r);\n const cos = Math.cos(r);\n const sin = Math.sin(r);\n const {\n a,\n b,\n c,\n d,\n e,\n f\n } = this;\n this.a = a * cos - b * sin;\n this.b = b * cos + a * sin;\n this.c = c * cos - d * sin;\n this.d = d * cos + c * sin;\n this.e = e * cos - f * sin + cy * sin - cx * cos + cx;\n this.f = f * cos + e * sin - cx * sin - cy * cos + cy;\n return this;\n } // Scale matrix\n\n\n scale(x, y, cx, cy) {\n return this.clone().scaleO(...arguments);\n }\n\n scaleO(x, y = x, cx = 0, cy = 0) {\n // Support uniform scaling\n if (arguments.length === 3) {\n cy = cx;\n cx = y;\n y = x;\n }\n\n const {\n a,\n b,\n c,\n d,\n e,\n f\n } = this;\n this.a = a * x;\n this.b = b * y;\n this.c = c * x;\n this.d = d * y;\n this.e = e * x - cx * x + cx;\n this.f = f * y - cy * y + cy;\n return this;\n } // Shear matrix\n\n\n shear(a, cx, cy) {\n return this.clone().shearO(a, cx, cy);\n }\n\n shearO(lx, cx = 0, cy = 0) {\n const {\n a,\n b,\n c,\n d,\n e,\n f\n } = this;\n this.a = a + b * lx;\n this.c = c + d * lx;\n this.e = e + f * lx - cy * lx;\n return this;\n } // Skew Matrix\n\n\n skew(x, y, cx, cy) {\n return this.clone().skewO(...arguments);\n }\n\n skewO(x, y = x, cx = 0, cy = 0) {\n // support uniformal skew\n if (arguments.length === 3) {\n cy = cx;\n cx = y;\n y = x;\n } // Convert degrees to radians\n\n\n x = radians(x);\n y = radians(y);\n const lx = Math.tan(x);\n const ly = Math.tan(y);\n const {\n a,\n b,\n c,\n d,\n e,\n f\n } = this;\n this.a = a + b * lx;\n this.b = b + a * ly;\n this.c = c + d * lx;\n this.d = d + c * ly;\n this.e = e + f * lx - cy * lx;\n this.f = f + e * ly - cx * ly;\n return this;\n } // SkewX\n\n\n skewX(x, cx, cy) {\n return this.skew(x, 0, cx, cy);\n } // SkewY\n\n\n skewY(y, cx, cy) {\n return this.skew(0, y, cx, cy);\n }\n\n toArray() {\n return [this.a, this.b, this.c, this.d, this.e, this.f];\n } // Convert matrix to string\n\n\n toString() {\n return 'matrix(' + this.a + ',' + this.b + ',' + this.c + ',' + this.d + ',' + this.e + ',' + this.f + ')';\n } // Transform a matrix into another matrix by manipulating the space\n\n\n transform(o) {\n // Check if o is a matrix and then left multiply it directly\n if (Matrix.isMatrixLike(o)) {\n const matrix = new Matrix(o);\n return matrix.multiplyO(this);\n } // Get the proposed transformations and the current transformations\n\n\n const t = Matrix.formatTransforms(o);\n const current = this;\n const {\n x: ox,\n y: oy\n } = new Point(t.ox, t.oy).transform(current); // Construct the resulting matrix\n\n const transformer = new Matrix().translateO(t.rx, t.ry).lmultiplyO(current).translateO(-ox, -oy).scaleO(t.scaleX, t.scaleY).skewO(t.skewX, t.skewY).shearO(t.shear).rotateO(t.theta).translateO(ox, oy); // If we want the origin at a particular place, we force it there\n\n if (isFinite(t.px) || isFinite(t.py)) {\n const origin = new Point(ox, oy).transform(transformer); // TODO: Replace t.px with isFinite(t.px)\n // Doesn't work because t.px is also 0 if it wasn't passed\n\n const dx = isFinite(t.px) ? t.px - origin.x : 0;\n const dy = isFinite(t.py) ? t.py - origin.y : 0;\n transformer.translateO(dx, dy);\n } // Translate now after positioning\n\n\n transformer.translateO(t.tx, t.ty);\n return transformer;\n } // Translate matrix\n\n\n translate(x, y) {\n return this.clone().translateO(x, y);\n }\n\n translateO(x, y) {\n this.e += x || 0;\n this.f += y || 0;\n return this;\n }\n\n valueOf() {\n return {\n a: this.a,\n b: this.b,\n c: this.c,\n d: this.d,\n e: this.e,\n f: this.f\n };\n }\n\n}\nfunction ctm() {\n return new Matrix(this.node.getCTM());\n}\nfunction screenCTM() {\n /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537\n This is needed because FF does not return the transformation matrix\n for the inner coordinate system when getScreenCTM() is called on nested svgs.\n However all other Browsers do that */\n if (typeof this.isRoot === 'function' && !this.isRoot()) {\n const rect = this.rect(1, 1);\n const m = rect.node.getScreenCTM();\n rect.remove();\n return new Matrix(m);\n }\n\n return new Matrix(this.node.getScreenCTM());\n}\nregister(Matrix, 'Matrix');\n\nfunction parser() {\n // Reuse cached element if possible\n if (!parser.nodes) {\n const svg = makeInstance().size(2, 0);\n svg.node.style.cssText = ['opacity: 0', 'position: absolute', 'left: -100%', 'top: -100%', 'overflow: hidden'].join(';');\n svg.attr('focusable', 'false');\n svg.attr('aria-hidden', 'true');\n const path = svg.path().node;\n parser.nodes = {\n svg,\n path\n };\n }\n\n if (!parser.nodes.svg.node.parentNode) {\n const b = globals.document.body || globals.document.documentElement;\n parser.nodes.svg.addTo(b);\n }\n\n return parser.nodes;\n}\n\nfunction isNulledBox(box) {\n return !box.width && !box.height && !box.x && !box.y;\n}\nfunction domContains(node) {\n return node === globals.document || (globals.document.documentElement.contains || function (node) {\n // This is IE - it does not support contains() for top-level SVGs\n while (node.parentNode) {\n node = node.parentNode;\n }\n\n return node === globals.document;\n }).call(globals.document.documentElement, node);\n}\nclass Box {\n constructor(...args) {\n this.init(...args);\n }\n\n addOffset() {\n // offset by window scroll position, because getBoundingClientRect changes when window is scrolled\n this.x += globals.window.pageXOffset;\n this.y += globals.window.pageYOffset;\n return new Box(this);\n }\n\n init(source) {\n const base = [0, 0, 0, 0];\n source = typeof source === 'string' ? source.split(delimiter).map(parseFloat) : Array.isArray(source) ? source : typeof source === 'object' ? [source.left != null ? source.left : source.x, source.top != null ? source.top : source.y, source.width, source.height] : arguments.length === 4 ? [].slice.call(arguments) : base;\n this.x = source[0] || 0;\n this.y = source[1] || 0;\n this.width = this.w = source[2] || 0;\n this.height = this.h = source[3] || 0; // Add more bounding box properties\n\n this.x2 = this.x + this.w;\n this.y2 = this.y + this.h;\n this.cx = this.x + this.w / 2;\n this.cy = this.y + this.h / 2;\n return this;\n }\n\n isNulled() {\n return isNulledBox(this);\n } // Merge rect box with another, return a new instance\n\n\n merge(box) {\n const x = Math.min(this.x, box.x);\n const y = Math.min(this.y, box.y);\n const width = Math.max(this.x + this.width, box.x + box.width) - x;\n const height = Math.max(this.y + this.height, box.y + box.height) - y;\n return new Box(x, y, width, height);\n }\n\n toArray() {\n return [this.x, this.y, this.width, this.height];\n }\n\n toString() {\n return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height;\n }\n\n transform(m) {\n if (!(m instanceof Matrix)) {\n m = new Matrix(m);\n }\n\n let xMin = Infinity;\n let xMax = -Infinity;\n let yMin = Infinity;\n let yMax = -Infinity;\n const pts = [new Point(this.x, this.y), new Point(this.x2, this.y), new Point(this.x, this.y2), new Point(this.x2, this.y2)];\n pts.forEach(function (p) {\n p = p.transform(m);\n xMin = Math.min(xMin, p.x);\n xMax = Math.max(xMax, p.x);\n yMin = Math.min(yMin, p.y);\n yMax = Math.max(yMax, p.y);\n });\n return new Box(xMin, yMin, xMax - xMin, yMax - yMin);\n }\n\n}\n\nfunction getBox(el, getBBoxFn, retry) {\n let box;\n\n try {\n // Try to get the box with the provided function\n box = getBBoxFn(el.node); // If the box is worthless and not even in the dom, retry\n // by throwing an error here...\n\n if (isNulledBox(box) && !domContains(el.node)) {\n throw new Error('Element not in the dom');\n }\n } catch (e) {\n // ... and calling the retry handler here\n box = retry(el);\n }\n\n return box;\n}\n\nfunction bbox() {\n // Function to get bbox is getBBox()\n const getBBox = node => node.getBBox(); // Take all measures so that a stupid browser renders the element\n // so we can get the bbox from it when we try again\n\n\n const retry = el => {\n try {\n const clone = el.clone().addTo(parser().svg).show();\n const box = clone.node.getBBox();\n clone.remove();\n return box;\n } catch (e) {\n // We give up...\n throw new Error(`Getting bbox of element \"${el.node.nodeName}\" is not possible: ${e.toString()}`);\n }\n };\n\n const box = getBox(this, getBBox, retry);\n const bbox = new Box(box);\n return bbox;\n}\nfunction rbox(el) {\n const getRBox = node => node.getBoundingClientRect();\n\n const retry = el => {\n // There is no point in trying tricks here because if we insert the element into the dom ourselves\n // it obviously will be at the wrong position\n throw new Error(`Getting rbox of element \"${el.node.nodeName}\" is not possible`);\n };\n\n const box = getBox(this, getRBox, retry);\n const rbox = new Box(box); // If an element was passed, we want the bbox in the coordinate system of that element\n\n if (el) {\n return rbox.transform(el.screenCTM().inverseO());\n } // Else we want it in absolute screen coordinates\n // Therefore we need to add the scrollOffset\n\n\n return rbox.addOffset();\n} // Checks whether the given point is inside the bounding box\n\nfunction inside(x, y) {\n const box = this.bbox();\n return x > box.x && y > box.y && x < box.x + box.width && y < box.y + box.height;\n}\nregisterMethods({\n viewbox: {\n viewbox(x, y, width, height) {\n // act as getter\n if (x == null) return new Box(this.attr('viewBox')); // act as setter\n\n return this.attr('viewBox', new Box(x, y, width, height));\n },\n\n zoom(level, point) {\n // Its best to rely on the attributes here and here is why:\n // clientXYZ: Doesn't work on non-root svgs because they dont have a CSSBox (silly!)\n // getBoundingClientRect: Doesn't work because Chrome just ignores width and height of nested svgs completely\n // that means, their clientRect is always as big as the content.\n // Furthermore this size is incorrect if the element is further transformed by its parents\n // computedStyle: Only returns meaningful values if css was used with px. We dont go this route here!\n // getBBox: returns the bounding box of its content - that doesn't help!\n let {\n width,\n height\n } = this.attr(['width', 'height']); // Width and height is a string when a number with a unit is present which we can't use\n // So we try clientXYZ\n\n if (!width && !height || typeof width === 'string' || typeof height === 'string') {\n width = this.node.clientWidth;\n height = this.node.clientHeight;\n } // Giving up...\n\n\n if (!width || !height) {\n throw new Error('Impossible to get absolute width and height. Please provide an absolute width and height attribute on the zooming element');\n }\n\n const v = this.viewbox();\n const zoomX = width / v.width;\n const zoomY = height / v.height;\n const zoom = Math.min(zoomX, zoomY);\n\n if (level == null) {\n return zoom;\n }\n\n let zoomAmount = zoom / level; // Set the zoomAmount to the highest value which is safe to process and recover from\n // The * 100 is a bit of wiggle room for the matrix transformation\n\n if (zoomAmount === Infinity) zoomAmount = Number.MAX_SAFE_INTEGER / 100;\n point = point || new Point(width / 2 / zoomX + v.x, height / 2 / zoomY + v.y);\n const box = new Box(v).transform(new Matrix({\n scale: zoomAmount,\n origin: point\n }));\n return this.viewbox(box);\n }\n\n }\n});\nregister(Box, 'Box');\n\nclass List extends Array {\n constructor(arr = [], ...args) {\n super(arr, ...args);\n if (typeof arr === 'number') return this;\n this.length = 0;\n this.push(...arr);\n }\n\n}\nextend([List], {\n each(fnOrMethodName, ...args) {\n if (typeof fnOrMethodName === 'function') {\n return this.map((el, i, arr) => {\n return fnOrMethodName.call(el, el, i, arr);\n });\n } else {\n return this.map(el => {\n return el[fnOrMethodName](...args);\n });\n }\n },\n\n toArray() {\n return Array.prototype.concat.apply([], this);\n }\n\n});\nconst reserved = ['toArray', 'constructor', 'each'];\n\nList.extend = function (methods) {\n methods = methods.reduce((obj, name) => {\n // Don't overwrite own methods\n if (reserved.includes(name)) return obj; // Don't add private methods\n\n if (name[0] === '_') return obj; // Relay every call to each()\n\n obj[name] = function (...attrs) {\n return this.each(name, ...attrs);\n };\n\n return obj;\n }, {});\n extend([List], methods);\n};\n\nfunction baseFind(query, parent) {\n return new List(map((parent || globals.document).querySelectorAll(query), function (node) {\n return adopt(node);\n }));\n} // Scoped find method\n\nfunction find(query) {\n return baseFind(query, this.node);\n}\nfunction findOne(query) {\n return adopt(this.node.querySelector(query));\n}\n\nlet listenerId = 0;\nconst windowEvents = {};\nfunction getEvents(instance) {\n let n = instance.getEventHolder(); // We dont want to save events in global space\n\n if (n === globals.window) n = windowEvents;\n if (!n.events) n.events = {};\n return n.events;\n}\nfunction getEventTarget(instance) {\n return instance.getEventTarget();\n}\nfunction clearEvents(instance) {\n let n = instance.getEventHolder();\n if (n === globals.window) n = windowEvents;\n if (n.events) n.events = {};\n} // Add event binder in the SVG namespace\n\nfunction on(node, events, listener, binding, options) {\n const l = listener.bind(binding || node);\n const instance = makeInstance(node);\n const bag = getEvents(instance);\n const n = getEventTarget(instance); // events can be an array of events or a string of events\n\n events = Array.isArray(events) ? events : events.split(delimiter); // add id to listener\n\n if (!listener._svgjsListenerId) {\n listener._svgjsListenerId = ++listenerId;\n }\n\n events.forEach(function (event) {\n const ev = event.split('.')[0];\n const ns = event.split('.')[1] || '*'; // ensure valid object\n\n bag[ev] = bag[ev] || {};\n bag[ev][ns] = bag[ev][ns] || {}; // reference listener\n\n bag[ev][ns][listener._svgjsListenerId] = l; // add listener\n\n n.addEventListener(ev, l, options || false);\n });\n} // Add event unbinder in the SVG namespace\n\nfunction off(node, events, listener, options) {\n const instance = makeInstance(node);\n const bag = getEvents(instance);\n const n = getEventTarget(instance); // listener can be a function or a number\n\n if (typeof listener === 'function') {\n listener = listener._svgjsListenerId;\n if (!listener) return;\n } // events can be an array of events or a string or undefined\n\n\n events = Array.isArray(events) ? events : (events || '').split(delimiter);\n events.forEach(function (event) {\n const ev = event && event.split('.')[0];\n const ns = event && event.split('.')[1];\n let namespace, l;\n\n if (listener) {\n // remove listener reference\n if (bag[ev] && bag[ev][ns || '*']) {\n // removeListener\n n.removeEventListener(ev, bag[ev][ns || '*'][listener], options || false);\n delete bag[ev][ns || '*'][listener];\n }\n } else if (ev && ns) {\n // remove all listeners for a namespaced event\n if (bag[ev] && bag[ev][ns]) {\n for (l in bag[ev][ns]) {\n off(n, [ev, ns].join('.'), l);\n }\n\n delete bag[ev][ns];\n }\n } else if (ns) {\n // remove all listeners for a specific namespace\n for (event in bag) {\n for (namespace in bag[event]) {\n if (ns === namespace) {\n off(n, [event, ns].join('.'));\n }\n }\n }\n } else if (ev) {\n // remove all listeners for the event\n if (bag[ev]) {\n for (namespace in bag[ev]) {\n off(n, [ev, namespace].join('.'));\n }\n\n delete bag[ev];\n }\n } else {\n // remove all listeners on a given node\n for (event in bag) {\n off(n, event);\n }\n\n clearEvents(instance);\n }\n });\n}\nfunction dispatch(node, event, data, options) {\n const n = getEventTarget(node); // Dispatch event\n\n if (event instanceof globals.window.Event) {\n n.dispatchEvent(event);\n } else {\n event = new globals.window.CustomEvent(event, {\n detail: data,\n cancelable: true,\n ...options\n });\n n.dispatchEvent(event);\n }\n\n return event;\n}\n\nclass EventTarget extends Base {\n addEventListener() {}\n\n dispatch(event, data, options) {\n return dispatch(this, event, data, options);\n }\n\n dispatchEvent(event) {\n const bag = this.getEventHolder().events;\n if (!bag) return true;\n const events = bag[event.type];\n\n for (const i in events) {\n for (const j in events[i]) {\n events[i][j](event);\n }\n }\n\n return !event.defaultPrevented;\n } // Fire given event\n\n\n fire(event, data, options) {\n this.dispatch(event, data, options);\n return this;\n }\n\n getEventHolder() {\n return this;\n }\n\n getEventTarget() {\n return this;\n } // Unbind event from listener\n\n\n off(event, listener, options) {\n off(this, event, listener, options);\n return this;\n } // Bind given event to listener\n\n\n on(event, listener, binding, options) {\n on(this, event, listener, binding, options);\n return this;\n }\n\n removeEventListener() {}\n\n}\nregister(EventTarget, 'EventTarget');\n\nfunction noop() {} // Default animation values\n\nconst timeline = {\n duration: 400,\n ease: '>',\n delay: 0\n}; // Default attribute values\n\nconst attrs = {\n // fill and stroke\n 'fill-opacity': 1,\n 'stroke-opacity': 1,\n 'stroke-width': 0,\n 'stroke-linejoin': 'miter',\n 'stroke-linecap': 'butt',\n fill: '#000000',\n stroke: '#000000',\n opacity: 1,\n // position\n x: 0,\n y: 0,\n cx: 0,\n cy: 0,\n // size\n width: 0,\n height: 0,\n // radius\n r: 0,\n rx: 0,\n ry: 0,\n // gradient\n offset: 0,\n 'stop-opacity': 1,\n 'stop-color': '#000000',\n // text\n 'text-anchor': 'start'\n};\n\nvar defaults = {\n __proto__: null,\n noop: noop,\n timeline: timeline,\n attrs: attrs\n};\n\nclass SVGArray extends Array {\n constructor(...args) {\n super(...args);\n this.init(...args);\n }\n\n clone() {\n return new this.constructor(this);\n }\n\n init(arr) {\n // This catches the case, that native map tries to create an array with new Array(1)\n if (typeof arr === 'number') return this;\n this.length = 0;\n this.push(...this.parse(arr));\n return this;\n } // Parse whitespace separated string\n\n\n parse(array = []) {\n // If already is an array, no need to parse it\n if (array instanceof Array) return array;\n return array.trim().split(delimiter).map(parseFloat);\n }\n\n toArray() {\n return Array.prototype.concat.apply([], this);\n }\n\n toSet() {\n return new Set(this);\n }\n\n toString() {\n return this.join(' ');\n } // Flattens the array if needed\n\n\n valueOf() {\n const ret = [];\n ret.push(...this);\n return ret;\n }\n\n}\n\nclass SVGNumber {\n // Initialize\n constructor(...args) {\n this.init(...args);\n }\n\n convert(unit) {\n return new SVGNumber(this.value, unit);\n } // Divide number\n\n\n divide(number) {\n number = new SVGNumber(number);\n return new SVGNumber(this / number, this.unit || number.unit);\n }\n\n init(value, unit) {\n unit = Array.isArray(value) ? value[1] : unit;\n value = Array.isArray(value) ? value[0] : value; // initialize defaults\n\n this.value = 0;\n this.unit = unit || ''; // parse value\n\n if (typeof value === 'number') {\n // ensure a valid numeric value\n this.value = isNaN(value) ? 0 : !isFinite(value) ? value < 0 ? -3.4e+38 : +3.4e+38 : value;\n } else if (typeof value === 'string') {\n unit = value.match(numberAndUnit);\n\n if (unit) {\n // make value numeric\n this.value = parseFloat(unit[1]); // normalize\n\n if (unit[5] === '%') {\n this.value /= 100;\n } else if (unit[5] === 's') {\n this.value *= 1000;\n } // store unit\n\n\n this.unit = unit[5];\n }\n } else {\n if (value instanceof SVGNumber) {\n this.value = value.valueOf();\n this.unit = value.unit;\n }\n }\n\n return this;\n } // Subtract number\n\n\n minus(number) {\n number = new SVGNumber(number);\n return new SVGNumber(this - number, this.unit || number.unit);\n } // Add number\n\n\n plus(number) {\n number = new SVGNumber(number);\n return new SVGNumber(this + number, this.unit || number.unit);\n } // Multiply number\n\n\n times(number) {\n number = new SVGNumber(number);\n return new SVGNumber(this * number, this.unit || number.unit);\n }\n\n toArray() {\n return [this.value, this.unit];\n }\n\n toJSON() {\n return this.toString();\n }\n\n toString() {\n return (this.unit === '%' ? ~~(this.value * 1e8) / 1e6 : this.unit === 's' ? this.value / 1e3 : this.value) + this.unit;\n }\n\n valueOf() {\n return this.value;\n }\n\n}\n\nconst hooks = [];\nfunction registerAttrHook(fn) {\n hooks.push(fn);\n} // Set svg element attribute\n\nfunction attr(attr, val, ns) {\n // act as full getter\n if (attr == null) {\n // get an object of attributes\n attr = {};\n val = this.node.attributes;\n\n for (const node of val) {\n attr[node.nodeName] = isNumber.test(node.nodeValue) ? parseFloat(node.nodeValue) : node.nodeValue;\n }\n\n return attr;\n } else if (attr instanceof Array) {\n // loop through array and get all values\n return attr.reduce((last, curr) => {\n last[curr] = this.attr(curr);\n return last;\n }, {});\n } else if (typeof attr === 'object' && attr.constructor === Object) {\n // apply every attribute individually if an object is passed\n for (val in attr) this.attr(val, attr[val]);\n } else if (val === null) {\n // remove value\n this.node.removeAttribute(attr);\n } else if (val == null) {\n // act as a getter if the first and only argument is not an object\n val = this.node.getAttribute(attr);\n return val == null ? attrs[attr] : isNumber.test(val) ? parseFloat(val) : val;\n } else {\n // Loop through hooks and execute them to convert value\n val = hooks.reduce((_val, hook) => {\n return hook(attr, _val, this);\n }, val); // ensure correct numeric values (also accepts NaN and Infinity)\n\n if (typeof val === 'number') {\n val = new SVGNumber(val);\n } else if (Color.isColor(val)) {\n // ensure full hex color\n val = new Color(val);\n } else if (val.constructor === Array) {\n // Check for plain arrays and parse array values\n val = new SVGArray(val);\n } // if the passed attribute is leading...\n\n\n if (attr === 'leading') {\n // ... call the leading method instead\n if (this.leading) {\n this.leading(val);\n }\n } else {\n // set given attribute on node\n typeof ns === 'string' ? this.node.setAttributeNS(ns, attr, val.toString()) : this.node.setAttribute(attr, val.toString());\n } // rebuild if required\n\n\n if (this.rebuild && (attr === 'font-size' || attr === 'x')) {\n this.rebuild();\n }\n }\n\n return this;\n}\n\nclass Dom extends EventTarget {\n constructor(node, attrs) {\n super();\n this.node = node;\n this.type = node.nodeName;\n\n if (attrs && node !== attrs) {\n this.attr(attrs);\n }\n } // Add given element at a position\n\n\n add(element, i) {\n element = makeInstance(element); // If non-root svg nodes are added we have to remove their namespaces\n\n if (element.removeNamespace && this.node instanceof globals.window.SVGElement) {\n element.removeNamespace();\n }\n\n if (i == null) {\n this.node.appendChild(element.node);\n } else if (element.node !== this.node.childNodes[i]) {\n this.node.insertBefore(element.node, this.node.childNodes[i]);\n }\n\n return this;\n } // Add element to given container and return self\n\n\n addTo(parent, i) {\n return makeInstance(parent).put(this, i);\n } // Returns all child elements\n\n\n children() {\n return new List(map(this.node.children, function (node) {\n return adopt(node);\n }));\n } // Remove all elements in this container\n\n\n clear() {\n // remove children\n while (this.node.hasChildNodes()) {\n this.node.removeChild(this.node.lastChild);\n }\n\n return this;\n } // Clone element\n\n\n clone(deep = true, assignNewIds = true) {\n // write dom data to the dom so the clone can pickup the data\n this.writeDataToDom(); // clone element\n\n let nodeClone = this.node.cloneNode(deep);\n\n if (assignNewIds) {\n // assign new id\n nodeClone = assignNewId(nodeClone);\n }\n\n return new this.constructor(nodeClone);\n } // Iterates over all children and invokes a given block\n\n\n each(block, deep) {\n const children = this.children();\n let i, il;\n\n for (i = 0, il = children.length; i < il; i++) {\n block.apply(children[i], [i, children]);\n\n if (deep) {\n children[i].each(block, deep);\n }\n }\n\n return this;\n }\n\n element(nodeName, attrs) {\n return this.put(new Dom(create(nodeName), attrs));\n } // Get first child\n\n\n first() {\n return adopt(this.node.firstChild);\n } // Get a element at the given index\n\n\n get(i) {\n return adopt(this.node.childNodes[i]);\n }\n\n getEventHolder() {\n return this.node;\n }\n\n getEventTarget() {\n return this.node;\n } // Checks if the given element is a child\n\n\n has(element) {\n return this.index(element) >= 0;\n }\n\n html(htmlOrFn, outerHTML) {\n return this.xml(htmlOrFn, outerHTML, html);\n } // Get / set id\n\n\n id(id) {\n // generate new id if no id set\n if (typeof id === 'undefined' && !this.node.id) {\n this.node.id = eid(this.type);\n } // don't set directly with this.node.id to make `null` work correctly\n\n\n return this.attr('id', id);\n } // Gets index of given element\n\n\n index(element) {\n return [].slice.call(this.node.childNodes).indexOf(element.node);\n } // Get the last child\n\n\n last() {\n return adopt(this.node.lastChild);\n } // matches the element vs a css selector\n\n\n matches(selector) {\n const el = this.node;\n const matcher = el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector || null;\n return matcher && matcher.call(el, selector);\n } // Returns the parent element instance\n\n\n parent(type) {\n let parent = this; // check for parent\n\n if (!parent.node.parentNode) return null; // get parent element\n\n parent = adopt(parent.node.parentNode);\n if (!type) return parent; // loop through ancestors if type is given\n\n do {\n if (typeof type === 'string' ? parent.matches(type) : parent instanceof type) return parent;\n } while (parent = adopt(parent.node.parentNode));\n\n return parent;\n } // Basically does the same as `add()` but returns the added element instead\n\n\n put(element, i) {\n element = makeInstance(element);\n this.add(element, i);\n return element;\n } // Add element to given container and return container\n\n\n putIn(parent, i) {\n return makeInstance(parent).add(this, i);\n } // Remove element\n\n\n remove() {\n if (this.parent()) {\n this.parent().removeElement(this);\n }\n\n return this;\n } // Remove a given child\n\n\n removeElement(element) {\n this.node.removeChild(element.node);\n return this;\n } // Replace this with element\n\n\n replace(element) {\n element = makeInstance(element);\n\n if (this.node.parentNode) {\n this.node.parentNode.replaceChild(element.node, this.node);\n }\n\n return element;\n }\n\n round(precision = 2, map = null) {\n const factor = 10 ** precision;\n const attrs = this.attr(map);\n\n for (const i in attrs) {\n if (typeof attrs[i] === 'number') {\n attrs[i] = Math.round(attrs[i] * factor) / factor;\n }\n }\n\n this.attr(attrs);\n return this;\n } // Import / Export raw svg\n\n\n svg(svgOrFn, outerSVG) {\n return this.xml(svgOrFn, outerSVG, svg);\n } // Return id on string conversion\n\n\n toString() {\n return this.id();\n }\n\n words(text) {\n // This is faster than removing all children and adding a new one\n this.node.textContent = text;\n return this;\n }\n\n wrap(node) {\n const parent = this.parent();\n\n if (!parent) {\n return this.addTo(node);\n }\n\n const position = parent.index(this);\n return parent.put(node, position).put(this);\n } // write svgjs data to the dom\n\n\n writeDataToDom() {\n // dump variables recursively\n this.each(function () {\n this.writeDataToDom();\n });\n return this;\n } // Import / Export raw svg\n\n\n xml(xmlOrFn, outerXML, ns) {\n if (typeof xmlOrFn === 'boolean') {\n ns = outerXML;\n outerXML = xmlOrFn;\n xmlOrFn = null;\n } // act as getter if no svg string is given\n\n\n if (xmlOrFn == null || typeof xmlOrFn === 'function') {\n // The default for exports is, that the outerNode is included\n outerXML = outerXML == null ? true : outerXML; // write svgjs data to the dom\n\n this.writeDataToDom();\n let current = this; // An export modifier was passed\n\n if (xmlOrFn != null) {\n current = adopt(current.node.cloneNode(true)); // If the user wants outerHTML we need to process this node, too\n\n if (outerXML) {\n const result = xmlOrFn(current);\n current = result || current; // The user does not want this node? Well, then he gets nothing\n\n if (result === false) return '';\n } // Deep loop through all children and apply modifier\n\n\n current.each(function () {\n const result = xmlOrFn(this);\n\n const _this = result || this; // If modifier returns false, discard node\n\n\n if (result === false) {\n this.remove(); // If modifier returns new node, use it\n } else if (result && this !== _this) {\n this.replace(_this);\n }\n }, true);\n } // Return outer or inner content\n\n\n return outerXML ? current.node.outerHTML : current.node.innerHTML;\n } // Act as setter if we got a string\n // The default for import is, that the current node is not replaced\n\n\n outerXML = outerXML == null ? false : outerXML; // Create temporary holder\n\n const well = create('wrapper', ns);\n const fragment = globals.document.createDocumentFragment(); // Dump raw svg\n\n well.innerHTML = xmlOrFn; // Transplant nodes into the fragment\n\n for (let len = well.children.length; len--;) {\n fragment.appendChild(well.firstElementChild);\n }\n\n const parent = this.parent(); // Add the whole fragment at once\n\n return outerXML ? this.replace(fragment) && parent : this.add(fragment);\n }\n\n}\nextend(Dom, {\n attr,\n find,\n findOne\n});\nregister(Dom, 'Dom');\n\nclass Element extends Dom {\n constructor(node, attrs) {\n super(node, attrs); // initialize data object\n\n this.dom = {}; // create circular reference\n\n this.node.instance = this;\n\n if (node.hasAttribute('svgjs:data')) {\n // pull svgjs data from the dom (getAttributeNS doesn't work in html5)\n this.setData(JSON.parse(node.getAttribute('svgjs:data')) || {});\n }\n } // Move element by its center\n\n\n center(x, y) {\n return this.cx(x).cy(y);\n } // Move by center over x-axis\n\n\n cx(x) {\n return x == null ? this.x() + this.width() / 2 : this.x(x - this.width() / 2);\n } // Move by center over y-axis\n\n\n cy(y) {\n return y == null ? this.y() + this.height() / 2 : this.y(y - this.height() / 2);\n } // Get defs\n\n\n defs() {\n const root = this.root();\n return root && root.defs();\n } // Relative move over x and y axes\n\n\n dmove(x, y) {\n return this.dx(x).dy(y);\n } // Relative move over x axis\n\n\n dx(x = 0) {\n return this.x(new SVGNumber(x).plus(this.x()));\n } // Relative move over y axis\n\n\n dy(y = 0) {\n return this.y(new SVGNumber(y).plus(this.y()));\n }\n\n getEventHolder() {\n return this;\n } // Set height of element\n\n\n height(height) {\n return this.attr('height', height);\n } // Move element to given x and y values\n\n\n move(x, y) {\n return this.x(x).y(y);\n } // return array of all ancestors of given type up to the root svg\n\n\n parents(until = this.root()) {\n const isSelector = typeof until === 'string';\n\n if (!isSelector) {\n until = makeInstance(until);\n }\n\n const parents = new List();\n let parent = this;\n\n while ((parent = parent.parent()) && parent.node !== globals.document && parent.nodeName !== '#document-fragment') {\n parents.push(parent);\n\n if (!isSelector && parent.node === until.node) {\n break;\n }\n\n if (isSelector && parent.matches(until)) {\n break;\n }\n\n if (parent.node === this.root().node) {\n // We worked our way to the root and didn't match `until`\n return null;\n }\n }\n\n return parents;\n } // Get referenced element form attribute value\n\n\n reference(attr) {\n attr = this.attr(attr);\n if (!attr) return null;\n const m = (attr + '').match(reference);\n return m ? makeInstance(m[1]) : null;\n } // Get parent document\n\n\n root() {\n const p = this.parent(getClass(root));\n return p && p.root();\n } // set given data to the elements data property\n\n\n setData(o) {\n this.dom = o;\n return this;\n } // Set element size to given width and height\n\n\n size(width, height) {\n const p = proportionalSize(this, width, height);\n return this.width(new SVGNumber(p.width)).height(new SVGNumber(p.height));\n } // Set width of element\n\n\n width(width) {\n return this.attr('width', width);\n } // write svgjs data to the dom\n\n\n writeDataToDom() {\n // remove previously set data\n this.node.removeAttribute('svgjs:data');\n\n if (Object.keys(this.dom).length) {\n this.node.setAttribute('svgjs:data', JSON.stringify(this.dom)); // see #428\n }\n\n return super.writeDataToDom();\n } // Move over x-axis\n\n\n x(x) {\n return this.attr('x', x);\n } // Move over y-axis\n\n\n y(y) {\n return this.attr('y', y);\n }\n\n}\nextend(Element, {\n bbox,\n rbox,\n inside,\n point,\n ctm,\n screenCTM\n});\nregister(Element, 'Element');\n\nconst sugar = {\n stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'],\n fill: ['color', 'opacity', 'rule'],\n prefix: function (t, a) {\n return a === 'color' ? t : t + '-' + a;\n }\n} // Add sugar for fill and stroke\n;\n['fill', 'stroke'].forEach(function (m) {\n const extension = {};\n let i;\n\n extension[m] = function (o) {\n if (typeof o === 'undefined') {\n return this.attr(m);\n }\n\n if (typeof o === 'string' || o instanceof Color || Color.isRgb(o) || o instanceof Element) {\n this.attr(m, o);\n } else {\n // set all attributes from sugar.fill and sugar.stroke list\n for (i = sugar[m].length - 1; i >= 0; i--) {\n if (o[sugar[m][i]] != null) {\n this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]]);\n }\n }\n }\n\n return this;\n };\n\n registerMethods(['Element', 'Runner'], extension);\n});\nregisterMethods(['Element', 'Runner'], {\n // Let the user set the matrix directly\n matrix: function (mat, b, c, d, e, f) {\n // Act as a getter\n if (mat == null) {\n return new Matrix(this);\n } // Act as a setter, the user can pass a matrix or a set of numbers\n\n\n return this.attr('transform', new Matrix(mat, b, c, d, e, f));\n },\n // Map rotation to transform\n rotate: function (angle, cx, cy) {\n return this.transform({\n rotate: angle,\n ox: cx,\n oy: cy\n }, true);\n },\n // Map skew to transform\n skew: function (x, y, cx, cy) {\n return arguments.length === 1 || arguments.length === 3 ? this.transform({\n skew: x,\n ox: y,\n oy: cx\n }, true) : this.transform({\n skew: [x, y],\n ox: cx,\n oy: cy\n }, true);\n },\n shear: function (lam, cx, cy) {\n return this.transform({\n shear: lam,\n ox: cx,\n oy: cy\n }, true);\n },\n // Map scale to transform\n scale: function (x, y, cx, cy) {\n return arguments.length === 1 || arguments.length === 3 ? this.transform({\n scale: x,\n ox: y,\n oy: cx\n }, true) : this.transform({\n scale: [x, y],\n ox: cx,\n oy: cy\n }, true);\n },\n // Map translate to transform\n translate: function (x, y) {\n return this.transform({\n translate: [x, y]\n }, true);\n },\n // Map relative translations to transform\n relative: function (x, y) {\n return this.transform({\n relative: [x, y]\n }, true);\n },\n // Map flip to transform\n flip: function (direction = 'both', origin = 'center') {\n if ('xybothtrue'.indexOf(direction) === -1) {\n origin = direction;\n direction = 'both';\n }\n\n return this.transform({\n flip: direction,\n origin: origin\n }, true);\n },\n // Opacity\n opacity: function (value) {\n return this.attr('opacity', value);\n }\n});\nregisterMethods('radius', {\n // Add x and y radius\n radius: function (x, y = x) {\n const type = (this._element || this).type;\n return type === 'radialGradient' ? this.attr('r', new SVGNumber(x)) : this.rx(x).ry(y);\n }\n});\nregisterMethods('Path', {\n // Get path length\n length: function () {\n return this.node.getTotalLength();\n },\n // Get point at length\n pointAt: function (length) {\n return new Point(this.node.getPointAtLength(length));\n }\n});\nregisterMethods(['Element', 'Runner'], {\n // Set font\n font: function (a, v) {\n if (typeof a === 'object') {\n for (v in a) this.font(v, a[v]);\n\n return this;\n }\n\n return a === 'leading' ? this.leading(v) : a === 'anchor' ? this.attr('text-anchor', v) : a === 'size' || a === 'family' || a === 'weight' || a === 'stretch' || a === 'variant' || a === 'style' ? this.attr('font-' + a, v) : this.attr(a, v);\n }\n}); // Add events to elements\n\nconst methods = ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove', 'mouseenter', 'mouseleave', 'touchstart', 'touchmove', 'touchleave', 'touchend', 'touchcancel'].reduce(function (last, event) {\n // add event to Element\n const fn = function (f) {\n if (f === null) {\n this.off(event);\n } else {\n this.on(event, f);\n }\n\n return this;\n };\n\n last[event] = fn;\n return last;\n}, {});\nregisterMethods('Element', methods);\n\nfunction untransform() {\n return this.attr('transform', null);\n} // merge the whole transformation chain into one matrix and returns it\n\nfunction matrixify() {\n const matrix = (this.attr('transform') || '' // split transformations\n ).split(transforms).slice(0, -1).map(function (str) {\n // generate key => value pairs\n const kv = str.trim().split('(');\n return [kv[0], kv[1].split(delimiter).map(function (str) {\n return parseFloat(str);\n })];\n }).reverse() // merge every transformation into one matrix\n .reduce(function (matrix, transform) {\n if (transform[0] === 'matrix') {\n return matrix.lmultiply(Matrix.fromArray(transform[1]));\n }\n\n return matrix[transform[0]].apply(matrix, transform[1]);\n }, new Matrix());\n return matrix;\n} // add an element to another parent without changing the visual representation on the screen\n\nfunction toParent(parent, i) {\n if (this === parent) return this;\n const ctm = this.screenCTM();\n const pCtm = parent.screenCTM().inverse();\n this.addTo(parent, i).untransform().transform(pCtm.multiply(ctm));\n return this;\n} // same as above with parent equals root-svg\n\nfunction toRoot(i) {\n return this.toParent(this.root(), i);\n} // Add transformations\n\nfunction transform(o, relative) {\n // Act as a getter if no object was passed\n if (o == null || typeof o === 'string') {\n const decomposed = new Matrix(this).decompose();\n return o == null ? decomposed : decomposed[o];\n }\n\n if (!Matrix.isMatrixLike(o)) {\n // Set the origin according to the defined transform\n o = { ...o,\n origin: getOrigin(o, this)\n };\n } // The user can pass a boolean, an Element or an Matrix or nothing\n\n\n const cleanRelative = relative === true ? this : relative || false;\n const result = new Matrix(cleanRelative).transform(o);\n return this.attr('transform', result);\n}\nregisterMethods('Element', {\n untransform,\n matrixify,\n toParent,\n toRoot,\n transform\n});\n\nclass Container extends Element {\n flatten(parent = this, index) {\n this.each(function () {\n if (this instanceof Container) {\n return this.flatten().ungroup();\n }\n });\n return this;\n }\n\n ungroup(parent = this.parent(), index = parent.index(this)) {\n // when parent != this, we want append all elements to the end\n index = index === -1 ? parent.children().length : index;\n this.each(function (i, children) {\n // reverse each\n return children[children.length - i - 1].toParent(parent, index);\n });\n return this.remove();\n }\n\n}\nregister(Container, 'Container');\n\nclass Defs extends Container {\n constructor(node, attrs = node) {\n super(nodeOrNew('defs', node), attrs);\n }\n\n flatten() {\n return this;\n }\n\n ungroup() {\n return this;\n }\n\n}\nregister(Defs, 'Defs');\n\nclass Shape extends Element {}\nregister(Shape, 'Shape');\n\nfunction rx(rx) {\n return this.attr('rx', rx);\n} // Radius y value\n\nfunction ry(ry) {\n return this.attr('ry', ry);\n} // Move over x-axis\n\nfunction x$3(x) {\n return x == null ? this.cx() - this.rx() : this.cx(x + this.rx());\n} // Move over y-axis\n\nfunction y$3(y) {\n return y == null ? this.cy() - this.ry() : this.cy(y + this.ry());\n} // Move by center over x-axis\n\nfunction cx$1(x) {\n return this.attr('cx', x);\n} // Move by center over y-axis\n\nfunction cy$1(y) {\n return this.attr('cy', y);\n} // Set width of element\n\nfunction width$2(width) {\n return width == null ? this.rx() * 2 : this.rx(new SVGNumber(width).divide(2));\n} // Set height of element\n\nfunction height$2(height) {\n return height == null ? this.ry() * 2 : this.ry(new SVGNumber(height).divide(2));\n}\n\nvar circled = {\n __proto__: null,\n rx: rx,\n ry: ry,\n x: x$3,\n y: y$3,\n cx: cx$1,\n cy: cy$1,\n width: width$2,\n height: height$2\n};\n\nclass Ellipse extends Shape {\n constructor(node, attrs = node) {\n super(nodeOrNew('ellipse', node), attrs);\n }\n\n size(width, height) {\n const p = proportionalSize(this, width, height);\n return this.rx(new SVGNumber(p.width).divide(2)).ry(new SVGNumber(p.height).divide(2));\n }\n\n}\nextend(Ellipse, circled);\nregisterMethods('Container', {\n // Create an ellipse\n ellipse: wrapWithAttrCheck(function (width = 0, height = width) {\n return this.put(new Ellipse()).size(width, height).move(0, 0);\n })\n});\nregister(Ellipse, 'Ellipse');\n\nclass Fragment extends Dom {\n constructor(node = globals.document.createDocumentFragment()) {\n super(node);\n } // Import / Export raw xml\n\n\n xml(xmlOrFn, outerXML, ns) {\n if (typeof xmlOrFn === 'boolean') {\n ns = outerXML;\n outerXML = xmlOrFn;\n xmlOrFn = null;\n } // because this is a fragment we have to put all elements into a wrapper first\n // before we can get the innerXML from it\n\n\n if (xmlOrFn == null || typeof xmlOrFn === 'function') {\n const wrapper = new Dom(create('wrapper', ns));\n wrapper.add(this.node.cloneNode(true));\n return wrapper.xml(false, ns);\n } // Act as setter if we got a string\n\n\n return super.xml(xmlOrFn, false, ns);\n }\n\n}\n\nregister(Fragment, 'Fragment');\n\nfunction from(x, y) {\n return (this._element || this).type === 'radialGradient' ? this.attr({\n fx: new SVGNumber(x),\n fy: new SVGNumber(y)\n }) : this.attr({\n x1: new SVGNumber(x),\n y1: new SVGNumber(y)\n });\n}\nfunction to(x, y) {\n return (this._element || this).type === 'radialGradient' ? this.attr({\n cx: new SVGNumber(x),\n cy: new SVGNumber(y)\n }) : this.attr({\n x2: new SVGNumber(x),\n y2: new SVGNumber(y)\n });\n}\n\nvar gradiented = {\n __proto__: null,\n from: from,\n to: to\n};\n\nclass Gradient extends Container {\n constructor(type, attrs) {\n super(nodeOrNew(type + 'Gradient', typeof type === 'string' ? null : type), attrs);\n } // custom attr to handle transform\n\n\n attr(a, b, c) {\n if (a === 'transform') a = 'gradientTransform';\n return super.attr(a, b, c);\n }\n\n bbox() {\n return new Box();\n }\n\n targets() {\n return baseFind('svg [fill*=' + this.id() + ']');\n } // Alias string conversion to fill\n\n\n toString() {\n return this.url();\n } // Update gradient\n\n\n update(block) {\n // remove all stops\n this.clear(); // invoke passed block\n\n if (typeof block === 'function') {\n block.call(this, this);\n }\n\n return this;\n } // Return the fill id\n\n\n url() {\n return 'url(#' + this.id() + ')';\n }\n\n}\nextend(Gradient, gradiented);\nregisterMethods({\n Container: {\n // Create gradient element in defs\n gradient(...args) {\n return this.defs().gradient(...args);\n }\n\n },\n // define gradient\n Defs: {\n gradient: wrapWithAttrCheck(function (type, block) {\n return this.put(new Gradient(type)).update(block);\n })\n }\n});\nregister(Gradient, 'Gradient');\n\nclass Pattern extends Container {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('pattern', node), attrs);\n } // custom attr to handle transform\n\n\n attr(a, b, c) {\n if (a === 'transform') a = 'patternTransform';\n return super.attr(a, b, c);\n }\n\n bbox() {\n return new Box();\n }\n\n targets() {\n return baseFind('svg [fill*=' + this.id() + ']');\n } // Alias string conversion to fill\n\n\n toString() {\n return this.url();\n } // Update pattern by rebuilding\n\n\n update(block) {\n // remove content\n this.clear(); // invoke passed block\n\n if (typeof block === 'function') {\n block.call(this, this);\n }\n\n return this;\n } // Return the fill id\n\n\n url() {\n return 'url(#' + this.id() + ')';\n }\n\n}\nregisterMethods({\n Container: {\n // Create pattern element in defs\n pattern(...args) {\n return this.defs().pattern(...args);\n }\n\n },\n Defs: {\n pattern: wrapWithAttrCheck(function (width, height, block) {\n return this.put(new Pattern()).update(block).attr({\n x: 0,\n y: 0,\n width: width,\n height: height,\n patternUnits: 'userSpaceOnUse'\n });\n })\n }\n});\nregister(Pattern, 'Pattern');\n\nclass Image extends Shape {\n constructor(node, attrs = node) {\n super(nodeOrNew('image', node), attrs);\n } // (re)load image\n\n\n load(url, callback) {\n if (!url) return this;\n const img = new globals.window.Image();\n on(img, 'load', function (e) {\n const p = this.parent(Pattern); // ensure image size\n\n if (this.width() === 0 && this.height() === 0) {\n this.size(img.width, img.height);\n }\n\n if (p instanceof Pattern) {\n // ensure pattern size if not set\n if (p.width() === 0 && p.height() === 0) {\n p.size(this.width(), this.height());\n }\n }\n\n if (typeof callback === 'function') {\n callback.call(this, e);\n }\n }, this);\n on(img, 'load error', function () {\n // dont forget to unbind memory leaking events\n off(img);\n });\n return this.attr('href', img.src = url, xlink);\n }\n\n}\nregisterAttrHook(function (attr, val, _this) {\n // convert image fill and stroke to patterns\n if (attr === 'fill' || attr === 'stroke') {\n if (isImage.test(val)) {\n val = _this.root().defs().image(val);\n }\n }\n\n if (val instanceof Image) {\n val = _this.root().defs().pattern(0, 0, pattern => {\n pattern.add(val);\n });\n }\n\n return val;\n});\nregisterMethods({\n Container: {\n // create image element, load image and set its size\n image: wrapWithAttrCheck(function (source, callback) {\n return this.put(new Image()).size(0, 0).load(source, callback);\n })\n }\n});\nregister(Image, 'Image');\n\nclass PointArray extends SVGArray {\n // Get bounding box of points\n bbox() {\n let maxX = -Infinity;\n let maxY = -Infinity;\n let minX = Infinity;\n let minY = Infinity;\n this.forEach(function (el) {\n maxX = Math.max(el[0], maxX);\n maxY = Math.max(el[1], maxY);\n minX = Math.min(el[0], minX);\n minY = Math.min(el[1], minY);\n });\n return new Box(minX, minY, maxX - minX, maxY - minY);\n } // Move point string\n\n\n move(x, y) {\n const box = this.bbox(); // get relative offset\n\n x -= box.x;\n y -= box.y; // move every point\n\n if (!isNaN(x) && !isNaN(y)) {\n for (let i = this.length - 1; i >= 0; i--) {\n this[i] = [this[i][0] + x, this[i][1] + y];\n }\n }\n\n return this;\n } // Parse point string and flat array\n\n\n parse(array = [0, 0]) {\n const points = []; // if it is an array, we flatten it and therefore clone it to 1 depths\n\n if (array instanceof Array) {\n array = Array.prototype.concat.apply([], array);\n } else {\n // Else, it is considered as a string\n // parse points\n array = array.trim().split(delimiter).map(parseFloat);\n } // validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints\n // Odd number of coordinates is an error. In such cases, drop the last odd coordinate.\n\n\n if (array.length % 2 !== 0) array.pop(); // wrap points in two-tuples\n\n for (let i = 0, len = array.length; i < len; i = i + 2) {\n points.push([array[i], array[i + 1]]);\n }\n\n return points;\n } // Resize poly string\n\n\n size(width, height) {\n let i;\n const box = this.bbox(); // recalculate position of all points according to new size\n\n for (i = this.length - 1; i >= 0; i--) {\n if (box.width) this[i][0] = (this[i][0] - box.x) * width / box.width + box.x;\n if (box.height) this[i][1] = (this[i][1] - box.y) * height / box.height + box.y;\n }\n\n return this;\n } // Convert array to line object\n\n\n toLine() {\n return {\n x1: this[0][0],\n y1: this[0][1],\n x2: this[1][0],\n y2: this[1][1]\n };\n } // Convert array to string\n\n\n toString() {\n const array = []; // convert to a poly point string\n\n for (let i = 0, il = this.length; i < il; i++) {\n array.push(this[i].join(','));\n }\n\n return array.join(' ');\n }\n\n transform(m) {\n return this.clone().transformO(m);\n } // transform points with matrix (similar to Point.transform)\n\n\n transformO(m) {\n if (!Matrix.isMatrixLike(m)) {\n m = new Matrix(m);\n }\n\n for (let i = this.length; i--;) {\n // Perform the matrix multiplication\n const [x, y] = this[i];\n this[i][0] = m.a * x + m.c * y + m.e;\n this[i][1] = m.b * x + m.d * y + m.f;\n }\n\n return this;\n }\n\n}\n\nconst MorphArray = PointArray; // Move by left top corner over x-axis\n\nfunction x$2(x) {\n return x == null ? this.bbox().x : this.move(x, this.bbox().y);\n} // Move by left top corner over y-axis\n\nfunction y$2(y) {\n return y == null ? this.bbox().y : this.move(this.bbox().x, y);\n} // Set width of element\n\nfunction width$1(width) {\n const b = this.bbox();\n return width == null ? b.width : this.size(width, b.height);\n} // Set height of element\n\nfunction height$1(height) {\n const b = this.bbox();\n return height == null ? b.height : this.size(b.width, height);\n}\n\nvar pointed = {\n __proto__: null,\n MorphArray: MorphArray,\n x: x$2,\n y: y$2,\n width: width$1,\n height: height$1\n};\n\nclass Line extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('line', node), attrs);\n } // Get array\n\n\n array() {\n return new PointArray([[this.attr('x1'), this.attr('y1')], [this.attr('x2'), this.attr('y2')]]);\n } // Move by left top corner\n\n\n move(x, y) {\n return this.attr(this.array().move(x, y).toLine());\n } // Overwrite native plot() method\n\n\n plot(x1, y1, x2, y2) {\n if (x1 == null) {\n return this.array();\n } else if (typeof y1 !== 'undefined') {\n x1 = {\n x1,\n y1,\n x2,\n y2\n };\n } else {\n x1 = new PointArray(x1).toLine();\n }\n\n return this.attr(x1);\n } // Set element size to given width and height\n\n\n size(width, height) {\n const p = proportionalSize(this, width, height);\n return this.attr(this.array().size(p.width, p.height).toLine());\n }\n\n}\nextend(Line, pointed);\nregisterMethods({\n Container: {\n // Create a line element\n line: wrapWithAttrCheck(function (...args) {\n // make sure plot is called as a setter\n // x1 is not necessarily a number, it can also be an array, a string and a PointArray\n return Line.prototype.plot.apply(this.put(new Line()), args[0] != null ? args : [0, 0, 0, 0]);\n })\n }\n});\nregister(Line, 'Line');\n\nclass Marker extends Container {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('marker', node), attrs);\n } // Set height of element\n\n\n height(height) {\n return this.attr('markerHeight', height);\n }\n\n orient(orient) {\n return this.attr('orient', orient);\n } // Set marker refX and refY\n\n\n ref(x, y) {\n return this.attr('refX', x).attr('refY', y);\n } // Return the fill id\n\n\n toString() {\n return 'url(#' + this.id() + ')';\n } // Update marker\n\n\n update(block) {\n // remove all content\n this.clear(); // invoke passed block\n\n if (typeof block === 'function') {\n block.call(this, this);\n }\n\n return this;\n } // Set width of element\n\n\n width(width) {\n return this.attr('markerWidth', width);\n }\n\n}\nregisterMethods({\n Container: {\n marker(...args) {\n // Create marker element in defs\n return this.defs().marker(...args);\n }\n\n },\n Defs: {\n // Create marker\n marker: wrapWithAttrCheck(function (width, height, block) {\n // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto\n return this.put(new Marker()).size(width, height).ref(width / 2, height / 2).viewbox(0, 0, width, height).attr('orient', 'auto').update(block);\n })\n },\n marker: {\n // Create and attach markers\n marker(marker, width, height, block) {\n let attr = ['marker']; // Build attribute name\n\n if (marker !== 'all') attr.push(marker);\n attr = attr.join('-'); // Set marker attribute\n\n marker = arguments[1] instanceof Marker ? arguments[1] : this.defs().marker(width, height, block);\n return this.attr(attr, marker);\n }\n\n }\n});\nregister(Marker, 'Marker');\n\n/***\nBase Class\n==========\nThe base stepper class that will be\n***/\n\nfunction makeSetterGetter(k, f) {\n return function (v) {\n if (v == null) return this[k];\n this[k] = v;\n if (f) f.call(this);\n return this;\n };\n}\n\nconst easing = {\n '-': function (pos) {\n return pos;\n },\n '<>': function (pos) {\n return -Math.cos(pos * Math.PI) / 2 + 0.5;\n },\n '>': function (pos) {\n return Math.sin(pos * Math.PI / 2);\n },\n '<': function (pos) {\n return -Math.cos(pos * Math.PI / 2) + 1;\n },\n bezier: function (x1, y1, x2, y2) {\n // see https://www.w3.org/TR/css-easing-1/#cubic-bezier-algo\n return function (t) {\n if (t < 0) {\n if (x1 > 0) {\n return y1 / x1 * t;\n } else if (x2 > 0) {\n return y2 / x2 * t;\n } else {\n return 0;\n }\n } else if (t > 1) {\n if (x2 < 1) {\n return (1 - y2) / (1 - x2) * t + (y2 - x2) / (1 - x2);\n } else if (x1 < 1) {\n return (1 - y1) / (1 - x1) * t + (y1 - x1) / (1 - x1);\n } else {\n return 1;\n }\n } else {\n return 3 * t * (1 - t) ** 2 * y1 + 3 * t ** 2 * (1 - t) * y2 + t ** 3;\n }\n };\n },\n // see https://www.w3.org/TR/css-easing-1/#step-timing-function-algo\n steps: function (steps, stepPosition = 'end') {\n // deal with \"jump-\" prefix\n stepPosition = stepPosition.split('-').reverse()[0];\n let jumps = steps;\n\n if (stepPosition === 'none') {\n --jumps;\n } else if (stepPosition === 'both') {\n ++jumps;\n } // The beforeFlag is essentially useless\n\n\n return (t, beforeFlag = false) => {\n // Step is called currentStep in referenced url\n let step = Math.floor(t * steps);\n const jumping = t * step % 1 === 0;\n\n if (stepPosition === 'start' || stepPosition === 'both') {\n ++step;\n }\n\n if (beforeFlag && jumping) {\n --step;\n }\n\n if (t >= 0 && step < 0) {\n step = 0;\n }\n\n if (t <= 1 && step > jumps) {\n step = jumps;\n }\n\n return step / jumps;\n };\n }\n};\nclass Stepper {\n done() {\n return false;\n }\n\n}\n/***\nEasing Functions\n================\n***/\n\nclass Ease extends Stepper {\n constructor(fn = timeline.ease) {\n super();\n this.ease = easing[fn] || fn;\n }\n\n step(from, to, pos) {\n if (typeof from !== 'number') {\n return pos < 1 ? from : to;\n }\n\n return from + (to - from) * this.ease(pos);\n }\n\n}\n/***\nController Types\n================\n***/\n\nclass Controller extends Stepper {\n constructor(fn) {\n super();\n this.stepper = fn;\n }\n\n done(c) {\n return c.done;\n }\n\n step(current, target, dt, c) {\n return this.stepper(current, target, dt, c);\n }\n\n}\n\nfunction recalculate() {\n // Apply the default parameters\n const duration = (this._duration || 500) / 1000;\n const overshoot = this._overshoot || 0; // Calculate the PID natural response\n\n const eps = 1e-10;\n const pi = Math.PI;\n const os = Math.log(overshoot / 100 + eps);\n const zeta = -os / Math.sqrt(pi * pi + os * os);\n const wn = 3.9 / (zeta * duration); // Calculate the Spring values\n\n this.d = 2 * zeta * wn;\n this.k = wn * wn;\n}\n\nclass Spring extends Controller {\n constructor(duration = 500, overshoot = 0) {\n super();\n this.duration(duration).overshoot(overshoot);\n }\n\n step(current, target, dt, c) {\n if (typeof current === 'string') return current;\n c.done = dt === Infinity;\n if (dt === Infinity) return target;\n if (dt === 0) return current;\n if (dt > 100) dt = 16;\n dt /= 1000; // Get the previous velocity\n\n const velocity = c.velocity || 0; // Apply the control to get the new position and store it\n\n const acceleration = -this.d * velocity - this.k * (current - target);\n const newPosition = current + velocity * dt + acceleration * dt * dt / 2; // Store the velocity\n\n c.velocity = velocity + acceleration * dt; // Figure out if we have converged, and if so, pass the value\n\n c.done = Math.abs(target - newPosition) + Math.abs(velocity) < 0.002;\n return c.done ? target : newPosition;\n }\n\n}\nextend(Spring, {\n duration: makeSetterGetter('_duration', recalculate),\n overshoot: makeSetterGetter('_overshoot', recalculate)\n});\nclass PID extends Controller {\n constructor(p = 0.1, i = 0.01, d = 0, windup = 1000) {\n super();\n this.p(p).i(i).d(d).windup(windup);\n }\n\n step(current, target, dt, c) {\n if (typeof current === 'string') return current;\n c.done = dt === Infinity;\n if (dt === Infinity) return target;\n if (dt === 0) return current;\n const p = target - current;\n let i = (c.integral || 0) + p * dt;\n const d = (p - (c.error || 0)) / dt;\n const windup = this._windup; // antiwindup\n\n if (windup !== false) {\n i = Math.max(-windup, Math.min(i, windup));\n }\n\n c.error = p;\n c.integral = i;\n c.done = Math.abs(p) < 0.001;\n return c.done ? target : current + (this.P * p + this.I * i + this.D * d);\n }\n\n}\nextend(PID, {\n windup: makeSetterGetter('_windup'),\n p: makeSetterGetter('P'),\n i: makeSetterGetter('I'),\n d: makeSetterGetter('D')\n});\n\nconst segmentParameters = {\n M: 2,\n L: 2,\n H: 1,\n V: 1,\n C: 6,\n S: 4,\n Q: 4,\n T: 2,\n A: 7,\n Z: 0\n};\nconst pathHandlers = {\n M: function (c, p, p0) {\n p.x = p0.x = c[0];\n p.y = p0.y = c[1];\n return ['M', p.x, p.y];\n },\n L: function (c, p) {\n p.x = c[0];\n p.y = c[1];\n return ['L', c[0], c[1]];\n },\n H: function (c, p) {\n p.x = c[0];\n return ['H', c[0]];\n },\n V: function (c, p) {\n p.y = c[0];\n return ['V', c[0]];\n },\n C: function (c, p) {\n p.x = c[4];\n p.y = c[5];\n return ['C', c[0], c[1], c[2], c[3], c[4], c[5]];\n },\n S: function (c, p) {\n p.x = c[2];\n p.y = c[3];\n return ['S', c[0], c[1], c[2], c[3]];\n },\n Q: function (c, p) {\n p.x = c[2];\n p.y = c[3];\n return ['Q', c[0], c[1], c[2], c[3]];\n },\n T: function (c, p) {\n p.x = c[0];\n p.y = c[1];\n return ['T', c[0], c[1]];\n },\n Z: function (c, p, p0) {\n p.x = p0.x;\n p.y = p0.y;\n return ['Z'];\n },\n A: function (c, p) {\n p.x = c[5];\n p.y = c[6];\n return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]];\n }\n};\nconst mlhvqtcsaz = 'mlhvqtcsaz'.split('');\n\nfor (let i = 0, il = mlhvqtcsaz.length; i < il; ++i) {\n pathHandlers[mlhvqtcsaz[i]] = function (i) {\n return function (c, p, p0) {\n if (i === 'H') c[0] = c[0] + p.x;else if (i === 'V') c[0] = c[0] + p.y;else if (i === 'A') {\n c[5] = c[5] + p.x;\n c[6] = c[6] + p.y;\n } else {\n for (let j = 0, jl = c.length; j < jl; ++j) {\n c[j] = c[j] + (j % 2 ? p.y : p.x);\n }\n }\n return pathHandlers[i](c, p, p0);\n };\n }(mlhvqtcsaz[i].toUpperCase());\n}\n\nfunction makeAbsolut(parser) {\n const command = parser.segment[0];\n return pathHandlers[command](parser.segment.slice(1), parser.p, parser.p0);\n}\n\nfunction segmentComplete(parser) {\n return parser.segment.length && parser.segment.length - 1 === segmentParameters[parser.segment[0].toUpperCase()];\n}\n\nfunction startNewSegment(parser, token) {\n parser.inNumber && finalizeNumber(parser, false);\n const pathLetter = isPathLetter.test(token);\n\n if (pathLetter) {\n parser.segment = [token];\n } else {\n const lastCommand = parser.lastCommand;\n const small = lastCommand.toLowerCase();\n const isSmall = lastCommand === small;\n parser.segment = [small === 'm' ? isSmall ? 'l' : 'L' : lastCommand];\n }\n\n parser.inSegment = true;\n parser.lastCommand = parser.segment[0];\n return pathLetter;\n}\n\nfunction finalizeNumber(parser, inNumber) {\n if (!parser.inNumber) throw new Error('Parser Error');\n parser.number && parser.segment.push(parseFloat(parser.number));\n parser.inNumber = inNumber;\n parser.number = '';\n parser.pointSeen = false;\n parser.hasExponent = false;\n\n if (segmentComplete(parser)) {\n finalizeSegment(parser);\n }\n}\n\nfunction finalizeSegment(parser) {\n parser.inSegment = false;\n\n if (parser.absolute) {\n parser.segment = makeAbsolut(parser);\n }\n\n parser.segments.push(parser.segment);\n}\n\nfunction isArcFlag(parser) {\n if (!parser.segment.length) return false;\n const isArc = parser.segment[0].toUpperCase() === 'A';\n const length = parser.segment.length;\n return isArc && (length === 4 || length === 5);\n}\n\nfunction isExponential(parser) {\n return parser.lastToken.toUpperCase() === 'E';\n}\n\nfunction pathParser(d, toAbsolute = true) {\n let index = 0;\n let token = '';\n const parser = {\n segment: [],\n inNumber: false,\n number: '',\n lastToken: '',\n inSegment: false,\n segments: [],\n pointSeen: false,\n hasExponent: false,\n absolute: toAbsolute,\n p0: new Point(),\n p: new Point()\n };\n\n while (parser.lastToken = token, token = d.charAt(index++)) {\n if (!parser.inSegment) {\n if (startNewSegment(parser, token)) {\n continue;\n }\n }\n\n if (token === '.') {\n if (parser.pointSeen || parser.hasExponent) {\n finalizeNumber(parser, false);\n --index;\n continue;\n }\n\n parser.inNumber = true;\n parser.pointSeen = true;\n parser.number += token;\n continue;\n }\n\n if (!isNaN(parseInt(token))) {\n if (parser.number === '0' || isArcFlag(parser)) {\n parser.inNumber = true;\n parser.number = token;\n finalizeNumber(parser, true);\n continue;\n }\n\n parser.inNumber = true;\n parser.number += token;\n continue;\n }\n\n if (token === ' ' || token === ',') {\n if (parser.inNumber) {\n finalizeNumber(parser, false);\n }\n\n continue;\n }\n\n if (token === '-') {\n if (parser.inNumber && !isExponential(parser)) {\n finalizeNumber(parser, false);\n --index;\n continue;\n }\n\n parser.number += token;\n parser.inNumber = true;\n continue;\n }\n\n if (token.toUpperCase() === 'E') {\n parser.number += token;\n parser.hasExponent = true;\n continue;\n }\n\n if (isPathLetter.test(token)) {\n if (parser.inNumber) {\n finalizeNumber(parser, false);\n } else if (!segmentComplete(parser)) {\n throw new Error('parser Error');\n } else {\n finalizeSegment(parser);\n }\n\n --index;\n }\n }\n\n if (parser.inNumber) {\n finalizeNumber(parser, false);\n }\n\n if (parser.inSegment && segmentComplete(parser)) {\n finalizeSegment(parser);\n }\n\n return parser.segments;\n}\n\nfunction arrayToString(a) {\n let s = '';\n\n for (let i = 0, il = a.length; i < il; i++) {\n s += a[i][0];\n\n if (a[i][1] != null) {\n s += a[i][1];\n\n if (a[i][2] != null) {\n s += ' ';\n s += a[i][2];\n\n if (a[i][3] != null) {\n s += ' ';\n s += a[i][3];\n s += ' ';\n s += a[i][4];\n\n if (a[i][5] != null) {\n s += ' ';\n s += a[i][5];\n s += ' ';\n s += a[i][6];\n\n if (a[i][7] != null) {\n s += ' ';\n s += a[i][7];\n }\n }\n }\n }\n }\n }\n\n return s + ' ';\n}\n\nclass PathArray extends SVGArray {\n // Get bounding box of path\n bbox() {\n parser().path.setAttribute('d', this.toString());\n return new Box(parser.nodes.path.getBBox());\n } // Move path string\n\n\n move(x, y) {\n // get bounding box of current situation\n const box = this.bbox(); // get relative offset\n\n x -= box.x;\n y -= box.y;\n\n if (!isNaN(x) && !isNaN(y)) {\n // move every point\n for (let l, i = this.length - 1; i >= 0; i--) {\n l = this[i][0];\n\n if (l === 'M' || l === 'L' || l === 'T') {\n this[i][1] += x;\n this[i][2] += y;\n } else if (l === 'H') {\n this[i][1] += x;\n } else if (l === 'V') {\n this[i][1] += y;\n } else if (l === 'C' || l === 'S' || l === 'Q') {\n this[i][1] += x;\n this[i][2] += y;\n this[i][3] += x;\n this[i][4] += y;\n\n if (l === 'C') {\n this[i][5] += x;\n this[i][6] += y;\n }\n } else if (l === 'A') {\n this[i][6] += x;\n this[i][7] += y;\n }\n }\n }\n\n return this;\n } // Absolutize and parse path to array\n\n\n parse(d = 'M0 0') {\n if (Array.isArray(d)) {\n d = Array.prototype.concat.apply([], d).toString();\n }\n\n return pathParser(d);\n } // Resize path string\n\n\n size(width, height) {\n // get bounding box of current situation\n const box = this.bbox();\n let i, l; // If the box width or height is 0 then we ignore\n // transformations on the respective axis\n\n box.width = box.width === 0 ? 1 : box.width;\n box.height = box.height === 0 ? 1 : box.height; // recalculate position of all points according to new size\n\n for (i = this.length - 1; i >= 0; i--) {\n l = this[i][0];\n\n if (l === 'M' || l === 'L' || l === 'T') {\n this[i][1] = (this[i][1] - box.x) * width / box.width + box.x;\n this[i][2] = (this[i][2] - box.y) * height / box.height + box.y;\n } else if (l === 'H') {\n this[i][1] = (this[i][1] - box.x) * width / box.width + box.x;\n } else if (l === 'V') {\n this[i][1] = (this[i][1] - box.y) * height / box.height + box.y;\n } else if (l === 'C' || l === 'S' || l === 'Q') {\n this[i][1] = (this[i][1] - box.x) * width / box.width + box.x;\n this[i][2] = (this[i][2] - box.y) * height / box.height + box.y;\n this[i][3] = (this[i][3] - box.x) * width / box.width + box.x;\n this[i][4] = (this[i][4] - box.y) * height / box.height + box.y;\n\n if (l === 'C') {\n this[i][5] = (this[i][5] - box.x) * width / box.width + box.x;\n this[i][6] = (this[i][6] - box.y) * height / box.height + box.y;\n }\n } else if (l === 'A') {\n // resize radii\n this[i][1] = this[i][1] * width / box.width;\n this[i][2] = this[i][2] * height / box.height; // move position values\n\n this[i][6] = (this[i][6] - box.x) * width / box.width + box.x;\n this[i][7] = (this[i][7] - box.y) * height / box.height + box.y;\n }\n }\n\n return this;\n } // Convert array to string\n\n\n toString() {\n return arrayToString(this);\n }\n\n}\n\nconst getClassForType = value => {\n const type = typeof value;\n\n if (type === 'number') {\n return SVGNumber;\n } else if (type === 'string') {\n if (Color.isColor(value)) {\n return Color;\n } else if (delimiter.test(value)) {\n return isPathLetter.test(value) ? PathArray : SVGArray;\n } else if (numberAndUnit.test(value)) {\n return SVGNumber;\n } else {\n return NonMorphable;\n }\n } else if (morphableTypes.indexOf(value.constructor) > -1) {\n return value.constructor;\n } else if (Array.isArray(value)) {\n return SVGArray;\n } else if (type === 'object') {\n return ObjectBag;\n } else {\n return NonMorphable;\n }\n};\n\nclass Morphable {\n constructor(stepper) {\n this._stepper = stepper || new Ease('-');\n this._from = null;\n this._to = null;\n this._type = null;\n this._context = null;\n this._morphObj = null;\n }\n\n at(pos) {\n return this._morphObj.morph(this._from, this._to, pos, this._stepper, this._context);\n }\n\n done() {\n const complete = this._context.map(this._stepper.done).reduce(function (last, curr) {\n return last && curr;\n }, true);\n\n return complete;\n }\n\n from(val) {\n if (val == null) {\n return this._from;\n }\n\n this._from = this._set(val);\n return this;\n }\n\n stepper(stepper) {\n if (stepper == null) return this._stepper;\n this._stepper = stepper;\n return this;\n }\n\n to(val) {\n if (val == null) {\n return this._to;\n }\n\n this._to = this._set(val);\n return this;\n }\n\n type(type) {\n // getter\n if (type == null) {\n return this._type;\n } // setter\n\n\n this._type = type;\n return this;\n }\n\n _set(value) {\n if (!this._type) {\n this.type(getClassForType(value));\n }\n\n let result = new this._type(value);\n\n if (this._type === Color) {\n result = this._to ? result[this._to[4]]() : this._from ? result[this._from[4]]() : result;\n }\n\n if (this._type === ObjectBag) {\n result = this._to ? result.align(this._to) : this._from ? result.align(this._from) : result;\n }\n\n result = result.toConsumable();\n this._morphObj = this._morphObj || new this._type();\n this._context = this._context || Array.apply(null, Array(result.length)).map(Object).map(function (o) {\n o.done = true;\n return o;\n });\n return result;\n }\n\n}\nclass NonMorphable {\n constructor(...args) {\n this.init(...args);\n }\n\n init(val) {\n val = Array.isArray(val) ? val[0] : val;\n this.value = val;\n return this;\n }\n\n toArray() {\n return [this.value];\n }\n\n valueOf() {\n return this.value;\n }\n\n}\nclass TransformBag {\n constructor(...args) {\n this.init(...args);\n }\n\n init(obj) {\n if (Array.isArray(obj)) {\n obj = {\n scaleX: obj[0],\n scaleY: obj[1],\n shear: obj[2],\n rotate: obj[3],\n translateX: obj[4],\n translateY: obj[5],\n originX: obj[6],\n originY: obj[7]\n };\n }\n\n Object.assign(this, TransformBag.defaults, obj);\n return this;\n }\n\n toArray() {\n const v = this;\n return [v.scaleX, v.scaleY, v.shear, v.rotate, v.translateX, v.translateY, v.originX, v.originY];\n }\n\n}\nTransformBag.defaults = {\n scaleX: 1,\n scaleY: 1,\n shear: 0,\n rotate: 0,\n translateX: 0,\n translateY: 0,\n originX: 0,\n originY: 0\n};\n\nconst sortByKey = (a, b) => {\n return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;\n};\n\nclass ObjectBag {\n constructor(...args) {\n this.init(...args);\n }\n\n align(other) {\n const values = this.values;\n\n for (let i = 0, il = values.length; i < il; ++i) {\n // If the type is the same we only need to check if the color is in the correct format\n if (values[i + 1] === other[i + 1]) {\n if (values[i + 1] === Color && other[i + 7] !== values[i + 7]) {\n const space = other[i + 7];\n const color = new Color(this.values.splice(i + 3, 5))[space]().toArray();\n this.values.splice(i + 3, 0, ...color);\n }\n\n i += values[i + 2] + 2;\n continue;\n }\n\n if (!other[i + 1]) {\n return this;\n } // The types differ, so we overwrite the new type with the old one\n // And initialize it with the types default (e.g. black for color or 0 for number)\n\n\n const defaultObject = new other[i + 1]().toArray(); // Than we fix the values array\n\n const toDelete = values[i + 2] + 3;\n values.splice(i, toDelete, other[i], other[i + 1], other[i + 2], ...defaultObject);\n i += values[i + 2] + 2;\n }\n\n return this;\n }\n\n init(objOrArr) {\n this.values = [];\n\n if (Array.isArray(objOrArr)) {\n this.values = objOrArr.slice();\n return;\n }\n\n objOrArr = objOrArr || {};\n const entries = [];\n\n for (const i in objOrArr) {\n const Type = getClassForType(objOrArr[i]);\n const val = new Type(objOrArr[i]).toArray();\n entries.push([i, Type, val.length, ...val]);\n }\n\n entries.sort(sortByKey);\n this.values = entries.reduce((last, curr) => last.concat(curr), []);\n return this;\n }\n\n toArray() {\n return this.values;\n }\n\n valueOf() {\n const obj = {};\n const arr = this.values; // for (var i = 0, len = arr.length; i < len; i += 2) {\n\n while (arr.length) {\n const key = arr.shift();\n const Type = arr.shift();\n const num = arr.shift();\n const values = arr.splice(0, num);\n obj[key] = new Type(values); // .valueOf()\n }\n\n return obj;\n }\n\n}\nconst morphableTypes = [NonMorphable, TransformBag, ObjectBag];\nfunction registerMorphableType(type = []) {\n morphableTypes.push(...[].concat(type));\n}\nfunction makeMorphable() {\n extend(morphableTypes, {\n to(val) {\n return new Morphable().type(this.constructor).from(this.toArray()) // this.valueOf())\n .to(val);\n },\n\n fromArray(arr) {\n this.init(arr);\n return this;\n },\n\n toConsumable() {\n return this.toArray();\n },\n\n morph(from, to, pos, stepper, context) {\n const mapper = function (i, index) {\n return stepper.step(i, to[index], pos, context[index], context);\n };\n\n return this.fromArray(from.map(mapper));\n }\n\n });\n}\n\nclass Path extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('path', node), attrs);\n } // Get array\n\n\n array() {\n return this._array || (this._array = new PathArray(this.attr('d')));\n } // Clear array cache\n\n\n clear() {\n delete this._array;\n return this;\n } // Set height of element\n\n\n height(height) {\n return height == null ? this.bbox().height : this.size(this.bbox().width, height);\n } // Move by left top corner\n\n\n move(x, y) {\n return this.attr('d', this.array().move(x, y));\n } // Plot new path\n\n\n plot(d) {\n return d == null ? this.array() : this.clear().attr('d', typeof d === 'string' ? d : this._array = new PathArray(d));\n } // Set element size to given width and height\n\n\n size(width, height) {\n const p = proportionalSize(this, width, height);\n return this.attr('d', this.array().size(p.width, p.height));\n } // Set width of element\n\n\n width(width) {\n return width == null ? this.bbox().width : this.size(width, this.bbox().height);\n } // Move by left top corner over x-axis\n\n\n x(x) {\n return x == null ? this.bbox().x : this.move(x, this.bbox().y);\n } // Move by left top corner over y-axis\n\n\n y(y) {\n return y == null ? this.bbox().y : this.move(this.bbox().x, y);\n }\n\n} // Define morphable array\n\nPath.prototype.MorphArray = PathArray; // Add parent method\n\nregisterMethods({\n Container: {\n // Create a wrapped path element\n path: wrapWithAttrCheck(function (d) {\n // make sure plot is called as a setter\n return this.put(new Path()).plot(d || new PathArray());\n })\n }\n});\nregister(Path, 'Path');\n\nfunction array() {\n return this._array || (this._array = new PointArray(this.attr('points')));\n} // Clear array cache\n\nfunction clear() {\n delete this._array;\n return this;\n} // Move by left top corner\n\nfunction move$2(x, y) {\n return this.attr('points', this.array().move(x, y));\n} // Plot new path\n\nfunction plot(p) {\n return p == null ? this.array() : this.clear().attr('points', typeof p === 'string' ? p : this._array = new PointArray(p));\n} // Set element size to given width and height\n\nfunction size$1(width, height) {\n const p = proportionalSize(this, width, height);\n return this.attr('points', this.array().size(p.width, p.height));\n}\n\nvar poly = {\n __proto__: null,\n array: array,\n clear: clear,\n move: move$2,\n plot: plot,\n size: size$1\n};\n\nclass Polygon extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('polygon', node), attrs);\n }\n\n}\nregisterMethods({\n Container: {\n // Create a wrapped polygon element\n polygon: wrapWithAttrCheck(function (p) {\n // make sure plot is called as a setter\n return this.put(new Polygon()).plot(p || new PointArray());\n })\n }\n});\nextend(Polygon, pointed);\nextend(Polygon, poly);\nregister(Polygon, 'Polygon');\n\nclass Polyline extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('polyline', node), attrs);\n }\n\n}\nregisterMethods({\n Container: {\n // Create a wrapped polygon element\n polyline: wrapWithAttrCheck(function (p) {\n // make sure plot is called as a setter\n return this.put(new Polyline()).plot(p || new PointArray());\n })\n }\n});\nextend(Polyline, pointed);\nextend(Polyline, poly);\nregister(Polyline, 'Polyline');\n\nclass Rect extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('rect', node), attrs);\n }\n\n}\nextend(Rect, {\n rx,\n ry\n});\nregisterMethods({\n Container: {\n // Create a rect element\n rect: wrapWithAttrCheck(function (width, height) {\n return this.put(new Rect()).size(width, height);\n })\n }\n});\nregister(Rect, 'Rect');\n\nclass Queue {\n constructor() {\n this._first = null;\n this._last = null;\n } // Shows us the first item in the list\n\n\n first() {\n return this._first && this._first.value;\n } // Shows us the last item in the list\n\n\n last() {\n return this._last && this._last.value;\n }\n\n push(value) {\n // An item stores an id and the provided value\n const item = typeof value.next !== 'undefined' ? value : {\n value: value,\n next: null,\n prev: null\n }; // Deal with the queue being empty or populated\n\n if (this._last) {\n item.prev = this._last;\n this._last.next = item;\n this._last = item;\n } else {\n this._last = item;\n this._first = item;\n } // Return the current item\n\n\n return item;\n } // Removes the item that was returned from the push\n\n\n remove(item) {\n // Relink the previous item\n if (item.prev) item.prev.next = item.next;\n if (item.next) item.next.prev = item.prev;\n if (item === this._last) this._last = item.prev;\n if (item === this._first) this._first = item.next; // Invalidate item\n\n item.prev = null;\n item.next = null;\n }\n\n shift() {\n // Check if we have a value\n const remove = this._first;\n if (!remove) return null; // If we do, remove it and relink things\n\n this._first = remove.next;\n if (this._first) this._first.prev = null;\n this._last = this._first ? this._last : null;\n return remove.value;\n }\n\n}\n\nconst Animator = {\n nextDraw: null,\n frames: new Queue(),\n timeouts: new Queue(),\n immediates: new Queue(),\n timer: () => globals.window.performance || globals.window.Date,\n transforms: [],\n\n frame(fn) {\n // Store the node\n const node = Animator.frames.push({\n run: fn\n }); // Request an animation frame if we don't have one\n\n if (Animator.nextDraw === null) {\n Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw);\n } // Return the node so we can remove it easily\n\n\n return node;\n },\n\n timeout(fn, delay) {\n delay = delay || 0; // Work out when the event should fire\n\n const time = Animator.timer().now() + delay; // Add the timeout to the end of the queue\n\n const node = Animator.timeouts.push({\n run: fn,\n time: time\n }); // Request another animation frame if we need one\n\n if (Animator.nextDraw === null) {\n Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw);\n }\n\n return node;\n },\n\n immediate(fn) {\n // Add the immediate fn to the end of the queue\n const node = Animator.immediates.push(fn); // Request another animation frame if we need one\n\n if (Animator.nextDraw === null) {\n Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw);\n }\n\n return node;\n },\n\n cancelFrame(node) {\n node != null && Animator.frames.remove(node);\n },\n\n clearTimeout(node) {\n node != null && Animator.timeouts.remove(node);\n },\n\n cancelImmediate(node) {\n node != null && Animator.immediates.remove(node);\n },\n\n _draw(now) {\n // Run all the timeouts we can run, if they are not ready yet, add them\n // to the end of the queue immediately! (bad timeouts!!! [sarcasm])\n let nextTimeout = null;\n const lastTimeout = Animator.timeouts.last();\n\n while (nextTimeout = Animator.timeouts.shift()) {\n // Run the timeout if its time, or push it to the end\n if (now >= nextTimeout.time) {\n nextTimeout.run();\n } else {\n Animator.timeouts.push(nextTimeout);\n } // If we hit the last item, we should stop shifting out more items\n\n\n if (nextTimeout === lastTimeout) break;\n } // Run all of the animation frames\n\n\n let nextFrame = null;\n const lastFrame = Animator.frames.last();\n\n while (nextFrame !== lastFrame && (nextFrame = Animator.frames.shift())) {\n nextFrame.run(now);\n }\n\n let nextImmediate = null;\n\n while (nextImmediate = Animator.immediates.shift()) {\n nextImmediate();\n } // If we have remaining timeouts or frames, draw until we don't anymore\n\n\n Animator.nextDraw = Animator.timeouts.first() || Animator.frames.first() ? globals.window.requestAnimationFrame(Animator._draw) : null;\n }\n\n};\n\nconst makeSchedule = function (runnerInfo) {\n const start = runnerInfo.start;\n const duration = runnerInfo.runner.duration();\n const end = start + duration;\n return {\n start: start,\n duration: duration,\n end: end,\n runner: runnerInfo.runner\n };\n};\n\nconst defaultSource = function () {\n const w = globals.window;\n return (w.performance || w.Date).now();\n};\n\nclass Timeline extends EventTarget {\n // Construct a new timeline on the given element\n constructor(timeSource = defaultSource) {\n super();\n this._timeSource = timeSource; // Store the timing variables\n\n this._startTime = 0;\n this._speed = 1.0; // Determines how long a runner is hold in memory. Can be a dt or true/false\n\n this._persist = 0; // Keep track of the running animations and their starting parameters\n\n this._nextFrame = null;\n this._paused = true;\n this._runners = [];\n this._runnerIds = [];\n this._lastRunnerId = -1;\n this._time = 0;\n this._lastSourceTime = 0;\n this._lastStepTime = 0; // Make sure that step is always called in class context\n\n this._step = this._stepFn.bind(this, false);\n this._stepImmediate = this._stepFn.bind(this, true);\n }\n\n active() {\n return !!this._nextFrame;\n }\n\n finish() {\n // Go to end and pause\n this.time(this.getEndTimeOfTimeline() + 1);\n return this.pause();\n } // Calculates the end of the timeline\n\n\n getEndTime() {\n const lastRunnerInfo = this.getLastRunnerInfo();\n const lastDuration = lastRunnerInfo ? lastRunnerInfo.runner.duration() : 0;\n const lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : this._time;\n return lastStartTime + lastDuration;\n }\n\n getEndTimeOfTimeline() {\n const endTimes = this._runners.map(i => i.start + i.runner.duration());\n\n return Math.max(0, ...endTimes);\n }\n\n getLastRunnerInfo() {\n return this.getRunnerInfoById(this._lastRunnerId);\n }\n\n getRunnerInfoById(id) {\n return this._runners[this._runnerIds.indexOf(id)] || null;\n }\n\n pause() {\n this._paused = true;\n return this._continue();\n }\n\n persist(dtOrForever) {\n if (dtOrForever == null) return this._persist;\n this._persist = dtOrForever;\n return this;\n }\n\n play() {\n // Now make sure we are not paused and continue the animation\n this._paused = false;\n return this.updateTime()._continue();\n }\n\n reverse(yes) {\n const currentSpeed = this.speed();\n if (yes == null) return this.speed(-currentSpeed);\n const positive = Math.abs(currentSpeed);\n return this.speed(yes ? -positive : positive);\n } // schedules a runner on the timeline\n\n\n schedule(runner, delay, when) {\n if (runner == null) {\n return this._runners.map(makeSchedule);\n } // The start time for the next animation can either be given explicitly,\n // derived from the current timeline time or it can be relative to the\n // last start time to chain animations directly\n\n\n let absoluteStartTime = 0;\n const endTime = this.getEndTime();\n delay = delay || 0; // Work out when to start the animation\n\n if (when == null || when === 'last' || when === 'after') {\n // Take the last time and increment\n absoluteStartTime = endTime;\n } else if (when === 'absolute' || when === 'start') {\n absoluteStartTime = delay;\n delay = 0;\n } else if (when === 'now') {\n absoluteStartTime = this._time;\n } else if (when === 'relative') {\n const runnerInfo = this.getRunnerInfoById(runner.id);\n\n if (runnerInfo) {\n absoluteStartTime = runnerInfo.start + delay;\n delay = 0;\n }\n } else if (when === 'with-last') {\n const lastRunnerInfo = this.getLastRunnerInfo();\n const lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : this._time;\n absoluteStartTime = lastStartTime;\n } else {\n throw new Error('Invalid value for the \"when\" parameter');\n } // Manage runner\n\n\n runner.unschedule();\n runner.timeline(this);\n const persist = runner.persist();\n const runnerInfo = {\n persist: persist === null ? this._persist : persist,\n start: absoluteStartTime + delay,\n runner\n };\n this._lastRunnerId = runner.id;\n\n this._runners.push(runnerInfo);\n\n this._runners.sort((a, b) => a.start - b.start);\n\n this._runnerIds = this._runners.map(info => info.runner.id);\n\n this.updateTime()._continue();\n\n return this;\n }\n\n seek(dt) {\n return this.time(this._time + dt);\n }\n\n source(fn) {\n if (fn == null) return this._timeSource;\n this._timeSource = fn;\n return this;\n }\n\n speed(speed) {\n if (speed == null) return this._speed;\n this._speed = speed;\n return this;\n }\n\n stop() {\n // Go to start and pause\n this.time(0);\n return this.pause();\n }\n\n time(time) {\n if (time == null) return this._time;\n this._time = time;\n return this._continue(true);\n } // Remove the runner from this timeline\n\n\n unschedule(runner) {\n const index = this._runnerIds.indexOf(runner.id);\n\n if (index < 0) return this;\n\n this._runners.splice(index, 1);\n\n this._runnerIds.splice(index, 1);\n\n runner.timeline(null);\n return this;\n } // Makes sure, that after pausing the time doesn't jump\n\n\n updateTime() {\n if (!this.active()) {\n this._lastSourceTime = this._timeSource();\n }\n\n return this;\n } // Checks if we are running and continues the animation\n\n\n _continue(immediateStep = false) {\n Animator.cancelFrame(this._nextFrame);\n this._nextFrame = null;\n if (immediateStep) return this._stepImmediate();\n if (this._paused) return this;\n this._nextFrame = Animator.frame(this._step);\n return this;\n }\n\n _stepFn(immediateStep = false) {\n // Get the time delta from the last time and update the time\n const time = this._timeSource();\n\n let dtSource = time - this._lastSourceTime;\n if (immediateStep) dtSource = 0;\n const dtTime = this._speed * dtSource + (this._time - this._lastStepTime);\n this._lastSourceTime = time; // Only update the time if we use the timeSource.\n // Otherwise use the current time\n\n if (!immediateStep) {\n // Update the time\n this._time += dtTime;\n this._time = this._time < 0 ? 0 : this._time;\n }\n\n this._lastStepTime = this._time;\n this.fire('time', this._time); // This is for the case that the timeline was seeked so that the time\n // is now before the startTime of the runner. That is why we need to set\n // the runner to position 0\n // FIXME:\n // However, resetting in insertion order leads to bugs. Considering the case,\n // where 2 runners change the same attribute but in different times,\n // resetting both of them will lead to the case where the later defined\n // runner always wins the reset even if the other runner started earlier\n // and therefore should win the attribute battle\n // this can be solved by resetting them backwards\n\n for (let k = this._runners.length; k--;) {\n // Get and run the current runner and ignore it if its inactive\n const runnerInfo = this._runners[k];\n const runner = runnerInfo.runner; // Make sure that we give the actual difference\n // between runner start time and now\n\n const dtToStart = this._time - runnerInfo.start; // Dont run runner if not started yet\n // and try to reset it\n\n if (dtToStart <= 0) {\n runner.reset();\n }\n } // Run all of the runners directly\n\n\n let runnersLeft = false;\n\n for (let i = 0, len = this._runners.length; i < len; i++) {\n // Get and run the current runner and ignore it if its inactive\n const runnerInfo = this._runners[i];\n const runner = runnerInfo.runner;\n let dt = dtTime; // Make sure that we give the actual difference\n // between runner start time and now\n\n const dtToStart = this._time - runnerInfo.start; // Dont run runner if not started yet\n\n if (dtToStart <= 0) {\n runnersLeft = true;\n continue;\n } else if (dtToStart < dt) {\n // Adjust dt to make sure that animation is on point\n dt = dtToStart;\n }\n\n if (!runner.active()) continue; // If this runner is still going, signal that we need another animation\n // frame, otherwise, remove the completed runner\n\n const finished = runner.step(dt).done;\n\n if (!finished) {\n runnersLeft = true; // continue\n } else if (runnerInfo.persist !== true) {\n // runner is finished. And runner might get removed\n const endTime = runner.duration() - runner.time() + this._time;\n\n if (endTime + runnerInfo.persist < this._time) {\n // Delete runner and correct index\n runner.unschedule();\n --i;\n --len;\n }\n }\n } // Basically: we continue when there are runners right from us in time\n // when -->, and when runners are left from us when <--\n\n\n if (runnersLeft && !(this._speed < 0 && this._time === 0) || this._runnerIds.length && this._speed < 0 && this._time > 0) {\n this._continue();\n } else {\n this.pause();\n this.fire('finished');\n }\n\n return this;\n }\n\n}\nregisterMethods({\n Element: {\n timeline: function (timeline) {\n if (timeline == null) {\n this._timeline = this._timeline || new Timeline();\n return this._timeline;\n } else {\n this._timeline = timeline;\n return this;\n }\n }\n }\n});\n\nclass Runner extends EventTarget {\n constructor(options) {\n super(); // Store a unique id on the runner, so that we can identify it later\n\n this.id = Runner.id++; // Ensure a default value\n\n options = options == null ? timeline.duration : options; // Ensure that we get a controller\n\n options = typeof options === 'function' ? new Controller(options) : options; // Declare all of the variables\n\n this._element = null;\n this._timeline = null;\n this.done = false;\n this._queue = []; // Work out the stepper and the duration\n\n this._duration = typeof options === 'number' && options;\n this._isDeclarative = options instanceof Controller;\n this._stepper = this._isDeclarative ? options : new Ease(); // We copy the current values from the timeline because they can change\n\n this._history = {}; // Store the state of the runner\n\n this.enabled = true;\n this._time = 0;\n this._lastTime = 0; // At creation, the runner is in reset state\n\n this._reseted = true; // Save transforms applied to this runner\n\n this.transforms = new Matrix();\n this.transformId = 1; // Looping variables\n\n this._haveReversed = false;\n this._reverse = false;\n this._loopsDone = 0;\n this._swing = false;\n this._wait = 0;\n this._times = 1;\n this._frameId = null; // Stores how long a runner is stored after being done\n\n this._persist = this._isDeclarative ? true : null;\n }\n\n static sanitise(duration, delay, when) {\n // Initialise the default parameters\n let times = 1;\n let swing = false;\n let wait = 0;\n duration = duration || timeline.duration;\n delay = delay || timeline.delay;\n when = when || 'last'; // If we have an object, unpack the values\n\n if (typeof duration === 'object' && !(duration instanceof Stepper)) {\n delay = duration.delay || delay;\n when = duration.when || when;\n swing = duration.swing || swing;\n times = duration.times || times;\n wait = duration.wait || wait;\n duration = duration.duration || timeline.duration;\n }\n\n return {\n duration: duration,\n delay: delay,\n swing: swing,\n times: times,\n wait: wait,\n when: when\n };\n }\n\n active(enabled) {\n if (enabled == null) return this.enabled;\n this.enabled = enabled;\n return this;\n }\n /*\n Private Methods\n ===============\n Methods that shouldn't be used externally\n */\n\n\n addTransform(transform, index) {\n this.transforms.lmultiplyO(transform);\n return this;\n }\n\n after(fn) {\n return this.on('finished', fn);\n }\n\n animate(duration, delay, when) {\n const o = Runner.sanitise(duration, delay, when);\n const runner = new Runner(o.duration);\n if (this._timeline) runner.timeline(this._timeline);\n if (this._element) runner.element(this._element);\n return runner.loop(o).schedule(o.delay, o.when);\n }\n\n clearTransform() {\n this.transforms = new Matrix();\n return this;\n } // TODO: Keep track of all transformations so that deletion is faster\n\n\n clearTransformsFromQueue() {\n if (!this.done || !this._timeline || !this._timeline._runnerIds.includes(this.id)) {\n this._queue = this._queue.filter(item => {\n return !item.isTransform;\n });\n }\n }\n\n delay(delay) {\n return this.animate(0, delay);\n }\n\n duration() {\n return this._times * (this._wait + this._duration) - this._wait;\n }\n\n during(fn) {\n return this.queue(null, fn);\n }\n\n ease(fn) {\n this._stepper = new Ease(fn);\n return this;\n }\n /*\n Runner Definitions\n ==================\n These methods help us define the runtime behaviour of the Runner or they\n help us make new runners from the current runner\n */\n\n\n element(element) {\n if (element == null) return this._element;\n this._element = element;\n\n element._prepareRunner();\n\n return this;\n }\n\n finish() {\n return this.step(Infinity);\n }\n\n loop(times, swing, wait) {\n // Deal with the user passing in an object\n if (typeof times === 'object') {\n swing = times.swing;\n wait = times.wait;\n times = times.times;\n } // Sanitise the values and store them\n\n\n this._times = times || Infinity;\n this._swing = swing || false;\n this._wait = wait || 0; // Allow true to be passed\n\n if (this._times === true) {\n this._times = Infinity;\n }\n\n return this;\n }\n\n loops(p) {\n const loopDuration = this._duration + this._wait;\n\n if (p == null) {\n const loopsDone = Math.floor(this._time / loopDuration);\n const relativeTime = this._time - loopsDone * loopDuration;\n const position = relativeTime / this._duration;\n return Math.min(loopsDone + position, this._times);\n }\n\n const whole = Math.floor(p);\n const partial = p % 1;\n const time = loopDuration * whole + this._duration * partial;\n return this.time(time);\n }\n\n persist(dtOrForever) {\n if (dtOrForever == null) return this._persist;\n this._persist = dtOrForever;\n return this;\n }\n\n position(p) {\n // Get all of the variables we need\n const x = this._time;\n const d = this._duration;\n const w = this._wait;\n const t = this._times;\n const s = this._swing;\n const r = this._reverse;\n let position;\n\n if (p == null) {\n /*\n This function converts a time to a position in the range [0, 1]\n The full explanation can be found in this desmos demonstration\n https://www.desmos.com/calculator/u4fbavgche\n The logic is slightly simplified here because we can use booleans\n */\n // Figure out the value without thinking about the start or end time\n const f = function (x) {\n const swinging = s * Math.floor(x % (2 * (w + d)) / (w + d));\n const backwards = swinging && !r || !swinging && r;\n const uncliped = Math.pow(-1, backwards) * (x % (w + d)) / d + backwards;\n const clipped = Math.max(Math.min(uncliped, 1), 0);\n return clipped;\n }; // Figure out the value by incorporating the start time\n\n\n const endTime = t * (w + d) - w;\n position = x <= 0 ? Math.round(f(1e-5)) : x < endTime ? f(x) : Math.round(f(endTime - 1e-5));\n return position;\n } // Work out the loops done and add the position to the loops done\n\n\n const loopsDone = Math.floor(this.loops());\n const swingForward = s && loopsDone % 2 === 0;\n const forwards = swingForward && !r || r && swingForward;\n position = loopsDone + (forwards ? p : 1 - p);\n return this.loops(position);\n }\n\n progress(p) {\n if (p == null) {\n return Math.min(1, this._time / this.duration());\n }\n\n return this.time(p * this.duration());\n }\n /*\n Basic Functionality\n ===================\n These methods allow us to attach basic functions to the runner directly\n */\n\n\n queue(initFn, runFn, retargetFn, isTransform) {\n this._queue.push({\n initialiser: initFn || noop,\n runner: runFn || noop,\n retarget: retargetFn,\n isTransform: isTransform,\n initialised: false,\n finished: false\n });\n\n const timeline = this.timeline();\n timeline && this.timeline()._continue();\n return this;\n }\n\n reset() {\n if (this._reseted) return this;\n this.time(0);\n this._reseted = true;\n return this;\n }\n\n reverse(reverse) {\n this._reverse = reverse == null ? !this._reverse : reverse;\n return this;\n }\n\n schedule(timeline, delay, when) {\n // The user doesn't need to pass a timeline if we already have one\n if (!(timeline instanceof Timeline)) {\n when = delay;\n delay = timeline;\n timeline = this.timeline();\n } // If there is no timeline, yell at the user...\n\n\n if (!timeline) {\n throw Error('Runner cannot be scheduled without timeline');\n } // Schedule the runner on the timeline provided\n\n\n timeline.schedule(this, delay, when);\n return this;\n }\n\n step(dt) {\n // If we are inactive, this stepper just gets skipped\n if (!this.enabled) return this; // Update the time and get the new position\n\n dt = dt == null ? 16 : dt;\n this._time += dt;\n const position = this.position(); // Figure out if we need to run the stepper in this frame\n\n const running = this._lastPosition !== position && this._time >= 0;\n this._lastPosition = position; // Figure out if we just started\n\n const duration = this.duration();\n const justStarted = this._lastTime <= 0 && this._time > 0;\n const justFinished = this._lastTime < duration && this._time >= duration;\n this._lastTime = this._time;\n\n if (justStarted) {\n this.fire('start', this);\n } // Work out if the runner is finished set the done flag here so animations\n // know, that they are running in the last step (this is good for\n // transformations which can be merged)\n\n\n const declarative = this._isDeclarative;\n this.done = !declarative && !justFinished && this._time >= duration; // Runner is running. So its not in reset state anymore\n\n this._reseted = false;\n let converged = false; // Call initialise and the run function\n\n if (running || declarative) {\n this._initialise(running); // clear the transforms on this runner so they dont get added again and again\n\n\n this.transforms = new Matrix();\n converged = this._run(declarative ? dt : position);\n this.fire('step', this);\n } // correct the done flag here\n // declarative animations itself know when they converged\n\n\n this.done = this.done || converged && declarative;\n\n if (justFinished) {\n this.fire('finished', this);\n }\n\n return this;\n }\n /*\n Runner animation methods\n ========================\n Control how the animation plays\n */\n\n\n time(time) {\n if (time == null) {\n return this._time;\n }\n\n const dt = time - this._time;\n this.step(dt);\n return this;\n }\n\n timeline(timeline) {\n // check explicitly for undefined so we can set the timeline to null\n if (typeof timeline === 'undefined') return this._timeline;\n this._timeline = timeline;\n return this;\n }\n\n unschedule() {\n const timeline = this.timeline();\n timeline && timeline.unschedule(this);\n return this;\n } // Run each initialise function in the runner if required\n\n\n _initialise(running) {\n // If we aren't running, we shouldn't initialise when not declarative\n if (!running && !this._isDeclarative) return; // Loop through all of the initialisers\n\n for (let i = 0, len = this._queue.length; i < len; ++i) {\n // Get the current initialiser\n const current = this._queue[i]; // Determine whether we need to initialise\n\n const needsIt = this._isDeclarative || !current.initialised && running;\n running = !current.finished; // Call the initialiser if we need to\n\n if (needsIt && running) {\n current.initialiser.call(this);\n current.initialised = true;\n }\n }\n } // Save a morpher to the morpher list so that we can retarget it later\n\n\n _rememberMorpher(method, morpher) {\n this._history[method] = {\n morpher: morpher,\n caller: this._queue[this._queue.length - 1]\n }; // We have to resume the timeline in case a controller\n // is already done without being ever run\n // This can happen when e.g. this is done:\n // anim = el.animate(new SVG.Spring)\n // and later\n // anim.move(...)\n\n if (this._isDeclarative) {\n const timeline = this.timeline();\n timeline && timeline.play();\n }\n } // Try to set the target for a morpher if the morpher exists, otherwise\n // Run each run function for the position or dt given\n\n\n _run(positionOrDt) {\n // Run all of the _queue directly\n let allfinished = true;\n\n for (let i = 0, len = this._queue.length; i < len; ++i) {\n // Get the current function to run\n const current = this._queue[i]; // Run the function if its not finished, we keep track of the finished\n // flag for the sake of declarative _queue\n\n const converged = current.runner.call(this, positionOrDt);\n current.finished = current.finished || converged === true;\n allfinished = allfinished && current.finished;\n } // We report when all of the constructors are finished\n\n\n return allfinished;\n } // do nothing and return false\n\n\n _tryRetarget(method, target, extra) {\n if (this._history[method]) {\n // if the last method wasn't even initialised, throw it away\n if (!this._history[method].caller.initialised) {\n const index = this._queue.indexOf(this._history[method].caller);\n\n this._queue.splice(index, 1);\n\n return false;\n } // for the case of transformations, we use the special retarget function\n // which has access to the outer scope\n\n\n if (this._history[method].caller.retarget) {\n this._history[method].caller.retarget.call(this, target, extra); // for everything else a simple morpher change is sufficient\n\n } else {\n this._history[method].morpher.to(target);\n }\n\n this._history[method].caller.finished = false;\n const timeline = this.timeline();\n timeline && timeline.play();\n return true;\n }\n\n return false;\n }\n\n}\nRunner.id = 0;\nclass FakeRunner {\n constructor(transforms = new Matrix(), id = -1, done = true) {\n this.transforms = transforms;\n this.id = id;\n this.done = done;\n }\n\n clearTransformsFromQueue() {}\n\n}\nextend([Runner, FakeRunner], {\n mergeWith(runner) {\n return new FakeRunner(runner.transforms.lmultiply(this.transforms), runner.id);\n }\n\n}); // FakeRunner.emptyRunner = new FakeRunner()\n\nconst lmultiply = (last, curr) => last.lmultiplyO(curr);\n\nconst getRunnerTransform = runner => runner.transforms;\n\nfunction mergeTransforms() {\n // Find the matrix to apply to the element and apply it\n const runners = this._transformationRunners.runners;\n const netTransform = runners.map(getRunnerTransform).reduce(lmultiply, new Matrix());\n this.transform(netTransform);\n\n this._transformationRunners.merge();\n\n if (this._transformationRunners.length() === 1) {\n this._frameId = null;\n }\n}\n\nclass RunnerArray {\n constructor() {\n this.runners = [];\n this.ids = [];\n }\n\n add(runner) {\n if (this.runners.includes(runner)) return;\n const id = runner.id + 1;\n this.runners.push(runner);\n this.ids.push(id);\n return this;\n }\n\n clearBefore(id) {\n const deleteCnt = this.ids.indexOf(id + 1) || 1;\n this.ids.splice(0, deleteCnt, 0);\n this.runners.splice(0, deleteCnt, new FakeRunner()).forEach(r => r.clearTransformsFromQueue());\n return this;\n }\n\n edit(id, newRunner) {\n const index = this.ids.indexOf(id + 1);\n this.ids.splice(index, 1, id + 1);\n this.runners.splice(index, 1, newRunner);\n return this;\n }\n\n getByID(id) {\n return this.runners[this.ids.indexOf(id + 1)];\n }\n\n length() {\n return this.ids.length;\n }\n\n merge() {\n let lastRunner = null;\n\n for (let i = 0; i < this.runners.length; ++i) {\n const runner = this.runners[i];\n const condition = lastRunner && runner.done && lastRunner.done // don't merge runner when persisted on timeline\n && (!runner._timeline || !runner._timeline._runnerIds.includes(runner.id)) && (!lastRunner._timeline || !lastRunner._timeline._runnerIds.includes(lastRunner.id));\n\n if (condition) {\n // the +1 happens in the function\n this.remove(runner.id);\n const newRunner = runner.mergeWith(lastRunner);\n this.edit(lastRunner.id, newRunner);\n lastRunner = newRunner;\n --i;\n } else {\n lastRunner = runner;\n }\n }\n\n return this;\n }\n\n remove(id) {\n const index = this.ids.indexOf(id + 1);\n this.ids.splice(index, 1);\n this.runners.splice(index, 1);\n return this;\n }\n\n}\nregisterMethods({\n Element: {\n animate(duration, delay, when) {\n const o = Runner.sanitise(duration, delay, when);\n const timeline = this.timeline();\n return new Runner(o.duration).loop(o).element(this).timeline(timeline.play()).schedule(o.delay, o.when);\n },\n\n delay(by, when) {\n return this.animate(0, by, when);\n },\n\n // this function searches for all runners on the element and deletes the ones\n // which run before the current one. This is because absolute transformations\n // overwrite anything anyway so there is no need to waste time computing\n // other runners\n _clearTransformRunnersBefore(currentRunner) {\n this._transformationRunners.clearBefore(currentRunner.id);\n },\n\n _currentTransform(current) {\n return this._transformationRunners.runners // we need the equal sign here to make sure, that also transformations\n // on the same runner which execute before the current transformation are\n // taken into account\n .filter(runner => runner.id <= current.id).map(getRunnerTransform).reduce(lmultiply, new Matrix());\n },\n\n _addRunner(runner) {\n this._transformationRunners.add(runner); // Make sure that the runner merge is executed at the very end of\n // all Animator functions. That is why we use immediate here to execute\n // the merge right after all frames are run\n\n\n Animator.cancelImmediate(this._frameId);\n this._frameId = Animator.immediate(mergeTransforms.bind(this));\n },\n\n _prepareRunner() {\n if (this._frameId == null) {\n this._transformationRunners = new RunnerArray().add(new FakeRunner(new Matrix(this)));\n }\n }\n\n }\n}); // Will output the elements from array A that are not in the array B\n\nconst difference = (a, b) => a.filter(x => !b.includes(x));\n\nextend(Runner, {\n attr(a, v) {\n return this.styleAttr('attr', a, v);\n },\n\n // Add animatable styles\n css(s, v) {\n return this.styleAttr('css', s, v);\n },\n\n styleAttr(type, nameOrAttrs, val) {\n if (typeof nameOrAttrs === 'string') {\n return this.styleAttr(type, {\n [nameOrAttrs]: val\n });\n }\n\n let attrs = nameOrAttrs;\n if (this._tryRetarget(type, attrs)) return this;\n let morpher = new Morphable(this._stepper).to(attrs);\n let keys = Object.keys(attrs);\n this.queue(function () {\n morpher = morpher.from(this.element()[type](keys));\n }, function (pos) {\n this.element()[type](morpher.at(pos).valueOf());\n return morpher.done();\n }, function (newToAttrs) {\n // Check if any new keys were added\n const newKeys = Object.keys(newToAttrs);\n const differences = difference(newKeys, keys); // If their are new keys, initialize them and add them to morpher\n\n if (differences.length) {\n // Get the values\n const addedFromAttrs = this.element()[type](differences); // Get the already initialized values\n\n const oldFromAttrs = new ObjectBag(morpher.from()).valueOf(); // Merge old and new\n\n Object.assign(oldFromAttrs, addedFromAttrs);\n morpher.from(oldFromAttrs);\n } // Get the object from the morpher\n\n\n const oldToAttrs = new ObjectBag(morpher.to()).valueOf(); // Merge in new attributes\n\n Object.assign(oldToAttrs, newToAttrs); // Change morpher target\n\n morpher.to(oldToAttrs); // Make sure that we save the work we did so we don't need it to do again\n\n keys = newKeys;\n attrs = newToAttrs;\n });\n\n this._rememberMorpher(type, morpher);\n\n return this;\n },\n\n zoom(level, point) {\n if (this._tryRetarget('zoom', level, point)) return this;\n let morpher = new Morphable(this._stepper).to(new SVGNumber(level));\n this.queue(function () {\n morpher = morpher.from(this.element().zoom());\n }, function (pos) {\n this.element().zoom(morpher.at(pos), point);\n return morpher.done();\n }, function (newLevel, newPoint) {\n point = newPoint;\n morpher.to(newLevel);\n });\n\n this._rememberMorpher('zoom', morpher);\n\n return this;\n },\n\n /**\n ** absolute transformations\n **/\n //\n // M v -----|-----(D M v = F v)------|-----> T v\n //\n // 1. define the final state (T) and decompose it (once)\n // t = [tx, ty, the, lam, sy, sx]\n // 2. on every frame: pull the current state of all previous transforms\n // (M - m can change)\n // and then write this as m = [tx0, ty0, the0, lam0, sy0, sx0]\n // 3. Find the interpolated matrix F(pos) = m + pos * (t - m)\n // - Note F(0) = M\n // - Note F(1) = T\n // 4. Now you get the delta matrix as a result: D = F * inv(M)\n transform(transforms, relative, affine) {\n // If we have a declarative function, we should retarget it if possible\n relative = transforms.relative || relative;\n\n if (this._isDeclarative && !relative && this._tryRetarget('transform', transforms)) {\n return this;\n } // Parse the parameters\n\n\n const isMatrix = Matrix.isMatrixLike(transforms);\n affine = transforms.affine != null ? transforms.affine : affine != null ? affine : !isMatrix; // Create a morpher and set its type\n\n const morpher = new Morphable(this._stepper).type(affine ? TransformBag : Matrix);\n let origin;\n let element;\n let current;\n let currentAngle;\n let startTransform;\n\n function setup() {\n // make sure element and origin is defined\n element = element || this.element();\n origin = origin || getOrigin(transforms, element);\n startTransform = new Matrix(relative ? undefined : element); // add the runner to the element so it can merge transformations\n\n element._addRunner(this); // Deactivate all transforms that have run so far if we are absolute\n\n\n if (!relative) {\n element._clearTransformRunnersBefore(this);\n }\n }\n\n function run(pos) {\n // clear all other transforms before this in case something is saved\n // on this runner. We are absolute. We dont need these!\n if (!relative) this.clearTransform();\n const {\n x,\n y\n } = new Point(origin).transform(element._currentTransform(this));\n let target = new Matrix({ ...transforms,\n origin: [x, y]\n });\n let start = this._isDeclarative && current ? current : startTransform;\n\n if (affine) {\n target = target.decompose(x, y);\n start = start.decompose(x, y); // Get the current and target angle as it was set\n\n const rTarget = target.rotate;\n const rCurrent = start.rotate; // Figure out the shortest path to rotate directly\n\n const possibilities = [rTarget - 360, rTarget, rTarget + 360];\n const distances = possibilities.map(a => Math.abs(a - rCurrent));\n const shortest = Math.min(...distances);\n const index = distances.indexOf(shortest);\n target.rotate = possibilities[index];\n }\n\n if (relative) {\n // we have to be careful here not to overwrite the rotation\n // with the rotate method of Matrix\n if (!isMatrix) {\n target.rotate = transforms.rotate || 0;\n }\n\n if (this._isDeclarative && currentAngle) {\n start.rotate = currentAngle;\n }\n }\n\n morpher.from(start);\n morpher.to(target);\n const affineParameters = morpher.at(pos);\n currentAngle = affineParameters.rotate;\n current = new Matrix(affineParameters);\n this.addTransform(current);\n\n element._addRunner(this);\n\n return morpher.done();\n }\n\n function retarget(newTransforms) {\n // only get a new origin if it changed since the last call\n if ((newTransforms.origin || 'center').toString() !== (transforms.origin || 'center').toString()) {\n origin = getOrigin(newTransforms, element);\n } // overwrite the old transformations with the new ones\n\n\n transforms = { ...newTransforms,\n origin\n };\n }\n\n this.queue(setup, run, retarget, true);\n this._isDeclarative && this._rememberMorpher('transform', morpher);\n return this;\n },\n\n // Animatable x-axis\n x(x, relative) {\n return this._queueNumber('x', x);\n },\n\n // Animatable y-axis\n y(y) {\n return this._queueNumber('y', y);\n },\n\n dx(x = 0) {\n return this._queueNumberDelta('x', x);\n },\n\n dy(y = 0) {\n return this._queueNumberDelta('y', y);\n },\n\n dmove(x, y) {\n return this.dx(x).dy(y);\n },\n\n _queueNumberDelta(method, to) {\n to = new SVGNumber(to); // Try to change the target if we have this method already registered\n\n if (this._tryRetarget(method, to)) return this; // Make a morpher and queue the animation\n\n const morpher = new Morphable(this._stepper).to(to);\n let from = null;\n this.queue(function () {\n from = this.element()[method]();\n morpher.from(from);\n morpher.to(from + to);\n }, function (pos) {\n this.element()[method](morpher.at(pos));\n return morpher.done();\n }, function (newTo) {\n morpher.to(from + new SVGNumber(newTo));\n }); // Register the morpher so that if it is changed again, we can retarget it\n\n this._rememberMorpher(method, morpher);\n\n return this;\n },\n\n _queueObject(method, to) {\n // Try to change the target if we have this method already registered\n if (this._tryRetarget(method, to)) return this; // Make a morpher and queue the animation\n\n const morpher = new Morphable(this._stepper).to(to);\n this.queue(function () {\n morpher.from(this.element()[method]());\n }, function (pos) {\n this.element()[method](morpher.at(pos));\n return morpher.done();\n }); // Register the morpher so that if it is changed again, we can retarget it\n\n this._rememberMorpher(method, morpher);\n\n return this;\n },\n\n _queueNumber(method, value) {\n return this._queueObject(method, new SVGNumber(value));\n },\n\n // Animatable center x-axis\n cx(x) {\n return this._queueNumber('cx', x);\n },\n\n // Animatable center y-axis\n cy(y) {\n return this._queueNumber('cy', y);\n },\n\n // Add animatable move\n move(x, y) {\n return this.x(x).y(y);\n },\n\n // Add animatable center\n center(x, y) {\n return this.cx(x).cy(y);\n },\n\n // Add animatable size\n size(width, height) {\n // animate bbox based size for all other elements\n let box;\n\n if (!width || !height) {\n box = this._element.bbox();\n }\n\n if (!width) {\n width = box.width / box.height * height;\n }\n\n if (!height) {\n height = box.height / box.width * width;\n }\n\n return this.width(width).height(height);\n },\n\n // Add animatable width\n width(width) {\n return this._queueNumber('width', width);\n },\n\n // Add animatable height\n height(height) {\n return this._queueNumber('height', height);\n },\n\n // Add animatable plot\n plot(a, b, c, d) {\n // Lines can be plotted with 4 arguments\n if (arguments.length === 4) {\n return this.plot([a, b, c, d]);\n }\n\n if (this._tryRetarget('plot', a)) return this;\n const morpher = new Morphable(this._stepper).type(this._element.MorphArray).to(a);\n this.queue(function () {\n morpher.from(this._element.array());\n }, function (pos) {\n this._element.plot(morpher.at(pos));\n\n return morpher.done();\n });\n\n this._rememberMorpher('plot', morpher);\n\n return this;\n },\n\n // Add leading method\n leading(value) {\n return this._queueNumber('leading', value);\n },\n\n // Add animatable viewbox\n viewbox(x, y, width, height) {\n return this._queueObject('viewbox', new Box(x, y, width, height));\n },\n\n update(o) {\n if (typeof o !== 'object') {\n return this.update({\n offset: arguments[0],\n color: arguments[1],\n opacity: arguments[2]\n });\n }\n\n if (o.opacity != null) this.attr('stop-opacity', o.opacity);\n if (o.color != null) this.attr('stop-color', o.color);\n if (o.offset != null) this.attr('offset', o.offset);\n return this;\n }\n\n});\nextend(Runner, {\n rx,\n ry,\n from,\n to\n});\nregister(Runner, 'Runner');\n\nclass Svg extends Container {\n constructor(node, attrs = node) {\n super(nodeOrNew('svg', node), attrs);\n this.namespace();\n } // Creates and returns defs element\n\n\n defs() {\n if (!this.isRoot()) return this.root().defs();\n return adopt(this.node.querySelector('defs')) || this.put(new Defs());\n }\n\n isRoot() {\n return !this.node.parentNode || !(this.node.parentNode instanceof globals.window.SVGElement) && this.node.parentNode.nodeName !== '#document-fragment';\n } // Add namespaces\n\n\n namespace() {\n if (!this.isRoot()) return this.root().namespace();\n return this.attr({\n xmlns: svg,\n version: '1.1'\n }).attr('xmlns:xlink', xlink, xmlns).attr('xmlns:svgjs', svgjs, xmlns);\n }\n\n removeNamespace() {\n return this.attr({\n xmlns: null,\n version: null\n }).attr('xmlns:xlink', null, xmlns).attr('xmlns:svgjs', null, xmlns);\n } // Check if this is a root svg\n // If not, call root() from this element\n\n\n root() {\n if (this.isRoot()) return this;\n return super.root();\n }\n\n}\nregisterMethods({\n Container: {\n // Create nested svg document\n nested: wrapWithAttrCheck(function () {\n return this.put(new Svg());\n })\n }\n});\nregister(Svg, 'Svg', true);\n\nclass Symbol extends Container {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('symbol', node), attrs);\n }\n\n}\nregisterMethods({\n Container: {\n symbol: wrapWithAttrCheck(function () {\n return this.put(new Symbol());\n })\n }\n});\nregister(Symbol, 'Symbol');\n\nfunction plain(text) {\n // clear if build mode is disabled\n if (this._build === false) {\n this.clear();\n } // create text node\n\n\n this.node.appendChild(globals.document.createTextNode(text));\n return this;\n} // Get length of text element\n\nfunction length() {\n return this.node.getComputedTextLength();\n} // Move over x-axis\n// Text is moved by its bounding box\n// text-anchor does NOT matter\n\nfunction x$1(x, box = this.bbox()) {\n if (x == null) {\n return box.x;\n }\n\n return this.attr('x', this.attr('x') + x - box.x);\n} // Move over y-axis\n\nfunction y$1(y, box = this.bbox()) {\n if (y == null) {\n return box.y;\n }\n\n return this.attr('y', this.attr('y') + y - box.y);\n}\nfunction move$1(x, y, box = this.bbox()) {\n return this.x(x, box).y(y, box);\n} // Move center over x-axis\n\nfunction cx(x, box = this.bbox()) {\n if (x == null) {\n return box.cx;\n }\n\n return this.attr('x', this.attr('x') + x - box.cx);\n} // Move center over y-axis\n\nfunction cy(y, box = this.bbox()) {\n if (y == null) {\n return box.cy;\n }\n\n return this.attr('y', this.attr('y') + y - box.cy);\n}\nfunction center(x, y, box = this.bbox()) {\n return this.cx(x, box).cy(y, box);\n}\nfunction ax(x) {\n return this.attr('x', x);\n}\nfunction ay(y) {\n return this.attr('y', y);\n}\nfunction amove(x, y) {\n return this.ax(x).ay(y);\n} // Enable / disable build mode\n\nfunction build(build) {\n this._build = !!build;\n return this;\n}\n\nvar textable = {\n __proto__: null,\n plain: plain,\n length: length,\n x: x$1,\n y: y$1,\n move: move$1,\n cx: cx,\n cy: cy,\n center: center,\n ax: ax,\n ay: ay,\n amove: amove,\n build: build\n};\n\nclass Text extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('text', node), attrs);\n this.dom.leading = new SVGNumber(1.3); // store leading value for rebuilding\n\n this._rebuild = true; // enable automatic updating of dy values\n\n this._build = false; // disable build mode for adding multiple lines\n } // Set / get leading\n\n\n leading(value) {\n // act as getter\n if (value == null) {\n return this.dom.leading;\n } // act as setter\n\n\n this.dom.leading = new SVGNumber(value);\n return this.rebuild();\n } // Rebuild appearance type\n\n\n rebuild(rebuild) {\n // store new rebuild flag if given\n if (typeof rebuild === 'boolean') {\n this._rebuild = rebuild;\n } // define position of all lines\n\n\n if (this._rebuild) {\n const self = this;\n let blankLineOffset = 0;\n const leading = this.dom.leading;\n this.each(function (i) {\n const fontSize = globals.window.getComputedStyle(this.node).getPropertyValue('font-size');\n const dy = leading * new SVGNumber(fontSize);\n\n if (this.dom.newLined) {\n this.attr('x', self.attr('x'));\n\n if (this.text() === '\\n') {\n blankLineOffset += dy;\n } else {\n this.attr('dy', i ? dy + blankLineOffset : 0);\n blankLineOffset = 0;\n }\n }\n });\n this.fire('rebuild');\n }\n\n return this;\n } // overwrite method from parent to set data properly\n\n\n setData(o) {\n this.dom = o;\n this.dom.leading = new SVGNumber(o.leading || 1.3);\n return this;\n } // Set the text content\n\n\n text(text) {\n // act as getter\n if (text === undefined) {\n const children = this.node.childNodes;\n let firstLine = 0;\n text = '';\n\n for (let i = 0, len = children.length; i < len; ++i) {\n // skip textPaths - they are no lines\n if (children[i].nodeName === 'textPath') {\n if (i === 0) firstLine = 1;\n continue;\n } // add newline if its not the first child and newLined is set to true\n\n\n if (i !== firstLine && children[i].nodeType !== 3 && adopt(children[i]).dom.newLined === true) {\n text += '\\n';\n } // add content of this node\n\n\n text += children[i].textContent;\n }\n\n return text;\n } // remove existing content\n\n\n this.clear().build(true);\n\n if (typeof text === 'function') {\n // call block\n text.call(this, this);\n } else {\n // store text and make sure text is not blank\n text = (text + '').split('\\n'); // build new lines\n\n for (let j = 0, jl = text.length; j < jl; j++) {\n this.newLine(text[j]);\n }\n } // disable build mode and rebuild lines\n\n\n return this.build(false).rebuild();\n }\n\n}\nextend(Text, textable);\nregisterMethods({\n Container: {\n // Create text element\n text: wrapWithAttrCheck(function (text = '') {\n return this.put(new Text()).text(text);\n }),\n // Create plain text element\n plain: wrapWithAttrCheck(function (text = '') {\n return this.put(new Text()).plain(text);\n })\n }\n});\nregister(Text, 'Text');\n\nclass Tspan extends Shape {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('tspan', node), attrs);\n this._build = false; // disable build mode for adding multiple lines\n } // Shortcut dx\n\n\n dx(dx) {\n return this.attr('dx', dx);\n } // Shortcut dy\n\n\n dy(dy) {\n return this.attr('dy', dy);\n } // Create new line\n\n\n newLine() {\n // mark new line\n this.dom.newLined = true; // fetch parent\n\n const text = this.parent(); // early return in case we are not in a text element\n\n if (!(text instanceof Text)) {\n return this;\n }\n\n const i = text.index(this);\n const fontSize = globals.window.getComputedStyle(this.node).getPropertyValue('font-size');\n const dy = text.dom.leading * new SVGNumber(fontSize); // apply new position\n\n return this.dy(i ? dy : 0).attr('x', text.x());\n } // Set text content\n\n\n text(text) {\n if (text == null) return this.node.textContent + (this.dom.newLined ? '\\n' : '');\n\n if (typeof text === 'function') {\n this.clear().build(true);\n text.call(this, this);\n this.build(false);\n } else {\n this.plain(text);\n }\n\n return this;\n }\n\n}\nextend(Tspan, textable);\nregisterMethods({\n Tspan: {\n tspan: wrapWithAttrCheck(function (text = '') {\n const tspan = new Tspan(); // clear if build mode is disabled\n\n if (!this._build) {\n this.clear();\n } // add new tspan\n\n\n return this.put(tspan).text(text);\n })\n },\n Text: {\n newLine: function (text = '') {\n return this.tspan(text).newLine();\n }\n }\n});\nregister(Tspan, 'Tspan');\n\nclass Circle extends Shape {\n constructor(node, attrs = node) {\n super(nodeOrNew('circle', node), attrs);\n }\n\n radius(r) {\n return this.attr('r', r);\n } // Radius x value\n\n\n rx(rx) {\n return this.attr('r', rx);\n } // Alias radius x value\n\n\n ry(ry) {\n return this.rx(ry);\n }\n\n size(size) {\n return this.radius(new SVGNumber(size).divide(2));\n }\n\n}\nextend(Circle, {\n x: x$3,\n y: y$3,\n cx: cx$1,\n cy: cy$1,\n width: width$2,\n height: height$2\n});\nregisterMethods({\n Container: {\n // Create circle element\n circle: wrapWithAttrCheck(function (size = 0) {\n return this.put(new Circle()).size(size).move(0, 0);\n })\n }\n});\nregister(Circle, 'Circle');\n\nclass ClipPath extends Container {\n constructor(node, attrs = node) {\n super(nodeOrNew('clipPath', node), attrs);\n } // Unclip all clipped elements and remove itself\n\n\n remove() {\n // unclip all targets\n this.targets().forEach(function (el) {\n el.unclip();\n }); // remove clipPath from parent\n\n return super.remove();\n }\n\n targets() {\n return baseFind('svg [clip-path*=' + this.id() + ']');\n }\n\n}\nregisterMethods({\n Container: {\n // Create clipping element\n clip: wrapWithAttrCheck(function () {\n return this.defs().put(new ClipPath());\n })\n },\n Element: {\n // Distribute clipPath to svg element\n clipper() {\n return this.reference('clip-path');\n },\n\n clipWith(element) {\n // use given clip or create a new one\n const clipper = element instanceof ClipPath ? element : this.parent().clip().add(element); // apply mask\n\n return this.attr('clip-path', 'url(#' + clipper.id() + ')');\n },\n\n // Unclip element\n unclip() {\n return this.attr('clip-path', null);\n }\n\n }\n});\nregister(ClipPath, 'ClipPath');\n\nclass ForeignObject extends Element {\n constructor(node, attrs = node) {\n super(nodeOrNew('foreignObject', node), attrs);\n }\n\n}\nregisterMethods({\n Container: {\n foreignObject: wrapWithAttrCheck(function (width, height) {\n return this.put(new ForeignObject()).size(width, height);\n })\n }\n});\nregister(ForeignObject, 'ForeignObject');\n\nfunction dmove(dx, dy) {\n this.children().forEach((child, i) => {\n let bbox; // We have to wrap this for elements that dont have a bbox\n // e.g. title and other descriptive elements\n\n try {\n // Get the childs bbox\n bbox = child.bbox();\n } catch (e) {\n return;\n } // Get childs matrix\n\n\n const m = new Matrix(child); // Translate childs matrix by amount and\n // transform it back into parents space\n\n const matrix = m.translate(dx, dy).transform(m.inverse()); // Calculate new x and y from old box\n\n const p = new Point(bbox.x, bbox.y).transform(matrix); // Move element\n\n child.move(p.x, p.y);\n });\n return this;\n}\nfunction dx(dx) {\n return this.dmove(dx, 0);\n}\nfunction dy(dy) {\n return this.dmove(0, dy);\n}\nfunction height(height, box = this.bbox()) {\n if (height == null) return box.height;\n return this.size(box.width, height, box);\n}\nfunction move(x = 0, y = 0, box = this.bbox()) {\n const dx = x - box.x;\n const dy = y - box.y;\n return this.dmove(dx, dy);\n}\nfunction size(width, height, box = this.bbox()) {\n const p = proportionalSize(this, width, height, box);\n const scaleX = p.width / box.width;\n const scaleY = p.height / box.height;\n this.children().forEach((child, i) => {\n const o = new Point(box).transform(new Matrix(child).inverse());\n child.scale(scaleX, scaleY, o.x, o.y);\n });\n return this;\n}\nfunction width(width, box = this.bbox()) {\n if (width == null) return box.width;\n return this.size(width, box.height, box);\n}\nfunction x(x, box = this.bbox()) {\n if (x == null) return box.x;\n return this.move(x, box.y, box);\n}\nfunction y(y, box = this.bbox()) {\n if (y == null) return box.y;\n return this.move(box.x, y, box);\n}\n\nvar containerGeometry = {\n __proto__: null,\n dmove: dmove,\n dx: dx,\n dy: dy,\n height: height,\n move: move,\n size: size,\n width: width,\n x: x,\n y: y\n};\n\nclass G extends Container {\n constructor(node, attrs = node) {\n super(nodeOrNew('g', node), attrs);\n }\n\n}\nextend(G, containerGeometry);\nregisterMethods({\n Container: {\n // Create a group element\n group: wrapWithAttrCheck(function () {\n return this.put(new G());\n })\n }\n});\nregister(G, 'G');\n\nclass A extends Container {\n constructor(node, attrs = node) {\n super(nodeOrNew('a', node), attrs);\n } // Link target attribute\n\n\n target(target) {\n return this.attr('target', target);\n } // Link url\n\n\n to(url) {\n return this.attr('href', url, xlink);\n }\n\n}\nextend(A, containerGeometry);\nregisterMethods({\n Container: {\n // Create a hyperlink element\n link: wrapWithAttrCheck(function (url) {\n return this.put(new A()).to(url);\n })\n },\n Element: {\n unlink() {\n const link = this.linker();\n if (!link) return this;\n const parent = link.parent();\n\n if (!parent) {\n return this.remove();\n }\n\n const index = parent.index(link);\n parent.add(this, index);\n link.remove();\n return this;\n },\n\n linkTo(url) {\n // reuse old link if possible\n let link = this.linker();\n\n if (!link) {\n link = new A();\n this.wrap(link);\n }\n\n if (typeof url === 'function') {\n url.call(link, link);\n } else {\n link.to(url);\n }\n\n return this;\n },\n\n linker() {\n const link = this.parent();\n\n if (link && link.node.nodeName.toLowerCase() === 'a') {\n return link;\n }\n\n return null;\n }\n\n }\n});\nregister(A, 'A');\n\nclass Mask extends Container {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('mask', node), attrs);\n } // Unmask all masked elements and remove itself\n\n\n remove() {\n // unmask all targets\n this.targets().forEach(function (el) {\n el.unmask();\n }); // remove mask from parent\n\n return super.remove();\n }\n\n targets() {\n return baseFind('svg [mask*=' + this.id() + ']');\n }\n\n}\nregisterMethods({\n Container: {\n mask: wrapWithAttrCheck(function () {\n return this.defs().put(new Mask());\n })\n },\n Element: {\n // Distribute mask to svg element\n masker() {\n return this.reference('mask');\n },\n\n maskWith(element) {\n // use given mask or create a new one\n const masker = element instanceof Mask ? element : this.parent().mask().add(element); // apply mask\n\n return this.attr('mask', 'url(#' + masker.id() + ')');\n },\n\n // Unmask element\n unmask() {\n return this.attr('mask', null);\n }\n\n }\n});\nregister(Mask, 'Mask');\n\nclass Stop extends Element {\n constructor(node, attrs = node) {\n super(nodeOrNew('stop', node), attrs);\n } // add color stops\n\n\n update(o) {\n if (typeof o === 'number' || o instanceof SVGNumber) {\n o = {\n offset: arguments[0],\n color: arguments[1],\n opacity: arguments[2]\n };\n } // set attributes\n\n\n if (o.opacity != null) this.attr('stop-opacity', o.opacity);\n if (o.color != null) this.attr('stop-color', o.color);\n if (o.offset != null) this.attr('offset', new SVGNumber(o.offset));\n return this;\n }\n\n}\nregisterMethods({\n Gradient: {\n // Add a color stop\n stop: function (offset, color, opacity) {\n return this.put(new Stop()).update(offset, color, opacity);\n }\n }\n});\nregister(Stop, 'Stop');\n\nfunction cssRule(selector, rule) {\n if (!selector) return '';\n if (!rule) return selector;\n let ret = selector + '{';\n\n for (const i in rule) {\n ret += unCamelCase(i) + ':' + rule[i] + ';';\n }\n\n ret += '}';\n return ret;\n}\n\nclass Style extends Element {\n constructor(node, attrs = node) {\n super(nodeOrNew('style', node), attrs);\n }\n\n addText(w = '') {\n this.node.textContent += w;\n return this;\n }\n\n font(name, src, params = {}) {\n return this.rule('@font-face', {\n fontFamily: name,\n src: src,\n ...params\n });\n }\n\n rule(selector, obj) {\n return this.addText(cssRule(selector, obj));\n }\n\n}\nregisterMethods('Dom', {\n style(selector, obj) {\n return this.put(new Style()).rule(selector, obj);\n },\n\n fontface(name, src, params) {\n return this.put(new Style()).font(name, src, params);\n }\n\n});\nregister(Style, 'Style');\n\nclass TextPath extends Text {\n // Initialize node\n constructor(node, attrs = node) {\n super(nodeOrNew('textPath', node), attrs);\n } // return the array of the path track element\n\n\n array() {\n const track = this.track();\n return track ? track.array() : null;\n } // Plot path if any\n\n\n plot(d) {\n const track = this.track();\n let pathArray = null;\n\n if (track) {\n pathArray = track.plot(d);\n }\n\n return d == null ? pathArray : this;\n } // Get the path element\n\n\n track() {\n return this.reference('href');\n }\n\n}\nregisterMethods({\n Container: {\n textPath: wrapWithAttrCheck(function (text, path) {\n // Convert text to instance if needed\n if (!(text instanceof Text)) {\n text = this.text(text);\n }\n\n return text.path(path);\n })\n },\n Text: {\n // Create path for text to run on\n path: wrapWithAttrCheck(function (track, importNodes = true) {\n const textPath = new TextPath(); // if track is a path, reuse it\n\n if (!(track instanceof Path)) {\n // create path element\n track = this.defs().path(track);\n } // link textPath to path and add content\n\n\n textPath.attr('href', '#' + track, xlink); // Transplant all nodes from text to textPath\n\n let node;\n\n if (importNodes) {\n while (node = this.node.firstChild) {\n textPath.node.appendChild(node);\n }\n } // add textPath element as child node and return textPath\n\n\n return this.put(textPath);\n }),\n\n // Get the textPath children\n textPath() {\n return this.findOne('textPath');\n }\n\n },\n Path: {\n // creates a textPath from this path\n text: wrapWithAttrCheck(function (text) {\n // Convert text to instance if needed\n if (!(text instanceof Text)) {\n text = new Text().addTo(this.parent()).text(text);\n } // Create textPath from text and path and return\n\n\n return text.path(this);\n }),\n\n targets() {\n return baseFind('svg textPath').filter(node => {\n return (node.attr('href') || '').includes(this.id());\n }); // Does not work in IE11. Use when IE support is dropped\n // return baseFind('svg textPath[*|href*=' + this.id() + ']')\n }\n\n }\n});\nTextPath.prototype.MorphArray = PathArray;\nregister(TextPath, 'TextPath');\n\nclass Use extends Shape {\n constructor(node, attrs = node) {\n super(nodeOrNew('use', node), attrs);\n } // Use element as a reference\n\n\n use(element, file) {\n // Set lined element\n return this.attr('href', (file || '') + '#' + element, xlink);\n }\n\n}\nregisterMethods({\n Container: {\n // Create a use element\n use: wrapWithAttrCheck(function (element, file) {\n return this.put(new Use()).use(element, file);\n })\n }\n});\nregister(Use, 'Use');\n\n/* Optional Modules */\nconst SVG = makeInstance;\nextend([Svg, Symbol, Image, Pattern, Marker], getMethodsFor('viewbox'));\nextend([Line, Polyline, Polygon, Path], getMethodsFor('marker'));\nextend(Text, getMethodsFor('Text'));\nextend(Path, getMethodsFor('Path'));\nextend(Defs, getMethodsFor('Defs'));\nextend([Text, Tspan], getMethodsFor('Tspan'));\nextend([Rect, Ellipse, Gradient, Runner], getMethodsFor('radius'));\nextend(EventTarget, getMethodsFor('EventTarget'));\nextend(Dom, getMethodsFor('Dom'));\nextend(Element, getMethodsFor('Element'));\nextend(Shape, getMethodsFor('Shape'));\nextend([Container, Fragment], getMethodsFor('Container'));\nextend(Gradient, getMethodsFor('Gradient'));\nextend(Runner, getMethodsFor('Runner'));\nList.extend(getMethodNames());\nregisterMorphableType([SVGNumber, Color, Box, Matrix, SVGArray, PointArray, PathArray, Point]);\nmakeMorphable();\n\n\n//# sourceMappingURL=svg.esm.js.map\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/@svgdotjs/svg.js/dist/svg.esm.js?",
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
/***/
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
/***/ './node_modules/@svgdotjs/svg.panzoom.js/dist/svg.panzoom.esm.js':
|
|
37
|
-
/*!***********************************************************************!*\
|
|
38
|
-
!*** ./node_modules/@svgdotjs/svg.panzoom.js/dist/svg.panzoom.esm.js ***!
|
|
39
|
-
\***********************************************************************/
|
|
40
|
-
/***/ (
|
|
41
|
-
__unused_webpack_module,
|
|
42
|
-
__webpack_exports__,
|
|
43
|
-
__webpack_require__,
|
|
44
|
-
) => {
|
|
45
|
-
eval(
|
|
46
|
-
"__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @svgdotjs/svg.js */ \"./node_modules/@svgdotjs/svg.js/dist/svg.esm.js\");\n/*!\n* @svgdotjs/svg.panzoom.js - A plugin for svg.js that enables panzoom for viewport elements\n* @version 2.1.2\n* https://github.com/svgdotjs/svg.panzoom.js#readme\n*\n* @copyright undefined\n* @license MIT\n*\n* BUILT: Thu Jul 22 2021 14:51:35 GMT+0200 (Mitteleuropäische Sommerzeit)\n*/;\n\n\nvar normalizeEvent = function normalizeEvent(ev) {\n return ev.touches || [{\n clientX: ev.clientX,\n clientY: ev.clientY\n }];\n};\n\n(0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.extend)(_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.Svg, {\n panZoom: function panZoom(options) {\n var _options,\n _options$zoomFactor,\n _options$zoomMin,\n _options$zoomMax,\n _options$wheelZoom,\n _options$pinchZoom,\n _options$panning,\n _options$panButton,\n _options$oneFingerPan,\n _options$margins,\n _options$wheelZoomDel,\n _options$wheelZoomDel2,\n _this = this;\n\n this.off('.panZoom'); // when called with false, disable panZoom\n\n if (options === false) return this;\n options = (_options = options) != null ? _options : {};\n var zoomFactor = (_options$zoomFactor = options.zoomFactor) != null ? _options$zoomFactor : 2;\n var zoomMin = (_options$zoomMin = options.zoomMin) != null ? _options$zoomMin : Number.MIN_VALUE;\n var zoomMax = (_options$zoomMax = options.zoomMax) != null ? _options$zoomMax : Number.MAX_VALUE;\n var doWheelZoom = (_options$wheelZoom = options.wheelZoom) != null ? _options$wheelZoom : true;\n var doPinchZoom = (_options$pinchZoom = options.pinchZoom) != null ? _options$pinchZoom : true;\n var doPanning = (_options$panning = options.panning) != null ? _options$panning : true;\n var panButton = (_options$panButton = options.panButton) != null ? _options$panButton : 0;\n var oneFingerPan = (_options$oneFingerPan = options.oneFingerPan) != null ? _options$oneFingerPan : false;\n var margins = (_options$margins = options.margins) != null ? _options$margins : false;\n var wheelZoomDeltaModeLinePixels = (_options$wheelZoomDel = options.wheelZoomDeltaModeLinePixels) != null ? _options$wheelZoomDel : 17;\n var wheelZoomDeltaModeScreenPixels = (_options$wheelZoomDel2 = options.wheelZoomDeltaModeScreenPixels) != null ? _options$wheelZoomDel2 : 53;\n var lastP;\n var lastTouches;\n var zoomInProgress = false;\n var viewbox = this.viewbox();\n\n var restrictToMargins = function restrictToMargins(box) {\n if (!margins) return box;\n var top = margins.top,\n left = margins.left,\n bottom = margins.bottom,\n right = margins.right;\n\n var _this$attr = _this.attr(['width', 'height']),\n width = _this$attr.width,\n height = _this$attr.height;\n\n var preserveAspectRatio = _this.node.preserveAspectRatio.baseVal; // The current viewport (exactly what is shown on the screen, what we ultimately want to restrict)\n // is not always exactly the same as current viewbox. They are different when the viewbox aspectRatio and the svg aspectRatio\n // are different and preserveAspectRatio is not \"none\". These offsets represent the difference in user coordinates\n // between the side of the viewbox and the side of the viewport.\n\n var viewportLeftOffset = 0;\n var viewportRightOffset = 0;\n var viewportTopOffset = 0;\n var viewportBottomOffset = 0; // preserveAspectRatio none has no offsets\n\n if (preserveAspectRatio.align !== preserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE) {\n var svgAspectRatio = width / height;\n var viewboxAspectRatio = viewbox.width / viewbox.height; // when aspectRatios are the same, there are no offsets\n\n if (viewboxAspectRatio !== svgAspectRatio) {\n // aspectRatio unknown is like meet because that's the default\n var isMeet = preserveAspectRatio.meetOrSlice !== preserveAspectRatio.SVG_MEETORSLICE_SLICE;\n var changedAxis = svgAspectRatio > viewboxAspectRatio ? 'width' : 'height';\n var isWidth = changedAxis === 'width';\n var changeHorizontal = isMeet && isWidth || !isMeet && !isWidth;\n var ratio = changeHorizontal ? svgAspectRatio / viewboxAspectRatio : viewboxAspectRatio / svgAspectRatio;\n var offset = box[changedAxis] - box[changedAxis] * ratio;\n\n if (changeHorizontal) {\n if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX) {\n viewportLeftOffset = offset / 2;\n viewportRightOffset = -offset / 2;\n } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX) {\n viewportRightOffset = -offset;\n } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX) {\n viewportLeftOffset = offset;\n }\n } else {\n if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID) {\n viewportTopOffset = offset / 2;\n viewportBottomOffset = -offset / 2;\n } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN) {\n viewportBottomOffset = -offset;\n } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX) {\n viewportTopOffset = offset;\n }\n }\n }\n } // when box.x == leftLimit, the image is panned to the left,\n // i.e the current box is to the right of the initial viewbox,\n // and only the right part of the initial image is visible, i.e.\n // the right side of the initial viewbox minus left margin (viewbox.x+viewbox.width-left)\n // is aligned with the left side of the viewport (box.x + viewportLeftOffset):\n // viewbox.width + viewbox.x - left = box.x + viewportLeftOffset\n // viewbox.width + viewbox.x - left - viewportLeftOffset = box.x (= leftLimit)\n\n\n var leftLimit = viewbox.width + viewbox.x - left - viewportLeftOffset; // when box.x == rightLimit, the image is panned to the right,\n // i.e the current box is to the left of the initial viewbox\n // and only the left part of the initial image is visible, i.e\n // the left side of the initial viewbox plus right margin (viewbox.x + right)\n // is aligned with the right side of the viewport (box.x + box.width + viewportRightOffset)\n // viewbox.x + right = box.x + box.width + viewportRightOffset\n // viewbox.x + right - box.width - viewportRightOffset = box.x (= rightLimit)\n\n var rightLimit = viewbox.x + right - box.width - viewportRightOffset; // same with top and bottom\n\n var topLimit = viewbox.height + viewbox.y - top - viewportTopOffset;\n var bottomLimit = viewbox.y + bottom - box.height - viewportBottomOffset;\n box.x = Math.min(leftLimit, Math.max(rightLimit, box.x)); // enforce rightLimit <= box.x <= leftLimit\n\n box.y = Math.min(topLimit, Math.max(bottomLimit, box.y)); // enforce bottomLimit <= box.y <= topLimit\n\n return box;\n };\n\n var wheelZoom = function wheelZoom(ev) {\n ev.preventDefault(); // When wheeling on a mouse,\n // - chrome by default uses deltaY = 53, deltaMode = 0 (pixel)\n // - firefox by default uses deltaY = 3, deltaMode = 1 (line)\n // - chrome and firefox on windows after configuring \"One screen at a time\"\n // use deltaY = 1, deltaMode = 2 (screen)\n //\n // Note that when when wheeling on a touchpad, deltaY depends on how fast\n // you swipe, but the deltaMode is still different between the browsers.\n //\n // Normalize everything so that zooming speed is approximately the same in all cases\n\n var normalizedPixelDeltaY;\n\n switch (ev.deltaMode) {\n case 1:\n normalizedPixelDeltaY = ev.deltaY * wheelZoomDeltaModeLinePixels;\n break;\n\n case 2:\n normalizedPixelDeltaY = ev.deltaY * wheelZoomDeltaModeScreenPixels;\n break;\n\n default:\n // 0 (already pixels) or new mode (avoid crashing)\n normalizedPixelDeltaY = ev.deltaY;\n break;\n }\n\n var lvl = Math.pow(1 + zoomFactor, -1 * normalizedPixelDeltaY / 100) * this.zoom();\n var p = this.point(ev.clientX, ev.clientY);\n\n if (lvl > zoomMax) {\n lvl = zoomMax;\n }\n\n if (lvl < zoomMin) {\n lvl = zoomMin;\n }\n\n if (this.dispatch('zoom', {\n level: lvl,\n focus: p\n }).defaultPrevented) {\n return this;\n }\n\n this.zoom(lvl, p);\n\n if (margins) {\n var box = restrictToMargins(this.viewbox());\n this.viewbox(box);\n }\n };\n\n var pinchZoomStart = function pinchZoomStart(ev) {\n lastTouches = normalizeEvent(ev); // Start panning in case only one touch is found\n\n if (lastTouches.length < 2) {\n if (doPanning && oneFingerPan) {\n panStart.call(this, ev);\n }\n\n return;\n } // Stop panning for more than one touch\n\n\n if (doPanning && oneFingerPan) {\n panStop.call(this, ev);\n } // We call it so late, so the user is still able to scroll / reload the page via gesture\n // In case oneFingerPan is not active\n\n\n ev.preventDefault();\n\n if (this.dispatch('pinchZoomStart', {\n event: ev\n }).defaultPrevented) {\n return;\n }\n\n this.off('touchstart.panZoom', pinchZoomStart);\n zoomInProgress = true;\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.on)(document, 'touchmove.panZoom', pinchZoom, this, {\n passive: false\n });\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.on)(document, 'touchend.panZoom', pinchZoomStop, this, {\n passive: false\n });\n };\n\n var pinchZoomStop = function pinchZoomStop(ev) {\n ev.preventDefault();\n var currentTouches = normalizeEvent(ev);\n\n if (currentTouches.length > 1) {\n return;\n }\n\n zoomInProgress = false;\n this.dispatch('pinchZoomEnd', {\n event: ev\n });\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.off)(document, 'touchmove.panZoom', pinchZoom);\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.off)(document, 'touchend.panZoom', pinchZoomStop);\n this.on('touchstart.panZoom', pinchZoomStart);\n\n if (currentTouches.length && doPanning && oneFingerPan) {\n panStart.call(this, ev);\n }\n };\n\n var pinchZoom = function pinchZoom(ev) {\n ev.preventDefault();\n var currentTouches = normalizeEvent(ev);\n var zoom = this.zoom(); // Distance Formula\n\n var lastDelta = Math.sqrt(Math.pow(lastTouches[0].clientX - lastTouches[1].clientX, 2) + Math.pow(lastTouches[0].clientY - lastTouches[1].clientY, 2));\n var currentDelta = Math.sqrt(Math.pow(currentTouches[0].clientX - currentTouches[1].clientX, 2) + Math.pow(currentTouches[0].clientY - currentTouches[1].clientY, 2));\n var zoomAmount = lastDelta / currentDelta;\n\n if (zoom < zoomMin && zoomAmount > 1 || zoom > zoomMax && zoomAmount < 1) {\n zoomAmount = 1;\n }\n\n var currentFocus = {\n x: currentTouches[0].clientX + 0.5 * (currentTouches[1].clientX - currentTouches[0].clientX),\n y: currentTouches[0].clientY + 0.5 * (currentTouches[1].clientY - currentTouches[0].clientY)\n };\n var lastFocus = {\n x: lastTouches[0].clientX + 0.5 * (lastTouches[1].clientX - lastTouches[0].clientX),\n y: lastTouches[0].clientY + 0.5 * (lastTouches[1].clientY - lastTouches[0].clientY)\n };\n var p = this.point(currentFocus.x, currentFocus.y);\n var focusP = this.point(2 * currentFocus.x - lastFocus.x, 2 * currentFocus.y - lastFocus.y);\n var box = new _svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.Box(this.viewbox()).transform(new _svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.Matrix().translate(-focusP.x, -focusP.y).scale(zoomAmount, 0, 0).translate(p.x, p.y));\n restrictToMargins(box);\n this.viewbox(box);\n lastTouches = currentTouches;\n this.dispatch('zoom', {\n box: box,\n focus: focusP\n });\n };\n\n var panStart = function panStart(ev) {\n var isMouse = ev.type.indexOf('mouse') > -1; // In case panStart is called with touch, ev.button is undefined\n\n if (isMouse && ev.button !== panButton && ev.which !== panButton + 1) {\n return;\n }\n\n ev.preventDefault();\n this.off('mousedown.panZoom', panStart);\n lastTouches = normalizeEvent(ev);\n if (zoomInProgress) return;\n this.dispatch('panStart', {\n event: ev\n });\n lastP = {\n x: lastTouches[0].clientX,\n y: lastTouches[0].clientY\n };\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.on)(document, 'touchmove.panZoom mousemove.panZoom', panning, this, {\n passive: false\n });\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.on)(document, 'touchend.panZoom mouseup.panZoom', panStop, this, {\n passive: false\n });\n };\n\n var panStop = function panStop(ev) {\n ev.preventDefault();\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.off)(document, 'touchmove.panZoom mousemove.panZoom', panning);\n (0,_svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.off)(document, 'touchend.panZoom mouseup.panZoom', panStop);\n this.on('mousedown.panZoom', panStart);\n this.dispatch('panEnd', {\n event: ev\n });\n };\n\n var panning = function panning(ev) {\n ev.preventDefault();\n var currentTouches = normalizeEvent(ev);\n var currentP = {\n x: currentTouches[0].clientX,\n y: currentTouches[0].clientY\n };\n var p1 = this.point(currentP.x, currentP.y);\n var p2 = this.point(lastP.x, lastP.y);\n var deltaP = [p2.x - p1.x, p2.y - p1.y];\n\n if (!deltaP[0] && !deltaP[1]) {\n return;\n }\n\n var box = new _svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.Box(this.viewbox()).transform(new _svgdotjs_svg_js__WEBPACK_IMPORTED_MODULE_0__.Matrix().translate(deltaP[0], deltaP[1]));\n lastP = currentP;\n restrictToMargins(box);\n\n if (this.dispatch('panning', {\n box: box,\n event: ev\n }).defaultPrevented) {\n return;\n }\n\n this.viewbox(box);\n };\n\n if (doWheelZoom) {\n this.on('wheel.panZoom', wheelZoom, this, {\n passive: false\n });\n }\n\n if (doPinchZoom) {\n this.on('touchstart.panZoom', pinchZoomStart, this, {\n passive: false\n });\n }\n\n if (doPanning) {\n this.on('mousedown.panZoom', panStart, this, {\n passive: false\n });\n }\n\n return this;\n }\n});\n//# sourceMappingURL=svg.panzoom.esm.js.map\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/@svgdotjs/svg.panzoom.js/dist/svg.panzoom.esm.js?",
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
/***/
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
/***/ './src/ApexTree.ts':
|
|
53
|
-
/*!*************************!*\
|
|
54
|
-
!*** ./src/ApexTree.ts ***!
|
|
55
|
-
\*************************/
|
|
56
|
-
/***/ (__unused_webpack_module, exports, __webpack_require__) => {
|
|
57
|
-
eval(
|
|
58
|
-
"\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.ApexTree = void 0;\nconst models_1 = __webpack_require__(/*! src/models */ \"./src/models/index.ts\");\nconst Options_1 = __webpack_require__(/*! ./settings/Options */ \"./src/settings/Options.ts\");\nclass ApexTree {\n constructor(element, options) {\n this.element = element;\n this.options = Object.assign(Object.assign({}, Options_1.DefaultOptions), options);\n const treeWrapper = document.createElement('div');\n treeWrapper.id = 'apexTreeWrapper';\n treeWrapper.style.position = 'relative';\n this.graph = new models_1.Graph(treeWrapper, this.options);\n this.element.append(treeWrapper);\n }\n render(data) {\n if (!this.element) {\n throw new Error('Element not found');\n }\n this.graph.construct(data);\n this.graph.render();\n if (this.options.enableToolbar) {\n const toolbar = new models_1.Toolbar(document.getElementById('apexTreeWrapper'), this.graph);\n toolbar.render();\n }\n return this.graph;\n }\n}\nexports.ApexTree = ApexTree;\n\n//# sourceURL=webpack://ApexTree/./src/ApexTree.ts?",
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
/***/
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
/***/ './src/models/Export.ts':
|
|
65
|
-
/*!******************************!*\
|
|
66
|
-
!*** ./src/models/Export.ts ***!
|
|
67
|
-
\******************************/
|
|
68
|
-
/***/ (__unused_webpack_module, exports) => {
|
|
69
|
-
eval(
|
|
70
|
-
"\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.Export = void 0;\nclass Export {\n constructor(graph) {\n this.graph = graph;\n }\n getSvgString() {\n const svgString = this.graph.canvas.svg();\n //due to SVG.js bug it retuns unclosed img, br and hr tags, so we explicitely closed it.\n return svgString.replace(/(<img [\\w\\W]+?)(>)/g, '$1 />').replace(/(<br)(>)/g, '$1 />').replace(/(<hr)(>)/g, '$1 />');\n }\n svgUrl() {\n const svgData = this.getSvgString();\n const svgBlob = new Blob([svgData], {\n type: 'image/svg+xml;charset=utf-8'\n });\n return URL.createObjectURL(svgBlob);\n }\n triggerDownload(href, filename) {\n const downloadLink = document.createElement('a');\n downloadLink.href = href;\n downloadLink.download = filename;\n document.body.appendChild(downloadLink);\n downloadLink.click();\n document.body.removeChild(downloadLink);\n }\n exportToSVG() {\n this.triggerDownload(this.svgUrl(), `apex-tree-${new Date().getTime()}.svg`);\n }\n}\nexports.Export = Export;\n\n//# sourceURL=webpack://ApexTree/./src/models/Export.ts?",
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
/***/
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
/***/ './src/models/Graph.ts':
|
|
77
|
-
/*!*****************************!*\
|
|
78
|
-
!*** ./src/models/Graph.ts ***!
|
|
79
|
-
\*****************************/
|
|
80
|
-
/***/ function (__unused_webpack_module, exports, __webpack_require__) {
|
|
81
|
-
eval(
|
|
82
|
-
"\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.Graph = void 0;\nconst d3_flextree_1 = __webpack_require__(/*! d3-flextree */ \"./node_modules/d3-flextree/index.js\");\nconst utils_1 = __webpack_require__(/*! src/utils */ \"./src/utils/index.ts\");\nconst utils_2 = __webpack_require__(/*! src/utils */ \"./src/utils/index.ts\");\nconst Paper_1 = __webpack_require__(/*! src/models/Paper */ \"./src/models/Paper.ts\");\nconst DirectionConfig_1 = __webpack_require__(/*! src/settings/DirectionConfig */ \"./src/settings/DirectionConfig.ts\");\nconst add_circle_svg_1 = __importDefault(__webpack_require__(/*! src/icons/add-circle.svg */ \"./src/icons/add-circle.svg\"));\nconst minus_circle_svg_1 = __importDefault(__webpack_require__(/*! src/icons/minus-circle.svg */ \"./src/icons/minus-circle.svg\"));\nclass Graph extends Paper_1.Paper {\n constructor(element, options) {\n super(element, options.width, options.height, options.canvasStyle);\n this.element = element;\n this.options = options;\n }\n construct(data) {\n const {\n nodeWidth,\n nodeHeight,\n siblingSpacing,\n childrenSpacing\n } = this.options;\n const flexLayout = (0, d3_flextree_1.flextree)({\n nodeSize: () => {\n return DirectionConfig_1.DirectionConfig[this.options.direction].nodeFlexSize({\n nodeWidth,\n nodeHeight,\n siblingSpacing,\n childrenSpacing\n });\n },\n spacing: 0\n });\n const tree = flexLayout.hierarchy(data);\n this.rootNode = flexLayout(tree);\n }\n renderNode(node, mainGroup) {\n var _a;\n const options = this.options;\n const {\n nodeWidth,\n nodeHeight,\n nodeTemplate,\n highlightOnHover,\n borderRadius,\n enableTooltip,\n tooltipTemplate,\n enableExpandCollapse\n } = options;\n const {\n tooltipId,\n tooltipMaxWidth,\n tooltipBGColor,\n tooltipBorderColor,\n fontSize,\n fontWeight,\n fontFamily,\n fontColor,\n borderWidth,\n borderStyle,\n borderColor,\n nodeBGColor,\n nodeStyle,\n nodeClassName\n } = Object.assign(Object.assign({}, options), node.data.options);\n const {\n x,\n y\n } = DirectionConfig_1.DirectionConfig[options.direction].swap(node);\n const graphInstance = this;\n const group = Paper_1.Paper.drawGroup(x, y, node.data.id, (_a = node.parent) === null || _a === void 0 ? void 0 : _a.data.id);\n const nodeContent = nodeTemplate(node.data[options.contentKey]);\n const object = Paper_1.Paper.drawTemplate(nodeContent, {\n nodeWidth,\n nodeHeight\n });\n const groupStyle = (0, utils_2.generateStyles)({\n fontSize,\n fontWeight,\n fontFamily,\n fontColor\n });\n const containerStyles = (0, utils_2.generateStyles)({\n borderColor,\n borderStyle,\n borderWidth: `${borderWidth}px`,\n borderRadius,\n backgroundColor: nodeBGColor,\n height: '100%',\n boxSizing: 'border-box'\n });\n object.first().attr('style', containerStyles.concat(nodeStyle));\n object.attr('class', nodeClassName);\n group.attr('style', groupStyle);\n group.add(object);\n const nodes = this.rootNode.nodes;\n if (highlightOnHover) {\n group.on('mouseover', function () {\n const self = this.node.dataset.self;\n const selfNode = nodes.find(n => n.data.id === self);\n selfNode && (0, utils_2.highlightToPath)(nodes, selfNode, true, options);\n });\n group.on('mouseout', function () {\n const self = this.node.dataset.self;\n const selfNode = nodes.find(n => n.data.id === self);\n selfNode && (0, utils_2.highlightToPath)(nodes, selfNode, false, options);\n });\n }\n if (enableTooltip) {\n const tooltipContent = tooltipTemplate ? tooltipTemplate(node.data[this.options.contentKey]) : nodeContent;\n group.on('mousemove', function (e) {\n const styles = (0, utils_2.getTooltipStyles)(e.pageX, e.pageY, tooltipMaxWidth, tooltipBorderColor, tooltipBGColor, !tooltipTemplate);\n (0, utils_2.updateTooltip)(tooltipId, styles.join(' '), tooltipContent);\n });\n group.on('mouseout', function (e) {\n if (e.relatedTarget.tagName === 'svg') {\n (0, utils_2.updateTooltip)(tooltipId);\n }\n });\n }\n mainGroup.add(group);\n if (!node.children && !node.hiddenChildren) {\n return;\n }\n if (enableExpandCollapse) {\n //add expand/collapse buttons\n const expandButtonRadius = utils_1.ExpandCollapseButtonSize / 2;\n const buttonGroup = Paper_1.Paper.drawGroup(x + nodeWidth / 2 - expandButtonRadius, y + nodeHeight - expandButtonRadius, node.data.id);\n const buttonClickArea = Paper_1.Paper.drawCircle({\n cx: expandButtonRadius,\n cy: expandButtonRadius,\n r: expandButtonRadius,\n style: 'fill: #FFF; cursor: pointer;'\n });\n buttonGroup.data('expanded', false);\n buttonGroup.add(buttonClickArea);\n if (node.hiddenChildren) {\n buttonGroup.add(add_circle_svg_1.default);\n } else {\n buttonGroup.add(minus_circle_svg_1.default);\n }\n buttonGroup.on('click', function () {\n if (node.hiddenChildren) {\n graphInstance.expand(this.node.dataset.self);\n } else {\n graphInstance.collapse(this.node.dataset.self);\n }\n });\n mainGroup.add(buttonGroup);\n }\n }\n renderEdge(node, group) {\n var _a;\n const {\n nodeWidth,\n nodeHeight\n } = this.options;\n const edge = (0, utils_1.getEdge)(node, nodeWidth, nodeHeight, this.options.direction);\n if (!edge) return;\n const path = Paper_1.Paper.drawPath(edge, {\n id: `${node.data.id}-${(_a = node.parent) === null || _a === void 0 ? void 0 : _a.data.id}`\n });\n node.edge = path;\n group.add(path);\n }\n collapse(nodeId) {\n const nodes = this.rootNode.descendants();\n const node = nodes.find(n => n.data.id === nodeId);\n if (node === null || node === void 0 ? void 0 : node.children) {\n node.hiddenChildren = node.children;\n node.hiddenChildren.forEach(child => this.collapse(child));\n node.children = undefined;\n this.render({\n keepOldPosition: true\n });\n }\n }\n expand(nodeId) {\n const nodes = this.rootNode.descendants();\n const node = nodes.find(n => n.data.id === nodeId);\n if (node === null || node === void 0 ? void 0 : node.hiddenChildren) {\n node.children = node.hiddenChildren;\n node.children.forEach(child => this.expand(child));\n node.hiddenChildren = undefined;\n this.render({\n keepOldPosition: true\n });\n }\n }\n changeLayout() {\n let direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'top';\n this.options = Object.assign(Object.assign({}, this.options), {\n direction\n });\n this.render({\n keepOldPosition: false\n });\n }\n fitScreen() {\n const {\n childrenSpacing,\n siblingSpacing\n } = this.options;\n const {\n viewBoxDimensions\n } = DirectionConfig_1.DirectionConfig[this.options.direction];\n const {\n x,\n y,\n width: vWidth,\n height: vHeight\n } = viewBoxDimensions({\n rootNode: this.rootNode,\n childrenSpacing,\n siblingSpacing\n });\n this.updateViewBox(x, y, vWidth, vHeight);\n }\n render() {\n let {\n keepOldPosition = false\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const oldViewbox = this.canvas.viewbox();\n this.clear();\n const {\n containerClassName,\n enableTooltip,\n tooltipId,\n fontSize,\n fontWeight,\n fontFamily,\n fontColor\n } = this.options;\n const globalStyle = (0, utils_2.generateStyles)({\n fontSize,\n fontWeight,\n fontFamily,\n fontColor\n });\n const mainGroup = Paper_1.Paper.drawGroup(0, 0, containerClassName);\n mainGroup.attr('style', globalStyle);\n mainGroup.id(containerClassName);\n const nodes = this.rootNode.nodes;\n //drawing edges first is neccessary to prevent overlap with nodes\n nodes.forEach(node => {\n this.renderEdge(node, mainGroup);\n });\n nodes.forEach(node => {\n this.renderNode(node, mainGroup);\n });\n this.add(mainGroup);\n this.fitScreen();\n if (keepOldPosition) {\n this.updateViewBox(oldViewbox.x, oldViewbox.y, oldViewbox.width, oldViewbox.height);\n }\n if (enableTooltip) {\n const tooltipElement = (0, utils_2.getTooltip)(tooltipId);\n const body = document.body || document.getElementsByTagName('body')[0];\n body.append(tooltipElement);\n }\n }\n}\nexports.Graph = Graph;\n\n//# sourceURL=webpack://ApexTree/./src/models/Graph.ts?",
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
/***/
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
/***/ './src/models/Paper.ts':
|
|
89
|
-
/*!*****************************!*\
|
|
90
|
-
!*** ./src/models/Paper.ts ***!
|
|
91
|
-
\*****************************/
|
|
92
|
-
/***/ (__unused_webpack_module, exports, __webpack_require__) => {
|
|
93
|
-
eval(
|
|
94
|
-
"\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.Paper = void 0;\nconst svg_js_1 = __webpack_require__(/*! @svgdotjs/svg.js */ \"./node_modules/@svgdotjs/svg.js/dist/svg.esm.js\");\nconst svg_js_2 = __webpack_require__(/*! @svgdotjs/svg.js */ \"./node_modules/@svgdotjs/svg.js/dist/svg.esm.js\");\n__webpack_require__(/*! @svgdotjs/svg.panzoom.js */ \"./node_modules/@svgdotjs/svg.panzoom.js/dist/svg.panzoom.esm.js\");\nconst Options_1 = __webpack_require__(/*! src/settings/Options */ \"./src/settings/Options.ts\");\nclass Paper {\n constructor(element, width, height, canvasStyle) {\n this.width = width;\n this.height = height;\n this.canvas = (0, svg_js_2.SVG)().addTo(element).size(width, height).viewbox(`0 0 ${width} ${height}`).panZoom({\n zoomFactor: 0.2,\n zoomMin: 0.1\n }).attr({\n style: canvasStyle\n });\n }\n add(element) {\n this.canvas.add(element);\n }\n resetViewBox() {\n this.canvas.viewbox(`0 0 ${this.width} ${this.height}`);\n }\n updateViewBox(x, y, width, height) {\n this.canvas.viewbox(`${x} ${y} ${width} ${height}`);\n }\n zoom(zoomFactor) {\n const newZoomVal = this.canvas.zoom() + zoomFactor;\n if (newZoomVal >= 0.1) {\n this.canvas.zoom(newZoomVal);\n }\n }\n get(selector) {\n return this.canvas.findOne(selector);\n }\n clear() {\n this.canvas.clear().viewbox(`0 0 ${this.width} ${this.height}`);\n }\n static drawRect() {\n let {\n x1 = undefined,\n y1 = undefined,\n width = 0,\n height = 0,\n radius = 0,\n color = '#fefefe',\n opacity = 1\n } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const rect = new svg_js_2.Rect();\n rect.attr({\n x: x1 !== null && x1 !== void 0 ? x1 : undefined,\n y: y1 !== null && y1 !== void 0 ? y1 : undefined,\n width,\n height,\n rx: radius,\n ry: radius,\n opacity\n });\n rect.fill(color);\n return rect;\n }\n static drawCircle() {\n let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const circle = new svg_js_1.Circle();\n circle.attr(attributes);\n return circle;\n }\n static drawText() {\n let text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n let {\n x,\n y,\n dx,\n dy\n } = arguments.length > 1 ? arguments[1] : undefined;\n const textSvg = new svg_js_2.Text();\n textSvg.font({\n fill: '#f06'\n });\n textSvg.tspan(text);\n if (x !== undefined && y !== undefined) {\n textSvg.move(x, y);\n }\n if (dx !== undefined && dy !== undefined) {\n textSvg.attr({\n dx,\n dy\n });\n }\n return textSvg;\n }\n static drawTemplate(template) {\n let {\n nodeWidth,\n nodeHeight\n } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n const object = new svg_js_2.ForeignObject({\n width: nodeWidth,\n height: nodeHeight\n });\n const element = document.createElement('div');\n element.innerHTML = template;\n element.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');\n object.add(element);\n return object;\n }\n static drawGroup() {\n let x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;\n let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n let id = arguments.length > 2 ? arguments[2] : undefined;\n let parent = arguments.length > 3 ? arguments[3] : undefined;\n const group = new svg_js_2.G();\n group.attr({\n transform: `translate(${x}, ${y})`,\n 'data-self': id,\n 'data-parent': parent\n });\n return group;\n }\n static drawPath(pathString) {\n let {\n id = '',\n borderColor = Options_1.DefaultOptions.borderColor\n } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n const path = new svg_js_2.Path({\n d: pathString\n });\n path.id(id);\n path.fill('none').stroke({\n color: borderColor,\n width: 1\n });\n return path;\n }\n}\nexports.Paper = Paper;\n\n//# sourceURL=webpack://ApexTree/./src/models/Paper.ts?",
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
/***/
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
/***/ './src/models/Toolbar.ts':
|
|
101
|
-
/*!*******************************!*\
|
|
102
|
-
!*** ./src/models/Toolbar.ts ***!
|
|
103
|
-
\*******************************/
|
|
104
|
-
/***/ function (__unused_webpack_module, exports, __webpack_require__) {
|
|
105
|
-
eval(
|
|
106
|
-
'\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n "default": mod\n };\n};\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.Toolbar = exports.ToolbarItem = void 0;\nconst zoom_in_icon_svg_1 = __importDefault(__webpack_require__(/*! src/icons/zoom-in-icon.svg */ "./src/icons/zoom-in-icon.svg"));\nconst zoom_out_icon_svg_1 = __importDefault(__webpack_require__(/*! src/icons/zoom-out-icon.svg */ "./src/icons/zoom-out-icon.svg"));\nconst fit_screen_icon_svg_1 = __importDefault(__webpack_require__(/*! src/icons/fit-screen-icon.svg */ "./src/icons/fit-screen-icon.svg"));\nconst export_icon_svg_1 = __importDefault(__webpack_require__(/*! src/icons/export-icon.svg */ "./src/icons/export-icon.svg"));\nconst Export_1 = __webpack_require__(/*! src/models/Export */ "./src/models/Export.ts");\nvar ToolbarItem;\n(function (ToolbarItem) {\n ToolbarItem["ZoomIn"] = "zoom-in";\n ToolbarItem["ZoomOut"] = "zoom-out";\n ToolbarItem["FitScreen"] = "fit-screen";\n ToolbarItem["Export"] = "export";\n})(ToolbarItem || (exports.ToolbarItem = ToolbarItem = {}));\nconst ToolBarIcons = {\n [ToolbarItem.ZoomIn]: zoom_in_icon_svg_1.default,\n [ToolbarItem.ZoomOut]: zoom_out_icon_svg_1.default,\n [ToolbarItem.FitScreen]: fit_screen_icon_svg_1.default,\n [ToolbarItem.Export]: export_icon_svg_1.default\n};\nconst ZoomChangeFactor = 0.1;\nclass Toolbar {\n constructor(element, graph) {\n this.element = element;\n this.graph = graph;\n this.export = new Export_1.Export(graph);\n }\n render() {\n var _a;\n const container = document.createElement(\'div\');\n container.id = \'toolbar\';\n container.setAttribute(\'style\', \'display: flex;gap: 5px;position: absolute;right: 20px;top: 20px;\');\n const btnZoomIn = this.createToolbarItem(ToolbarItem.ZoomIn, ToolBarIcons[ToolbarItem.ZoomIn]);\n const btnZoomOut = this.createToolbarItem(ToolbarItem.ZoomOut, ToolBarIcons[ToolbarItem.ZoomOut]);\n const btnFitScreen = this.createToolbarItem(ToolbarItem.FitScreen, ToolBarIcons[ToolbarItem.FitScreen]);\n const btnExport = this.createToolbarItem(ToolbarItem.Export, ToolBarIcons[ToolbarItem.Export]);\n btnZoomIn.addEventListener(\'click\', () => {\n this.graph.zoom(ZoomChangeFactor);\n });\n btnZoomOut.addEventListener(\'click\', () => {\n this.graph.zoom(-ZoomChangeFactor);\n });\n btnFitScreen.addEventListener(\'click\', () => {\n this.graph.fitScreen();\n });\n btnExport.addEventListener(\'click\', () => {\n this.export.exportToSVG();\n });\n container.append(btnZoomIn, btnZoomOut, btnFitScreen, btnExport);\n (_a = this.element) === null || _a === void 0 ? void 0 : _a.append(container);\n }\n createToolbarItem(itemName, icon) {\n const itemContainer = document.createElement(\'div\');\n itemContainer.id = itemName;\n itemContainer.innerHTML = icon;\n itemContainer.setAttribute(\'style\', \'width: 30px;height: 30px;display: flex;align-items: center;justify-content: center;border: 1px solid #BCBCBC;background-color: #FFFFFF;cursor: pointer;\');\n return itemContainer;\n }\n}\nexports.Toolbar = Toolbar;\n\n//# sourceURL=webpack://ApexTree/./src/models/Toolbar.ts?',
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
/***/
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
/***/ './src/models/index.ts':
|
|
113
|
-
/*!*****************************!*\
|
|
114
|
-
!*** ./src/models/index.ts ***!
|
|
115
|
-
\*****************************/
|
|
116
|
-
/***/ (__unused_webpack_module, exports, __webpack_require__) => {
|
|
117
|
-
eval(
|
|
118
|
-
'\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.Toolbar = exports.TreeNode = exports.Node = exports.GraphPoint = exports.Graph = void 0;\nvar Graph_1 = __webpack_require__(/*! ./Graph */ "./src/models/Graph.ts");\nObject.defineProperty(exports, "Graph", ({\n enumerable: true,\n get: function () {\n return Graph_1.Graph;\n }\n}));\nObject.defineProperty(exports, "GraphPoint", ({\n enumerable: true,\n get: function () {\n return Graph_1.GraphPoint;\n }\n}));\nObject.defineProperty(exports, "Node", ({\n enumerable: true,\n get: function () {\n return Graph_1.Node;\n }\n}));\nObject.defineProperty(exports, "TreeNode", ({\n enumerable: true,\n get: function () {\n return Graph_1.TreeNode;\n }\n}));\nvar Toolbar_1 = __webpack_require__(/*! ./Toolbar */ "./src/models/Toolbar.ts");\nObject.defineProperty(exports, "Toolbar", ({\n enumerable: true,\n get: function () {\n return Toolbar_1.Toolbar;\n }\n}));\n\n//# sourceURL=webpack://ApexTree/./src/models/index.ts?',
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
/***/
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
/***/ './src/settings/DirectionConfig.ts':
|
|
125
|
-
/*!*****************************************!*\
|
|
126
|
-
!*** ./src/settings/DirectionConfig.ts ***!
|
|
127
|
-
\*****************************************/
|
|
128
|
-
/***/ (__unused_webpack_module, exports) => {
|
|
129
|
-
eval(
|
|
130
|
-
"\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.DirectionConfig = exports.curvedEdgesVertical = exports.curvedEdgesHorizontal = void 0;\n/* Horizontal diagonal generation algorithm - https://observablehq.com/@bumbeishvili/curved-edges-compact-horizontal */\nconst curvedEdgesHorizontal = (s, t, m) => {\n var _a, _b;\n // Define source and target x,y coordinates\n const x = s.x;\n const y = s.y;\n const ex = t.x;\n const ey = t.y;\n const mx = (_a = m === null || m === void 0 ? void 0 : m.x) !== null && _a !== void 0 ? _a : x;\n const my = (_b = m === null || m === void 0 ? void 0 : m.y) !== null && _b !== void 0 ? _b : y;\n // Values in case of top reversed and left reversed diagonals\n const xrvs = ex - x < 0 ? -1 : 1;\n const yrvs = ey - y < 0 ? -1 : 1;\n // Define preferred curve radius\n const rdef = 35;\n // Reduce curve radius, if source-target x space is smaller\n let r = Math.abs(ex - x) / 2 < rdef ? Math.abs(ex - x) / 2 : rdef;\n // Further reduce curve radius, is y space is more small\n r = Math.abs(ey - y) / 2 < r ? Math.abs(ey - y) / 2 : r;\n // Defin width and height of link, excluding radius\n // const h = Math.abs(ey - y) / 2 - r;\n const w = Math.abs(ex - x) / 2 - r;\n // Build and return custom arc command\n const pathArray = [`M ${mx} ${my}`, `L ${mx} ${y}`, `L ${x} ${y}`, `L ${x + w * xrvs} ${y}`, `C ${x + w * xrvs + r * xrvs} ${y} ${x + w * xrvs + r * xrvs} ${y} ${x + w * xrvs + r * xrvs} ${y + r * yrvs}`, `L ${x + w * xrvs + r * xrvs} ${ey - r * yrvs}`, `C ${x + w * xrvs + r * xrvs} ${ey} ${x + w * xrvs + r * xrvs} ${ey} ${ex - w * xrvs} ${ey}`, `L ${ex} ${ey}`];\n return pathArray.join(' ');\n};\nexports.curvedEdgesHorizontal = curvedEdgesHorizontal;\n/* Vertical diagonal generation algorithm - https://observablehq.com/@bumbeishvili/curved-edges-compacty-vertical */\nconst curvedEdgesVertical = function (s, t, m) {\n let offsets = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {\n sy: 0\n };\n var _a, _b;\n const x = s.x;\n let y = s.y;\n const ex = t.x;\n const ey = t.y;\n const mx = (_a = m === null || m === void 0 ? void 0 : m.x) !== null && _a !== void 0 ? _a : x;\n const my = (_b = m === null || m === void 0 ? void 0 : m.y) !== null && _b !== void 0 ? _b : y;\n const xrvs = ex - x < 0 ? -1 : 1;\n const yrvs = ey - y < 0 ? -1 : 1;\n y += offsets.sy;\n const rdef = 35;\n let r = Math.abs(ex - x) / 2 < rdef ? Math.abs(ex - x) / 2 : rdef;\n r = Math.abs(ey - y) / 2 < r ? Math.abs(ey - y) / 2 : r;\n const h = Math.abs(ey - y) / 2 - r;\n const w = Math.abs(ex - x) - r * 2;\n //w=0;\n const pathArray = [`M ${mx} ${my}`, `L ${x} ${my}`, `L ${x} ${y}`, `L ${x} ${y + h * yrvs}`, `C ${x} ${y + h * yrvs + r * yrvs} ${x} ${y + h * yrvs + r * yrvs} ${x + r * xrvs} ${y + h * yrvs + r * yrvs}`, `L ${x + w * xrvs + r * xrvs} ${y + h * yrvs + r * yrvs}`, `C ${ex} ${y + h * yrvs + r * yrvs} ${ex} ${y + h * yrvs + r * yrvs} ${ex} ${ey - h * yrvs}`, `L ${ex} ${ey}`];\n return pathArray.join(' ');\n};\nexports.curvedEdgesVertical = curvedEdgesVertical;\nexports.DirectionConfig = {\n top: {\n containerX: _ref => {\n let {\n width\n } = _ref;\n return width / 2;\n },\n containerY: () => 0,\n edgeX: _ref2 => {\n let {\n node,\n nodeWidth\n } = _ref2;\n return node.x + nodeWidth / 2;\n },\n edgeY: _ref3 => {\n let {\n node\n } = _ref3;\n return node.y;\n },\n edgeMidX: _ref4 => {\n let {\n node,\n nodeWidth\n } = _ref4;\n return node.x + nodeWidth / 2;\n },\n edgeMidY: _ref5 => {\n let {\n node\n } = _ref5;\n return node.y;\n },\n edgeParentX: _ref6 => {\n let {\n parent,\n nodeWidth\n } = _ref6;\n return parent.x + nodeWidth / 2;\n },\n edgeParentY: _ref7 => {\n let {\n parent,\n nodeHeight\n } = _ref7;\n return parent.y + nodeHeight;\n },\n nodeFlexSize: _ref8 => {\n let {\n nodeWidth,\n nodeHeight,\n siblingSpacing,\n childrenSpacing\n } = _ref8;\n return [nodeWidth + siblingSpacing, nodeHeight + childrenSpacing];\n },\n calculateEdge: exports.curvedEdgesVertical,\n swap: node => ({\n x: node.left,\n y: node.top\n }),\n viewBoxDimensions: _ref9 => {\n let {\n rootNode,\n childrenSpacing,\n siblingSpacing\n } = _ref9;\n const {\n left,\n top,\n right,\n bottom\n } = rootNode.extents;\n const width = Math.abs(left) + Math.abs(right);\n const height = Math.abs(top) + Math.abs(bottom);\n const x = Math.abs(left) + siblingSpacing / 2;\n const y = (rootNode.ySize - childrenSpacing) / 2;\n return {\n x: -x,\n y: -y,\n width,\n height\n };\n }\n },\n bottom: {\n containerX: _ref10 => {\n let {\n width\n } = _ref10;\n return width / 2;\n },\n containerY: _ref11 => {\n let {\n height,\n nodeHeight\n } = _ref11;\n return height - nodeHeight - 10;\n },\n edgeX: _ref12 => {\n let {\n node,\n nodeWidth\n } = _ref12;\n return node.x + nodeWidth / 2;\n },\n edgeY: _ref13 => {\n let {\n node,\n nodeHeight\n } = _ref13;\n return node.y + nodeHeight;\n },\n edgeMidX: _ref14 => {\n let {\n node,\n nodeWidth\n } = _ref14;\n return node.x + nodeWidth / 2;\n },\n edgeMidY: _ref15 => {\n let {\n node,\n nodeHeight\n } = _ref15;\n return node.y + nodeHeight;\n },\n edgeParentX: _ref16 => {\n let {\n parent,\n nodeWidth\n } = _ref16;\n return parent.x + nodeWidth / 2;\n },\n edgeParentY: _ref17 => {\n let {\n parent\n } = _ref17;\n return parent.y;\n },\n nodeFlexSize: _ref18 => {\n let {\n nodeWidth,\n nodeHeight,\n siblingSpacing,\n childrenSpacing\n } = _ref18;\n return [nodeWidth + siblingSpacing, nodeHeight + childrenSpacing];\n },\n calculateEdge: exports.curvedEdgesVertical,\n swap: node => Object.assign(Object.assign({}, node), {\n y: -node.y\n }),\n viewBoxDimensions: _ref19 => {\n let {\n rootNode,\n childrenSpacing,\n siblingSpacing\n } = _ref19;\n const {\n left,\n top,\n right,\n bottom\n } = rootNode.extents;\n const width = Math.abs(left) + Math.abs(right);\n const height = Math.abs(top) + Math.abs(bottom);\n const x = Math.abs(left) - (rootNode.xSize - siblingSpacing) / 2;\n const y = height - rootNode.ySize + childrenSpacing / 2;\n return {\n x: -x,\n y: -y,\n width,\n height\n };\n }\n },\n left: {\n containerX: () => 10,\n containerY: _ref20 => {\n let {\n height\n } = _ref20;\n return height / 2;\n },\n edgeX: _ref21 => {\n let {\n node\n } = _ref21;\n return node.x;\n },\n edgeY: _ref22 => {\n let {\n node,\n nodeHeight\n } = _ref22;\n return node.y + nodeHeight / 2;\n },\n edgeMidX: _ref23 => {\n let {\n node\n } = _ref23;\n return node.x;\n },\n edgeMidY: _ref24 => {\n let {\n node,\n nodeHeight\n } = _ref24;\n return node.y + nodeHeight / 2;\n },\n edgeParentX: _ref25 => {\n let {\n parent,\n nodeWidth\n } = _ref25;\n return parent.x + nodeWidth;\n },\n edgeParentY: _ref26 => {\n let {\n parent,\n nodeHeight\n } = _ref26;\n return parent.y + nodeHeight / 2;\n },\n nodeFlexSize: _ref27 => {\n let {\n nodeWidth,\n nodeHeight,\n siblingSpacing,\n childrenSpacing\n } = _ref27;\n return [nodeHeight + siblingSpacing, nodeWidth + childrenSpacing];\n },\n calculateEdge: exports.curvedEdgesHorizontal,\n swap: node => Object.assign(Object.assign({}, node), {\n x: node.y,\n y: node.x\n }),\n viewBoxDimensions: _ref28 => {\n let {\n rootNode,\n childrenSpacing,\n siblingSpacing\n } = _ref28;\n const {\n left,\n top,\n right,\n bottom\n } = rootNode.extents;\n const width = Math.abs(top) + Math.abs(bottom);\n const height = Math.abs(left) + Math.abs(right);\n const x = Math.abs(top) + childrenSpacing / 2;\n const y = Math.abs(left) - siblingSpacing;\n return {\n x: -x,\n y: -y,\n width,\n height\n };\n }\n },\n right: {\n containerX: _ref29 => {\n let {\n width,\n nodeWidth\n } = _ref29;\n return width - nodeWidth - 10;\n },\n containerY: _ref30 => {\n let {\n height\n } = _ref30;\n return height / 2;\n },\n edgeX: _ref31 => {\n let {\n node,\n nodeWidth\n } = _ref31;\n return node.x + nodeWidth;\n },\n edgeY: _ref32 => {\n let {\n node,\n nodeHeight\n } = _ref32;\n return node.y + nodeHeight / 2;\n },\n edgeMidX: _ref33 => {\n let {\n node,\n nodeWidth\n } = _ref33;\n return node.x + nodeWidth;\n },\n edgeMidY: _ref34 => {\n let {\n node,\n nodeHeight\n } = _ref34;\n return node.y + nodeHeight / 2;\n },\n edgeParentX: _ref35 => {\n let {\n parent\n } = _ref35;\n return parent.x;\n },\n edgeParentY: _ref36 => {\n let {\n parent,\n nodeHeight\n } = _ref36;\n return parent.y + nodeHeight / 2;\n },\n nodeFlexSize: _ref37 => {\n let {\n nodeWidth,\n nodeHeight,\n siblingSpacing,\n childrenSpacing\n } = _ref37;\n return [nodeHeight + siblingSpacing, nodeWidth + childrenSpacing];\n },\n calculateEdge: exports.curvedEdgesHorizontal,\n swap: node => Object.assign(Object.assign({}, node), {\n x: -node.y,\n y: node.x\n }),\n viewBoxDimensions: _ref38 => {\n let {\n rootNode,\n siblingSpacing,\n childrenSpacing\n } = _ref38;\n const {\n left,\n top,\n right,\n bottom\n } = rootNode.extents;\n const width = Math.abs(top) + Math.abs(bottom);\n const height = Math.abs(left) + Math.abs(right);\n const x = width - rootNode.ySize + childrenSpacing / 2;\n const y = Math.abs(left) - siblingSpacing;\n return {\n x: -x,\n y: -y,\n width,\n height\n };\n }\n }\n};\n\n//# sourceURL=webpack://ApexTree/./src/settings/DirectionConfig.ts?",
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
/***/
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
/***/ './src/settings/Options.ts':
|
|
137
|
-
/*!*********************************!*\
|
|
138
|
-
!*** ./src/settings/Options.ts ***!
|
|
139
|
-
\*********************************/
|
|
140
|
-
/***/ (__unused_webpack_module, exports) => {
|
|
141
|
-
eval(
|
|
142
|
-
"\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.DefaultOptions = void 0;\nconst defaultNodeTemplate = content => {\n return `<div style='display: flex;justify-content: center;align-items: center; text-align: center; height: 100%;'>${content}</div>`;\n};\nexports.DefaultOptions = {\n width: 400,\n height: 400,\n contentKey: 'name',\n nodeWidth: 50,\n nodeHeight: 30,\n nodeTemplate: defaultNodeTemplate,\n nodeBGColor: '#FFFFFF',\n nodeBGColorHover: '#FFFFFF',\n nodeStyle: '',\n nodeClassName: 'apextree-node',\n borderWidth: 1,\n borderStyle: 'solid',\n borderRadius: '5px',\n borderColor: '#BCBCBC',\n borderColorHover: '#5C6BC0',\n enableExpandCollapse: false,\n siblingSpacing: 50,\n childrenSpacing: 50,\n direction: 'top',\n highlightOnHover: true,\n containerClassName: 'root',\n enableTooltip: false,\n tooltipId: 'apextree-tooltip-container',\n tooltipMaxWidth: 100,\n tooltipBorderColor: '#BCBCBC',\n tooltipBGColor: '#FFFFFF',\n fontSize: '14px',\n fontFamily: '',\n fontWeight: 400,\n fontColor: '#000000',\n canvasStyle: '',\n enableToolbar: false,\n edgeWidth: 1,\n edgeColor: '#BCBCBC',\n edgeColorHover: '#5C6BC0'\n};\n\n//# sourceURL=webpack://ApexTree/./src/settings/Options.ts?",
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
/***/
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
/***/ './src/utils/EdgeUtils.ts':
|
|
149
|
-
/*!********************************!*\
|
|
150
|
-
!*** ./src/utils/EdgeUtils.ts ***!
|
|
151
|
-
\********************************/
|
|
152
|
-
/***/ (__unused_webpack_module, exports, __webpack_require__) => {
|
|
153
|
-
eval(
|
|
154
|
-
'\n\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\nexports.getEdge = void 0;\nconst DirectionConfig_1 = __webpack_require__(/*! src/settings/DirectionConfig */ "./src/settings/DirectionConfig.ts");\nconst getEdge = (node, nodeWidth, nodeHeight, graphDirection) => {\n if (!node || !node.parent) return null;\n const {\n edgeX,\n edgeY,\n edgeParentX,\n edgeParentY,\n edgeMidX,\n edgeMidY,\n calculateEdge,\n swap\n } = DirectionConfig_1.DirectionConfig[graphDirection];\n const newNode = swap(node);\n const newParent = swap(node.parent);\n const child = {\n x: edgeX({\n node: newNode,\n nodeWidth,\n nodeHeight\n }),\n y: edgeY({\n node: newNode,\n nodeWidth,\n nodeHeight\n })\n };\n const parent = {\n x: edgeParentX({\n parent: newParent,\n nodeWidth,\n nodeHeight\n }),\n y: edgeParentY({\n parent: newParent,\n nodeWidth,\n nodeHeight\n })\n };\n const mid = {\n x: edgeMidX({\n node: newNode,\n nodeWidth,\n nodeHeight\n }),\n y: edgeMidY({\n node: newNode,\n nodeWidth,\n nodeHeight\n })\n };\n return calculateEdge(child, parent, mid, {\n sy: 0\n });\n};\nexports.getEdge = getEdge;\n\n//# sourceURL=webpack://ApexTree/./src/utils/EdgeUtils.ts?',
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
/***/
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
/***/ './src/utils/GraphUtils.ts':
|
|
161
|
-
/*!*********************************!*\
|
|
162
|
-
!*** ./src/utils/GraphUtils.ts ***!
|
|
163
|
-
\*********************************/
|
|
164
|
-
/***/ (__unused_webpack_module, exports) => {
|
|
165
|
-
eval(
|
|
166
|
-
"\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.camelToKebabCase = exports.updateTooltip = exports.getTooltip = exports.generateStyles = exports.getTooltipStyles = exports.highlightToPath = exports.ExpandCollapseButtonSize = exports.setAttributes = void 0;\nconst setAttributes = function (element) {\n let attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n for (const key in attrs) {\n element === null || element === void 0 ? void 0 : element.setAttribute(key, attrs[key]);\n }\n};\nexports.setAttributes = setAttributes;\nexports.ExpandCollapseButtonSize = 14;\nconst highlightToPath = (nodes, selfNode, isHighlighted, options) => {\n var _a;\n const nodeOptions = selfNode === null || selfNode === void 0 ? void 0 : selfNode.data.options;\n let nodeBorderWidth = (nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.borderWidth) || options.borderWidth;\n let borderColor = (nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.borderColor) || options.borderColor;\n let backgroundColor = (nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.nodeBGColor) || options.nodeBGColor;\n if (isHighlighted) {\n // borderWidth = borderWidth + 1;\n borderColor = (nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.borderColorHover) || options.borderColorHover;\n backgroundColor = (nodeOptions === null || nodeOptions === void 0 ? void 0 : nodeOptions.nodeBGColorHover) || options.nodeBGColorHover;\n }\n const selfContentElement = document.querySelector(`[data-self='${selfNode.data.id}'] foreignObject div`);\n if (selfContentElement) {\n selfContentElement.style.borderWidth = `${nodeBorderWidth}px`;\n selfContentElement.style.borderColor = borderColor;\n selfContentElement.style.backgroundColor = backgroundColor;\n }\n if (selfNode.parent) {\n const edge = document.getElementById(`${selfNode.data.id}-${(_a = selfNode.parent) === null || _a === void 0 ? void 0 : _a.data.id}`);\n if (isHighlighted) {\n (0, exports.setAttributes)(edge, {\n 'stroke-width': options.edgeWidth + 1,\n stroke: options.edgeColorHover\n });\n } else {\n (0, exports.setAttributes)(edge, {\n 'stroke-width': options.edgeWidth,\n stroke: options.edgeColor\n });\n }\n selfNode.parent && (0, exports.highlightToPath)(nodes, selfNode.parent, isHighlighted, options);\n }\n};\nexports.highlightToPath = highlightToPath;\nconst getTooltipStyles = (x, y, maxWidth, borderColor, bgColor, addPadding) => {\n const styles = ['position: absolute;', `left: ${x + 20}px;`, `top: ${y + 20}px;`, `border: 1px solid ${borderColor};`, `border-radius: 5px;`, `max-width: ${maxWidth}px;`, `background-color: ${bgColor};`];\n if (addPadding) {\n styles.push('padding: 10px;');\n }\n return styles;\n};\nexports.getTooltipStyles = getTooltipStyles;\nconst generateStyles = function () {\n let styleObject = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const styles = [];\n for (const styleKey in styleObject) {\n let key = styleKey;\n if (styleKey === 'fontColor') {\n key = 'color';\n }\n const styleString = `${(0, exports.camelToKebabCase)(key)}: ${styleObject[styleKey]};`;\n styles.push(styleString);\n }\n return styles.join(' ');\n};\nexports.generateStyles = generateStyles;\nconst getTooltip = function () {\n let tooltipId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'apextree-tooltip-container';\n const tooltipElement = document.getElementById(tooltipId) || document.createElement('div');\n tooltipElement.id = tooltipId;\n return tooltipElement;\n};\nexports.getTooltip = getTooltip;\nconst updateTooltip = function () {\n let id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n let styles = arguments.length > 1 ? arguments[1] : undefined;\n let content = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';\n const tooltipElement = document.getElementById(id);\n if (styles) {\n tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.setAttribute('style', styles);\n } else {\n tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.removeAttribute('style');\n }\n if ((tooltipElement === null || tooltipElement === void 0 ? void 0 : tooltipElement.innerHTML.replaceAll(\"'\", '\"')) !== content.replaceAll(\"'\", '\"')) {\n tooltipElement && (tooltipElement.innerHTML = content);\n }\n};\nexports.updateTooltip = updateTooltip;\nconst camelToKebabCase = str => {\n return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());\n};\nexports.camelToKebabCase = camelToKebabCase;\n\n//# sourceURL=webpack://ApexTree/./src/utils/GraphUtils.ts?",
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
/***/
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
/***/ './src/utils/index.ts':
|
|
173
|
-
/*!****************************!*\
|
|
174
|
-
!*** ./src/utils/index.ts ***!
|
|
175
|
-
\****************************/
|
|
176
|
-
/***/ function (__unused_webpack_module, exports, __webpack_require__) {
|
|
177
|
-
eval(
|
|
178
|
-
'\n\nvar __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = {\n enumerable: true,\n get: function () {\n return m[k];\n }\n };\n }\n Object.defineProperty(o, k2, desc);\n} : function (o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\nvar __exportStar = this && this.__exportStar || function (m, exports) {\n for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, "__esModule", ({\n value: true\n}));\n__exportStar(__webpack_require__(/*! ./EdgeUtils */ "./src/utils/EdgeUtils.ts"), exports);\n__exportStar(__webpack_require__(/*! ./GraphUtils */ "./src/utils/GraphUtils.ts"), exports);\n\n//# sourceURL=webpack://ApexTree/./src/utils/index.ts?',
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
/***/
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
/***/ './node_modules/d3-flextree/index.js':
|
|
185
|
-
/*!*******************************************!*\
|
|
186
|
-
!*** ./node_modules/d3-flextree/index.js ***!
|
|
187
|
-
\*******************************************/
|
|
188
|
-
/***/ (
|
|
189
|
-
__unused_webpack_module,
|
|
190
|
-
__webpack_exports__,
|
|
191
|
-
__webpack_require__,
|
|
192
|
-
) => {
|
|
193
|
-
eval(
|
|
194
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ flextree: () => (/* reexport safe */ _src_flextree__WEBPACK_IMPORTED_MODULE_0__["default"])\n/* harmony export */ });\n/* harmony import */ var _src_flextree__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/flextree */ "./node_modules/d3-flextree/src/flextree.js");\n\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-flextree/index.js?',
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
/***/
|
|
198
|
-
},
|
|
199
|
-
|
|
200
|
-
/***/ './node_modules/d3-flextree/src/flextree.js':
|
|
201
|
-
/*!**************************************************!*\
|
|
202
|
-
!*** ./node_modules/d3-flextree/src/flextree.js ***!
|
|
203
|
-
\**************************************************/
|
|
204
|
-
/***/ (
|
|
205
|
-
__unused_webpack_module,
|
|
206
|
-
__webpack_exports__,
|
|
207
|
-
__webpack_require__,
|
|
208
|
-
) => {
|
|
209
|
-
eval(
|
|
210
|
-
"__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ flextree)\n/* harmony export */ });\n/* harmony import */ var d3_hierarchy__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-hierarchy */ \"./node_modules/d3-hierarchy/src/hierarchy/index.js\");\n/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../package.json */ \"./node_modules/d3-flextree/package.json\");\n\n\n\nconst {version} = _package_json__WEBPACK_IMPORTED_MODULE_0__;\nconst defaults = Object.freeze({\n children: data => data.children,\n nodeSize: node => node.data.size,\n spacing: 0,\n});\n\n// Create a layout function with customizable options. Per D3-style, the\n// options can be set at any time using setter methods. The layout function\n// will compute the tree node positions based on the options in effect at the\n// time it is called.\nfunction flextree(options) {\n const opts = Object.assign({}, defaults, options);\n function accessor(name) {\n const opt = opts[name];\n return typeof opt === 'function' ? opt : () => opt;\n }\n\n function layout(tree) {\n const wtree = wrap(getWrapper(), tree, node=>node.children);\n wtree.update();\n return wtree.data;\n }\n\n function getFlexNode() {\n const nodeSize = accessor('nodeSize');\n const spacing = accessor('spacing');\n return class FlexNode extends d3_hierarchy__WEBPACK_IMPORTED_MODULE_1__[\"default\"].prototype.constructor {\n constructor(data) {\n super(data);\n }\n copy() {\n const c = wrap(this.constructor, this, node=>node.children);\n c.each(node => node.data = node.data.data);\n return c;\n }\n get size() { return nodeSize(this); }\n spacing(oNode) { return spacing(this, oNode); }\n get nodes() { return this.descendants(); }\n get xSize() { return this.size[0]; }\n get ySize() { return this.size[1]; }\n get top() { return this.y; }\n get bottom() { return this.y + this.ySize; }\n get left() { return this.x - this.xSize / 2; }\n get right() { return this.x + this.xSize / 2; }\n get root() {\n const ancs = this.ancestors();\n return ancs[ancs.length - 1];\n }\n get numChildren() {\n return this.hasChildren ? this.children.length : 0;\n }\n get hasChildren() { return !this.noChildren; }\n get noChildren() { return this.children === null; }\n get firstChild() {\n return this.hasChildren ? this.children[0] : null;\n }\n get lastChild() {\n return this.hasChildren ? this.children[this.numChildren - 1] : null;\n }\n get extents() {\n return (this.children || []).reduce(\n (acc, kid) => FlexNode.maxExtents(acc, kid.extents),\n this.nodeExtents);\n }\n get nodeExtents() {\n return {\n top: this.top,\n bottom: this.bottom,\n left: this.left,\n right: this.right,\n };\n }\n static maxExtents(e0, e1) {\n return {\n top: Math.min(e0.top, e1.top),\n bottom: Math.max(e0.bottom, e1.bottom),\n left: Math.min(e0.left, e1.left),\n right: Math.max(e0.right, e1.right),\n };\n }\n };\n }\n\n function getWrapper() {\n const FlexNode = getFlexNode();\n const nodeSize = accessor('nodeSize');\n const spacing = accessor('spacing');\n return class extends FlexNode {\n constructor(data) {\n super(data);\n Object.assign(this, {\n x: 0, y: 0,\n relX: 0, prelim: 0, shift: 0, change: 0,\n lExt: this, lExtRelX: 0, lThr: null,\n rExt: this, rExtRelX: 0, rThr: null,\n });\n }\n get size() { return nodeSize(this.data); }\n spacing(oNode) { return spacing(this.data, oNode.data); }\n get x() { return this.data.x; }\n set x(v) { this.data.x = v; }\n get y() { return this.data.y; }\n set y(v) { this.data.y = v; }\n update() {\n layoutChildren(this);\n resolveX(this);\n return this;\n }\n };\n }\n\n function wrap(FlexClass, treeData, children) {\n const _wrap = (data, parent) => {\n const node = new FlexClass(data);\n Object.assign(node, {\n parent,\n depth: parent === null ? 0 : parent.depth + 1,\n height: 0,\n length: 1,\n });\n const kidsData = children(data) || [];\n node.children = kidsData.length === 0 ? null\n : kidsData.map(kd => _wrap(kd, node));\n if (node.children) {\n Object.assign(node, node.children.reduce(\n (hl, kid) => ({\n height: Math.max(hl.height, kid.height + 1),\n length: hl.length + kid.length,\n }), node\n ));\n }\n return node;\n };\n return _wrap(treeData, null);\n }\n\n\n Object.assign(layout, {\n nodeSize(arg) {\n return arguments.length ? (opts.nodeSize = arg, layout) : opts.nodeSize;\n },\n spacing(arg) {\n return arguments.length ? (opts.spacing = arg, layout) : opts.spacing;\n },\n children(arg) {\n return arguments.length ? (opts.children = arg, layout) : opts.children;\n },\n hierarchy(treeData, children) {\n const kids = typeof children === 'undefined' ? opts.children : children;\n return wrap(getFlexNode(), treeData, kids);\n },\n dump(tree) {\n const nodeSize = accessor('nodeSize');\n const _dump = i0 => node => {\n const i1 = i0 + ' ';\n const i2 = i0 + ' ';\n const {x, y} = node;\n const size = nodeSize(node);\n const kids = (node.children || []);\n const kdumps = (kids.length === 0) ? ' ' :\n `,${i1}children: [${i2}${kids.map(_dump(i2)).join(i2)}${i1}],${i0}`;\n return `{ size: [${size.join(', ')}],${i1}x: ${x}, y: ${y}${kdumps}},`;\n };\n return _dump('\\n')(tree);\n },\n });\n return layout;\n}\nflextree.version = version;\n\nconst layoutChildren = (w, y = 0) => {\n w.y = y;\n (w.children || []).reduce((acc, kid) => {\n const [i, lastLows] = acc;\n layoutChildren(kid, w.y + w.ySize);\n // The lowest vertical coordinate while extreme nodes still point\n // in current subtree.\n const lowY = (i === 0 ? kid.lExt : kid.rExt).bottom;\n if (i !== 0) separate(w, i, lastLows);\n const lows = updateLows(lowY, i, lastLows);\n return [i + 1, lows];\n }, [0, null]);\n shiftChange(w);\n positionRoot(w);\n return w;\n};\n\n// Resolves the relative coordinate properties - relX and prelim --\n// to set the final, absolute x coordinate for each node. This also sets\n// `prelim` to 0, so that `relX` for each node is its x-coordinate relative\n// to its parent.\nconst resolveX = (w, prevSum, parentX) => {\n // A call to resolveX without arguments is assumed to be for the root of\n // the tree. This will set the root's x-coord to zero.\n if (typeof prevSum === 'undefined') {\n prevSum = -w.relX - w.prelim;\n parentX = 0;\n }\n const sum = prevSum + w.relX;\n w.relX = sum + w.prelim - parentX;\n w.prelim = 0;\n w.x = parentX + w.relX;\n (w.children || []).forEach(k => resolveX(k, sum, w.x));\n return w;\n};\n\n// Process shift and change for all children, to add intermediate spacing to\n// each child's modifier.\nconst shiftChange = w => {\n (w.children || []).reduce((acc, child) => {\n const [lastShiftSum, lastChangeSum] = acc;\n const shiftSum = lastShiftSum + child.shift;\n const changeSum = lastChangeSum + shiftSum + child.change;\n child.relX += changeSum;\n return [shiftSum, changeSum];\n }, [0, 0]);\n};\n\n// Separates the latest child from its previous sibling\n/* eslint-disable complexity */\nconst separate = (w, i, lows) => {\n const lSib = w.children[i - 1];\n const curSubtree = w.children[i];\n let rContour = lSib;\n let rSumMods = lSib.relX;\n let lContour = curSubtree;\n let lSumMods = curSubtree.relX;\n let isFirst = true;\n while (rContour && lContour) {\n if (rContour.bottom > lows.lowY) lows = lows.next;\n // How far to the left of the right side of rContour is the left side\n // of lContour? First compute the center-to-center distance, then add\n // the \"spacing\"\n const dist =\n (rSumMods + rContour.prelim) - (lSumMods + lContour.prelim) +\n rContour.xSize / 2 + lContour.xSize / 2 +\n rContour.spacing(lContour);\n if (dist > 0 || (dist < 0 && isFirst)) {\n lSumMods += dist;\n // Move subtree by changing relX.\n moveSubtree(curSubtree, dist);\n distributeExtra(w, i, lows.index, dist);\n }\n isFirst = false;\n // Advance highest node(s) and sum(s) of modifiers\n const rightBottom = rContour.bottom;\n const leftBottom = lContour.bottom;\n if (rightBottom <= leftBottom) {\n rContour = nextRContour(rContour);\n if (rContour) rSumMods += rContour.relX;\n }\n if (rightBottom >= leftBottom) {\n lContour = nextLContour(lContour);\n if (lContour) lSumMods += lContour.relX;\n }\n }\n // Set threads and update extreme nodes. In the first case, the\n // current subtree is taller than the left siblings.\n if (!rContour && lContour) setLThr(w, i, lContour, lSumMods);\n // In the next case, the left siblings are taller than the current subtree\n else if (rContour && !lContour) setRThr(w, i, rContour, rSumMods);\n};\n/* eslint-enable complexity */\n\n// Move subtree by changing relX.\nconst moveSubtree = (subtree, distance) => {\n subtree.relX += distance;\n subtree.lExtRelX += distance;\n subtree.rExtRelX += distance;\n};\n\nconst distributeExtra = (w, curSubtreeI, leftSibI, dist) => {\n const curSubtree = w.children[curSubtreeI];\n const n = curSubtreeI - leftSibI;\n // Are there intermediate children?\n if (n > 1) {\n const delta = dist / n;\n w.children[leftSibI + 1].shift += delta;\n curSubtree.shift -= delta;\n curSubtree.change -= dist - delta;\n }\n};\n\nconst nextLContour = w => {\n return w.hasChildren ? w.firstChild : w.lThr;\n};\n\nconst nextRContour = w => {\n return w.hasChildren ? w.lastChild : w.rThr;\n};\n\nconst setLThr = (w, i, lContour, lSumMods) => {\n const firstChild = w.firstChild;\n const lExt = firstChild.lExt;\n const curSubtree = w.children[i];\n lExt.lThr = lContour;\n // Change relX so that the sum of modifier after following thread is correct.\n const diff = lSumMods - lContour.relX - firstChild.lExtRelX;\n lExt.relX += diff;\n // Change preliminary x coordinate so that the node does not move.\n lExt.prelim -= diff;\n // Update extreme node and its sum of modifiers.\n firstChild.lExt = curSubtree.lExt;\n firstChild.lExtRelX = curSubtree.lExtRelX;\n};\n\n// Mirror image of setLThr.\nconst setRThr = (w, i, rContour, rSumMods) => {\n const curSubtree = w.children[i];\n const rExt = curSubtree.rExt;\n const lSib = w.children[i - 1];\n rExt.rThr = rContour;\n const diff = rSumMods - rContour.relX - curSubtree.rExtRelX;\n rExt.relX += diff;\n rExt.prelim -= diff;\n curSubtree.rExt = lSib.rExt;\n curSubtree.rExtRelX = lSib.rExtRelX;\n};\n\n// Position root between children, taking into account their modifiers\nconst positionRoot = w => {\n if (w.hasChildren) {\n const k0 = w.firstChild;\n const kf = w.lastChild;\n const prelim = (k0.prelim + k0.relX - k0.xSize / 2 +\n kf.relX + kf.prelim + kf.xSize / 2 ) / 2;\n Object.assign(w, {\n prelim,\n lExt: k0.lExt, lExtRelX: k0.lExtRelX,\n rExt: kf.rExt, rExtRelX: kf.rExtRelX,\n });\n }\n};\n\n// Make/maintain a linked list of the indexes of left siblings and their\n// lowest vertical coordinate.\nconst updateLows = (lowY, index, lastLows) => {\n // Remove siblings that are hidden by the new subtree.\n while (lastLows !== null && lowY >= lastLows.lowY)\n lastLows = lastLows.next;\n // Prepend the new subtree.\n return {\n lowY,\n index,\n next: lastLows,\n };\n};\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-flextree/src/flextree.js?",
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
/***/
|
|
214
|
-
},
|
|
215
|
-
|
|
216
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/ancestors.js':
|
|
217
|
-
/*!**************************************************************!*\
|
|
218
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/ancestors.js ***!
|
|
219
|
-
\**************************************************************/
|
|
220
|
-
/***/ (
|
|
221
|
-
__unused_webpack_module,
|
|
222
|
-
__webpack_exports__,
|
|
223
|
-
__webpack_require__,
|
|
224
|
-
) => {
|
|
225
|
-
eval(
|
|
226
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {\n var node = this, nodes = [node];\n while (node = node.parent) {\n nodes.push(node);\n }\n return nodes;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/ancestors.js?',
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
/***/
|
|
230
|
-
},
|
|
231
|
-
|
|
232
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/count.js':
|
|
233
|
-
/*!**********************************************************!*\
|
|
234
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/count.js ***!
|
|
235
|
-
\**********************************************************/
|
|
236
|
-
/***/ (
|
|
237
|
-
__unused_webpack_module,
|
|
238
|
-
__webpack_exports__,
|
|
239
|
-
__webpack_require__,
|
|
240
|
-
) => {
|
|
241
|
-
eval(
|
|
242
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction count(node) {\n var sum = 0,\n children = node.children,\n i = children && children.length;\n if (!i) sum = 1;\n else while (--i >= 0) sum += children[i].value;\n node.value = sum;\n}\n\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {\n return this.eachAfter(count);\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/count.js?',
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
/***/
|
|
246
|
-
},
|
|
247
|
-
|
|
248
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/descendants.js':
|
|
249
|
-
/*!****************************************************************!*\
|
|
250
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/descendants.js ***!
|
|
251
|
-
\****************************************************************/
|
|
252
|
-
/***/ (
|
|
253
|
-
__unused_webpack_module,
|
|
254
|
-
__webpack_exports__,
|
|
255
|
-
__webpack_require__,
|
|
256
|
-
) => {
|
|
257
|
-
eval(
|
|
258
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {\n var nodes = [];\n this.each(function(node) {\n nodes.push(node);\n });\n return nodes;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/descendants.js?',
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
/***/
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/each.js':
|
|
265
|
-
/*!*********************************************************!*\
|
|
266
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/each.js ***!
|
|
267
|
-
\*********************************************************/
|
|
268
|
-
/***/ (
|
|
269
|
-
__unused_webpack_module,
|
|
270
|
-
__webpack_exports__,
|
|
271
|
-
__webpack_require__,
|
|
272
|
-
) => {
|
|
273
|
-
eval(
|
|
274
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(callback) {\n var node = this, current, next = [node], children, i, n;\n do {\n current = next.reverse(), next = [];\n while (node = current.pop()) {\n callback(node), children = node.children;\n if (children) for (i = 0, n = children.length; i < n; ++i) {\n next.push(children[i]);\n }\n }\n } while (next.length);\n return this;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/each.js?',
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
/***/
|
|
278
|
-
},
|
|
279
|
-
|
|
280
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/eachAfter.js':
|
|
281
|
-
/*!**************************************************************!*\
|
|
282
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/eachAfter.js ***!
|
|
283
|
-
\**************************************************************/
|
|
284
|
-
/***/ (
|
|
285
|
-
__unused_webpack_module,
|
|
286
|
-
__webpack_exports__,
|
|
287
|
-
__webpack_require__,
|
|
288
|
-
) => {
|
|
289
|
-
eval(
|
|
290
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(callback) {\n var node = this, nodes = [node], next = [], children, i, n;\n while (node = nodes.pop()) {\n next.push(node), children = node.children;\n if (children) for (i = 0, n = children.length; i < n; ++i) {\n nodes.push(children[i]);\n }\n }\n while (node = next.pop()) {\n callback(node);\n }\n return this;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/eachAfter.js?',
|
|
291
|
-
);
|
|
292
|
-
|
|
293
|
-
/***/
|
|
294
|
-
},
|
|
295
|
-
|
|
296
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/eachBefore.js':
|
|
297
|
-
/*!***************************************************************!*\
|
|
298
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/eachBefore.js ***!
|
|
299
|
-
\***************************************************************/
|
|
300
|
-
/***/ (
|
|
301
|
-
__unused_webpack_module,
|
|
302
|
-
__webpack_exports__,
|
|
303
|
-
__webpack_require__,
|
|
304
|
-
) => {
|
|
305
|
-
eval(
|
|
306
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(callback) {\n var node = this, nodes = [node], children, i;\n while (node = nodes.pop()) {\n callback(node), children = node.children;\n if (children) for (i = children.length - 1; i >= 0; --i) {\n nodes.push(children[i]);\n }\n }\n return this;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/eachBefore.js?',
|
|
307
|
-
);
|
|
308
|
-
|
|
309
|
-
/***/
|
|
310
|
-
},
|
|
311
|
-
|
|
312
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/index.js':
|
|
313
|
-
/*!**********************************************************!*\
|
|
314
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/index.js ***!
|
|
315
|
-
\**********************************************************/
|
|
316
|
-
/***/ (
|
|
317
|
-
__unused_webpack_module,
|
|
318
|
-
__webpack_exports__,
|
|
319
|
-
__webpack_require__,
|
|
320
|
-
) => {
|
|
321
|
-
eval(
|
|
322
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Node: () => (/* binding */ Node),\n/* harmony export */ computeHeight: () => (/* binding */ computeHeight),\n/* harmony export */ "default": () => (/* binding */ hierarchy)\n/* harmony export */ });\n/* harmony import */ var _count_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./count.js */ "./node_modules/d3-hierarchy/src/hierarchy/count.js");\n/* harmony import */ var _each_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./each.js */ "./node_modules/d3-hierarchy/src/hierarchy/each.js");\n/* harmony import */ var _eachBefore_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./eachBefore.js */ "./node_modules/d3-hierarchy/src/hierarchy/eachBefore.js");\n/* harmony import */ var _eachAfter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./eachAfter.js */ "./node_modules/d3-hierarchy/src/hierarchy/eachAfter.js");\n/* harmony import */ var _sum_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./sum.js */ "./node_modules/d3-hierarchy/src/hierarchy/sum.js");\n/* harmony import */ var _sort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./sort.js */ "./node_modules/d3-hierarchy/src/hierarchy/sort.js");\n/* harmony import */ var _path_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./path.js */ "./node_modules/d3-hierarchy/src/hierarchy/path.js");\n/* harmony import */ var _ancestors_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ancestors.js */ "./node_modules/d3-hierarchy/src/hierarchy/ancestors.js");\n/* harmony import */ var _descendants_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./descendants.js */ "./node_modules/d3-hierarchy/src/hierarchy/descendants.js");\n/* harmony import */ var _leaves_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./leaves.js */ "./node_modules/d3-hierarchy/src/hierarchy/leaves.js");\n/* harmony import */ var _links_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./links.js */ "./node_modules/d3-hierarchy/src/hierarchy/links.js");\n\n\n\n\n\n\n\n\n\n\n\n\nfunction hierarchy(data, children) {\n var root = new Node(data),\n valued = +data.value && (root.value = data.value),\n node,\n nodes = [root],\n child,\n childs,\n i,\n n;\n\n if (children == null) children = defaultChildren;\n\n while (node = nodes.pop()) {\n if (valued) node.value = +node.data.value;\n if ((childs = children(node.data)) && (n = childs.length)) {\n node.children = new Array(n);\n for (i = n - 1; i >= 0; --i) {\n nodes.push(child = node.children[i] = new Node(childs[i]));\n child.parent = node;\n child.depth = node.depth + 1;\n }\n }\n }\n\n return root.eachBefore(computeHeight);\n}\n\nfunction node_copy() {\n return hierarchy(this).eachBefore(copyData);\n}\n\nfunction defaultChildren(d) {\n return d.children;\n}\n\nfunction copyData(node) {\n node.data = node.data.data;\n}\n\nfunction computeHeight(node) {\n var height = 0;\n do node.height = height;\n while ((node = node.parent) && (node.height < ++height));\n}\n\nfunction Node(data) {\n this.data = data;\n this.depth =\n this.height = 0;\n this.parent = null;\n}\n\nNode.prototype = hierarchy.prototype = {\n constructor: Node,\n count: _count_js__WEBPACK_IMPORTED_MODULE_0__["default"],\n each: _each_js__WEBPACK_IMPORTED_MODULE_1__["default"],\n eachAfter: _eachAfter_js__WEBPACK_IMPORTED_MODULE_2__["default"],\n eachBefore: _eachBefore_js__WEBPACK_IMPORTED_MODULE_3__["default"],\n sum: _sum_js__WEBPACK_IMPORTED_MODULE_4__["default"],\n sort: _sort_js__WEBPACK_IMPORTED_MODULE_5__["default"],\n path: _path_js__WEBPACK_IMPORTED_MODULE_6__["default"],\n ancestors: _ancestors_js__WEBPACK_IMPORTED_MODULE_7__["default"],\n descendants: _descendants_js__WEBPACK_IMPORTED_MODULE_8__["default"],\n leaves: _leaves_js__WEBPACK_IMPORTED_MODULE_9__["default"],\n links: _links_js__WEBPACK_IMPORTED_MODULE_10__["default"],\n copy: node_copy\n};\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/index.js?',
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
/***/
|
|
326
|
-
},
|
|
327
|
-
|
|
328
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/leaves.js':
|
|
329
|
-
/*!***********************************************************!*\
|
|
330
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/leaves.js ***!
|
|
331
|
-
\***********************************************************/
|
|
332
|
-
/***/ (
|
|
333
|
-
__unused_webpack_module,
|
|
334
|
-
__webpack_exports__,
|
|
335
|
-
__webpack_require__,
|
|
336
|
-
) => {
|
|
337
|
-
eval(
|
|
338
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {\n var leaves = [];\n this.eachBefore(function(node) {\n if (!node.children) {\n leaves.push(node);\n }\n });\n return leaves;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/leaves.js?',
|
|
339
|
-
);
|
|
340
|
-
|
|
341
|
-
/***/
|
|
342
|
-
},
|
|
343
|
-
|
|
344
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/links.js':
|
|
345
|
-
/*!**********************************************************!*\
|
|
346
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/links.js ***!
|
|
347
|
-
\**********************************************************/
|
|
348
|
-
/***/ (
|
|
349
|
-
__unused_webpack_module,
|
|
350
|
-
__webpack_exports__,
|
|
351
|
-
__webpack_require__,
|
|
352
|
-
) => {
|
|
353
|
-
eval(
|
|
354
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {\n var root = this, links = [];\n root.each(function(node) {\n if (node !== root) { // Don’t include the root’s parent, if any.\n links.push({source: node.parent, target: node});\n }\n });\n return links;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/links.js?',
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
/***/
|
|
358
|
-
},
|
|
359
|
-
|
|
360
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/path.js':
|
|
361
|
-
/*!*********************************************************!*\
|
|
362
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/path.js ***!
|
|
363
|
-
\*********************************************************/
|
|
364
|
-
/***/ (
|
|
365
|
-
__unused_webpack_module,
|
|
366
|
-
__webpack_exports__,
|
|
367
|
-
__webpack_require__,
|
|
368
|
-
) => {
|
|
369
|
-
eval(
|
|
370
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(end) {\n var start = this,\n ancestor = leastCommonAncestor(start, end),\n nodes = [start];\n while (start !== ancestor) {\n start = start.parent;\n nodes.push(start);\n }\n var k = nodes.length;\n while (end !== ancestor) {\n nodes.splice(k, 0, end);\n end = end.parent;\n }\n return nodes;\n}\n\nfunction leastCommonAncestor(a, b) {\n if (a === b) return a;\n var aNodes = a.ancestors(),\n bNodes = b.ancestors(),\n c = null;\n a = aNodes.pop();\n b = bNodes.pop();\n while (a === b) {\n c = a;\n a = aNodes.pop();\n b = bNodes.pop();\n }\n return c;\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/path.js?',
|
|
371
|
-
);
|
|
372
|
-
|
|
373
|
-
/***/
|
|
374
|
-
},
|
|
375
|
-
|
|
376
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/sort.js':
|
|
377
|
-
/*!*********************************************************!*\
|
|
378
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/sort.js ***!
|
|
379
|
-
\*********************************************************/
|
|
380
|
-
/***/ (
|
|
381
|
-
__unused_webpack_module,
|
|
382
|
-
__webpack_exports__,
|
|
383
|
-
__webpack_require__,
|
|
384
|
-
) => {
|
|
385
|
-
eval(
|
|
386
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(compare) {\n return this.eachBefore(function(node) {\n if (node.children) {\n node.children.sort(compare);\n }\n });\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/sort.js?',
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
/***/
|
|
390
|
-
},
|
|
391
|
-
|
|
392
|
-
/***/ './node_modules/d3-hierarchy/src/hierarchy/sum.js':
|
|
393
|
-
/*!********************************************************!*\
|
|
394
|
-
!*** ./node_modules/d3-hierarchy/src/hierarchy/sum.js ***!
|
|
395
|
-
\********************************************************/
|
|
396
|
-
/***/ (
|
|
397
|
-
__unused_webpack_module,
|
|
398
|
-
__webpack_exports__,
|
|
399
|
-
__webpack_require__,
|
|
400
|
-
) => {
|
|
401
|
-
eval(
|
|
402
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(value) {\n return this.eachAfter(function(node) {\n var sum = +value(node.data) || 0,\n children = node.children,\n i = children && children.length;\n while (--i >= 0) sum += children[i].value;\n node.value = sum;\n });\n}\n\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-hierarchy/src/hierarchy/sum.js?',
|
|
403
|
-
);
|
|
404
|
-
|
|
405
|
-
/***/
|
|
406
|
-
},
|
|
407
|
-
|
|
408
|
-
/***/ './src/icons/add-circle.svg':
|
|
409
|
-
/*!**********************************!*\
|
|
410
|
-
!*** ./src/icons/add-circle.svg ***!
|
|
411
|
-
\**********************************/
|
|
412
|
-
/***/ (
|
|
413
|
-
__unused_webpack_module,
|
|
414
|
-
__webpack_exports__,
|
|
415
|
-
__webpack_require__,
|
|
416
|
-
) => {
|
|
417
|
-
eval(
|
|
418
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<svg height=\\"14\\" viewBox=\\"0 0 24 24\\" width=\\"14\\" xmlns=\\"http://www.w3.org/2000/svg\\">\\n <path d=\\"m12 0a12 12 0 1 0 12 12 12.013 12.013 0 0 0 -12-12zm0 22a10 10 0 1 1 10-10 10.011 10.011 0 0 1 -10 10zm5-10a1 1 0 0 1 -1 1h-3v3a1 1 0 0 1 -2 0v-3h-3a1 1 0 0 1 0-2h3v-3a1 1 0 0 1 2 0v3h3a1 1 0 0 1 1 1z\\"/>\\n</svg>");\n\n//# sourceURL=webpack://ApexTree/./src/icons/add-circle.svg?',
|
|
419
|
-
);
|
|
420
|
-
|
|
421
|
-
/***/
|
|
422
|
-
},
|
|
423
|
-
|
|
424
|
-
/***/ './src/icons/export-icon.svg':
|
|
425
|
-
/*!***********************************!*\
|
|
426
|
-
!*** ./src/icons/export-icon.svg ***!
|
|
427
|
-
\***********************************/
|
|
428
|
-
/***/ (
|
|
429
|
-
__unused_webpack_module,
|
|
430
|
-
__webpack_exports__,
|
|
431
|
-
__webpack_require__,
|
|
432
|
-
) => {
|
|
433
|
-
eval(
|
|
434
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>\\n<svg fill=\\"#000000\\" width=\\"20px\\" height=\\"20px\\" viewBox=\\"0 0 24 24\\" id=\\"export-2\\" xmlns=\\"http://www.w3.org/2000/svg\\" class=\\"icon line\\"><polyline id=\\"primary\\" points=\\"15 3 21 3 21 9\\" style=\\"fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5;\\"></polyline><path id=\\"primary-2\\" data-name=\\"primary\\" d=\\"M21,13v7a1,1,0,0,1-1,1H4a1,1,0,0,1-1-1V4A1,1,0,0,1,4,3h7\\" style=\\"fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5;\\"></path><line id=\\"primary-3\\" data-name=\\"primary\\" x1=\\"11\\" y1=\\"13\\" x2=\\"21\\" y2=\\"3\\" style=\\"fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5;\\"></line></svg>");\n\n//# sourceURL=webpack://ApexTree/./src/icons/export-icon.svg?',
|
|
435
|
-
);
|
|
436
|
-
|
|
437
|
-
/***/
|
|
438
|
-
},
|
|
439
|
-
|
|
440
|
-
/***/ './src/icons/fit-screen-icon.svg':
|
|
441
|
-
/*!***************************************!*\
|
|
442
|
-
!*** ./src/icons/fit-screen-icon.svg ***!
|
|
443
|
-
\***************************************/
|
|
444
|
-
/***/ (
|
|
445
|
-
__unused_webpack_module,
|
|
446
|
-
__webpack_exports__,
|
|
447
|
-
__webpack_require__,
|
|
448
|
-
) => {
|
|
449
|
-
eval(
|
|
450
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>\\n<svg width=\\"20px\\" height=\\"20px\\" viewBox=\\"0 0 32 32\\" id=\\"icon\\" xmlns=\\"http://www.w3.org/2000/svg\\">\\n <polygon points=\\"8 2 2 2 2 8 4 8 4 4 8 4 8 2\\"/>\\n <polygon points=\\"24 2 30 2 30 8 28 8 28 4 24 4 24 2\\"/>\\n <polygon points=\\"8 30 2 30 2 24 4 24 4 28 8 28 8 30\\"/>\\n <polygon points=\\"24 30 30 30 30 24 28 24 28 28 24 28 24 30\\"/>\\n <path d=\\"M24,24H8a2.0023,2.0023,0,0,1-2-2V10A2.0023,2.0023,0,0,1,8,8H24a2.0023,2.0023,0,0,1,2,2V22A2.0023,2.0023,0,0,1,24,24ZM8,10V22H24V10Z\\"/>\\n <rect fill=\\"none\\" width=\\"32\\" height=\\"32\\"/>\\n</svg>");\n\n//# sourceURL=webpack://ApexTree/./src/icons/fit-screen-icon.svg?',
|
|
451
|
-
);
|
|
452
|
-
|
|
453
|
-
/***/
|
|
454
|
-
},
|
|
455
|
-
|
|
456
|
-
/***/ './src/icons/minus-circle.svg':
|
|
457
|
-
/*!************************************!*\
|
|
458
|
-
!*** ./src/icons/minus-circle.svg ***!
|
|
459
|
-
\************************************/
|
|
460
|
-
/***/ (
|
|
461
|
-
__unused_webpack_module,
|
|
462
|
-
__webpack_exports__,
|
|
463
|
-
__webpack_require__,
|
|
464
|
-
) => {
|
|
465
|
-
eval(
|
|
466
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"14\\" height=\\"14\\">\\n <path d=\\"m12,0C5.383,0,0,5.383,0,12s5.383,12,12,12,12-5.383,12-12S18.617,0,12,0Zm0,22c-5.514,0-10-4.486-10-10S6.486,2,12,2s10,4.486,10,10-4.486,10-10,10Zm5-10c0,.552-.448,1-1,1h-8c-.552,0-1-.448-1-1s.448-1,1-1h8c.552,0,1,.448,1,1Z\\"/>\\n</svg>\\n");\n\n//# sourceURL=webpack://ApexTree/./src/icons/minus-circle.svg?',
|
|
467
|
-
);
|
|
468
|
-
|
|
469
|
-
/***/
|
|
470
|
-
},
|
|
471
|
-
|
|
472
|
-
/***/ './src/icons/zoom-in-icon.svg':
|
|
473
|
-
/*!************************************!*\
|
|
474
|
-
!*** ./src/icons/zoom-in-icon.svg ***!
|
|
475
|
-
\************************************/
|
|
476
|
-
/***/ (
|
|
477
|
-
__unused_webpack_module,
|
|
478
|
-
__webpack_exports__,
|
|
479
|
-
__webpack_require__,
|
|
480
|
-
) => {
|
|
481
|
-
eval(
|
|
482
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"no\\"?>\\r\\n<svg width=\\"20px\\" height=\\"20px\\" viewBox=\\"0 0 32 32\\" version=\\"1.1\\" xmlns=\\"http://www.w3.org/2000/svg\\" xmlns:xlink=\\"http://www.w3.org/1999/xlink\\" xmlns:sketch=\\"http://www.bohemiancoding.com/sketch/ns\\">\\r\\n <g stroke=\\"none\\" stroke-width=\\"1\\" fill=\\"none\\" fill-rule=\\"evenodd\\">\\r\\n <g transform=\\"translate(-308.000000, -1139.000000)\\" fill=\\"#000000\\">\\r\\n <path d=\\"M321.46,1163.45 C315.17,1163.45 310.07,1158.44 310.07,1152.25 C310.07,1146.06 315.17,1141.04 321.46,1141.04 C327.75,1141.04 332.85,1146.06 332.85,1152.25 C332.85,1158.44 327.75,1163.45 321.46,1163.45 L321.46,1163.45 Z M339.688,1169.25 L331.429,1161.12 C333.592,1158.77 334.92,1155.67 334.92,1152.25 C334.92,1144.93 328.894,1139 321.46,1139 C314.026,1139 308,1144.93 308,1152.25 C308,1159.56 314.026,1165.49 321.46,1165.49 C324.672,1165.49 327.618,1164.38 329.932,1162.53 L338.225,1170.69 C338.629,1171.09 339.284,1171.09 339.688,1170.69 C340.093,1170.3 340.093,1169.65 339.688,1169.25 L339.688,1169.25 Z M326.519,1151.41 L322.522,1151.41 L322.522,1147.41 C322.522,1146.85 322.075,1146.41 321.523,1146.41 C320.972,1146.41 320.524,1146.85 320.524,1147.41 L320.524,1151.41 L316.529,1151.41 C315.978,1151.41 315.53,1151.59 315.53,1152.14 C315.53,1152.7 315.978,1153.41 316.529,1153.41 L320.524,1153.41 L320.524,1157.41 C320.524,1157.97 320.972,1158.41 321.523,1158.41 C322.075,1158.41 322.522,1157.97 322.522,1157.41 L322.522,1153.41 L326.519,1153.41 C327.07,1153.41 327.518,1152.96 327.518,1152.41 C327.518,1151.86 327.07,1151.41 326.519,1151.41 L326.519,1151.41 Z\\" />\\r\\n </g>\\r\\n </g>\\r\\n</svg>");\n\n//# sourceURL=webpack://ApexTree/./src/icons/zoom-in-icon.svg?',
|
|
483
|
-
);
|
|
484
|
-
|
|
485
|
-
/***/
|
|
486
|
-
},
|
|
487
|
-
|
|
488
|
-
/***/ './src/icons/zoom-out-icon.svg':
|
|
489
|
-
/*!*************************************!*\
|
|
490
|
-
!*** ./src/icons/zoom-out-icon.svg ***!
|
|
491
|
-
\*************************************/
|
|
492
|
-
/***/ (
|
|
493
|
-
__unused_webpack_module,
|
|
494
|
-
__webpack_exports__,
|
|
495
|
-
__webpack_require__,
|
|
496
|
-
) => {
|
|
497
|
-
eval(
|
|
498
|
-
'__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ("<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"no\\"?>\\r\\n<svg width=\\"20px\\" height=\\"20px\\" viewBox=\\"0 0 32 32\\" version=\\"1.1\\" xmlns=\\"http://www.w3.org/2000/svg\\" xmlns:xlink=\\"http://www.w3.org/1999/xlink\\">\\r\\n <g stroke=\\"none\\" stroke-width=\\"1\\" fill=\\"none\\" fill-rule=\\"evenodd\\" >\\r\\n <g transform=\\"translate(-360.000000, -1139.000000)\\" fill=\\"#000000\\">\\r\\n <path d=\\"M373.46,1163.45 C367.17,1163.45 362.071,1158.44 362.071,1152.25 C362.071,1146.06 367.17,1141.04 373.46,1141.04 C379.75,1141.04 384.85,1146.06 384.85,1152.25 C384.85,1158.44 379.75,1163.45 373.46,1163.45 L373.46,1163.45 Z M391.688,1169.25 L383.429,1161.12 C385.592,1158.77 386.92,1155.67 386.92,1152.25 C386.92,1144.93 380.894,1139 373.46,1139 C366.026,1139 360,1144.93 360,1152.25 C360,1159.56 366.026,1165.49 373.46,1165.49 C376.672,1165.49 379.618,1164.38 381.932,1162.53 L390.225,1170.69 C390.629,1171.09 391.284,1171.09 391.688,1170.69 C392.093,1170.3 392.093,1169.65 391.688,1169.25 L391.688,1169.25 Z M378.689,1151.41 L368.643,1151.41 C368.102,1151.41 367.663,1151.84 367.663,1152.37 C367.663,1152.9 368.102,1153.33 368.643,1153.33 L378.689,1153.33 C379.23,1153.33 379.669,1152.9 379.669,1152.37 C379.669,1151.84 379.23,1151.41 378.689,1151.41 L378.689,1151.41 Z\\" />\\r\\n </g>\\r\\n </g>\\r\\n</svg>");\n\n//# sourceURL=webpack://ApexTree/./src/icons/zoom-out-icon.svg?',
|
|
499
|
-
);
|
|
500
|
-
|
|
501
|
-
/***/
|
|
502
|
-
},
|
|
503
|
-
|
|
504
|
-
/***/ './node_modules/d3-flextree/package.json':
|
|
505
|
-
/*!***********************************************!*\
|
|
506
|
-
!*** ./node_modules/d3-flextree/package.json ***!
|
|
507
|
-
\***********************************************/
|
|
508
|
-
/***/ (module) => {
|
|
509
|
-
eval(
|
|
510
|
-
'module.exports = JSON.parse(\'{"name":"d3-flextree","version":"2.1.2","main":"build/d3-flextree.js","module":"index","jsnext:main":"index","author":{"name":"Chris Maloney","url":"http://chrismaloney.org"},"description":"Flexible tree layout algorithm that allows for variable node sizes.","keywords":["d3","d3-module","layout","tree","hierarchy","d3-hierarchy","plugin","d3-plugin","infovis","visualization","2d"],"homepage":"https://github.com/klortho/d3-flextree","license":"WTFPL","repository":{"type":"git","url":"https://github.com/klortho/d3-flextree.git"},"scripts":{"clean":"rm -rf build demo test","build:demo":"rollup -c --environment BUILD:demo","build:dev":"rollup -c --environment BUILD:dev","build:prod":"rollup -c --environment BUILD:prod","build:test":"rollup -c --environment BUILD:test","build":"rollup -c","lint":"eslint index.js src","test:main":"node test/bundle.js","test:browser":"node test/browser-tests.js","test":"npm-run-all test:*","prepare":"npm-run-all clean build lint test"},"dependencies":{"d3-hierarchy":"^1.1.5"},"devDependencies":{"babel-plugin-external-helpers":"^6.22.0","babel-preset-es2015-rollup":"^3.0.0","d3":"^4.13.0","d3-selection-multi":"^1.0.1","eslint":"^4.19.1","jsdom":"^11.6.2","npm-run-all":"^4.1.2","rollup":"^0.55.3","rollup-plugin-babel":"^2.7.1","rollup-plugin-commonjs":"^8.0.2","rollup-plugin-copy":"^0.2.3","rollup-plugin-json":"^2.3.0","rollup-plugin-node-resolve":"^3.0.2","rollup-plugin-uglify":"^3.0.0","uglify-es":"^3.3.9"}}\');\n\n//# sourceURL=webpack://ApexTree/./node_modules/d3-flextree/package.json?',
|
|
511
|
-
);
|
|
512
|
-
|
|
513
|
-
/***/
|
|
514
|
-
},
|
|
515
|
-
|
|
516
|
-
/******/
|
|
517
|
-
};
|
|
518
|
-
/************************************************************************/
|
|
519
|
-
/******/ // The module cache
|
|
520
|
-
/******/ var __webpack_module_cache__ = {};
|
|
521
|
-
/******/
|
|
522
|
-
/******/ // The require function
|
|
523
|
-
/******/ function __webpack_require__(moduleId) {
|
|
524
|
-
/******/ // Check if module is in cache
|
|
525
|
-
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
526
|
-
/******/ if (cachedModule !== undefined) {
|
|
527
|
-
/******/ return cachedModule.exports;
|
|
528
|
-
/******/
|
|
529
|
-
}
|
|
530
|
-
/******/ // Create a new module (and put it into the cache)
|
|
531
|
-
/******/ var module = (__webpack_module_cache__[moduleId] = {
|
|
532
|
-
/******/ // no module.id needed
|
|
533
|
-
/******/ // no module.loaded needed
|
|
534
|
-
/******/ exports: {},
|
|
535
|
-
/******/
|
|
536
|
-
});
|
|
537
|
-
/******/
|
|
538
|
-
/******/ // Execute the module function
|
|
539
|
-
/******/ __webpack_modules__[moduleId].call(
|
|
540
|
-
module.exports,
|
|
541
|
-
module,
|
|
542
|
-
module.exports,
|
|
543
|
-
__webpack_require__,
|
|
544
|
-
);
|
|
545
|
-
/******/
|
|
546
|
-
/******/ // Return the exports of the module
|
|
547
|
-
/******/ return module.exports;
|
|
548
|
-
/******/
|
|
549
|
-
}
|
|
550
|
-
/******/
|
|
551
|
-
/************************************************************************/
|
|
552
|
-
/******/ /* webpack/runtime/define property getters */
|
|
553
|
-
/******/ (() => {
|
|
554
|
-
/******/ // define getter functions for harmony exports
|
|
555
|
-
/******/ __webpack_require__.d = (exports, definition) => {
|
|
556
|
-
/******/ for (var key in definition) {
|
|
557
|
-
/******/ if (
|
|
558
|
-
__webpack_require__.o(definition, key) &&
|
|
559
|
-
!__webpack_require__.o(exports, key)
|
|
560
|
-
) {
|
|
561
|
-
/******/ Object.defineProperty(exports, key, {
|
|
562
|
-
enumerable: true,
|
|
563
|
-
get: definition[key],
|
|
564
|
-
});
|
|
565
|
-
/******/
|
|
566
|
-
}
|
|
567
|
-
/******/
|
|
568
|
-
}
|
|
569
|
-
/******/
|
|
570
|
-
};
|
|
571
|
-
/******/
|
|
572
|
-
})();
|
|
573
|
-
/******/
|
|
574
|
-
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
575
|
-
/******/ (() => {
|
|
576
|
-
/******/ __webpack_require__.o = (obj, prop) =>
|
|
577
|
-
Object.prototype.hasOwnProperty.call(obj, prop);
|
|
578
|
-
/******/
|
|
579
|
-
})();
|
|
580
|
-
/******/
|
|
581
|
-
/******/ /* webpack/runtime/make namespace object */
|
|
582
|
-
/******/ (() => {
|
|
583
|
-
/******/ // define __esModule on exports
|
|
584
|
-
/******/ __webpack_require__.r = (exports) => {
|
|
585
|
-
/******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
586
|
-
/******/ Object.defineProperty(exports, Symbol.toStringTag, {
|
|
587
|
-
value: 'Module',
|
|
588
|
-
});
|
|
589
|
-
/******/
|
|
590
|
-
}
|
|
591
|
-
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
592
|
-
/******/
|
|
593
|
-
};
|
|
594
|
-
/******/
|
|
595
|
-
})();
|
|
596
|
-
/******/
|
|
597
|
-
/************************************************************************/
|
|
598
|
-
/******/
|
|
599
|
-
/******/ // startup
|
|
600
|
-
/******/ // Load entry module and return exports
|
|
601
|
-
/******/ // This entry module can't be inlined because the eval devtool is used.
|
|
602
|
-
/******/ var __webpack_exports__ = __webpack_require__('./src/ApexTree.ts');
|
|
603
|
-
/******/ __webpack_exports__ = __webpack_exports__.ApexTree;
|
|
604
|
-
/******/
|
|
605
|
-
/******/ return __webpack_exports__;
|
|
606
|
-
/******/
|
|
607
|
-
})();
|
|
608
|
-
});
|