UNPKG

1.54 MBJavaScriptView Raw
1/**
2 * vis-network
3 * https://visjs.github.io/vis-network/
4 *
5 * A dynamic, browser-based visualization library.
6 *
7 * @version 9.1.0
8 * @date 2021-08-29T08:43:14.666Z
9 *
10 * @copyright (c) 2011-2017 Almende B.V, http://almende.com
11 * @copyright (c) 2017-2019 visjs contributors, https://github.com/visjs
12 *
13 * @license
14 * vis.js is dual licensed under both
15 *
16 * 1. The Apache 2.0 License
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * and
20 *
21 * 2. The MIT License
22 * http://opensource.org/licenses/MIT
23 *
24 * vis.js may be distributed under either license.
25 */
26
27var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
28
29var check = function (it) {
30 return it && it.Math == Math && it;
31}; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
32
33
34var global$k = // eslint-disable-next-line es/no-global-this -- safe
35check(typeof globalThis == 'object' && globalThis) || check(typeof window == 'object' && window) || // eslint-disable-next-line no-restricted-globals -- safe
36check(typeof self == 'object' && self) || check(typeof commonjsGlobal == 'object' && commonjsGlobal) || // eslint-disable-next-line no-new-func -- fallback
37function () {
38 return this;
39}() || Function('return this')();
40
41var objectGetOwnPropertyDescriptor = {};
42
43var fails$m = function (exec) {
44 try {
45 return !!exec();
46 } catch (error) {
47 return true;
48 }
49};
50
51var fails$l = fails$m; // Detect IE8's incomplete defineProperty implementation
52
53var descriptors = !fails$l(function () {
54 // eslint-disable-next-line es/no-object-defineproperty -- required for testing
55 return Object.defineProperty({}, 1, {
56 get: function () {
57 return 7;
58 }
59 })[1] != 7;
60});
61
62var objectPropertyIsEnumerable = {};
63
64var $propertyIsEnumerable$1 = {}.propertyIsEnumerable; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
65
66var getOwnPropertyDescriptor$7 = Object.getOwnPropertyDescriptor; // Nashorn ~ JDK8 bug
67
68var NASHORN_BUG = getOwnPropertyDescriptor$7 && !$propertyIsEnumerable$1.call({
69 1: 2
70}, 1); // `Object.prototype.propertyIsEnumerable` method implementation
71// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
72
73objectPropertyIsEnumerable.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
74 var descriptor = getOwnPropertyDescriptor$7(this, V);
75 return !!descriptor && descriptor.enumerable;
76} : $propertyIsEnumerable$1;
77
78var createPropertyDescriptor$5 = function (bitmap, value) {
79 return {
80 enumerable: !(bitmap & 1),
81 configurable: !(bitmap & 2),
82 writable: !(bitmap & 4),
83 value: value
84 };
85};
86
87var toString$a = {}.toString;
88
89var classofRaw$1 = function (it) {
90 return toString$a.call(it).slice(8, -1);
91};
92
93var fails$k = fails$m;
94var classof$b = classofRaw$1;
95var split = ''.split; // fallback for non-array-like ES3 and non-enumerable old V8 strings
96
97var indexedObject = fails$k(function () {
98 // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
99 // eslint-disable-next-line no-prototype-builtins -- safe
100 return !Object('z').propertyIsEnumerable(0);
101}) ? function (it) {
102 return classof$b(it) == 'String' ? split.call(it, '') : Object(it);
103} : Object;
104
105// https://tc39.es/ecma262/#sec-requireobjectcoercible
106
107var requireObjectCoercible$5 = function (it) {
108 if (it == undefined) throw TypeError("Can't call method on " + it);
109 return it;
110};
111
112var IndexedObject$3 = indexedObject;
113var requireObjectCoercible$4 = requireObjectCoercible$5;
114
115var toIndexedObject$a = function (it) {
116 return IndexedObject$3(requireObjectCoercible$4(it));
117};
118
119var isObject$j = function (it) {
120 return typeof it === 'object' ? it !== null : typeof it === 'function';
121};
122
123var path$x = {};
124
125var path$w = path$x;
126var global$j = global$k;
127
128var aFunction$7 = function (variable) {
129 return typeof variable == 'function' ? variable : undefined;
130};
131
132var getBuiltIn$8 = function (namespace, method) {
133 return arguments.length < 2 ? aFunction$7(path$w[namespace]) || aFunction$7(global$j[namespace]) : path$w[namespace] && path$w[namespace][method] || global$j[namespace] && global$j[namespace][method];
134};
135
136var getBuiltIn$7 = getBuiltIn$8;
137var engineUserAgent = getBuiltIn$7('navigator', 'userAgent') || '';
138
139var global$i = global$k;
140var userAgent$3 = engineUserAgent;
141var process = global$i.process;
142var Deno = global$i.Deno;
143var versions = process && process.versions || Deno && Deno.version;
144var v8 = versions && versions.v8;
145var match, version;
146
147if (v8) {
148 match = v8.split('.');
149 version = match[0] < 4 ? 1 : match[0] + match[1];
150} else if (userAgent$3) {
151 match = userAgent$3.match(/Edge\/(\d+)/);
152
153 if (!match || match[1] >= 74) {
154 match = userAgent$3.match(/Chrome\/(\d+)/);
155 if (match) version = match[1];
156 }
157}
158
159var engineV8Version = version && +version;
160
161/* eslint-disable es/no-symbol -- required for testing */
162var V8_VERSION$2 = engineV8Version;
163var fails$j = fails$m; // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
164
165var nativeSymbol = !!Object.getOwnPropertySymbols && !fails$j(function () {
166 var symbol = Symbol(); // Chrome 38 Symbol has incorrect toString conversion
167 // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
168
169 return !String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
170 !Symbol.sham && V8_VERSION$2 && V8_VERSION$2 < 41;
171});
172
173/* eslint-disable es/no-symbol -- required for testing */
174var NATIVE_SYMBOL$2 = nativeSymbol;
175var useSymbolAsUid = NATIVE_SYMBOL$2 && !Symbol.sham && typeof Symbol.iterator == 'symbol';
176
177var getBuiltIn$6 = getBuiltIn$8;
178var USE_SYMBOL_AS_UID$1 = useSymbolAsUid;
179var isSymbol$4 = USE_SYMBOL_AS_UID$1 ? function (it) {
180 return typeof it == 'symbol';
181} : function (it) {
182 var $Symbol = getBuiltIn$6('Symbol');
183 return typeof $Symbol == 'function' && Object(it) instanceof $Symbol;
184};
185
186var isObject$i = isObject$j; // `OrdinaryToPrimitive` abstract operation
187// https://tc39.es/ecma262/#sec-ordinarytoprimitive
188
189var ordinaryToPrimitive$1 = function (input, pref) {
190 var fn, val;
191 if (pref === 'string' && typeof (fn = input.toString) == 'function' && !isObject$i(val = fn.call(input))) return val;
192 if (typeof (fn = input.valueOf) == 'function' && !isObject$i(val = fn.call(input))) return val;
193 if (pref !== 'string' && typeof (fn = input.toString) == 'function' && !isObject$i(val = fn.call(input))) return val;
194 throw TypeError("Can't convert object to primitive value");
195};
196
197var shared$4 = {exports: {}};
198
199var global$h = global$k;
200
201var setGlobal$1 = function (key, value) {
202 try {
203 // eslint-disable-next-line es/no-object-defineproperty -- safe
204 Object.defineProperty(global$h, key, {
205 value: value,
206 configurable: true,
207 writable: true
208 });
209 } catch (error) {
210 global$h[key] = value;
211 }
212
213 return value;
214};
215
216var global$g = global$k;
217var setGlobal = setGlobal$1;
218var SHARED = '__core-js_shared__';
219var store$3 = global$g[SHARED] || setGlobal(SHARED, {});
220var sharedStore = store$3;
221
222var store$2 = sharedStore;
223(shared$4.exports = function (key, value) {
224 return store$2[key] || (store$2[key] = value !== undefined ? value : {});
225})('versions', []).push({
226 version: '3.16.1',
227 mode: 'pure' ,
228 copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
229});
230
231var requireObjectCoercible$3 = requireObjectCoercible$5; // `ToObject` abstract operation
232// https://tc39.es/ecma262/#sec-toobject
233
234var toObject$e = function (argument) {
235 return Object(requireObjectCoercible$3(argument));
236};
237
238var toObject$d = toObject$e;
239var hasOwnProperty = {}.hasOwnProperty;
240
241var has$c = Object.hasOwn || function hasOwn(it, key) {
242 return hasOwnProperty.call(toObject$d(it), key);
243};
244
245var id$2 = 0;
246var postfix = Math.random();
247
248var uid$4 = function (key) {
249 return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id$2 + postfix).toString(36);
250};
251
252var global$f = global$k;
253var shared$3 = shared$4.exports;
254var has$b = has$c;
255var uid$3 = uid$4;
256var NATIVE_SYMBOL$1 = nativeSymbol;
257var USE_SYMBOL_AS_UID = useSymbolAsUid;
258var WellKnownSymbolsStore$1 = shared$3('wks');
259var Symbol$1 = global$f.Symbol;
260var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$3;
261
262var wellKnownSymbol$j = function (name) {
263 if (!has$b(WellKnownSymbolsStore$1, name) || !(NATIVE_SYMBOL$1 || typeof WellKnownSymbolsStore$1[name] == 'string')) {
264 if (NATIVE_SYMBOL$1 && has$b(Symbol$1, name)) {
265 WellKnownSymbolsStore$1[name] = Symbol$1[name];
266 } else {
267 WellKnownSymbolsStore$1[name] = createWellKnownSymbol('Symbol.' + name);
268 }
269 }
270
271 return WellKnownSymbolsStore$1[name];
272};
273
274var isObject$h = isObject$j;
275var isSymbol$3 = isSymbol$4;
276var ordinaryToPrimitive = ordinaryToPrimitive$1;
277var wellKnownSymbol$i = wellKnownSymbol$j;
278var TO_PRIMITIVE$1 = wellKnownSymbol$i('toPrimitive'); // `ToPrimitive` abstract operation
279// https://tc39.es/ecma262/#sec-toprimitive
280
281var toPrimitive$1 = function (input, pref) {
282 if (!isObject$h(input) || isSymbol$3(input)) return input;
283 var exoticToPrim = input[TO_PRIMITIVE$1];
284 var result;
285
286 if (exoticToPrim !== undefined) {
287 if (pref === undefined) pref = 'default';
288 result = exoticToPrim.call(input, pref);
289 if (!isObject$h(result) || isSymbol$3(result)) return result;
290 throw TypeError("Can't convert object to primitive value");
291 }
292
293 if (pref === undefined) pref = 'number';
294 return ordinaryToPrimitive(input, pref);
295};
296
297var toPrimitive = toPrimitive$1;
298var isSymbol$2 = isSymbol$4; // `ToPropertyKey` abstract operation
299// https://tc39.es/ecma262/#sec-topropertykey
300
301var toPropertyKey$4 = function (argument) {
302 var key = toPrimitive(argument, 'string');
303 return isSymbol$2(key) ? key : String(key);
304};
305
306var global$e = global$k;
307var isObject$g = isObject$j;
308var document$1 = global$e.document; // typeof document.createElement is 'object' in old IE
309
310var EXISTS = isObject$g(document$1) && isObject$g(document$1.createElement);
311
312var documentCreateElement$1 = function (it) {
313 return EXISTS ? document$1.createElement(it) : {};
314};
315
316var DESCRIPTORS$f = descriptors;
317var fails$i = fails$m;
318var createElement = documentCreateElement$1; // Thank's IE8 for his funny defineProperty
319
320var ie8DomDefine = !DESCRIPTORS$f && !fails$i(function () {
321 // eslint-disable-next-line es/no-object-defineproperty -- requied for testing
322 return Object.defineProperty(createElement('div'), 'a', {
323 get: function () {
324 return 7;
325 }
326 }).a != 7;
327});
328
329var DESCRIPTORS$e = descriptors;
330var propertyIsEnumerableModule$2 = objectPropertyIsEnumerable;
331var createPropertyDescriptor$4 = createPropertyDescriptor$5;
332var toIndexedObject$9 = toIndexedObject$a;
333var toPropertyKey$3 = toPropertyKey$4;
334var has$a = has$c;
335var IE8_DOM_DEFINE$1 = ie8DomDefine; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
336
337var $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; // `Object.getOwnPropertyDescriptor` method
338// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
339
340objectGetOwnPropertyDescriptor.f = DESCRIPTORS$e ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) {
341 O = toIndexedObject$9(O);
342 P = toPropertyKey$3(P);
343 if (IE8_DOM_DEFINE$1) try {
344 return $getOwnPropertyDescriptor$1(O, P);
345 } catch (error) {
346 /* empty */
347 }
348 if (has$a(O, P)) return createPropertyDescriptor$4(!propertyIsEnumerableModule$2.f.call(O, P), O[P]);
349};
350
351var fails$h = fails$m;
352var replacement = /#|\.prototype\./;
353
354var isForced$1 = function (feature, detection) {
355 var value = data[normalize(feature)];
356 return value == POLYFILL ? true : value == NATIVE ? false : typeof detection == 'function' ? fails$h(detection) : !!detection;
357};
358
359var normalize = isForced$1.normalize = function (string) {
360 return String(string).replace(replacement, '.').toLowerCase();
361};
362
363var data = isForced$1.data = {};
364var NATIVE = isForced$1.NATIVE = 'N';
365var POLYFILL = isForced$1.POLYFILL = 'P';
366var isForced_1 = isForced$1;
367
368var aFunction$6 = function (it) {
369 if (typeof it != 'function') {
370 throw TypeError(String(it) + ' is not a function');
371 }
372
373 return it;
374};
375
376var aFunction$5 = aFunction$6; // optional / simple context binding
377
378var functionBindContext = function (fn, that, length) {
379 aFunction$5(fn);
380 if (that === undefined) return fn;
381
382 switch (length) {
383 case 0:
384 return function () {
385 return fn.call(that);
386 };
387
388 case 1:
389 return function (a) {
390 return fn.call(that, a);
391 };
392
393 case 2:
394 return function (a, b) {
395 return fn.call(that, a, b);
396 };
397
398 case 3:
399 return function (a, b, c) {
400 return fn.call(that, a, b, c);
401 };
402 }
403
404 return function () {
405 return fn.apply(that, arguments);
406 };
407};
408
409var objectDefineProperty = {};
410
411var isObject$f = isObject$j;
412
413var anObject$d = function (it) {
414 if (!isObject$f(it)) {
415 throw TypeError(String(it) + ' is not an object');
416 }
417
418 return it;
419};
420
421var DESCRIPTORS$d = descriptors;
422var IE8_DOM_DEFINE = ie8DomDefine;
423var anObject$c = anObject$d;
424var toPropertyKey$2 = toPropertyKey$4; // eslint-disable-next-line es/no-object-defineproperty -- safe
425
426var $defineProperty$1 = Object.defineProperty; // `Object.defineProperty` method
427// https://tc39.es/ecma262/#sec-object.defineproperty
428
429objectDefineProperty.f = DESCRIPTORS$d ? $defineProperty$1 : function defineProperty(O, P, Attributes) {
430 anObject$c(O);
431 P = toPropertyKey$2(P);
432 anObject$c(Attributes);
433 if (IE8_DOM_DEFINE) try {
434 return $defineProperty$1(O, P, Attributes);
435 } catch (error) {
436 /* empty */
437 }
438 if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
439 if ('value' in Attributes) O[P] = Attributes.value;
440 return O;
441};
442
443var DESCRIPTORS$c = descriptors;
444var definePropertyModule$4 = objectDefineProperty;
445var createPropertyDescriptor$3 = createPropertyDescriptor$5;
446var createNonEnumerableProperty$9 = DESCRIPTORS$c ? function (object, key, value) {
447 return definePropertyModule$4.f(object, key, createPropertyDescriptor$3(1, value));
448} : function (object, key, value) {
449 object[key] = value;
450 return object;
451};
452
453var global$d = global$k;
454var getOwnPropertyDescriptor$6 = objectGetOwnPropertyDescriptor.f;
455var isForced = isForced_1;
456var path$v = path$x;
457var bind$b = functionBindContext;
458var createNonEnumerableProperty$8 = createNonEnumerableProperty$9;
459var has$9 = has$c;
460
461var wrapConstructor = function (NativeConstructor) {
462 var Wrapper = function (a, b, c) {
463 if (this instanceof NativeConstructor) {
464 switch (arguments.length) {
465 case 0:
466 return new NativeConstructor();
467
468 case 1:
469 return new NativeConstructor(a);
470
471 case 2:
472 return new NativeConstructor(a, b);
473 }
474
475 return new NativeConstructor(a, b, c);
476 }
477
478 return NativeConstructor.apply(this, arguments);
479 };
480
481 Wrapper.prototype = NativeConstructor.prototype;
482 return Wrapper;
483};
484/*
485 options.target - name of the target object
486 options.global - target is the global object
487 options.stat - export as static methods of target
488 options.proto - export as prototype methods of target
489 options.real - real prototype method for the `pure` version
490 options.forced - export even if the native feature is available
491 options.bind - bind methods to the target, required for the `pure` version
492 options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
493 options.unsafe - use the simple assignment of property instead of delete + defineProperty
494 options.sham - add a flag to not completely full polyfills
495 options.enumerable - export as enumerable property
496 options.noTargetGet - prevent calling a getter on target
497*/
498
499
500var _export = function (options, source) {
501 var TARGET = options.target;
502 var GLOBAL = options.global;
503 var STATIC = options.stat;
504 var PROTO = options.proto;
505 var nativeSource = GLOBAL ? global$d : STATIC ? global$d[TARGET] : (global$d[TARGET] || {}).prototype;
506 var target = GLOBAL ? path$v : path$v[TARGET] || (path$v[TARGET] = {});
507 var targetPrototype = target.prototype;
508 var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE;
509 var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor;
510
511 for (key in source) {
512 FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); // contains in native
513
514 USE_NATIVE = !FORCED && nativeSource && has$9(nativeSource, key);
515 targetProperty = target[key];
516 if (USE_NATIVE) if (options.noTargetGet) {
517 descriptor = getOwnPropertyDescriptor$6(nativeSource, key);
518 nativeProperty = descriptor && descriptor.value;
519 } else nativeProperty = nativeSource[key]; // export native or implementation
520
521 sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key];
522 if (USE_NATIVE && typeof targetProperty === typeof sourceProperty) continue; // bind timers to global for call from export context
523
524 if (options.bind && USE_NATIVE) resultProperty = bind$b(sourceProperty, global$d); // wrap global constructors for prevent changs in this version
525 else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty); // make static versions for prototype methods
526 else if (PROTO && typeof sourceProperty == 'function') resultProperty = bind$b(Function.call, sourceProperty); // default case
527 else resultProperty = sourceProperty; // add a flag to not completely full polyfills
528
529 if (options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) {
530 createNonEnumerableProperty$8(resultProperty, 'sham', true);
531 }
532
533 target[key] = resultProperty;
534
535 if (PROTO) {
536 VIRTUAL_PROTOTYPE = TARGET + 'Prototype';
537
538 if (!has$9(path$v, VIRTUAL_PROTOTYPE)) {
539 createNonEnumerableProperty$8(path$v, VIRTUAL_PROTOTYPE, {});
540 } // export virtual prototype methods
541
542
543 path$v[VIRTUAL_PROTOTYPE][key] = sourceProperty; // export real prototype methods
544
545 if (options.real && targetPrototype && !targetPrototype[key]) {
546 createNonEnumerableProperty$8(targetPrototype, key, sourceProperty);
547 }
548 }
549 }
550};
551
552var ceil = Math.ceil;
553var floor$1 = Math.floor; // `ToInteger` abstract operation
554// https://tc39.es/ecma262/#sec-tointeger
555
556var toInteger$4 = function (argument) {
557 return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor$1 : ceil)(argument);
558};
559
560var toInteger$3 = toInteger$4;
561var min$2 = Math.min; // `ToLength` abstract operation
562// https://tc39.es/ecma262/#sec-tolength
563
564var toLength$c = function (argument) {
565 return argument > 0 ? min$2(toInteger$3(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
566};
567
568var toInteger$2 = toInteger$4;
569var max$2 = Math.max;
570var min$1 = Math.min; // Helper for a popular repeating case of the spec:
571// Let integer be ? ToInteger(index).
572// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
573
574var toAbsoluteIndex$4 = function (index, length) {
575 var integer = toInteger$2(index);
576 return integer < 0 ? max$2(integer + length, 0) : min$1(integer, length);
577};
578
579var toIndexedObject$8 = toIndexedObject$a;
580var toLength$b = toLength$c;
581var toAbsoluteIndex$3 = toAbsoluteIndex$4; // `Array.prototype.{ indexOf, includes }` methods implementation
582
583var createMethod$5 = function (IS_INCLUDES) {
584 return function ($this, el, fromIndex) {
585 var O = toIndexedObject$8($this);
586 var length = toLength$b(O.length);
587 var index = toAbsoluteIndex$3(fromIndex, length);
588 var value; // Array#includes uses SameValueZero equality algorithm
589 // eslint-disable-next-line no-self-compare -- NaN check
590
591 if (IS_INCLUDES && el != el) while (length > index) {
592 value = O[index++]; // eslint-disable-next-line no-self-compare -- NaN check
593
594 if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not
595 } else for (; length > index; index++) {
596 if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
597 }
598 return !IS_INCLUDES && -1;
599 };
600};
601
602var arrayIncludes$1 = {
603 // `Array.prototype.includes` method
604 // https://tc39.es/ecma262/#sec-array.prototype.includes
605 includes: createMethod$5(true),
606 // `Array.prototype.indexOf` method
607 // https://tc39.es/ecma262/#sec-array.prototype.indexof
608 indexOf: createMethod$5(false)
609};
610
611var hiddenKeys$6 = {};
612
613var has$8 = has$c;
614var toIndexedObject$7 = toIndexedObject$a;
615var indexOf$4 = arrayIncludes$1.indexOf;
616var hiddenKeys$5 = hiddenKeys$6;
617
618var objectKeysInternal = function (object, names) {
619 var O = toIndexedObject$7(object);
620 var i = 0;
621 var result = [];
622 var key;
623
624 for (key in O) !has$8(hiddenKeys$5, key) && has$8(O, key) && result.push(key); // Don't enum bug & hidden keys
625
626
627 while (names.length > i) if (has$8(O, key = names[i++])) {
628 ~indexOf$4(result, key) || result.push(key);
629 }
630
631 return result;
632};
633
634var enumBugKeys$3 = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];
635
636var internalObjectKeys$1 = objectKeysInternal;
637var enumBugKeys$2 = enumBugKeys$3; // `Object.keys` method
638// https://tc39.es/ecma262/#sec-object.keys
639// eslint-disable-next-line es/no-object-keys -- safe
640
641var objectKeys$4 = Object.keys || function keys(O) {
642 return internalObjectKeys$1(O, enumBugKeys$2);
643};
644
645var objectGetOwnPropertySymbols = {};
646
647objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols;
648
649var DESCRIPTORS$b = descriptors;
650var fails$g = fails$m;
651var objectKeys$3 = objectKeys$4;
652var getOwnPropertySymbolsModule$2 = objectGetOwnPropertySymbols;
653var propertyIsEnumerableModule$1 = objectPropertyIsEnumerable;
654var toObject$c = toObject$e;
655var IndexedObject$2 = indexedObject; // eslint-disable-next-line es/no-object-assign -- safe
656
657var $assign = Object.assign; // eslint-disable-next-line es/no-object-defineproperty -- required for testing
658
659var defineProperty$b = Object.defineProperty; // `Object.assign` method
660// https://tc39.es/ecma262/#sec-object.assign
661
662var objectAssign = !$assign || fails$g(function () {
663 // should have correct order of operations (Edge bug)
664 if (DESCRIPTORS$b && $assign({
665 b: 1
666 }, $assign(defineProperty$b({}, 'a', {
667 enumerable: true,
668 get: function () {
669 defineProperty$b(this, 'b', {
670 value: 3,
671 enumerable: false
672 });
673 }
674 }), {
675 b: 2
676 })).b !== 1) return true; // should work with symbols and should have deterministic property order (V8 bug)
677
678 var A = {};
679 var B = {}; // eslint-disable-next-line es/no-symbol -- safe
680
681 var symbol = Symbol();
682 var alphabet = 'abcdefghijklmnopqrst';
683 A[symbol] = 7;
684 alphabet.split('').forEach(function (chr) {
685 B[chr] = chr;
686 });
687 return $assign({}, A)[symbol] != 7 || objectKeys$3($assign({}, B)).join('') != alphabet;
688}) ? function assign(target, source) {
689 // eslint-disable-line no-unused-vars -- required for `.length`
690 var T = toObject$c(target);
691 var argumentsLength = arguments.length;
692 var index = 1;
693 var getOwnPropertySymbols = getOwnPropertySymbolsModule$2.f;
694 var propertyIsEnumerable = propertyIsEnumerableModule$1.f;
695
696 while (argumentsLength > index) {
697 var S = IndexedObject$2(arguments[index++]);
698 var keys = getOwnPropertySymbols ? objectKeys$3(S).concat(getOwnPropertySymbols(S)) : objectKeys$3(S);
699 var length = keys.length;
700 var j = 0;
701 var key;
702
703 while (length > j) {
704 key = keys[j++];
705 if (!DESCRIPTORS$b || propertyIsEnumerable.call(S, key)) T[key] = S[key];
706 }
707 }
708
709 return T;
710} : $assign;
711
712var $$J = _export;
713var assign$5 = objectAssign; // `Object.assign` method
714// https://tc39.es/ecma262/#sec-object.assign
715// eslint-disable-next-line es/no-object-assign -- required for testing
716
717$$J({
718 target: 'Object',
719 stat: true,
720 forced: Object.assign !== assign$5
721}, {
722 assign: assign$5
723});
724
725var path$u = path$x;
726var assign$4 = path$u.Object.assign;
727
728var parent$Z = assign$4;
729var assign$3 = parent$Z;
730
731var assign$2 = assign$3;
732
733var aFunction$4 = aFunction$6;
734var isObject$e = isObject$j;
735var slice$7 = [].slice;
736var factories = {};
737
738var construct$3 = function (C, argsLength, args) {
739 if (!(argsLength in factories)) {
740 for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; // eslint-disable-next-line no-new-func -- we have no proper alternatives, IE8- only
741
742
743 factories[argsLength] = Function('C,a', 'return new C(' + list.join(',') + ')');
744 }
745
746 return factories[argsLength](C, args);
747}; // `Function.prototype.bind` method implementation
748// https://tc39.es/ecma262/#sec-function.prototype.bind
749
750
751var functionBind = Function.bind || function bind(that
752/* , ...args */
753) {
754 var fn = aFunction$4(this);
755 var partArgs = slice$7.call(arguments, 1);
756
757 var boundFunction = function bound() {
758 var args = partArgs.concat(slice$7.call(arguments));
759 return this instanceof boundFunction ? construct$3(fn, args.length, args) : fn.apply(that, args);
760 };
761
762 if (isObject$e(fn.prototype)) boundFunction.prototype = fn.prototype;
763 return boundFunction;
764};
765
766var $$I = _export;
767var bind$a = functionBind; // `Function.prototype.bind` method
768// https://tc39.es/ecma262/#sec-function.prototype.bind
769
770$$I({
771 target: 'Function',
772 proto: true
773}, {
774 bind: bind$a
775});
776
777var path$t = path$x;
778
779var entryVirtual$l = function (CONSTRUCTOR) {
780 return path$t[CONSTRUCTOR + 'Prototype'];
781};
782
783var entryVirtual$k = entryVirtual$l;
784var bind$9 = entryVirtual$k('Function').bind;
785
786var bind$8 = bind$9;
787var FunctionPrototype = Function.prototype;
788
789var bind_1 = function (it) {
790 var own = it.bind;
791 return it === FunctionPrototype || it instanceof Function && own === FunctionPrototype.bind ? bind$8 : own;
792};
793
794var parent$Y = bind_1;
795var bind$7 = parent$Y;
796
797var bind$6 = bind$7;
798
799/**
800 * Draw a circle.
801 *
802 * @param ctx - The context this shape will be rendered to.
803 * @param x - The position of the center on the x axis.
804 * @param y - The position of the center on the y axis.
805 * @param r - The radius of the circle.
806 */
807function drawCircle(ctx, x, y, r) {
808 ctx.beginPath();
809 ctx.arc(x, y, r, 0, 2 * Math.PI, false);
810 ctx.closePath();
811}
812/**
813 * Draw a square.
814 *
815 * @param ctx - The context this shape will be rendered to.
816 * @param x - The position of the center on the x axis.
817 * @param y - The position of the center on the y axis.
818 * @param r - Half of the width and height of the square.
819 */
820
821function drawSquare(ctx, x, y, r) {
822 ctx.beginPath();
823 ctx.rect(x - r, y - r, r * 2, r * 2);
824 ctx.closePath();
825}
826/**
827 * Draw an equilateral triangle standing on a side.
828 *
829 * @param ctx - The context this shape will be rendered to.
830 * @param x - The position of the center on the x axis.
831 * @param y - The position of the center on the y axis.
832 * @param r - Half of the length of the sides.
833 *
834 * @remarks
835 * http://en.wikipedia.org/wiki/Equilateral_triangle
836 */
837
838function drawTriangle(ctx, x, y, r) {
839 ctx.beginPath(); // the change in radius and the offset is here to center the shape
840
841 r *= 1.15;
842 y += 0.275 * r;
843 var s = r * 2;
844 var s2 = s / 2;
845 var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
846
847 var h = Math.sqrt(s * s - s2 * s2); // height
848
849 ctx.moveTo(x, y - (h - ir));
850 ctx.lineTo(x + s2, y + ir);
851 ctx.lineTo(x - s2, y + ir);
852 ctx.lineTo(x, y - (h - ir));
853 ctx.closePath();
854}
855/**
856 * Draw an equilateral triangle standing on a vertex.
857 *
858 * @param ctx - The context this shape will be rendered to.
859 * @param x - The position of the center on the x axis.
860 * @param y - The position of the center on the y axis.
861 * @param r - Half of the length of the sides.
862 *
863 * @remarks
864 * http://en.wikipedia.org/wiki/Equilateral_triangle
865 */
866
867function drawTriangleDown(ctx, x, y, r) {
868 ctx.beginPath(); // the change in radius and the offset is here to center the shape
869
870 r *= 1.15;
871 y -= 0.275 * r;
872 var s = r * 2;
873 var s2 = s / 2;
874 var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
875
876 var h = Math.sqrt(s * s - s2 * s2); // height
877
878 ctx.moveTo(x, y + (h - ir));
879 ctx.lineTo(x + s2, y - ir);
880 ctx.lineTo(x - s2, y - ir);
881 ctx.lineTo(x, y + (h - ir));
882 ctx.closePath();
883}
884/**
885 * Draw a star.
886 *
887 * @param ctx - The context this shape will be rendered to.
888 * @param x - The position of the center on the x axis.
889 * @param y - The position of the center on the y axis.
890 * @param r - The outer radius of the star.
891 */
892
893function drawStar(ctx, x, y, r) {
894 // http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
895 ctx.beginPath(); // the change in radius and the offset is here to center the shape
896
897 r *= 0.82;
898 y += 0.1 * r;
899
900 for (var n = 0; n < 10; n++) {
901 var radius = n % 2 === 0 ? r * 1.3 : r * 0.5;
902 ctx.lineTo(x + radius * Math.sin(n * 2 * Math.PI / 10), y - radius * Math.cos(n * 2 * Math.PI / 10));
903 }
904
905 ctx.closePath();
906}
907/**
908 * Draw a diamond.
909 *
910 * @param ctx - The context this shape will be rendered to.
911 * @param x - The position of the center on the x axis.
912 * @param y - The position of the center on the y axis.
913 * @param r - Half of the width and height of the diamond.
914 *
915 * @remarks
916 * http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
917 */
918
919function drawDiamond(ctx, x, y, r) {
920 ctx.beginPath();
921 ctx.lineTo(x, y + r);
922 ctx.lineTo(x + r, y);
923 ctx.lineTo(x, y - r);
924 ctx.lineTo(x - r, y);
925 ctx.closePath();
926}
927/**
928 * Draw a rectangle with rounded corners.
929 *
930 * @param ctx - The context this shape will be rendered to.
931 * @param x - The position of the center on the x axis.
932 * @param y - The position of the center on the y axis.
933 * @param w - The width of the rectangle.
934 * @param h - The height of the rectangle.
935 * @param r - The radius of the corners.
936 *
937 * @remarks
938 * http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
939 */
940
941function drawRoundRect(ctx, x, y, w, h, r) {
942 var r2d = Math.PI / 180;
943
944 if (w - 2 * r < 0) {
945 r = w / 2;
946 } //ensure that the radius isn't too large for x
947
948
949 if (h - 2 * r < 0) {
950 r = h / 2;
951 } //ensure that the radius isn't too large for y
952
953
954 ctx.beginPath();
955 ctx.moveTo(x + r, y);
956 ctx.lineTo(x + w - r, y);
957 ctx.arc(x + w - r, y + r, r, r2d * 270, r2d * 360, false);
958 ctx.lineTo(x + w, y + h - r);
959 ctx.arc(x + w - r, y + h - r, r, 0, r2d * 90, false);
960 ctx.lineTo(x + r, y + h);
961 ctx.arc(x + r, y + h - r, r, r2d * 90, r2d * 180, false);
962 ctx.lineTo(x, y + r);
963 ctx.arc(x + r, y + r, r, r2d * 180, r2d * 270, false);
964 ctx.closePath();
965}
966/**
967 * Draw an ellipse.
968 *
969 * @param ctx - The context this shape will be rendered to.
970 * @param x - The position of the center on the x axis.
971 * @param y - The position of the center on the y axis.
972 * @param w - The width of the ellipse.
973 * @param h - The height of the ellipse.
974 *
975 * @remarks
976 * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
977 *
978 * Postfix '_vis' added to discern it from standard method ellipse().
979 */
980
981function drawEllipse(ctx, x, y, w, h) {
982 var kappa = 0.5522848,
983 ox = w / 2 * kappa,
984 // control point offset horizontal
985 oy = h / 2 * kappa,
986 // control point offset vertical
987 xe = x + w,
988 // x-end
989 ye = y + h,
990 // y-end
991 xm = x + w / 2,
992 // x-middle
993 ym = y + h / 2; // y-middle
994
995 ctx.beginPath();
996 ctx.moveTo(x, ym);
997 ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
998 ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
999 ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
1000 ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
1001 ctx.closePath();
1002}
1003/**
1004 * Draw an isometric cylinder.
1005 *
1006 * @param ctx - The context this shape will be rendered to.
1007 * @param x - The position of the center on the x axis.
1008 * @param y - The position of the center on the y axis.
1009 * @param w - The width of the database.
1010 * @param h - The height of the database.
1011 *
1012 * @remarks
1013 * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
1014 */
1015
1016function drawDatabase(ctx, x, y, w, h) {
1017 var f = 1 / 3;
1018 var wEllipse = w;
1019 var hEllipse = h * f;
1020 var kappa = 0.5522848,
1021 ox = wEllipse / 2 * kappa,
1022 // control point offset horizontal
1023 oy = hEllipse / 2 * kappa,
1024 // control point offset vertical
1025 xe = x + wEllipse,
1026 // x-end
1027 ye = y + hEllipse,
1028 // y-end
1029 xm = x + wEllipse / 2,
1030 // x-middle
1031 ym = y + hEllipse / 2,
1032 // y-middle
1033 ymb = y + (h - hEllipse / 2),
1034 // y-midlle, bottom ellipse
1035 yeb = y + h; // y-end, bottom ellipse
1036
1037 ctx.beginPath();
1038 ctx.moveTo(xe, ym);
1039 ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
1040 ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
1041 ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
1042 ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
1043 ctx.lineTo(xe, ymb);
1044 ctx.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb);
1045 ctx.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb);
1046 ctx.lineTo(x, ym);
1047}
1048/**
1049 * Draw a dashed line.
1050 *
1051 * @param ctx - The context this shape will be rendered to.
1052 * @param x - The start position on the x axis.
1053 * @param y - The start position on the y axis.
1054 * @param x2 - The end position on the x axis.
1055 * @param y2 - The end position on the y axis.
1056 * @param pattern - List of lengths starting with line and then alternating between space and line.
1057 *
1058 * @author David Jordan
1059 * @remarks
1060 * date 2012-08-08
1061 * http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
1062 */
1063
1064function drawDashedLine(ctx, x, y, x2, y2, pattern) {
1065 ctx.beginPath();
1066 ctx.moveTo(x, y);
1067 var patternLength = pattern.length;
1068 var dx = x2 - x;
1069 var dy = y2 - y;
1070 var slope = dy / dx;
1071 var distRemaining = Math.sqrt(dx * dx + dy * dy);
1072 var patternIndex = 0;
1073 var draw = true;
1074 var xStep = 0;
1075 var dashLength = +pattern[0];
1076
1077 while (distRemaining >= 0.1) {
1078 dashLength = +pattern[patternIndex++ % patternLength];
1079
1080 if (dashLength > distRemaining) {
1081 dashLength = distRemaining;
1082 }
1083
1084 xStep = Math.sqrt(dashLength * dashLength / (1 + slope * slope));
1085 xStep = dx < 0 ? -xStep : xStep;
1086 x += xStep;
1087 y += slope * xStep;
1088
1089 if (draw === true) {
1090 ctx.lineTo(x, y);
1091 } else {
1092 ctx.moveTo(x, y);
1093 }
1094
1095 distRemaining -= dashLength;
1096 draw = !draw;
1097 }
1098}
1099/**
1100 * Draw a hexagon.
1101 *
1102 * @param ctx - The context this shape will be rendered to.
1103 * @param x - The position of the center on the x axis.
1104 * @param y - The position of the center on the y axis.
1105 * @param r - The radius of the hexagon.
1106 */
1107
1108function drawHexagon(ctx, x, y, r) {
1109 ctx.beginPath();
1110 var sides = 6;
1111 var a = Math.PI * 2 / sides;
1112 ctx.moveTo(x + r, y);
1113
1114 for (var i = 1; i < sides; i++) {
1115 ctx.lineTo(x + r * Math.cos(a * i), y + r * Math.sin(a * i));
1116 }
1117
1118 ctx.closePath();
1119}
1120var shapeMap = {
1121 circle: drawCircle,
1122 dashedLine: drawDashedLine,
1123 database: drawDatabase,
1124 diamond: drawDiamond,
1125 ellipse: drawEllipse,
1126 ellipse_vis: drawEllipse,
1127 hexagon: drawHexagon,
1128 roundRect: drawRoundRect,
1129 square: drawSquare,
1130 star: drawStar,
1131 triangle: drawTriangle,
1132 triangleDown: drawTriangleDown
1133};
1134/**
1135 * Returns either custom or native drawing function base on supplied name.
1136 *
1137 * @param name - The name of the function. Either the name of a
1138 * CanvasRenderingContext2D property or an export from shapes.ts without the
1139 * draw prefix.
1140 *
1141 * @returns The function that can be used for rendering. In case of native
1142 * CanvasRenderingContext2D function the API is normalized to
1143 * `(ctx: CanvasRenderingContext2D, ...originalArgs) => void`.
1144 */
1145
1146function getShape(name) {
1147 if (Object.prototype.hasOwnProperty.call(shapeMap, name)) {
1148 return shapeMap[name];
1149 } else {
1150 return function (ctx) {
1151 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1152 args[_key - 1] = arguments[_key];
1153 }
1154
1155 CanvasRenderingContext2D.prototype[name].call(ctx, args);
1156 };
1157 }
1158}
1159
1160function styleInject(css, ref) {
1161 if (ref === void 0) ref = {};
1162 var insertAt = ref.insertAt;
1163
1164 if (!css || typeof document === 'undefined') {
1165 return;
1166 }
1167
1168 var head = document.head || document.getElementsByTagName('head')[0];
1169 var style = document.createElement('style');
1170 style.type = 'text/css';
1171
1172 if (insertAt === 'top') {
1173 if (head.firstChild) {
1174 head.insertBefore(style, head.firstChild);
1175 } else {
1176 head.appendChild(style);
1177 }
1178 } else {
1179 head.appendChild(style);
1180 }
1181
1182 if (style.styleSheet) {
1183 style.styleSheet.cssText = css;
1184 } else {
1185 style.appendChild(document.createTextNode(css));
1186 }
1187}
1188
1189var css_248z$6 = ".vis-overlay {\n position: absolute;\n top: 0px;\n right: 0px;\n bottom: 0px;\n left: 0px;\n\n /* Must be displayed above for example selected Timeline items */\n z-index: 10;\n}\n\n.vis-active {\n box-shadow: 0 0 10px #86d5f8;\n}\n";
1190styleInject(css_248z$6);
1191
1192var css_248z$5 = "/* override some bootstrap styles screwing up the timelines css */\n\n.vis [class*=\"span\"] {\n min-height: 0;\n width: auto;\n}\n";
1193styleInject(css_248z$5);
1194
1195var css_248z$4 = "div.vis-color-picker {\n position: absolute;\n top: 0px;\n left: 30px;\n margin-top: -140px;\n margin-left: 30px;\n width: 310px;\n height: 444px;\n z-index: 1;\n padding: 10px;\n border-radius: 15px;\n background-color: #ffffff;\n display: none;\n box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 10px 0px;\n}\n\ndiv.vis-color-picker div.vis-arrow {\n position: absolute;\n top: 147px;\n left: 5px;\n}\n\ndiv.vis-color-picker div.vis-arrow::after,\ndiv.vis-color-picker div.vis-arrow::before {\n right: 100%;\n top: 50%;\n border: solid transparent;\n content: \" \";\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n}\n\ndiv.vis-color-picker div.vis-arrow:after {\n border-color: rgba(255, 255, 255, 0);\n border-right-color: #ffffff;\n border-width: 30px;\n margin-top: -30px;\n}\n\ndiv.vis-color-picker div.vis-color {\n position: absolute;\n width: 289px;\n height: 289px;\n cursor: pointer;\n}\n\ndiv.vis-color-picker div.vis-brightness {\n position: absolute;\n top: 313px;\n}\n\ndiv.vis-color-picker div.vis-opacity {\n position: absolute;\n top: 350px;\n}\n\ndiv.vis-color-picker div.vis-selector {\n position: absolute;\n top: 137px;\n left: 137px;\n width: 15px;\n height: 15px;\n border-radius: 15px;\n border: 1px solid #ffffff;\n background: #4c4c4c; /* Old browsers */\n background: -moz-linear-gradient(\n top,\n #4c4c4c 0%,\n #595959 12%,\n #666666 25%,\n #474747 39%,\n #2c2c2c 50%,\n #000000 51%,\n #111111 60%,\n #2b2b2b 76%,\n #1c1c1c 91%,\n #131313 100%\n ); /* FF3.6+ */\n background: -webkit-gradient(\n linear,\n left top,\n left bottom,\n color-stop(0%, #4c4c4c),\n color-stop(12%, #595959),\n color-stop(25%, #666666),\n color-stop(39%, #474747),\n color-stop(50%, #2c2c2c),\n color-stop(51%, #000000),\n color-stop(60%, #111111),\n color-stop(76%, #2b2b2b),\n color-stop(91%, #1c1c1c),\n color-stop(100%, #131313)\n ); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(\n top,\n #4c4c4c 0%,\n #595959 12%,\n #666666 25%,\n #474747 39%,\n #2c2c2c 50%,\n #000000 51%,\n #111111 60%,\n #2b2b2b 76%,\n #1c1c1c 91%,\n #131313 100%\n ); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(\n top,\n #4c4c4c 0%,\n #595959 12%,\n #666666 25%,\n #474747 39%,\n #2c2c2c 50%,\n #000000 51%,\n #111111 60%,\n #2b2b2b 76%,\n #1c1c1c 91%,\n #131313 100%\n ); /* Opera 11.10+ */\n background: -ms-linear-gradient(\n top,\n #4c4c4c 0%,\n #595959 12%,\n #666666 25%,\n #474747 39%,\n #2c2c2c 50%,\n #000000 51%,\n #111111 60%,\n #2b2b2b 76%,\n #1c1c1c 91%,\n #131313 100%\n ); /* IE10+ */\n background: linear-gradient(\n to bottom,\n #4c4c4c 0%,\n #595959 12%,\n #666666 25%,\n #474747 39%,\n #2c2c2c 50%,\n #000000 51%,\n #111111 60%,\n #2b2b2b 76%,\n #1c1c1c 91%,\n #131313 100%\n ); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */\n}\n\ndiv.vis-color-picker div.vis-new-color {\n position: absolute;\n width: 140px;\n height: 20px;\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 5px;\n top: 380px;\n left: 159px;\n text-align: right;\n padding-right: 2px;\n font-size: 10px;\n color: rgba(0, 0, 0, 0.4);\n vertical-align: middle;\n line-height: 20px;\n}\n\ndiv.vis-color-picker div.vis-initial-color {\n position: absolute;\n width: 140px;\n height: 20px;\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 5px;\n top: 380px;\n left: 10px;\n text-align: left;\n padding-left: 2px;\n font-size: 10px;\n color: rgba(0, 0, 0, 0.4);\n vertical-align: middle;\n line-height: 20px;\n}\n\ndiv.vis-color-picker div.vis-label {\n position: absolute;\n width: 300px;\n left: 10px;\n}\n\ndiv.vis-color-picker div.vis-label.vis-brightness {\n top: 300px;\n}\n\ndiv.vis-color-picker div.vis-label.vis-opacity {\n top: 338px;\n}\n\ndiv.vis-color-picker div.vis-button {\n position: absolute;\n width: 68px;\n height: 25px;\n border-radius: 10px;\n vertical-align: middle;\n text-align: center;\n line-height: 25px;\n top: 410px;\n border: 2px solid #d9d9d9;\n background-color: #f7f7f7;\n cursor: pointer;\n}\n\ndiv.vis-color-picker div.vis-button.vis-cancel {\n /*border:2px solid #ff4e33;*/\n /*background-color: #ff7761;*/\n left: 5px;\n}\ndiv.vis-color-picker div.vis-button.vis-load {\n /*border:2px solid #a153e6;*/\n /*background-color: #cb8dff;*/\n left: 82px;\n}\ndiv.vis-color-picker div.vis-button.vis-apply {\n /*border:2px solid #4588e6;*/\n /*background-color: #82b6ff;*/\n left: 159px;\n}\ndiv.vis-color-picker div.vis-button.vis-save {\n /*border:2px solid #45e655;*/\n /*background-color: #6dff7c;*/\n left: 236px;\n}\n\ndiv.vis-color-picker input.vis-range {\n width: 290px;\n height: 20px;\n}\n\n/* TODO: is this redundant?\ndiv.vis-color-picker input.vis-range-brightness {\n width: 289px !important;\n}\n\n\ndiv.vis-color-picker input.vis-saturation-range {\n width: 289px !important;\n}*/\n";
1196styleInject(css_248z$4);
1197
1198var css_248z$3 = "div.vis-configuration {\n position: relative;\n display: block;\n float: left;\n font-size: 12px;\n}\n\ndiv.vis-configuration-wrapper {\n display: block;\n width: 700px;\n}\n\ndiv.vis-configuration-wrapper::after {\n clear: both;\n content: \"\";\n display: block;\n}\n\ndiv.vis-configuration.vis-config-option-container {\n display: block;\n width: 495px;\n background-color: #ffffff;\n border: 2px solid #f7f8fa;\n border-radius: 4px;\n margin-top: 20px;\n left: 10px;\n padding-left: 5px;\n}\n\ndiv.vis-configuration.vis-config-button {\n display: block;\n width: 495px;\n height: 25px;\n vertical-align: middle;\n line-height: 25px;\n background-color: #f7f8fa;\n border: 2px solid #ceced0;\n border-radius: 4px;\n margin-top: 20px;\n left: 10px;\n padding-left: 5px;\n cursor: pointer;\n margin-bottom: 30px;\n}\n\ndiv.vis-configuration.vis-config-button.hover {\n background-color: #4588e6;\n border: 2px solid #214373;\n color: #ffffff;\n}\n\ndiv.vis-configuration.vis-config-item {\n display: block;\n float: left;\n width: 495px;\n height: 25px;\n vertical-align: middle;\n line-height: 25px;\n}\n\ndiv.vis-configuration.vis-config-item.vis-config-s2 {\n left: 10px;\n background-color: #f7f8fa;\n padding-left: 5px;\n border-radius: 3px;\n}\ndiv.vis-configuration.vis-config-item.vis-config-s3 {\n left: 20px;\n background-color: #e4e9f0;\n padding-left: 5px;\n border-radius: 3px;\n}\ndiv.vis-configuration.vis-config-item.vis-config-s4 {\n left: 30px;\n background-color: #cfd8e6;\n padding-left: 5px;\n border-radius: 3px;\n}\n\ndiv.vis-configuration.vis-config-header {\n font-size: 18px;\n font-weight: bold;\n}\n\ndiv.vis-configuration.vis-config-label {\n width: 120px;\n height: 25px;\n line-height: 25px;\n}\n\ndiv.vis-configuration.vis-config-label.vis-config-s3 {\n width: 110px;\n}\ndiv.vis-configuration.vis-config-label.vis-config-s4 {\n width: 100px;\n}\n\ndiv.vis-configuration.vis-config-colorBlock {\n top: 1px;\n width: 30px;\n height: 19px;\n border: 1px solid #444444;\n border-radius: 2px;\n padding: 0px;\n margin: 0px;\n cursor: pointer;\n}\n\ninput.vis-configuration.vis-config-checkbox {\n left: -5px;\n}\n\ninput.vis-configuration.vis-config-rangeinput {\n position: relative;\n top: -5px;\n width: 60px;\n /*height:13px;*/\n padding: 1px;\n margin: 0;\n pointer-events: none;\n}\n\ninput.vis-configuration.vis-config-range {\n /*removes default webkit styles*/\n -webkit-appearance: none;\n\n /*fix for FF unable to apply focus style bug */\n border: 0px solid white;\n background-color: rgba(0, 0, 0, 0);\n\n /*required for proper track sizing in FF*/\n width: 300px;\n height: 20px;\n}\ninput.vis-configuration.vis-config-range::-webkit-slider-runnable-track {\n width: 300px;\n height: 5px;\n background: #dedede; /* Old browsers */\n background: -moz-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* FF3.6+ */\n background: -webkit-gradient(\n linear,\n left top,\n left bottom,\n color-stop(0%, #dedede),\n color-stop(99%, #c8c8c8)\n ); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(\n top,\n #dedede 0%,\n #c8c8c8 99%\n ); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(\n top,\n #dedede 0%,\n #c8c8c8 99%\n ); /* Opera 11.10+ */\n background: -ms-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* IE10+ */\n background: linear-gradient(to bottom, #dedede 0%, #c8c8c8 99%); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dedede', endColorstr='#c8c8c8',GradientType=0 ); /* IE6-9 */\n\n border: 1px solid #999999;\n box-shadow: #aaaaaa 0px 0px 3px 0px;\n border-radius: 3px;\n}\ninput.vis-configuration.vis-config-range::-webkit-slider-thumb {\n -webkit-appearance: none;\n border: 1px solid #14334b;\n height: 17px;\n width: 17px;\n border-radius: 50%;\n background: #3876c2; /* Old browsers */\n background: -moz-linear-gradient(top, #3876c2 0%, #385380 100%); /* FF3.6+ */\n background: -webkit-gradient(\n linear,\n left top,\n left bottom,\n color-stop(0%, #3876c2),\n color-stop(100%, #385380)\n ); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(\n top,\n #3876c2 0%,\n #385380 100%\n ); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(\n top,\n #3876c2 0%,\n #385380 100%\n ); /* Opera 11.10+ */\n background: -ms-linear-gradient(top, #3876c2 0%, #385380 100%); /* IE10+ */\n background: linear-gradient(to bottom, #3876c2 0%, #385380 100%); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3876c2', endColorstr='#385380',GradientType=0 ); /* IE6-9 */\n box-shadow: #111927 0px 0px 1px 0px;\n margin-top: -7px;\n}\ninput.vis-configuration.vis-config-range:focus {\n outline: none;\n}\ninput.vis-configuration.vis-config-range:focus::-webkit-slider-runnable-track {\n background: #9d9d9d; /* Old browsers */\n background: -moz-linear-gradient(top, #9d9d9d 0%, #c8c8c8 99%); /* FF3.6+ */\n background: -webkit-gradient(\n linear,\n left top,\n left bottom,\n color-stop(0%, #9d9d9d),\n color-stop(99%, #c8c8c8)\n ); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(\n top,\n #9d9d9d 0%,\n #c8c8c8 99%\n ); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(\n top,\n #9d9d9d 0%,\n #c8c8c8 99%\n ); /* Opera 11.10+ */\n background: -ms-linear-gradient(top, #9d9d9d 0%, #c8c8c8 99%); /* IE10+ */\n background: linear-gradient(to bottom, #9d9d9d 0%, #c8c8c8 99%); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9d9d9d', endColorstr='#c8c8c8',GradientType=0 ); /* IE6-9 */\n}\n\ninput.vis-configuration.vis-config-range::-moz-range-track {\n width: 300px;\n height: 10px;\n background: #dedede; /* Old browsers */\n background: -moz-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* FF3.6+ */\n background: -webkit-gradient(\n linear,\n left top,\n left bottom,\n color-stop(0%, #dedede),\n color-stop(99%, #c8c8c8)\n ); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(\n top,\n #dedede 0%,\n #c8c8c8 99%\n ); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(\n top,\n #dedede 0%,\n #c8c8c8 99%\n ); /* Opera 11.10+ */\n background: -ms-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* IE10+ */\n background: linear-gradient(to bottom, #dedede 0%, #c8c8c8 99%); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dedede', endColorstr='#c8c8c8',GradientType=0 ); /* IE6-9 */\n\n border: 1px solid #999999;\n box-shadow: #aaaaaa 0px 0px 3px 0px;\n border-radius: 3px;\n}\ninput.vis-configuration.vis-config-range::-moz-range-thumb {\n border: none;\n height: 16px;\n width: 16px;\n\n border-radius: 50%;\n background: #385380;\n}\n\n/*hide the outline behind the border*/\ninput.vis-configuration.vis-config-range:-moz-focusring {\n outline: 1px solid white;\n outline-offset: -1px;\n}\n\ninput.vis-configuration.vis-config-range::-ms-track {\n width: 300px;\n height: 5px;\n\n /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */\n background: transparent;\n\n /*leave room for the larger thumb to overflow with a transparent border */\n border-color: transparent;\n border-width: 6px 0;\n\n /*remove default tick marks*/\n color: transparent;\n}\ninput.vis-configuration.vis-config-range::-ms-fill-lower {\n background: #777;\n border-radius: 10px;\n}\ninput.vis-configuration.vis-config-range::-ms-fill-upper {\n background: #ddd;\n border-radius: 10px;\n}\ninput.vis-configuration.vis-config-range::-ms-thumb {\n border: none;\n height: 16px;\n width: 16px;\n border-radius: 50%;\n background: #385380;\n}\ninput.vis-configuration.vis-config-range:focus::-ms-fill-lower {\n background: #888;\n}\ninput.vis-configuration.vis-config-range:focus::-ms-fill-upper {\n background: #ccc;\n}\n\n.vis-configuration-popup {\n position: absolute;\n background: rgba(57, 76, 89, 0.85);\n border: 2px solid #f2faff;\n line-height: 30px;\n height: 30px;\n width: 150px;\n text-align: center;\n color: #ffffff;\n font-size: 14px;\n border-radius: 4px;\n -webkit-transition: opacity 0.3s ease-in-out;\n -moz-transition: opacity 0.3s ease-in-out;\n transition: opacity 0.3s ease-in-out;\n}\n.vis-configuration-popup:after,\n.vis-configuration-popup:before {\n left: 100%;\n top: 50%;\n border: solid transparent;\n content: \" \";\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n}\n\n.vis-configuration-popup:after {\n border-color: rgba(136, 183, 213, 0);\n border-left-color: rgba(57, 76, 89, 0.85);\n border-width: 8px;\n margin-top: -8px;\n}\n.vis-configuration-popup:before {\n border-color: rgba(194, 225, 245, 0);\n border-left-color: #f2faff;\n border-width: 12px;\n margin-top: -12px;\n}\n";
1199styleInject(css_248z$3);
1200
1201var css_248z$2 = "div.vis-tooltip {\n position: absolute;\n visibility: hidden;\n padding: 5px;\n white-space: nowrap;\n\n font-family: verdana;\n font-size: 14px;\n color: #000000;\n background-color: #f5f4ed;\n\n -moz-border-radius: 3px;\n -webkit-border-radius: 3px;\n border-radius: 3px;\n border: 1px solid #808074;\n\n box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);\n pointer-events: none;\n\n z-index: 5;\n}\n";
1202styleInject(css_248z$2);
1203
1204var componentEmitter = {exports: {}};
1205
1206(function (module) {
1207 /**
1208 * Expose `Emitter`.
1209 */
1210 {
1211 module.exports = Emitter;
1212 }
1213 /**
1214 * Initialize a new `Emitter`.
1215 *
1216 * @api public
1217 */
1218
1219
1220 function Emitter(obj) {
1221 if (obj) return mixin(obj);
1222 }
1223 /**
1224 * Mixin the emitter properties.
1225 *
1226 * @param {Object} obj
1227 * @return {Object}
1228 * @api private
1229 */
1230
1231 function mixin(obj) {
1232 for (var key in Emitter.prototype) {
1233 obj[key] = Emitter.prototype[key];
1234 }
1235
1236 return obj;
1237 }
1238 /**
1239 * Listen on the given `event` with `fn`.
1240 *
1241 * @param {String} event
1242 * @param {Function} fn
1243 * @return {Emitter}
1244 * @api public
1245 */
1246
1247
1248 Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
1249 this._callbacks = this._callbacks || {};
1250 (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);
1251 return this;
1252 };
1253 /**
1254 * Adds an `event` listener that will be invoked a single
1255 * time then automatically removed.
1256 *
1257 * @param {String} event
1258 * @param {Function} fn
1259 * @return {Emitter}
1260 * @api public
1261 */
1262
1263
1264 Emitter.prototype.once = function (event, fn) {
1265 function on() {
1266 this.off(event, on);
1267 fn.apply(this, arguments);
1268 }
1269
1270 on.fn = fn;
1271 this.on(event, on);
1272 return this;
1273 };
1274 /**
1275 * Remove the given callback for `event` or all
1276 * registered callbacks.
1277 *
1278 * @param {String} event
1279 * @param {Function} fn
1280 * @return {Emitter}
1281 * @api public
1282 */
1283
1284
1285 Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
1286 this._callbacks = this._callbacks || {}; // all
1287
1288 if (0 == arguments.length) {
1289 this._callbacks = {};
1290 return this;
1291 } // specific event
1292
1293
1294 var callbacks = this._callbacks['$' + event];
1295 if (!callbacks) return this; // remove all handlers
1296
1297 if (1 == arguments.length) {
1298 delete this._callbacks['$' + event];
1299 return this;
1300 } // remove specific handler
1301
1302
1303 var cb;
1304
1305 for (var i = 0; i < callbacks.length; i++) {
1306 cb = callbacks[i];
1307
1308 if (cb === fn || cb.fn === fn) {
1309 callbacks.splice(i, 1);
1310 break;
1311 }
1312 } // Remove event specific arrays for event types that no
1313 // one is subscribed for to avoid memory leak.
1314
1315
1316 if (callbacks.length === 0) {
1317 delete this._callbacks['$' + event];
1318 }
1319
1320 return this;
1321 };
1322 /**
1323 * Emit `event` with the given args.
1324 *
1325 * @param {String} event
1326 * @param {Mixed} ...
1327 * @return {Emitter}
1328 */
1329
1330
1331 Emitter.prototype.emit = function (event) {
1332 this._callbacks = this._callbacks || {};
1333 var args = new Array(arguments.length - 1),
1334 callbacks = this._callbacks['$' + event];
1335
1336 for (var i = 1; i < arguments.length; i++) {
1337 args[i - 1] = arguments[i];
1338 }
1339
1340 if (callbacks) {
1341 callbacks = callbacks.slice(0);
1342
1343 for (var i = 0, len = callbacks.length; i < len; ++i) {
1344 callbacks[i].apply(this, args);
1345 }
1346 }
1347
1348 return this;
1349 };
1350 /**
1351 * Return array of callbacks for `event`.
1352 *
1353 * @param {String} event
1354 * @return {Array}
1355 * @api public
1356 */
1357
1358
1359 Emitter.prototype.listeners = function (event) {
1360 this._callbacks = this._callbacks || {};
1361 return this._callbacks['$' + event] || [];
1362 };
1363 /**
1364 * Check if this emitter has `event` handlers.
1365 *
1366 * @param {String} event
1367 * @return {Boolean}
1368 * @api public
1369 */
1370
1371
1372 Emitter.prototype.hasListeners = function (event) {
1373 return !!this.listeners(event).length;
1374 };
1375})(componentEmitter);
1376
1377var Emitter = componentEmitter.exports;
1378
1379var isSymbol$1 = isSymbol$4;
1380
1381var toString$9 = function (argument) {
1382 if (isSymbol$1(argument)) throw TypeError('Cannot convert a Symbol value to a string');
1383 return String(argument);
1384};
1385
1386var toInteger$1 = toInteger$4;
1387var toString$8 = toString$9;
1388var requireObjectCoercible$2 = requireObjectCoercible$5; // `String.prototype.codePointAt` methods implementation
1389
1390var createMethod$4 = function (CONVERT_TO_STRING) {
1391 return function ($this, pos) {
1392 var S = toString$8(requireObjectCoercible$2($this));
1393 var position = toInteger$1(pos);
1394 var size = S.length;
1395 var first, second;
1396 if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
1397 first = S.charCodeAt(position);
1398 return first < 0xD800 || first > 0xDBFF || position + 1 === size || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF ? CONVERT_TO_STRING ? S.charAt(position) : first : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
1399 };
1400};
1401
1402var stringMultibyte = {
1403 // `String.prototype.codePointAt` method
1404 // https://tc39.es/ecma262/#sec-string.prototype.codepointat
1405 codeAt: createMethod$4(false),
1406 // `String.prototype.at` method
1407 // https://github.com/mathiasbynens/String.prototype.at
1408 charAt: createMethod$4(true)
1409};
1410
1411var store$1 = sharedStore;
1412var functionToString = Function.toString; // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper
1413
1414if (typeof store$1.inspectSource != 'function') {
1415 store$1.inspectSource = function (it) {
1416 return functionToString.call(it);
1417 };
1418}
1419
1420var inspectSource$1 = store$1.inspectSource;
1421
1422var global$c = global$k;
1423var inspectSource = inspectSource$1;
1424var WeakMap$1 = global$c.WeakMap;
1425var nativeWeakMap = typeof WeakMap$1 === 'function' && /native code/.test(inspectSource(WeakMap$1));
1426
1427var shared$2 = shared$4.exports;
1428var uid$2 = uid$4;
1429var keys$7 = shared$2('keys');
1430
1431var sharedKey$4 = function (key) {
1432 return keys$7[key] || (keys$7[key] = uid$2(key));
1433};
1434
1435var NATIVE_WEAK_MAP$1 = nativeWeakMap;
1436var global$b = global$k;
1437var isObject$d = isObject$j;
1438var createNonEnumerableProperty$7 = createNonEnumerableProperty$9;
1439var objectHas = has$c;
1440var shared$1 = sharedStore;
1441var sharedKey$3 = sharedKey$4;
1442var hiddenKeys$4 = hiddenKeys$6;
1443var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
1444var WeakMap = global$b.WeakMap;
1445var set$3, get$5, has$7;
1446
1447var enforce = function (it) {
1448 return has$7(it) ? get$5(it) : set$3(it, {});
1449};
1450
1451var getterFor = function (TYPE) {
1452 return function (it) {
1453 var state;
1454
1455 if (!isObject$d(it) || (state = get$5(it)).type !== TYPE) {
1456 throw TypeError('Incompatible receiver, ' + TYPE + ' required');
1457 }
1458
1459 return state;
1460 };
1461};
1462
1463if (NATIVE_WEAK_MAP$1 || shared$1.state) {
1464 var store = shared$1.state || (shared$1.state = new WeakMap());
1465 var wmget = store.get;
1466 var wmhas = store.has;
1467 var wmset = store.set;
1468
1469 set$3 = function (it, metadata) {
1470 if (wmhas.call(store, it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
1471 metadata.facade = it;
1472 wmset.call(store, it, metadata);
1473 return metadata;
1474 };
1475
1476 get$5 = function (it) {
1477 return wmget.call(store, it) || {};
1478 };
1479
1480 has$7 = function (it) {
1481 return wmhas.call(store, it);
1482 };
1483} else {
1484 var STATE = sharedKey$3('state');
1485 hiddenKeys$4[STATE] = true;
1486
1487 set$3 = function (it, metadata) {
1488 if (objectHas(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
1489 metadata.facade = it;
1490 createNonEnumerableProperty$7(it, STATE, metadata);
1491 return metadata;
1492 };
1493
1494 get$5 = function (it) {
1495 return objectHas(it, STATE) ? it[STATE] : {};
1496 };
1497
1498 has$7 = function (it) {
1499 return objectHas(it, STATE);
1500 };
1501}
1502
1503var internalState = {
1504 set: set$3,
1505 get: get$5,
1506 has: has$7,
1507 enforce: enforce,
1508 getterFor: getterFor
1509};
1510
1511var fails$f = fails$m;
1512var correctPrototypeGetter = !fails$f(function () {
1513 function F() {
1514 /* empty */
1515 }
1516
1517 F.prototype.constructor = null; // eslint-disable-next-line es/no-object-getprototypeof -- required for testing
1518
1519 return Object.getPrototypeOf(new F()) !== F.prototype;
1520});
1521
1522var has$6 = has$c;
1523var toObject$b = toObject$e;
1524var sharedKey$2 = sharedKey$4;
1525var CORRECT_PROTOTYPE_GETTER$1 = correctPrototypeGetter;
1526var IE_PROTO$1 = sharedKey$2('IE_PROTO');
1527var ObjectPrototype$1 = Object.prototype; // `Object.getPrototypeOf` method
1528// https://tc39.es/ecma262/#sec-object.getprototypeof
1529// eslint-disable-next-line es/no-object-getprototypeof -- safe
1530
1531var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER$1 ? Object.getPrototypeOf : function (O) {
1532 O = toObject$b(O);
1533 if (has$6(O, IE_PROTO$1)) return O[IE_PROTO$1];
1534
1535 if (typeof O.constructor == 'function' && O instanceof O.constructor) {
1536 return O.constructor.prototype;
1537 }
1538
1539 return O instanceof Object ? ObjectPrototype$1 : null;
1540};
1541
1542var fails$e = fails$m;
1543var getPrototypeOf$7 = objectGetPrototypeOf;
1544var createNonEnumerableProperty$6 = createNonEnumerableProperty$9;
1545var has$5 = has$c;
1546var wellKnownSymbol$h = wellKnownSymbol$j;
1547var ITERATOR$4 = wellKnownSymbol$h('iterator');
1548var BUGGY_SAFARI_ITERATORS$1 = false;
1549
1550var returnThis$2 = function () {
1551 return this;
1552}; // `%IteratorPrototype%` object
1553// https://tc39.es/ecma262/#sec-%iteratorprototype%-object
1554
1555
1556var IteratorPrototype$2, PrototypeOfArrayIteratorPrototype, arrayIterator;
1557/* eslint-disable es/no-array-prototype-keys -- safe */
1558
1559if ([].keys) {
1560 arrayIterator = [].keys(); // Safari 8 has buggy iterators w/o `next`
1561
1562 if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS$1 = true;else {
1563 PrototypeOfArrayIteratorPrototype = getPrototypeOf$7(getPrototypeOf$7(arrayIterator));
1564 if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype$2 = PrototypeOfArrayIteratorPrototype;
1565 }
1566}
1567
1568var NEW_ITERATOR_PROTOTYPE = IteratorPrototype$2 == undefined || fails$e(function () {
1569 var test = {}; // FF44- legacy iterators case
1570
1571 return IteratorPrototype$2[ITERATOR$4].call(test) !== test;
1572});
1573if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype$2 = {}; // `%IteratorPrototype%[@@iterator]()` method
1574// https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator
1575
1576if ((NEW_ITERATOR_PROTOTYPE) && !has$5(IteratorPrototype$2, ITERATOR$4)) {
1577 createNonEnumerableProperty$6(IteratorPrototype$2, ITERATOR$4, returnThis$2);
1578}
1579
1580var iteratorsCore = {
1581 IteratorPrototype: IteratorPrototype$2,
1582 BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS$1
1583};
1584
1585var DESCRIPTORS$a = descriptors;
1586var definePropertyModule$3 = objectDefineProperty;
1587var anObject$b = anObject$d;
1588var objectKeys$2 = objectKeys$4; // `Object.defineProperties` method
1589// https://tc39.es/ecma262/#sec-object.defineproperties
1590// eslint-disable-next-line es/no-object-defineproperties -- safe
1591
1592var objectDefineProperties = DESCRIPTORS$a ? Object.defineProperties : function defineProperties(O, Properties) {
1593 anObject$b(O);
1594 var keys = objectKeys$2(Properties);
1595 var length = keys.length;
1596 var index = 0;
1597 var key;
1598
1599 while (length > index) definePropertyModule$3.f(O, key = keys[index++], Properties[key]);
1600
1601 return O;
1602};
1603
1604var getBuiltIn$5 = getBuiltIn$8;
1605var html$1 = getBuiltIn$5('document', 'documentElement');
1606
1607/* global ActiveXObject -- old IE, WSH */
1608var anObject$a = anObject$d;
1609var defineProperties$5 = objectDefineProperties;
1610var enumBugKeys$1 = enumBugKeys$3;
1611var hiddenKeys$3 = hiddenKeys$6;
1612var html = html$1;
1613var documentCreateElement = documentCreateElement$1;
1614var sharedKey$1 = sharedKey$4;
1615var GT = '>';
1616var LT = '<';
1617var PROTOTYPE$1 = 'prototype';
1618var SCRIPT = 'script';
1619var IE_PROTO = sharedKey$1('IE_PROTO');
1620
1621var EmptyConstructor = function () {
1622 /* empty */
1623};
1624
1625var scriptTag = function (content) {
1626 return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
1627}; // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
1628
1629
1630var NullProtoObjectViaActiveX = function (activeXDocument) {
1631 activeXDocument.write(scriptTag(''));
1632 activeXDocument.close();
1633 var temp = activeXDocument.parentWindow.Object;
1634 activeXDocument = null; // avoid memory leak
1635
1636 return temp;
1637}; // Create object with fake `null` prototype: use iframe Object with cleared prototype
1638
1639
1640var NullProtoObjectViaIFrame = function () {
1641 // Thrash, waste and sodomy: IE GC bug
1642 var iframe = documentCreateElement('iframe');
1643 var JS = 'java' + SCRIPT + ':';
1644 var iframeDocument;
1645
1646 if (iframe.style) {
1647 iframe.style.display = 'none';
1648 html.appendChild(iframe); // https://github.com/zloirock/core-js/issues/475
1649
1650 iframe.src = String(JS);
1651 iframeDocument = iframe.contentWindow.document;
1652 iframeDocument.open();
1653 iframeDocument.write(scriptTag('document.F=Object'));
1654 iframeDocument.close();
1655 return iframeDocument.F;
1656 }
1657}; // Check for document.domain and active x support
1658// No need to use active x approach when document.domain is not set
1659// see https://github.com/es-shims/es5-shim/issues/150
1660// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
1661// avoid IE GC bug
1662
1663
1664var activeXDocument;
1665
1666var NullProtoObject = function () {
1667 try {
1668 activeXDocument = new ActiveXObject('htmlfile');
1669 } catch (error) {
1670 /* ignore */
1671 }
1672
1673 NullProtoObject = document.domain && activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : // old IE
1674 NullProtoObjectViaIFrame() || NullProtoObjectViaActiveX(activeXDocument); // WSH
1675
1676 var length = enumBugKeys$1.length;
1677
1678 while (length--) delete NullProtoObject[PROTOTYPE$1][enumBugKeys$1[length]];
1679
1680 return NullProtoObject();
1681};
1682
1683hiddenKeys$3[IE_PROTO] = true; // `Object.create` method
1684// https://tc39.es/ecma262/#sec-object.create
1685
1686var objectCreate = Object.create || function create(O, Properties) {
1687 var result;
1688
1689 if (O !== null) {
1690 EmptyConstructor[PROTOTYPE$1] = anObject$a(O);
1691 result = new EmptyConstructor();
1692 EmptyConstructor[PROTOTYPE$1] = null; // add "__proto__" for Object.getPrototypeOf polyfill
1693
1694 result[IE_PROTO] = O;
1695 } else result = NullProtoObject();
1696
1697 return Properties === undefined ? result : defineProperties$5(result, Properties);
1698};
1699
1700var wellKnownSymbol$g = wellKnownSymbol$j;
1701var TO_STRING_TAG$3 = wellKnownSymbol$g('toStringTag');
1702var test$2 = {};
1703test$2[TO_STRING_TAG$3] = 'z';
1704var toStringTagSupport = String(test$2) === '[object z]';
1705
1706var TO_STRING_TAG_SUPPORT$2 = toStringTagSupport;
1707var classofRaw = classofRaw$1;
1708var wellKnownSymbol$f = wellKnownSymbol$j;
1709var TO_STRING_TAG$2 = wellKnownSymbol$f('toStringTag'); // ES3 wrong here
1710
1711var CORRECT_ARGUMENTS = classofRaw(function () {
1712 return arguments;
1713}()) == 'Arguments'; // fallback for IE11 Script Access Denied error
1714
1715var tryGet = function (it, key) {
1716 try {
1717 return it[key];
1718 } catch (error) {
1719 /* empty */
1720 }
1721}; // getting tag from ES6+ `Object.prototype.toString`
1722
1723
1724var classof$a = TO_STRING_TAG_SUPPORT$2 ? classofRaw : function (it) {
1725 var O, tag, result;
1726 return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case
1727 : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$2)) == 'string' ? tag // builtinTag case
1728 : CORRECT_ARGUMENTS ? classofRaw(O) // ES3 arguments fallback
1729 : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
1730};
1731
1732var TO_STRING_TAG_SUPPORT$1 = toStringTagSupport;
1733var classof$9 = classof$a; // `Object.prototype.toString` method implementation
1734// https://tc39.es/ecma262/#sec-object.prototype.tostring
1735
1736var objectToString = TO_STRING_TAG_SUPPORT$1 ? {}.toString : function toString() {
1737 return '[object ' + classof$9(this) + ']';
1738};
1739
1740var TO_STRING_TAG_SUPPORT = toStringTagSupport;
1741var defineProperty$a = objectDefineProperty.f;
1742var createNonEnumerableProperty$5 = createNonEnumerableProperty$9;
1743var has$4 = has$c;
1744var toString$7 = objectToString;
1745var wellKnownSymbol$e = wellKnownSymbol$j;
1746var TO_STRING_TAG$1 = wellKnownSymbol$e('toStringTag');
1747
1748var setToStringTag$5 = function (it, TAG, STATIC, SET_METHOD) {
1749 if (it) {
1750 var target = STATIC ? it : it.prototype;
1751
1752 if (!has$4(target, TO_STRING_TAG$1)) {
1753 defineProperty$a(target, TO_STRING_TAG$1, {
1754 configurable: true,
1755 value: TAG
1756 });
1757 }
1758
1759 if (SET_METHOD && !TO_STRING_TAG_SUPPORT) {
1760 createNonEnumerableProperty$5(target, 'toString', toString$7);
1761 }
1762 }
1763};
1764
1765var iterators = {};
1766
1767var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
1768var create$8 = objectCreate;
1769var createPropertyDescriptor$2 = createPropertyDescriptor$5;
1770var setToStringTag$4 = setToStringTag$5;
1771var Iterators$5 = iterators;
1772
1773var returnThis$1 = function () {
1774 return this;
1775};
1776
1777var createIteratorConstructor$1 = function (IteratorConstructor, NAME, next) {
1778 var TO_STRING_TAG = NAME + ' Iterator';
1779 IteratorConstructor.prototype = create$8(IteratorPrototype$1, {
1780 next: createPropertyDescriptor$2(1, next)
1781 });
1782 setToStringTag$4(IteratorConstructor, TO_STRING_TAG, false, true);
1783 Iterators$5[TO_STRING_TAG] = returnThis$1;
1784 return IteratorConstructor;
1785};
1786
1787var isObject$c = isObject$j;
1788
1789var aPossiblePrototype$1 = function (it) {
1790 if (!isObject$c(it) && it !== null) {
1791 throw TypeError("Can't set " + String(it) + ' as a prototype');
1792 }
1793
1794 return it;
1795};
1796
1797/* eslint-disable no-proto -- safe */
1798var anObject$9 = anObject$d;
1799var aPossiblePrototype = aPossiblePrototype$1; // `Object.setPrototypeOf` method
1800// https://tc39.es/ecma262/#sec-object.setprototypeof
1801// Works with __proto__ only. Old v8 can't work with null proto objects.
1802// eslint-disable-next-line es/no-object-setprototypeof -- safe
1803
1804var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
1805 var CORRECT_SETTER = false;
1806 var test = {};
1807 var setter;
1808
1809 try {
1810 // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
1811 setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
1812 setter.call(test, []);
1813 CORRECT_SETTER = test instanceof Array;
1814 } catch (error) {
1815 /* empty */
1816 }
1817
1818 return function setPrototypeOf(O, proto) {
1819 anObject$9(O);
1820 aPossiblePrototype(proto);
1821 if (CORRECT_SETTER) setter.call(O, proto);else O.__proto__ = proto;
1822 return O;
1823 };
1824}() : undefined);
1825
1826var createNonEnumerableProperty$4 = createNonEnumerableProperty$9;
1827
1828var redefine$3 = function (target, key, value, options) {
1829 if (options && options.enumerable) target[key] = value;else createNonEnumerableProperty$4(target, key, value);
1830};
1831
1832var $$H = _export;
1833var createIteratorConstructor = createIteratorConstructor$1;
1834var getPrototypeOf$6 = objectGetPrototypeOf;
1835var setToStringTag$3 = setToStringTag$5;
1836var createNonEnumerableProperty$3 = createNonEnumerableProperty$9;
1837var redefine$2 = redefine$3;
1838var wellKnownSymbol$d = wellKnownSymbol$j;
1839var Iterators$4 = iterators;
1840var IteratorsCore = iteratorsCore;
1841var IteratorPrototype = IteratorsCore.IteratorPrototype;
1842var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
1843var ITERATOR$3 = wellKnownSymbol$d('iterator');
1844var KEYS = 'keys';
1845var VALUES = 'values';
1846var ENTRIES = 'entries';
1847
1848var returnThis = function () {
1849 return this;
1850};
1851
1852var defineIterator$3 = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
1853 createIteratorConstructor(IteratorConstructor, NAME, next);
1854
1855 var getIterationMethod = function (KIND) {
1856 if (KIND === DEFAULT && defaultIterator) return defaultIterator;
1857 if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND];
1858
1859 switch (KIND) {
1860 case KEYS:
1861 return function keys() {
1862 return new IteratorConstructor(this, KIND);
1863 };
1864
1865 case VALUES:
1866 return function values() {
1867 return new IteratorConstructor(this, KIND);
1868 };
1869
1870 case ENTRIES:
1871 return function entries() {
1872 return new IteratorConstructor(this, KIND);
1873 };
1874 }
1875
1876 return function () {
1877 return new IteratorConstructor(this);
1878 };
1879 };
1880
1881 var TO_STRING_TAG = NAME + ' Iterator';
1882 var INCORRECT_VALUES_NAME = false;
1883 var IterablePrototype = Iterable.prototype;
1884 var nativeIterator = IterablePrototype[ITERATOR$3] || IterablePrototype['@@iterator'] || DEFAULT && IterablePrototype[DEFAULT];
1885 var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);
1886 var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
1887 var CurrentIteratorPrototype, methods, KEY; // fix native
1888
1889 if (anyNativeIterator) {
1890 CurrentIteratorPrototype = getPrototypeOf$6(anyNativeIterator.call(new Iterable()));
1891
1892 if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {
1893
1894
1895 setToStringTag$3(CurrentIteratorPrototype, TO_STRING_TAG, true, true);
1896 Iterators$4[TO_STRING_TAG] = returnThis;
1897 }
1898 } // fix Array.prototype.{ values, @@iterator }.name in V8 / FF
1899
1900
1901 if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
1902 INCORRECT_VALUES_NAME = true;
1903
1904 defaultIterator = function values() {
1905 return nativeIterator.call(this);
1906 };
1907 } // define iterator
1908
1909
1910 if ((FORCED) && IterablePrototype[ITERATOR$3] !== defaultIterator) {
1911 createNonEnumerableProperty$3(IterablePrototype, ITERATOR$3, defaultIterator);
1912 }
1913
1914 Iterators$4[NAME] = defaultIterator; // export additional methods
1915
1916 if (DEFAULT) {
1917 methods = {
1918 values: getIterationMethod(VALUES),
1919 keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
1920 entries: getIterationMethod(ENTRIES)
1921 };
1922 if (FORCED) for (KEY in methods) {
1923 if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
1924 redefine$2(IterablePrototype, KEY, methods[KEY]);
1925 }
1926 } else $$H({
1927 target: NAME,
1928 proto: true,
1929 forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME
1930 }, methods);
1931 }
1932
1933 return methods;
1934};
1935
1936var charAt = stringMultibyte.charAt;
1937var toString$6 = toString$9;
1938var InternalStateModule$5 = internalState;
1939var defineIterator$2 = defineIterator$3;
1940var STRING_ITERATOR = 'String Iterator';
1941var setInternalState$5 = InternalStateModule$5.set;
1942var getInternalState$2 = InternalStateModule$5.getterFor(STRING_ITERATOR); // `String.prototype[@@iterator]` method
1943// https://tc39.es/ecma262/#sec-string.prototype-@@iterator
1944
1945defineIterator$2(String, 'String', function (iterated) {
1946 setInternalState$5(this, {
1947 type: STRING_ITERATOR,
1948 string: toString$6(iterated),
1949 index: 0
1950 }); // `%StringIteratorPrototype%.next` method
1951 // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next
1952}, function next() {
1953 var state = getInternalState$2(this);
1954 var string = state.string;
1955 var index = state.index;
1956 var point;
1957 if (index >= string.length) return {
1958 value: undefined,
1959 done: true
1960 };
1961 point = charAt(string, index);
1962 state.index += point.length;
1963 return {
1964 value: point,
1965 done: false
1966 };
1967});
1968
1969var anObject$8 = anObject$d;
1970
1971var iteratorClose$2 = function (iterator) {
1972 var returnMethod = iterator['return'];
1973
1974 if (returnMethod !== undefined) {
1975 return anObject$8(returnMethod.call(iterator)).value;
1976 }
1977};
1978
1979var anObject$7 = anObject$d;
1980var iteratorClose$1 = iteratorClose$2; // call something on iterator step with safe closing on error
1981
1982var callWithSafeIterationClosing$1 = function (iterator, fn, value, ENTRIES) {
1983 try {
1984 return ENTRIES ? fn(anObject$7(value)[0], value[1]) : fn(value);
1985 } catch (error) {
1986 iteratorClose$1(iterator);
1987 throw error;
1988 }
1989};
1990
1991var wellKnownSymbol$c = wellKnownSymbol$j;
1992var Iterators$3 = iterators;
1993var ITERATOR$2 = wellKnownSymbol$c('iterator');
1994var ArrayPrototype$i = Array.prototype; // check on default Array iterator
1995
1996var isArrayIteratorMethod$2 = function (it) {
1997 return it !== undefined && (Iterators$3.Array === it || ArrayPrototype$i[ITERATOR$2] === it);
1998};
1999
2000var toPropertyKey$1 = toPropertyKey$4;
2001var definePropertyModule$2 = objectDefineProperty;
2002var createPropertyDescriptor$1 = createPropertyDescriptor$5;
2003
2004var createProperty$5 = function (object, key, value) {
2005 var propertyKey = toPropertyKey$1(key);
2006 if (propertyKey in object) definePropertyModule$2.f(object, propertyKey, createPropertyDescriptor$1(0, value));else object[propertyKey] = value;
2007};
2008
2009var classof$8 = classof$a;
2010var Iterators$2 = iterators;
2011var wellKnownSymbol$b = wellKnownSymbol$j;
2012var ITERATOR$1 = wellKnownSymbol$b('iterator');
2013
2014var getIteratorMethod$7 = function (it) {
2015 if (it != undefined) return it[ITERATOR$1] || it['@@iterator'] || Iterators$2[classof$8(it)];
2016};
2017
2018var bind$5 = functionBindContext;
2019var toObject$a = toObject$e;
2020var callWithSafeIterationClosing = callWithSafeIterationClosing$1;
2021var isArrayIteratorMethod$1 = isArrayIteratorMethod$2;
2022var toLength$a = toLength$c;
2023var createProperty$4 = createProperty$5;
2024var getIteratorMethod$6 = getIteratorMethod$7; // `Array.from` method implementation
2025// https://tc39.es/ecma262/#sec-array.from
2026
2027var arrayFrom = function from(arrayLike
2028/* , mapfn = undefined, thisArg = undefined */
2029) {
2030 var O = toObject$a(arrayLike);
2031 var C = typeof this == 'function' ? this : Array;
2032 var argumentsLength = arguments.length;
2033 var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
2034 var mapping = mapfn !== undefined;
2035 var iteratorMethod = getIteratorMethod$6(O);
2036 var index = 0;
2037 var length, result, step, iterator, next, value;
2038 if (mapping) mapfn = bind$5(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2); // if the target is not iterable or it's an array with the default iterator - use a simple case
2039
2040 if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod$1(iteratorMethod))) {
2041 iterator = iteratorMethod.call(O);
2042 next = iterator.next;
2043 result = new C();
2044
2045 for (; !(step = next.call(iterator)).done; index++) {
2046 value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value;
2047 createProperty$4(result, index, value);
2048 }
2049 } else {
2050 length = toLength$a(O.length);
2051 result = new C(length);
2052
2053 for (; length > index; index++) {
2054 value = mapping ? mapfn(O[index], index) : O[index];
2055 createProperty$4(result, index, value);
2056 }
2057 }
2058
2059 result.length = index;
2060 return result;
2061};
2062
2063var wellKnownSymbol$a = wellKnownSymbol$j;
2064var ITERATOR = wellKnownSymbol$a('iterator');
2065var SAFE_CLOSING = false;
2066
2067try {
2068 var called = 0;
2069 var iteratorWithReturn = {
2070 next: function () {
2071 return {
2072 done: !!called++
2073 };
2074 },
2075 'return': function () {
2076 SAFE_CLOSING = true;
2077 }
2078 };
2079
2080 iteratorWithReturn[ITERATOR] = function () {
2081 return this;
2082 }; // eslint-disable-next-line es/no-array-from, no-throw-literal -- required for testing
2083
2084
2085 Array.from(iteratorWithReturn, function () {
2086 throw 2;
2087 });
2088} catch (error) {
2089 /* empty */
2090}
2091
2092var checkCorrectnessOfIteration$1 = function (exec, SKIP_CLOSING) {
2093 if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
2094 var ITERATION_SUPPORT = false;
2095
2096 try {
2097 var object = {};
2098
2099 object[ITERATOR] = function () {
2100 return {
2101 next: function () {
2102 return {
2103 done: ITERATION_SUPPORT = true
2104 };
2105 }
2106 };
2107 };
2108
2109 exec(object);
2110 } catch (error) {
2111 /* empty */
2112 }
2113
2114 return ITERATION_SUPPORT;
2115};
2116
2117var $$G = _export;
2118var from$5 = arrayFrom;
2119var checkCorrectnessOfIteration = checkCorrectnessOfIteration$1;
2120var INCORRECT_ITERATION = !checkCorrectnessOfIteration(function (iterable) {
2121 // eslint-disable-next-line es/no-array-from -- required for testing
2122 Array.from(iterable);
2123}); // `Array.from` method
2124// https://tc39.es/ecma262/#sec-array.from
2125
2126$$G({
2127 target: 'Array',
2128 stat: true,
2129 forced: INCORRECT_ITERATION
2130}, {
2131 from: from$5
2132});
2133
2134var path$s = path$x;
2135var from$4 = path$s.Array.from;
2136
2137var parent$X = from$4;
2138var from$3 = parent$X;
2139
2140var from$2 = from$3;
2141
2142var toIndexedObject$6 = toIndexedObject$a;
2143var Iterators$1 = iterators;
2144var InternalStateModule$4 = internalState;
2145var defineIterator$1 = defineIterator$3;
2146var ARRAY_ITERATOR = 'Array Iterator';
2147var setInternalState$4 = InternalStateModule$4.set;
2148var getInternalState$1 = InternalStateModule$4.getterFor(ARRAY_ITERATOR); // `Array.prototype.entries` method
2149// https://tc39.es/ecma262/#sec-array.prototype.entries
2150// `Array.prototype.keys` method
2151// https://tc39.es/ecma262/#sec-array.prototype.keys
2152// `Array.prototype.values` method
2153// https://tc39.es/ecma262/#sec-array.prototype.values
2154// `Array.prototype[@@iterator]` method
2155// https://tc39.es/ecma262/#sec-array.prototype-@@iterator
2156// `CreateArrayIterator` internal method
2157// https://tc39.es/ecma262/#sec-createarrayiterator
2158
2159defineIterator$1(Array, 'Array', function (iterated, kind) {
2160 setInternalState$4(this, {
2161 type: ARRAY_ITERATOR,
2162 target: toIndexedObject$6(iterated),
2163 // target
2164 index: 0,
2165 // next index
2166 kind: kind // kind
2167
2168 }); // `%ArrayIteratorPrototype%.next` method
2169 // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next
2170}, function () {
2171 var state = getInternalState$1(this);
2172 var target = state.target;
2173 var kind = state.kind;
2174 var index = state.index++;
2175
2176 if (!target || index >= target.length) {
2177 state.target = undefined;
2178 return {
2179 value: undefined,
2180 done: true
2181 };
2182 }
2183
2184 if (kind == 'keys') return {
2185 value: index,
2186 done: false
2187 };
2188 if (kind == 'values') return {
2189 value: target[index],
2190 done: false
2191 };
2192 return {
2193 value: [index, target[index]],
2194 done: false
2195 };
2196}, 'values'); // argumentsList[@@iterator] is %ArrayProto_values%
2197// https://tc39.es/ecma262/#sec-createunmappedargumentsobject
2198// https://tc39.es/ecma262/#sec-createmappedargumentsobject
2199
2200Iterators$1.Arguments = Iterators$1.Array; // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
2201
2202var getIteratorMethod$5 = getIteratorMethod$7;
2203var getIteratorMethod_1 = getIteratorMethod$5;
2204
2205// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
2206
2207var domIterables = {
2208 CSSRuleList: 0,
2209 CSSStyleDeclaration: 0,
2210 CSSValueList: 0,
2211 ClientRectList: 0,
2212 DOMRectList: 0,
2213 DOMStringList: 0,
2214 DOMTokenList: 1,
2215 DataTransferItemList: 0,
2216 FileList: 0,
2217 HTMLAllCollection: 0,
2218 HTMLCollection: 0,
2219 HTMLFormElement: 0,
2220 HTMLSelectElement: 0,
2221 MediaList: 0,
2222 MimeTypeArray: 0,
2223 NamedNodeMap: 0,
2224 NodeList: 1,
2225 PaintRequestList: 0,
2226 Plugin: 0,
2227 PluginArray: 0,
2228 SVGLengthList: 0,
2229 SVGNumberList: 0,
2230 SVGPathSegList: 0,
2231 SVGPointList: 0,
2232 SVGStringList: 0,
2233 SVGTransformList: 0,
2234 SourceBufferList: 0,
2235 StyleSheetList: 0,
2236 TextTrackCueList: 0,
2237 TextTrackList: 0,
2238 TouchList: 0
2239};
2240
2241var DOMIterables$4 = domIterables;
2242var global$a = global$k;
2243var classof$7 = classof$a;
2244var createNonEnumerableProperty$2 = createNonEnumerableProperty$9;
2245var Iterators = iterators;
2246var wellKnownSymbol$9 = wellKnownSymbol$j;
2247var TO_STRING_TAG = wellKnownSymbol$9('toStringTag');
2248
2249for (var COLLECTION_NAME in DOMIterables$4) {
2250 var Collection = global$a[COLLECTION_NAME];
2251 var CollectionPrototype = Collection && Collection.prototype;
2252
2253 if (CollectionPrototype && classof$7(CollectionPrototype) !== TO_STRING_TAG) {
2254 createNonEnumerableProperty$2(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);
2255 }
2256
2257 Iterators[COLLECTION_NAME] = Iterators.Array;
2258}
2259
2260var parent$W = getIteratorMethod_1;
2261var getIteratorMethod$4 = parent$W;
2262
2263var parent$V = getIteratorMethod$4;
2264var getIteratorMethod$3 = parent$V;
2265
2266var getIteratorMethod$2 = getIteratorMethod$3;
2267
2268var classof$6 = classofRaw$1; // `IsArray` abstract operation
2269// https://tc39.es/ecma262/#sec-isarray
2270// eslint-disable-next-line es/no-array-isarray -- safe
2271
2272var isArray$c = Array.isArray || function isArray(arg) {
2273 return classof$6(arg) == 'Array';
2274};
2275
2276var objectGetOwnPropertyNames = {};
2277
2278var internalObjectKeys = objectKeysInternal;
2279var enumBugKeys = enumBugKeys$3;
2280var hiddenKeys$2 = enumBugKeys.concat('length', 'prototype'); // `Object.getOwnPropertyNames` method
2281// https://tc39.es/ecma262/#sec-object.getownpropertynames
2282// eslint-disable-next-line es/no-object-getownpropertynames -- safe
2283
2284objectGetOwnPropertyNames.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
2285 return internalObjectKeys(O, hiddenKeys$2);
2286};
2287
2288var objectGetOwnPropertyNamesExternal = {};
2289
2290/* eslint-disable es/no-object-getownpropertynames -- safe */
2291var toIndexedObject$5 = toIndexedObject$a;
2292var $getOwnPropertyNames$1 = objectGetOwnPropertyNames.f;
2293var toString$5 = {}.toString;
2294var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : [];
2295
2296var getWindowNames = function (it) {
2297 try {
2298 return $getOwnPropertyNames$1(it);
2299 } catch (error) {
2300 return windowNames.slice();
2301 }
2302}; // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
2303
2304
2305objectGetOwnPropertyNamesExternal.f = function getOwnPropertyNames(it) {
2306 return windowNames && toString$5.call(it) == '[object Window]' ? getWindowNames(it) : $getOwnPropertyNames$1(toIndexedObject$5(it));
2307};
2308
2309var wellKnownSymbolWrapped = {};
2310
2311var wellKnownSymbol$8 = wellKnownSymbol$j;
2312wellKnownSymbolWrapped.f = wellKnownSymbol$8;
2313
2314var path$r = path$x;
2315var has$3 = has$c;
2316var wrappedWellKnownSymbolModule$1 = wellKnownSymbolWrapped;
2317var defineProperty$9 = objectDefineProperty.f;
2318
2319var defineWellKnownSymbol$l = function (NAME) {
2320 var Symbol = path$r.Symbol || (path$r.Symbol = {});
2321 if (!has$3(Symbol, NAME)) defineProperty$9(Symbol, NAME, {
2322 value: wrappedWellKnownSymbolModule$1.f(NAME)
2323 });
2324};
2325
2326var isObject$b = isObject$j;
2327var isArray$b = isArray$c;
2328var wellKnownSymbol$7 = wellKnownSymbol$j;
2329var SPECIES$3 = wellKnownSymbol$7('species'); // a part of `ArraySpeciesCreate` abstract operation
2330// https://tc39.es/ecma262/#sec-arrayspeciescreate
2331
2332var arraySpeciesConstructor$1 = function (originalArray) {
2333 var C;
2334
2335 if (isArray$b(originalArray)) {
2336 C = originalArray.constructor; // cross-realm fallback
2337
2338 if (typeof C == 'function' && (C === Array || isArray$b(C.prototype))) C = undefined;else if (isObject$b(C)) {
2339 C = C[SPECIES$3];
2340 if (C === null) C = undefined;
2341 }
2342 }
2343
2344 return C === undefined ? Array : C;
2345};
2346
2347var arraySpeciesConstructor = arraySpeciesConstructor$1; // `ArraySpeciesCreate` abstract operation
2348// https://tc39.es/ecma262/#sec-arrayspeciescreate
2349
2350var arraySpeciesCreate$4 = function (originalArray, length) {
2351 return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
2352};
2353
2354var bind$4 = functionBindContext;
2355var IndexedObject$1 = indexedObject;
2356var toObject$9 = toObject$e;
2357var toLength$9 = toLength$c;
2358var arraySpeciesCreate$3 = arraySpeciesCreate$4;
2359var push = [].push; // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation
2360
2361var createMethod$3 = function (TYPE) {
2362 var IS_MAP = TYPE == 1;
2363 var IS_FILTER = TYPE == 2;
2364 var IS_SOME = TYPE == 3;
2365 var IS_EVERY = TYPE == 4;
2366 var IS_FIND_INDEX = TYPE == 6;
2367 var IS_FILTER_REJECT = TYPE == 7;
2368 var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
2369 return function ($this, callbackfn, that, specificCreate) {
2370 var O = toObject$9($this);
2371 var self = IndexedObject$1(O);
2372 var boundFunction = bind$4(callbackfn, that, 3);
2373 var length = toLength$9(self.length);
2374 var index = 0;
2375 var create = specificCreate || arraySpeciesCreate$3;
2376 var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined;
2377 var value, result;
2378
2379 for (; length > index; index++) if (NO_HOLES || index in self) {
2380 value = self[index];
2381 result = boundFunction(value, index, O);
2382
2383 if (TYPE) {
2384 if (IS_MAP) target[index] = result; // map
2385 else if (result) switch (TYPE) {
2386 case 3:
2387 return true;
2388 // some
2389
2390 case 5:
2391 return value;
2392 // find
2393
2394 case 6:
2395 return index;
2396 // findIndex
2397
2398 case 2:
2399 push.call(target, value);
2400 // filter
2401 } else switch (TYPE) {
2402 case 4:
2403 return false;
2404 // every
2405
2406 case 7:
2407 push.call(target, value);
2408 // filterReject
2409 }
2410 }
2411 }
2412
2413 return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
2414 };
2415};
2416
2417var arrayIteration = {
2418 // `Array.prototype.forEach` method
2419 // https://tc39.es/ecma262/#sec-array.prototype.foreach
2420 forEach: createMethod$3(0),
2421 // `Array.prototype.map` method
2422 // https://tc39.es/ecma262/#sec-array.prototype.map
2423 map: createMethod$3(1),
2424 // `Array.prototype.filter` method
2425 // https://tc39.es/ecma262/#sec-array.prototype.filter
2426 filter: createMethod$3(2),
2427 // `Array.prototype.some` method
2428 // https://tc39.es/ecma262/#sec-array.prototype.some
2429 some: createMethod$3(3),
2430 // `Array.prototype.every` method
2431 // https://tc39.es/ecma262/#sec-array.prototype.every
2432 every: createMethod$3(4),
2433 // `Array.prototype.find` method
2434 // https://tc39.es/ecma262/#sec-array.prototype.find
2435 find: createMethod$3(5),
2436 // `Array.prototype.findIndex` method
2437 // https://tc39.es/ecma262/#sec-array.prototype.findIndex
2438 findIndex: createMethod$3(6),
2439 // `Array.prototype.filterReject` method
2440 // https://github.com/tc39/proposal-array-filtering
2441 filterReject: createMethod$3(7)
2442};
2443
2444var $$F = _export;
2445var global$9 = global$k;
2446var getBuiltIn$4 = getBuiltIn$8;
2447var DESCRIPTORS$9 = descriptors;
2448var NATIVE_SYMBOL = nativeSymbol;
2449var fails$d = fails$m;
2450var has$2 = has$c;
2451var isArray$a = isArray$c;
2452var isObject$a = isObject$j;
2453var isSymbol = isSymbol$4;
2454var anObject$6 = anObject$d;
2455var toObject$8 = toObject$e;
2456var toIndexedObject$4 = toIndexedObject$a;
2457var toPropertyKey = toPropertyKey$4;
2458var $toString = toString$9;
2459var createPropertyDescriptor = createPropertyDescriptor$5;
2460var nativeObjectCreate = objectCreate;
2461var objectKeys$1 = objectKeys$4;
2462var getOwnPropertyNamesModule$2 = objectGetOwnPropertyNames;
2463var getOwnPropertyNamesExternal = objectGetOwnPropertyNamesExternal;
2464var getOwnPropertySymbolsModule$1 = objectGetOwnPropertySymbols;
2465var getOwnPropertyDescriptorModule$2 = objectGetOwnPropertyDescriptor;
2466var definePropertyModule$1 = objectDefineProperty;
2467var propertyIsEnumerableModule = objectPropertyIsEnumerable;
2468var createNonEnumerableProperty$1 = createNonEnumerableProperty$9;
2469var redefine$1 = redefine$3;
2470var shared = shared$4.exports;
2471var sharedKey = sharedKey$4;
2472var hiddenKeys$1 = hiddenKeys$6;
2473var uid$1 = uid$4;
2474var wellKnownSymbol$6 = wellKnownSymbol$j;
2475var wrappedWellKnownSymbolModule = wellKnownSymbolWrapped;
2476var defineWellKnownSymbol$k = defineWellKnownSymbol$l;
2477var setToStringTag$2 = setToStringTag$5;
2478var InternalStateModule$3 = internalState;
2479var $forEach$1 = arrayIteration.forEach;
2480var HIDDEN = sharedKey('hidden');
2481var SYMBOL = 'Symbol';
2482var PROTOTYPE = 'prototype';
2483var TO_PRIMITIVE = wellKnownSymbol$6('toPrimitive');
2484var setInternalState$3 = InternalStateModule$3.set;
2485var getInternalState = InternalStateModule$3.getterFor(SYMBOL);
2486var ObjectPrototype = Object[PROTOTYPE];
2487var $Symbol = global$9.Symbol;
2488var $stringify$1 = getBuiltIn$4('JSON', 'stringify');
2489var nativeGetOwnPropertyDescriptor$1 = getOwnPropertyDescriptorModule$2.f;
2490var nativeDefineProperty = definePropertyModule$1.f;
2491var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;
2492var nativePropertyIsEnumerable = propertyIsEnumerableModule.f;
2493var AllSymbols = shared('symbols');
2494var ObjectPrototypeSymbols = shared('op-symbols');
2495var StringToSymbolRegistry = shared('string-to-symbol-registry');
2496var SymbolToStringRegistry = shared('symbol-to-string-registry');
2497var WellKnownSymbolsStore = shared('wks');
2498var QObject = global$9.QObject; // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
2499
2500var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
2501
2502var setSymbolDescriptor = DESCRIPTORS$9 && fails$d(function () {
2503 return nativeObjectCreate(nativeDefineProperty({}, 'a', {
2504 get: function () {
2505 return nativeDefineProperty(this, 'a', {
2506 value: 7
2507 }).a;
2508 }
2509 })).a != 7;
2510}) ? function (O, P, Attributes) {
2511 var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor$1(ObjectPrototype, P);
2512 if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];
2513 nativeDefineProperty(O, P, Attributes);
2514
2515 if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {
2516 nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor);
2517 }
2518} : nativeDefineProperty;
2519
2520var wrap$1 = function (tag, description) {
2521 var symbol = AllSymbols[tag] = nativeObjectCreate($Symbol[PROTOTYPE]);
2522 setInternalState$3(symbol, {
2523 type: SYMBOL,
2524 tag: tag,
2525 description: description
2526 });
2527 if (!DESCRIPTORS$9) symbol.description = description;
2528 return symbol;
2529};
2530
2531var $defineProperty = function defineProperty(O, P, Attributes) {
2532 if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
2533 anObject$6(O);
2534 var key = toPropertyKey(P);
2535 anObject$6(Attributes);
2536
2537 if (has$2(AllSymbols, key)) {
2538 if (!Attributes.enumerable) {
2539 if (!has$2(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {}));
2540 O[HIDDEN][key] = true;
2541 } else {
2542 if (has$2(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
2543 Attributes = nativeObjectCreate(Attributes, {
2544 enumerable: createPropertyDescriptor(0, false)
2545 });
2546 }
2547
2548 return setSymbolDescriptor(O, key, Attributes);
2549 }
2550
2551 return nativeDefineProperty(O, key, Attributes);
2552};
2553
2554var $defineProperties = function defineProperties(O, Properties) {
2555 anObject$6(O);
2556 var properties = toIndexedObject$4(Properties);
2557 var keys = objectKeys$1(properties).concat($getOwnPropertySymbols(properties));
2558 $forEach$1(keys, function (key) {
2559 if (!DESCRIPTORS$9 || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]);
2560 });
2561 return O;
2562};
2563
2564var $create = function create(O, Properties) {
2565 return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties);
2566};
2567
2568var $propertyIsEnumerable = function propertyIsEnumerable(V) {
2569 var P = toPropertyKey(V);
2570 var enumerable = nativePropertyIsEnumerable.call(this, P);
2571 if (this === ObjectPrototype && has$2(AllSymbols, P) && !has$2(ObjectPrototypeSymbols, P)) return false;
2572 return enumerable || !has$2(this, P) || !has$2(AllSymbols, P) || has$2(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true;
2573};
2574
2575var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
2576 var it = toIndexedObject$4(O);
2577 var key = toPropertyKey(P);
2578 if (it === ObjectPrototype && has$2(AllSymbols, key) && !has$2(ObjectPrototypeSymbols, key)) return;
2579 var descriptor = nativeGetOwnPropertyDescriptor$1(it, key);
2580
2581 if (descriptor && has$2(AllSymbols, key) && !(has$2(it, HIDDEN) && it[HIDDEN][key])) {
2582 descriptor.enumerable = true;
2583 }
2584
2585 return descriptor;
2586};
2587
2588var $getOwnPropertyNames = function getOwnPropertyNames(O) {
2589 var names = nativeGetOwnPropertyNames(toIndexedObject$4(O));
2590 var result = [];
2591 $forEach$1(names, function (key) {
2592 if (!has$2(AllSymbols, key) && !has$2(hiddenKeys$1, key)) result.push(key);
2593 });
2594 return result;
2595};
2596
2597var $getOwnPropertySymbols = function getOwnPropertySymbols(O) {
2598 var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;
2599 var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject$4(O));
2600 var result = [];
2601 $forEach$1(names, function (key) {
2602 if (has$2(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has$2(ObjectPrototype, key))) {
2603 result.push(AllSymbols[key]);
2604 }
2605 });
2606 return result;
2607}; // `Symbol` constructor
2608// https://tc39.es/ecma262/#sec-symbol-constructor
2609
2610
2611if (!NATIVE_SYMBOL) {
2612 $Symbol = function Symbol() {
2613 if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
2614 var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]);
2615 var tag = uid$1(description);
2616
2617 var setter = function (value) {
2618 if (this === ObjectPrototype) setter.call(ObjectPrototypeSymbols, value);
2619 if (has$2(this, HIDDEN) && has$2(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
2620 setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
2621 };
2622
2623 if (DESCRIPTORS$9 && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, {
2624 configurable: true,
2625 set: setter
2626 });
2627 return wrap$1(tag, description);
2628 };
2629
2630 redefine$1($Symbol[PROTOTYPE], 'toString', function toString() {
2631 return getInternalState(this).tag;
2632 });
2633 redefine$1($Symbol, 'withoutSetter', function (description) {
2634 return wrap$1(uid$1(description), description);
2635 });
2636 propertyIsEnumerableModule.f = $propertyIsEnumerable;
2637 definePropertyModule$1.f = $defineProperty;
2638 getOwnPropertyDescriptorModule$2.f = $getOwnPropertyDescriptor;
2639 getOwnPropertyNamesModule$2.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;
2640 getOwnPropertySymbolsModule$1.f = $getOwnPropertySymbols;
2641
2642 wrappedWellKnownSymbolModule.f = function (name) {
2643 return wrap$1(wellKnownSymbol$6(name), name);
2644 };
2645
2646 if (DESCRIPTORS$9) {
2647 // https://github.com/tc39/proposal-Symbol-description
2648 nativeDefineProperty($Symbol[PROTOTYPE], 'description', {
2649 configurable: true,
2650 get: function description() {
2651 return getInternalState(this).description;
2652 }
2653 });
2654 }
2655}
2656
2657$$F({
2658 global: true,
2659 wrap: true,
2660 forced: !NATIVE_SYMBOL,
2661 sham: !NATIVE_SYMBOL
2662}, {
2663 Symbol: $Symbol
2664});
2665$forEach$1(objectKeys$1(WellKnownSymbolsStore), function (name) {
2666 defineWellKnownSymbol$k(name);
2667});
2668$$F({
2669 target: SYMBOL,
2670 stat: true,
2671 forced: !NATIVE_SYMBOL
2672}, {
2673 // `Symbol.for` method
2674 // https://tc39.es/ecma262/#sec-symbol.for
2675 'for': function (key) {
2676 var string = $toString(key);
2677 if (has$2(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
2678 var symbol = $Symbol(string);
2679 StringToSymbolRegistry[string] = symbol;
2680 SymbolToStringRegistry[symbol] = string;
2681 return symbol;
2682 },
2683 // `Symbol.keyFor` method
2684 // https://tc39.es/ecma262/#sec-symbol.keyfor
2685 keyFor: function keyFor(sym) {
2686 if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
2687 if (has$2(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
2688 },
2689 useSetter: function () {
2690 USE_SETTER = true;
2691 },
2692 useSimple: function () {
2693 USE_SETTER = false;
2694 }
2695});
2696$$F({
2697 target: 'Object',
2698 stat: true,
2699 forced: !NATIVE_SYMBOL,
2700 sham: !DESCRIPTORS$9
2701}, {
2702 // `Object.create` method
2703 // https://tc39.es/ecma262/#sec-object.create
2704 create: $create,
2705 // `Object.defineProperty` method
2706 // https://tc39.es/ecma262/#sec-object.defineproperty
2707 defineProperty: $defineProperty,
2708 // `Object.defineProperties` method
2709 // https://tc39.es/ecma262/#sec-object.defineproperties
2710 defineProperties: $defineProperties,
2711 // `Object.getOwnPropertyDescriptor` method
2712 // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
2713 getOwnPropertyDescriptor: $getOwnPropertyDescriptor
2714});
2715$$F({
2716 target: 'Object',
2717 stat: true,
2718 forced: !NATIVE_SYMBOL
2719}, {
2720 // `Object.getOwnPropertyNames` method
2721 // https://tc39.es/ecma262/#sec-object.getownpropertynames
2722 getOwnPropertyNames: $getOwnPropertyNames,
2723 // `Object.getOwnPropertySymbols` method
2724 // https://tc39.es/ecma262/#sec-object.getownpropertysymbols
2725 getOwnPropertySymbols: $getOwnPropertySymbols
2726}); // Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
2727// https://bugs.chromium.org/p/v8/issues/detail?id=3443
2728
2729$$F({
2730 target: 'Object',
2731 stat: true,
2732 forced: fails$d(function () {
2733 getOwnPropertySymbolsModule$1.f(1);
2734 })
2735}, {
2736 getOwnPropertySymbols: function getOwnPropertySymbols(it) {
2737 return getOwnPropertySymbolsModule$1.f(toObject$8(it));
2738 }
2739}); // `JSON.stringify` method behavior with symbols
2740// https://tc39.es/ecma262/#sec-json.stringify
2741
2742if ($stringify$1) {
2743 var FORCED_JSON_STRINGIFY = !NATIVE_SYMBOL || fails$d(function () {
2744 var symbol = $Symbol(); // MS Edge converts symbol values to JSON as {}
2745
2746 return $stringify$1([symbol]) != '[null]' // WebKit converts symbol values to JSON as null
2747 || $stringify$1({
2748 a: symbol
2749 }) != '{}' // V8 throws on boxed symbols
2750 || $stringify$1(Object(symbol)) != '{}';
2751 });
2752 $$F({
2753 target: 'JSON',
2754 stat: true,
2755 forced: FORCED_JSON_STRINGIFY
2756 }, {
2757 // eslint-disable-next-line no-unused-vars -- required for `.length`
2758 stringify: function stringify(it, replacer, space) {
2759 var args = [it];
2760 var index = 1;
2761 var $replacer;
2762
2763 while (arguments.length > index) args.push(arguments[index++]);
2764
2765 $replacer = replacer;
2766 if (!isObject$a(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
2767
2768 if (!isArray$a(replacer)) replacer = function (key, value) {
2769 if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
2770 if (!isSymbol(value)) return value;
2771 };
2772 args[1] = replacer;
2773 return $stringify$1.apply(null, args);
2774 }
2775 });
2776} // `Symbol.prototype[@@toPrimitive]` method
2777// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
2778
2779
2780if (!$Symbol[PROTOTYPE][TO_PRIMITIVE]) {
2781 createNonEnumerableProperty$1($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
2782} // `Symbol.prototype[@@toStringTag]` property
2783// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag
2784
2785
2786setToStringTag$2($Symbol, SYMBOL);
2787hiddenKeys$1[HIDDEN] = true;
2788
2789var path$q = path$x;
2790var getOwnPropertySymbols$2 = path$q.Object.getOwnPropertySymbols;
2791
2792var parent$U = getOwnPropertySymbols$2;
2793var getOwnPropertySymbols$1 = parent$U;
2794
2795var getOwnPropertySymbols = getOwnPropertySymbols$1;
2796
2797var getOwnPropertyDescriptor$5 = {exports: {}};
2798
2799var $$E = _export;
2800var fails$c = fails$m;
2801var toIndexedObject$3 = toIndexedObject$a;
2802var nativeGetOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
2803var DESCRIPTORS$8 = descriptors;
2804var FAILS_ON_PRIMITIVES$3 = fails$c(function () {
2805 nativeGetOwnPropertyDescriptor(1);
2806});
2807var FORCED$6 = !DESCRIPTORS$8 || FAILS_ON_PRIMITIVES$3; // `Object.getOwnPropertyDescriptor` method
2808// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
2809
2810$$E({
2811 target: 'Object',
2812 stat: true,
2813 forced: FORCED$6,
2814 sham: !DESCRIPTORS$8
2815}, {
2816 getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {
2817 return nativeGetOwnPropertyDescriptor(toIndexedObject$3(it), key);
2818 }
2819});
2820
2821var path$p = path$x;
2822var Object$5 = path$p.Object;
2823
2824var getOwnPropertyDescriptor$4 = getOwnPropertyDescriptor$5.exports = function getOwnPropertyDescriptor(it, key) {
2825 return Object$5.getOwnPropertyDescriptor(it, key);
2826};
2827
2828if (Object$5.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor$4.sham = true;
2829
2830var parent$T = getOwnPropertyDescriptor$5.exports;
2831var getOwnPropertyDescriptor$3 = parent$T;
2832
2833var getOwnPropertyDescriptor$2 = getOwnPropertyDescriptor$3;
2834
2835var getBuiltIn$3 = getBuiltIn$8;
2836var getOwnPropertyNamesModule$1 = objectGetOwnPropertyNames;
2837var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols;
2838var anObject$5 = anObject$d; // all object keys, includes non-enumerable and symbols
2839
2840var ownKeys$a = getBuiltIn$3('Reflect', 'ownKeys') || function ownKeys(it) {
2841 var keys = getOwnPropertyNamesModule$1.f(anObject$5(it));
2842 var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
2843 return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
2844};
2845
2846var $$D = _export;
2847var DESCRIPTORS$7 = descriptors;
2848var ownKeys$9 = ownKeys$a;
2849var toIndexedObject$2 = toIndexedObject$a;
2850var getOwnPropertyDescriptorModule$1 = objectGetOwnPropertyDescriptor;
2851var createProperty$3 = createProperty$5; // `Object.getOwnPropertyDescriptors` method
2852// https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
2853
2854$$D({
2855 target: 'Object',
2856 stat: true,
2857 sham: !DESCRIPTORS$7
2858}, {
2859 getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {
2860 var O = toIndexedObject$2(object);
2861 var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule$1.f;
2862 var keys = ownKeys$9(O);
2863 var result = {};
2864 var index = 0;
2865 var key, descriptor;
2866
2867 while (keys.length > index) {
2868 descriptor = getOwnPropertyDescriptor(O, key = keys[index++]);
2869 if (descriptor !== undefined) createProperty$3(result, key, descriptor);
2870 }
2871
2872 return result;
2873 }
2874});
2875
2876var path$o = path$x;
2877var getOwnPropertyDescriptors$2 = path$o.Object.getOwnPropertyDescriptors;
2878
2879var parent$S = getOwnPropertyDescriptors$2;
2880var getOwnPropertyDescriptors$1 = parent$S;
2881
2882var getOwnPropertyDescriptors = getOwnPropertyDescriptors$1;
2883
2884var defineProperties$4 = {exports: {}};
2885
2886var $$C = _export;
2887var DESCRIPTORS$6 = descriptors;
2888var defineProperties$3 = objectDefineProperties; // `Object.defineProperties` method
2889// https://tc39.es/ecma262/#sec-object.defineproperties
2890
2891$$C({
2892 target: 'Object',
2893 stat: true,
2894 forced: !DESCRIPTORS$6,
2895 sham: !DESCRIPTORS$6
2896}, {
2897 defineProperties: defineProperties$3
2898});
2899
2900var path$n = path$x;
2901var Object$4 = path$n.Object;
2902
2903var defineProperties$2 = defineProperties$4.exports = function defineProperties(T, D) {
2904 return Object$4.defineProperties(T, D);
2905};
2906
2907if (Object$4.defineProperties.sham) defineProperties$2.sham = true;
2908
2909var parent$R = defineProperties$4.exports;
2910var defineProperties$1 = parent$R;
2911
2912var defineProperties = defineProperties$1;
2913
2914var defineProperty$8 = {exports: {}};
2915
2916var $$B = _export;
2917var DESCRIPTORS$5 = descriptors;
2918var objectDefinePropertyModile = objectDefineProperty; // `Object.defineProperty` method
2919// https://tc39.es/ecma262/#sec-object.defineproperty
2920
2921$$B({
2922 target: 'Object',
2923 stat: true,
2924 forced: !DESCRIPTORS$5,
2925 sham: !DESCRIPTORS$5
2926}, {
2927 defineProperty: objectDefinePropertyModile.f
2928});
2929
2930var path$m = path$x;
2931var Object$3 = path$m.Object;
2932
2933var defineProperty$7 = defineProperty$8.exports = function defineProperty(it, key, desc) {
2934 return Object$3.defineProperty(it, key, desc);
2935};
2936
2937if (Object$3.defineProperty.sham) defineProperty$7.sham = true;
2938
2939var parent$Q = defineProperty$8.exports;
2940var defineProperty$6 = parent$Q;
2941
2942var defineProperty$5 = defineProperty$6;
2943
2944function _classCallCheck(instance, Constructor) {
2945 if (!(instance instanceof Constructor)) {
2946 throw new TypeError("Cannot call a class as a function");
2947 }
2948}
2949
2950var parent$P = defineProperty$6;
2951var defineProperty$4 = parent$P;
2952
2953var defineProperty$3 = defineProperty$4;
2954
2955function _defineProperties(target, props) {
2956 for (var i = 0; i < props.length; i++) {
2957 var descriptor = props[i];
2958 descriptor.enumerable = descriptor.enumerable || false;
2959 descriptor.configurable = true;
2960 if ("value" in descriptor) descriptor.writable = true;
2961
2962 defineProperty$3(target, descriptor.key, descriptor);
2963 }
2964}
2965
2966function _createClass(Constructor, protoProps, staticProps) {
2967 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
2968 if (staticProps) _defineProperties(Constructor, staticProps);
2969 return Constructor;
2970}
2971
2972function _defineProperty(obj, key, value) {
2973 if (key in obj) {
2974 defineProperty$3(obj, key, {
2975 value: value,
2976 enumerable: true,
2977 configurable: true,
2978 writable: true
2979 });
2980 } else {
2981 obj[key] = value;
2982 }
2983
2984 return obj;
2985}
2986
2987var $$A = _export;
2988var isArray$9 = isArray$c; // `Array.isArray` method
2989// https://tc39.es/ecma262/#sec-array.isarray
2990
2991$$A({
2992 target: 'Array',
2993 stat: true
2994}, {
2995 isArray: isArray$9
2996});
2997
2998var path$l = path$x;
2999var isArray$8 = path$l.Array.isArray;
3000
3001var parent$O = isArray$8;
3002var isArray$7 = parent$O;
3003
3004var parent$N = isArray$7;
3005var isArray$6 = parent$N;
3006
3007var isArray$5 = isArray$6;
3008
3009function _arrayWithHoles(arr) {
3010 if (isArray$5(arr)) return arr;
3011}
3012
3013var fails$b = fails$m;
3014var wellKnownSymbol$5 = wellKnownSymbol$j;
3015var V8_VERSION$1 = engineV8Version;
3016var SPECIES$2 = wellKnownSymbol$5('species');
3017
3018var arrayMethodHasSpeciesSupport$5 = function (METHOD_NAME) {
3019 // We can't use this feature detection in V8 since it causes
3020 // deoptimization and serious performance degradation
3021 // https://github.com/zloirock/core-js/issues/677
3022 return V8_VERSION$1 >= 51 || !fails$b(function () {
3023 var array = [];
3024 var constructor = array.constructor = {};
3025
3026 constructor[SPECIES$2] = function () {
3027 return {
3028 foo: 1
3029 };
3030 };
3031
3032 return array[METHOD_NAME](Boolean).foo !== 1;
3033 });
3034};
3035
3036var $$z = _export;
3037var fails$a = fails$m;
3038var isArray$4 = isArray$c;
3039var isObject$9 = isObject$j;
3040var toObject$7 = toObject$e;
3041var toLength$8 = toLength$c;
3042var createProperty$2 = createProperty$5;
3043var arraySpeciesCreate$2 = arraySpeciesCreate$4;
3044var arrayMethodHasSpeciesSupport$4 = arrayMethodHasSpeciesSupport$5;
3045var wellKnownSymbol$4 = wellKnownSymbol$j;
3046var V8_VERSION = engineV8Version;
3047var IS_CONCAT_SPREADABLE = wellKnownSymbol$4('isConcatSpreadable');
3048var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
3049var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded'; // We can't use this feature detection in V8 since it causes
3050// deoptimization and serious performance degradation
3051// https://github.com/zloirock/core-js/issues/679
3052
3053var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails$a(function () {
3054 var array = [];
3055 array[IS_CONCAT_SPREADABLE] = false;
3056 return array.concat()[0] !== array;
3057});
3058var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport$4('concat');
3059
3060var isConcatSpreadable = function (O) {
3061 if (!isObject$9(O)) return false;
3062 var spreadable = O[IS_CONCAT_SPREADABLE];
3063 return spreadable !== undefined ? !!spreadable : isArray$4(O);
3064};
3065
3066var FORCED$5 = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT; // `Array.prototype.concat` method
3067// https://tc39.es/ecma262/#sec-array.prototype.concat
3068// with adding support of @@isConcatSpreadable and @@species
3069
3070$$z({
3071 target: 'Array',
3072 proto: true,
3073 forced: FORCED$5
3074}, {
3075 // eslint-disable-next-line no-unused-vars -- required for `.length`
3076 concat: function concat(arg) {
3077 var O = toObject$7(this);
3078 var A = arraySpeciesCreate$2(O, 0);
3079 var n = 0;
3080 var i, k, length, len, E;
3081
3082 for (i = -1, length = arguments.length; i < length; i++) {
3083 E = i === -1 ? O : arguments[i];
3084
3085 if (isConcatSpreadable(E)) {
3086 len = toLength$8(E.length);
3087 if (n + len > MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
3088
3089 for (k = 0; k < len; k++, n++) if (k in E) createProperty$2(A, n, E[k]);
3090 } else {
3091 if (n >= MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
3092 createProperty$2(A, n++, E);
3093 }
3094 }
3095
3096 A.length = n;
3097 return A;
3098 }
3099});
3100
3101var defineWellKnownSymbol$j = defineWellKnownSymbol$l; // `Symbol.asyncIterator` well-known symbol
3102// https://tc39.es/ecma262/#sec-symbol.asynciterator
3103
3104defineWellKnownSymbol$j('asyncIterator');
3105
3106var defineWellKnownSymbol$i = defineWellKnownSymbol$l; // `Symbol.hasInstance` well-known symbol
3107// https://tc39.es/ecma262/#sec-symbol.hasinstance
3108
3109defineWellKnownSymbol$i('hasInstance');
3110
3111var defineWellKnownSymbol$h = defineWellKnownSymbol$l; // `Symbol.isConcatSpreadable` well-known symbol
3112// https://tc39.es/ecma262/#sec-symbol.isconcatspreadable
3113
3114defineWellKnownSymbol$h('isConcatSpreadable');
3115
3116var defineWellKnownSymbol$g = defineWellKnownSymbol$l; // `Symbol.iterator` well-known symbol
3117// https://tc39.es/ecma262/#sec-symbol.iterator
3118
3119defineWellKnownSymbol$g('iterator');
3120
3121var defineWellKnownSymbol$f = defineWellKnownSymbol$l; // `Symbol.match` well-known symbol
3122// https://tc39.es/ecma262/#sec-symbol.match
3123
3124defineWellKnownSymbol$f('match');
3125
3126var defineWellKnownSymbol$e = defineWellKnownSymbol$l; // `Symbol.matchAll` well-known symbol
3127// https://tc39.es/ecma262/#sec-symbol.matchall
3128
3129defineWellKnownSymbol$e('matchAll');
3130
3131var defineWellKnownSymbol$d = defineWellKnownSymbol$l; // `Symbol.replace` well-known symbol
3132// https://tc39.es/ecma262/#sec-symbol.replace
3133
3134defineWellKnownSymbol$d('replace');
3135
3136var defineWellKnownSymbol$c = defineWellKnownSymbol$l; // `Symbol.search` well-known symbol
3137// https://tc39.es/ecma262/#sec-symbol.search
3138
3139defineWellKnownSymbol$c('search');
3140
3141var defineWellKnownSymbol$b = defineWellKnownSymbol$l; // `Symbol.species` well-known symbol
3142// https://tc39.es/ecma262/#sec-symbol.species
3143
3144defineWellKnownSymbol$b('species');
3145
3146var defineWellKnownSymbol$a = defineWellKnownSymbol$l; // `Symbol.split` well-known symbol
3147// https://tc39.es/ecma262/#sec-symbol.split
3148
3149defineWellKnownSymbol$a('split');
3150
3151var defineWellKnownSymbol$9 = defineWellKnownSymbol$l; // `Symbol.toPrimitive` well-known symbol
3152// https://tc39.es/ecma262/#sec-symbol.toprimitive
3153
3154defineWellKnownSymbol$9('toPrimitive');
3155
3156var defineWellKnownSymbol$8 = defineWellKnownSymbol$l; // `Symbol.toStringTag` well-known symbol
3157// https://tc39.es/ecma262/#sec-symbol.tostringtag
3158
3159defineWellKnownSymbol$8('toStringTag');
3160
3161var defineWellKnownSymbol$7 = defineWellKnownSymbol$l; // `Symbol.unscopables` well-known symbol
3162// https://tc39.es/ecma262/#sec-symbol.unscopables
3163
3164defineWellKnownSymbol$7('unscopables');
3165
3166var global$8 = global$k;
3167var setToStringTag$1 = setToStringTag$5; // JSON[@@toStringTag] property
3168// https://tc39.es/ecma262/#sec-json-@@tostringtag
3169
3170setToStringTag$1(global$8.JSON, 'JSON', true);
3171
3172var path$k = path$x;
3173var symbol$4 = path$k.Symbol;
3174
3175var parent$M = symbol$4;
3176var symbol$3 = parent$M;
3177
3178var defineWellKnownSymbol$6 = defineWellKnownSymbol$l; // `Symbol.asyncDispose` well-known symbol
3179// https://github.com/tc39/proposal-using-statement
3180
3181defineWellKnownSymbol$6('asyncDispose');
3182
3183var defineWellKnownSymbol$5 = defineWellKnownSymbol$l; // `Symbol.dispose` well-known symbol
3184// https://github.com/tc39/proposal-using-statement
3185
3186defineWellKnownSymbol$5('dispose');
3187
3188var defineWellKnownSymbol$4 = defineWellKnownSymbol$l; // `Symbol.matcher` well-known symbol
3189// https://github.com/tc39/proposal-pattern-matching
3190
3191defineWellKnownSymbol$4('matcher');
3192
3193var defineWellKnownSymbol$3 = defineWellKnownSymbol$l; // `Symbol.metadata` well-known symbol
3194// https://github.com/tc39/proposal-decorators
3195
3196defineWellKnownSymbol$3('metadata');
3197
3198var defineWellKnownSymbol$2 = defineWellKnownSymbol$l; // `Symbol.observable` well-known symbol
3199// https://github.com/tc39/proposal-observable
3200
3201defineWellKnownSymbol$2('observable');
3202
3203var defineWellKnownSymbol$1 = defineWellKnownSymbol$l; // `Symbol.patternMatch` well-known symbol
3204// https://github.com/tc39/proposal-pattern-matching
3205
3206defineWellKnownSymbol$1('patternMatch');
3207
3208var defineWellKnownSymbol = defineWellKnownSymbol$l;
3209defineWellKnownSymbol('replaceAll');
3210
3211var parent$L = symbol$3; // TODO: Remove from `core-js@4`
3212// TODO: Remove from `core-js@4`
3213
3214var symbol$2 = parent$L;
3215
3216var symbol$1 = symbol$2;
3217
3218function _iterableToArrayLimit(arr, i) {
3219 var _i = arr == null ? null : typeof symbol$1 !== "undefined" && getIteratorMethod$2(arr) || arr["@@iterator"];
3220
3221 if (_i == null) return;
3222 var _arr = [];
3223 var _n = true;
3224 var _d = false;
3225
3226 var _s, _e;
3227
3228 try {
3229 for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
3230 _arr.push(_s.value);
3231
3232 if (i && _arr.length === i) break;
3233 }
3234 } catch (err) {
3235 _d = true;
3236 _e = err;
3237 } finally {
3238 try {
3239 if (!_n && _i["return"] != null) _i["return"]();
3240 } finally {
3241 if (_d) throw _e;
3242 }
3243 }
3244
3245 return _arr;
3246}
3247
3248var $$y = _export;
3249var isObject$8 = isObject$j;
3250var isArray$3 = isArray$c;
3251var toAbsoluteIndex$2 = toAbsoluteIndex$4;
3252var toLength$7 = toLength$c;
3253var toIndexedObject$1 = toIndexedObject$a;
3254var createProperty$1 = createProperty$5;
3255var wellKnownSymbol$3 = wellKnownSymbol$j;
3256var arrayMethodHasSpeciesSupport$3 = arrayMethodHasSpeciesSupport$5;
3257var HAS_SPECIES_SUPPORT$3 = arrayMethodHasSpeciesSupport$3('slice');
3258var SPECIES$1 = wellKnownSymbol$3('species');
3259var nativeSlice = [].slice;
3260var max$1 = Math.max; // `Array.prototype.slice` method
3261// https://tc39.es/ecma262/#sec-array.prototype.slice
3262// fallback for not array-like ES3 strings and DOM objects
3263
3264$$y({
3265 target: 'Array',
3266 proto: true,
3267 forced: !HAS_SPECIES_SUPPORT$3
3268}, {
3269 slice: function slice(start, end) {
3270 var O = toIndexedObject$1(this);
3271 var length = toLength$7(O.length);
3272 var k = toAbsoluteIndex$2(start, length);
3273 var fin = toAbsoluteIndex$2(end === undefined ? length : end, length); // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
3274
3275 var Constructor, result, n;
3276
3277 if (isArray$3(O)) {
3278 Constructor = O.constructor; // cross-realm fallback
3279
3280 if (typeof Constructor == 'function' && (Constructor === Array || isArray$3(Constructor.prototype))) {
3281 Constructor = undefined;
3282 } else if (isObject$8(Constructor)) {
3283 Constructor = Constructor[SPECIES$1];
3284 if (Constructor === null) Constructor = undefined;
3285 }
3286
3287 if (Constructor === Array || Constructor === undefined) {
3288 return nativeSlice.call(O, k, fin);
3289 }
3290 }
3291
3292 result = new (Constructor === undefined ? Array : Constructor)(max$1(fin - k, 0));
3293
3294 for (n = 0; k < fin; k++, n++) if (k in O) createProperty$1(result, n, O[k]);
3295
3296 result.length = n;
3297 return result;
3298 }
3299});
3300
3301var entryVirtual$j = entryVirtual$l;
3302var slice$6 = entryVirtual$j('Array').slice;
3303
3304var slice$5 = slice$6;
3305var ArrayPrototype$h = Array.prototype;
3306
3307var slice_1 = function (it) {
3308 var own = it.slice;
3309 return it === ArrayPrototype$h || it instanceof Array && own === ArrayPrototype$h.slice ? slice$5 : own;
3310};
3311
3312var parent$K = slice_1;
3313var slice$4 = parent$K;
3314
3315var parent$J = slice$4;
3316var slice$3 = parent$J;
3317
3318var slice$2 = slice$3;
3319
3320var parent$I = from$3;
3321var from$1 = parent$I;
3322
3323var from = from$1;
3324
3325function _arrayLikeToArray$9(arr, len) {
3326 if (len == null || len > arr.length) len = arr.length;
3327
3328 for (var i = 0, arr2 = new Array(len); i < len; i++) {
3329 arr2[i] = arr[i];
3330 }
3331
3332 return arr2;
3333}
3334
3335function _unsupportedIterableToArray$9(o, minLen) {
3336 var _context;
3337
3338 if (!o) return;
3339 if (typeof o === "string") return _arrayLikeToArray$9(o, minLen);
3340
3341 var n = slice$2(_context = Object.prototype.toString.call(o)).call(_context, 8, -1);
3342
3343 if (n === "Object" && o.constructor) n = o.constructor.name;
3344 if (n === "Map" || n === "Set") return from(o);
3345 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$9(o, minLen);
3346}
3347
3348function _nonIterableRest() {
3349 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3350}
3351
3352function _slicedToArray(arr, i) {
3353 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray$9(arr, i) || _nonIterableRest();
3354}
3355
3356var WrappedWellKnownSymbolModule = wellKnownSymbolWrapped;
3357var iterator$4 = WrappedWellKnownSymbolModule.f('iterator');
3358
3359var parent$H = iterator$4;
3360var iterator$3 = parent$H;
3361
3362var parent$G = iterator$3;
3363var iterator$2 = parent$G;
3364
3365var iterator$1 = iterator$2;
3366
3367function _typeof(obj) {
3368 "@babel/helpers - typeof";
3369
3370 if (typeof symbol$1 === "function" && typeof iterator$1 === "symbol") {
3371 _typeof = function _typeof(obj) {
3372 return typeof obj;
3373 };
3374 } else {
3375 _typeof = function _typeof(obj) {
3376 return obj && typeof symbol$1 === "function" && obj.constructor === symbol$1 && obj !== symbol$1.prototype ? "symbol" : typeof obj;
3377 };
3378 }
3379
3380 return _typeof(obj);
3381}
3382
3383function _arrayWithoutHoles(arr) {
3384 if (isArray$5(arr)) return _arrayLikeToArray$9(arr);
3385}
3386
3387function _iterableToArray(iter) {
3388 if (typeof symbol$1 !== "undefined" && getIteratorMethod$2(iter) != null || iter["@@iterator"] != null) return from(iter);
3389}
3390
3391function _nonIterableSpread() {
3392 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3393}
3394
3395function _toConsumableArray(arr) {
3396 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray$9(arr) || _nonIterableSpread();
3397}
3398
3399var symbol = symbol$3;
3400
3401var entryVirtual$i = entryVirtual$l;
3402var concat$3 = entryVirtual$i('Array').concat;
3403
3404var concat$2 = concat$3;
3405var ArrayPrototype$g = Array.prototype;
3406
3407var concat_1 = function (it) {
3408 var own = it.concat;
3409 return it === ArrayPrototype$g || it instanceof Array && own === ArrayPrototype$g.concat ? concat$2 : own;
3410};
3411
3412var parent$F = concat_1;
3413var concat$1 = parent$F;
3414
3415var concat = concat$1;
3416
3417var slice$1 = slice$4;
3418
3419var $$x = _export;
3420var ownKeys$8 = ownKeys$a; // `Reflect.ownKeys` method
3421// https://tc39.es/ecma262/#sec-reflect.ownkeys
3422
3423$$x({
3424 target: 'Reflect',
3425 stat: true
3426}, {
3427 ownKeys: ownKeys$8
3428});
3429
3430var path$j = path$x;
3431var ownKeys$7 = path$j.Reflect.ownKeys;
3432
3433var parent$E = ownKeys$7;
3434var ownKeys$6 = parent$E;
3435
3436var ownKeys$5 = ownKeys$6;
3437
3438var isArray$2 = isArray$7;
3439
3440var $$w = _export;
3441var $map = arrayIteration.map;
3442var arrayMethodHasSpeciesSupport$2 = arrayMethodHasSpeciesSupport$5;
3443var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport$2('map'); // `Array.prototype.map` method
3444// https://tc39.es/ecma262/#sec-array.prototype.map
3445// with adding support of @@species
3446
3447$$w({
3448 target: 'Array',
3449 proto: true,
3450 forced: !HAS_SPECIES_SUPPORT$2
3451}, {
3452 map: function map(callbackfn
3453 /* , thisArg */
3454 ) {
3455 return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
3456 }
3457});
3458
3459var entryVirtual$h = entryVirtual$l;
3460var map$6 = entryVirtual$h('Array').map;
3461
3462var map$5 = map$6;
3463var ArrayPrototype$f = Array.prototype;
3464
3465var map_1 = function (it) {
3466 var own = it.map;
3467 return it === ArrayPrototype$f || it instanceof Array && own === ArrayPrototype$f.map ? map$5 : own;
3468};
3469
3470var parent$D = map_1;
3471var map$4 = parent$D;
3472
3473var map$3 = map$4;
3474
3475var $$v = _export;
3476var toObject$6 = toObject$e;
3477var nativeKeys = objectKeys$4;
3478var fails$9 = fails$m;
3479var FAILS_ON_PRIMITIVES$2 = fails$9(function () {
3480 nativeKeys(1);
3481}); // `Object.keys` method
3482// https://tc39.es/ecma262/#sec-object.keys
3483
3484$$v({
3485 target: 'Object',
3486 stat: true,
3487 forced: FAILS_ON_PRIMITIVES$2
3488}, {
3489 keys: function keys(it) {
3490 return nativeKeys(toObject$6(it));
3491 }
3492});
3493
3494var path$i = path$x;
3495var keys$6 = path$i.Object.keys;
3496
3497var parent$C = keys$6;
3498var keys$5 = parent$C;
3499
3500var keys$4 = keys$5;
3501
3502var $$u = _export; // `Date.now` method
3503// https://tc39.es/ecma262/#sec-date.now
3504
3505$$u({
3506 target: 'Date',
3507 stat: true
3508}, {
3509 now: function now() {
3510 return new Date().getTime();
3511 }
3512});
3513
3514var path$h = path$x;
3515var now$3 = path$h.Date.now;
3516
3517var parent$B = now$3;
3518var now$2 = parent$B;
3519
3520var now$1 = now$2;
3521
3522var fails$8 = fails$m;
3523
3524var arrayMethodIsStrict$6 = function (METHOD_NAME, argument) {
3525 var method = [][METHOD_NAME];
3526 return !!method && fails$8(function () {
3527 // eslint-disable-next-line no-useless-call,no-throw-literal -- required for testing
3528 method.call(null, argument || function () {
3529 throw 1;
3530 }, 1);
3531 });
3532};
3533
3534var $forEach = arrayIteration.forEach;
3535var arrayMethodIsStrict$5 = arrayMethodIsStrict$6;
3536var STRICT_METHOD$5 = arrayMethodIsStrict$5('forEach'); // `Array.prototype.forEach` method implementation
3537// https://tc39.es/ecma262/#sec-array.prototype.foreach
3538
3539var arrayForEach = !STRICT_METHOD$5 ? function forEach(callbackfn
3540/* , thisArg */
3541) {
3542 return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); // eslint-disable-next-line es/no-array-prototype-foreach -- safe
3543} : [].forEach;
3544
3545var $$t = _export;
3546var forEach$6 = arrayForEach; // `Array.prototype.forEach` method
3547// https://tc39.es/ecma262/#sec-array.prototype.foreach
3548// eslint-disable-next-line es/no-array-prototype-foreach -- safe
3549
3550$$t({
3551 target: 'Array',
3552 proto: true,
3553 forced: [].forEach != forEach$6
3554}, {
3555 forEach: forEach$6
3556});
3557
3558var entryVirtual$g = entryVirtual$l;
3559var forEach$5 = entryVirtual$g('Array').forEach;
3560
3561var parent$A = forEach$5;
3562var forEach$4 = parent$A;
3563
3564var forEach$3 = forEach$4;
3565var classof$5 = classof$a;
3566var ArrayPrototype$e = Array.prototype;
3567var DOMIterables$3 = {
3568 DOMTokenList: true,
3569 NodeList: true
3570};
3571
3572var forEach_1 = function (it) {
3573 var own = it.forEach;
3574 return it === ArrayPrototype$e || it instanceof Array && own === ArrayPrototype$e.forEach // eslint-disable-next-line no-prototype-builtins -- safe
3575 || DOMIterables$3.hasOwnProperty(classof$5(it)) ? forEach$3 : own;
3576};
3577
3578var forEach$2 = forEach_1;
3579
3580var $$s = _export;
3581var isArray$1 = isArray$c;
3582var nativeReverse = [].reverse;
3583var test$1 = [1, 2]; // `Array.prototype.reverse` method
3584// https://tc39.es/ecma262/#sec-array.prototype.reverse
3585// fix for Safari 12.0 bug
3586// https://bugs.webkit.org/show_bug.cgi?id=188794
3587
3588$$s({
3589 target: 'Array',
3590 proto: true,
3591 forced: String(test$1) === String(test$1.reverse())
3592}, {
3593 reverse: function reverse() {
3594 // eslint-disable-next-line no-self-assign -- dirty hack
3595 if (isArray$1(this)) this.length = this.length;
3596 return nativeReverse.call(this);
3597 }
3598});
3599
3600var entryVirtual$f = entryVirtual$l;
3601var reverse$3 = entryVirtual$f('Array').reverse;
3602
3603var reverse$2 = reverse$3;
3604var ArrayPrototype$d = Array.prototype;
3605
3606var reverse_1 = function (it) {
3607 var own = it.reverse;
3608 return it === ArrayPrototype$d || it instanceof Array && own === ArrayPrototype$d.reverse ? reverse$2 : own;
3609};
3610
3611var parent$z = reverse_1;
3612var reverse$1 = parent$z;
3613
3614var reverse = reverse$1;
3615
3616var $$r = _export;
3617var toAbsoluteIndex$1 = toAbsoluteIndex$4;
3618var toInteger = toInteger$4;
3619var toLength$6 = toLength$c;
3620var toObject$5 = toObject$e;
3621var arraySpeciesCreate$1 = arraySpeciesCreate$4;
3622var createProperty = createProperty$5;
3623var arrayMethodHasSpeciesSupport$1 = arrayMethodHasSpeciesSupport$5;
3624var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport$1('splice');
3625var max = Math.max;
3626var min = Math.min;
3627var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
3628var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded'; // `Array.prototype.splice` method
3629// https://tc39.es/ecma262/#sec-array.prototype.splice
3630// with adding support of @@species
3631
3632$$r({
3633 target: 'Array',
3634 proto: true,
3635 forced: !HAS_SPECIES_SUPPORT$1
3636}, {
3637 splice: function splice(start, deleteCount
3638 /* , ...items */
3639 ) {
3640 var O = toObject$5(this);
3641 var len = toLength$6(O.length);
3642 var actualStart = toAbsoluteIndex$1(start, len);
3643 var argumentsLength = arguments.length;
3644 var insertCount, actualDeleteCount, A, k, from, to;
3645
3646 if (argumentsLength === 0) {
3647 insertCount = actualDeleteCount = 0;
3648 } else if (argumentsLength === 1) {
3649 insertCount = 0;
3650 actualDeleteCount = len - actualStart;
3651 } else {
3652 insertCount = argumentsLength - 2;
3653 actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);
3654 }
3655
3656 if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
3657 throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
3658 }
3659
3660 A = arraySpeciesCreate$1(O, actualDeleteCount);
3661
3662 for (k = 0; k < actualDeleteCount; k++) {
3663 from = actualStart + k;
3664 if (from in O) createProperty(A, k, O[from]);
3665 }
3666
3667 A.length = actualDeleteCount;
3668
3669 if (insertCount < actualDeleteCount) {
3670 for (k = actualStart; k < len - actualDeleteCount; k++) {
3671 from = k + actualDeleteCount;
3672 to = k + insertCount;
3673 if (from in O) O[to] = O[from];else delete O[to];
3674 }
3675
3676 for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
3677 } else if (insertCount > actualDeleteCount) {
3678 for (k = len - actualDeleteCount; k > actualStart; k--) {
3679 from = k + actualDeleteCount - 1;
3680 to = k + insertCount - 1;
3681 if (from in O) O[to] = O[from];else delete O[to];
3682 }
3683 }
3684
3685 for (k = 0; k < insertCount; k++) {
3686 O[k + actualStart] = arguments[k + 2];
3687 }
3688
3689 O.length = len - actualDeleteCount + insertCount;
3690 return A;
3691 }
3692});
3693
3694var entryVirtual$e = entryVirtual$l;
3695var splice$3 = entryVirtual$e('Array').splice;
3696
3697var splice$2 = splice$3;
3698var ArrayPrototype$c = Array.prototype;
3699
3700var splice_1 = function (it) {
3701 var own = it.splice;
3702 return it === ArrayPrototype$c || it instanceof Array && own === ArrayPrototype$c.splice ? splice$2 : own;
3703};
3704
3705var parent$y = splice_1;
3706var splice$1 = parent$y;
3707
3708var splice = splice$1;
3709
3710var $$q = _export;
3711var $includes = arrayIncludes$1.includes;
3712// https://tc39.es/ecma262/#sec-array.prototype.includes
3713
3714$$q({
3715 target: 'Array',
3716 proto: true
3717}, {
3718 includes: function includes(el
3719 /* , fromIndex = 0 */
3720 ) {
3721 return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
3722 }
3723}); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
3724
3725var entryVirtual$d = entryVirtual$l;
3726var includes$4 = entryVirtual$d('Array').includes;
3727
3728var isObject$7 = isObject$j;
3729var classof$4 = classofRaw$1;
3730var wellKnownSymbol$2 = wellKnownSymbol$j;
3731var MATCH$1 = wellKnownSymbol$2('match'); // `IsRegExp` abstract operation
3732// https://tc39.es/ecma262/#sec-isregexp
3733
3734var isRegexp = function (it) {
3735 var isRegExp;
3736 return isObject$7(it) && ((isRegExp = it[MATCH$1]) !== undefined ? !!isRegExp : classof$4(it) == 'RegExp');
3737};
3738
3739var isRegExp = isRegexp;
3740
3741var notARegexp = function (it) {
3742 if (isRegExp(it)) {
3743 throw TypeError("The method doesn't accept regular expressions");
3744 }
3745
3746 return it;
3747};
3748
3749var wellKnownSymbol$1 = wellKnownSymbol$j;
3750var MATCH = wellKnownSymbol$1('match');
3751
3752var correctIsRegexpLogic = function (METHOD_NAME) {
3753 var regexp = /./;
3754
3755 try {
3756 '/./'[METHOD_NAME](regexp);
3757 } catch (error1) {
3758 try {
3759 regexp[MATCH] = false;
3760 return '/./'[METHOD_NAME](regexp);
3761 } catch (error2) {
3762 /* empty */
3763 }
3764 }
3765
3766 return false;
3767};
3768
3769var $$p = _export;
3770var notARegExp = notARegexp;
3771var requireObjectCoercible$1 = requireObjectCoercible$5;
3772var toString$4 = toString$9;
3773var correctIsRegExpLogic = correctIsRegexpLogic; // `String.prototype.includes` method
3774// https://tc39.es/ecma262/#sec-string.prototype.includes
3775
3776$$p({
3777 target: 'String',
3778 proto: true,
3779 forced: !correctIsRegExpLogic('includes')
3780}, {
3781 includes: function includes(searchString
3782 /* , position = 0 */
3783 ) {
3784 return !!~toString$4(requireObjectCoercible$1(this)).indexOf(toString$4(notARegExp(searchString)), arguments.length > 1 ? arguments[1] : undefined);
3785 }
3786});
3787
3788var entryVirtual$c = entryVirtual$l;
3789var includes$3 = entryVirtual$c('String').includes;
3790
3791var arrayIncludes = includes$4;
3792var stringIncludes = includes$3;
3793var ArrayPrototype$b = Array.prototype;
3794var StringPrototype = String.prototype;
3795
3796var includes$2 = function (it) {
3797 var own = it.includes;
3798 if (it === ArrayPrototype$b || it instanceof Array && own === ArrayPrototype$b.includes) return arrayIncludes;
3799
3800 if (typeof it === 'string' || it === StringPrototype || it instanceof String && own === StringPrototype.includes) {
3801 return stringIncludes;
3802 }
3803
3804 return own;
3805};
3806
3807var parent$x = includes$2;
3808var includes$1 = parent$x;
3809
3810var includes = includes$1;
3811
3812var $$o = _export;
3813var fails$7 = fails$m;
3814var toObject$4 = toObject$e;
3815var nativeGetPrototypeOf = objectGetPrototypeOf;
3816var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter;
3817var FAILS_ON_PRIMITIVES$1 = fails$7(function () {
3818 nativeGetPrototypeOf(1);
3819}); // `Object.getPrototypeOf` method
3820// https://tc39.es/ecma262/#sec-object.getprototypeof
3821
3822$$o({
3823 target: 'Object',
3824 stat: true,
3825 forced: FAILS_ON_PRIMITIVES$1,
3826 sham: !CORRECT_PROTOTYPE_GETTER
3827}, {
3828 getPrototypeOf: function getPrototypeOf(it) {
3829 return nativeGetPrototypeOf(toObject$4(it));
3830 }
3831});
3832
3833var path$g = path$x;
3834var getPrototypeOf$5 = path$g.Object.getPrototypeOf;
3835
3836var parent$w = getPrototypeOf$5;
3837var getPrototypeOf$4 = parent$w;
3838
3839var getPrototypeOf$3 = getPrototypeOf$4;
3840
3841var $$n = _export;
3842var $filter = arrayIteration.filter;
3843var arrayMethodHasSpeciesSupport = arrayMethodHasSpeciesSupport$5;
3844var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter'); // `Array.prototype.filter` method
3845// https://tc39.es/ecma262/#sec-array.prototype.filter
3846// with adding support of @@species
3847
3848$$n({
3849 target: 'Array',
3850 proto: true,
3851 forced: !HAS_SPECIES_SUPPORT
3852}, {
3853 filter: function filter(callbackfn
3854 /* , thisArg */
3855 ) {
3856 return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
3857 }
3858});
3859
3860var entryVirtual$b = entryVirtual$l;
3861var filter$3 = entryVirtual$b('Array').filter;
3862
3863var filter$2 = filter$3;
3864var ArrayPrototype$a = Array.prototype;
3865
3866var filter_1 = function (it) {
3867 var own = it.filter;
3868 return it === ArrayPrototype$a || it instanceof Array && own === ArrayPrototype$a.filter ? filter$2 : own;
3869};
3870
3871var parent$v = filter_1;
3872var filter$1 = parent$v;
3873
3874var filter = filter$1;
3875
3876var DESCRIPTORS$4 = descriptors;
3877var objectKeys = objectKeys$4;
3878var toIndexedObject = toIndexedObject$a;
3879var propertyIsEnumerable = objectPropertyIsEnumerable.f; // `Object.{ entries, values }` methods implementation
3880
3881var createMethod$2 = function (TO_ENTRIES) {
3882 return function (it) {
3883 var O = toIndexedObject(it);
3884 var keys = objectKeys(O);
3885 var length = keys.length;
3886 var i = 0;
3887 var result = [];
3888 var key;
3889
3890 while (length > i) {
3891 key = keys[i++];
3892
3893 if (!DESCRIPTORS$4 || propertyIsEnumerable.call(O, key)) {
3894 result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
3895 }
3896 }
3897
3898 return result;
3899 };
3900};
3901
3902var objectToArray = {
3903 // `Object.entries` method
3904 // https://tc39.es/ecma262/#sec-object.entries
3905 entries: createMethod$2(true),
3906 // `Object.values` method
3907 // https://tc39.es/ecma262/#sec-object.values
3908 values: createMethod$2(false)
3909};
3910
3911var $$m = _export;
3912var $values = objectToArray.values; // `Object.values` method
3913// https://tc39.es/ecma262/#sec-object.values
3914
3915$$m({
3916 target: 'Object',
3917 stat: true
3918}, {
3919 values: function values(O) {
3920 return $values(O);
3921 }
3922});
3923
3924var path$f = path$x;
3925path$f.Object.values;
3926
3927var whitespaces$4 = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
3928
3929var requireObjectCoercible = requireObjectCoercible$5;
3930var toString$3 = toString$9;
3931var whitespaces$3 = whitespaces$4;
3932var whitespace = '[' + whitespaces$3 + ']';
3933var ltrim = RegExp('^' + whitespace + whitespace + '*');
3934var rtrim = RegExp(whitespace + whitespace + '*$'); // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
3935
3936var createMethod$1 = function (TYPE) {
3937 return function ($this) {
3938 var string = toString$3(requireObjectCoercible($this));
3939 if (TYPE & 1) string = string.replace(ltrim, '');
3940 if (TYPE & 2) string = string.replace(rtrim, '');
3941 return string;
3942 };
3943};
3944
3945var stringTrim = {
3946 // `String.prototype.{ trimLeft, trimStart }` methods
3947 // https://tc39.es/ecma262/#sec-string.prototype.trimstart
3948 start: createMethod$1(1),
3949 // `String.prototype.{ trimRight, trimEnd }` methods
3950 // https://tc39.es/ecma262/#sec-string.prototype.trimend
3951 end: createMethod$1(2),
3952 // `String.prototype.trim` method
3953 // https://tc39.es/ecma262/#sec-string.prototype.trim
3954 trim: createMethod$1(3)
3955};
3956
3957var global$7 = global$k;
3958var toString$2 = toString$9;
3959var trim$1 = stringTrim.trim;
3960var whitespaces$2 = whitespaces$4;
3961var $parseInt = global$7.parseInt;
3962var hex = /^[+-]?0[Xx]/;
3963var FORCED$4 = $parseInt(whitespaces$2 + '08') !== 8 || $parseInt(whitespaces$2 + '0x16') !== 22; // `parseInt` method
3964// https://tc39.es/ecma262/#sec-parseint-string-radix
3965
3966var numberParseInt = FORCED$4 ? function parseInt(string, radix) {
3967 var S = trim$1(toString$2(string));
3968 return $parseInt(S, radix >>> 0 || (hex.test(S) ? 16 : 10));
3969} : $parseInt;
3970
3971var $$l = _export;
3972var parseIntImplementation = numberParseInt; // `parseInt` method
3973// https://tc39.es/ecma262/#sec-parseint-string-radix
3974
3975$$l({
3976 global: true,
3977 forced: parseInt != parseIntImplementation
3978}, {
3979 parseInt: parseIntImplementation
3980});
3981
3982var path$e = path$x;
3983var _parseInt$2 = path$e.parseInt;
3984
3985var parent$u = _parseInt$2;
3986var _parseInt$1 = parent$u;
3987
3988var _parseInt = _parseInt$1;
3989
3990/* eslint-disable es/no-array-prototype-indexof -- required for testing */
3991
3992
3993var $$k = _export;
3994var $indexOf = arrayIncludes$1.indexOf;
3995var arrayMethodIsStrict$4 = arrayMethodIsStrict$6;
3996var nativeIndexOf = [].indexOf;
3997var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
3998var STRICT_METHOD$4 = arrayMethodIsStrict$4('indexOf'); // `Array.prototype.indexOf` method
3999// https://tc39.es/ecma262/#sec-array.prototype.indexof
4000
4001$$k({
4002 target: 'Array',
4003 proto: true,
4004 forced: NEGATIVE_ZERO || !STRICT_METHOD$4
4005}, {
4006 indexOf: function indexOf(searchElement
4007 /* , fromIndex = 0 */
4008 ) {
4009 return NEGATIVE_ZERO // convert -0 to +0
4010 ? nativeIndexOf.apply(this, arguments) || 0 : $indexOf(this, searchElement, arguments.length > 1 ? arguments[1] : undefined);
4011 }
4012});
4013
4014var entryVirtual$a = entryVirtual$l;
4015var indexOf$3 = entryVirtual$a('Array').indexOf;
4016
4017var indexOf$2 = indexOf$3;
4018var ArrayPrototype$9 = Array.prototype;
4019
4020var indexOf_1 = function (it) {
4021 var own = it.indexOf;
4022 return it === ArrayPrototype$9 || it instanceof Array && own === ArrayPrototype$9.indexOf ? indexOf$2 : own;
4023};
4024
4025var parent$t = indexOf_1;
4026var indexOf$1 = parent$t;
4027
4028var indexOf = indexOf$1;
4029
4030var fails$6 = fails$m;
4031var whitespaces$1 = whitespaces$4;
4032var non = '\u200B\u0085\u180E'; // check that a method works with the correct list
4033// of whitespaces and has a correct name
4034
4035var stringTrimForced = function (METHOD_NAME) {
4036 return fails$6(function () {
4037 return !!whitespaces$1[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces$1[METHOD_NAME].name !== METHOD_NAME;
4038 });
4039};
4040
4041var $$j = _export;
4042var $trim = stringTrim.trim;
4043var forcedStringTrimMethod = stringTrimForced; // `String.prototype.trim` method
4044// https://tc39.es/ecma262/#sec-string.prototype.trim
4045
4046$$j({
4047 target: 'String',
4048 proto: true,
4049 forced: forcedStringTrimMethod('trim')
4050}, {
4051 trim: function trim() {
4052 return $trim(this);
4053 }
4054});
4055
4056var entryVirtual$9 = entryVirtual$l;
4057entryVirtual$9('String').trim;
4058
4059var $$i = _export;
4060var DESCRIPTORS$3 = descriptors;
4061var create$7 = objectCreate; // `Object.create` method
4062// https://tc39.es/ecma262/#sec-object.create
4063
4064$$i({
4065 target: 'Object',
4066 stat: true,
4067 sham: !DESCRIPTORS$3
4068}, {
4069 create: create$7
4070});
4071
4072var path$d = path$x;
4073var Object$2 = path$d.Object;
4074
4075var create$6 = function create(P, D) {
4076 return Object$2.create(P, D);
4077};
4078
4079var parent$s = create$6;
4080var create$5 = parent$s;
4081
4082var create$4 = create$5;
4083
4084var $$h = _export;
4085var getBuiltIn$2 = getBuiltIn$8;
4086var fails$5 = fails$m;
4087var $stringify = getBuiltIn$2('JSON', 'stringify');
4088var re = /[\uD800-\uDFFF]/g;
4089var low = /^[\uD800-\uDBFF]$/;
4090var hi = /^[\uDC00-\uDFFF]$/;
4091
4092var fix = function (match, offset, string) {
4093 var prev = string.charAt(offset - 1);
4094 var next = string.charAt(offset + 1);
4095
4096 if (low.test(match) && !hi.test(next) || hi.test(match) && !low.test(prev)) {
4097 return '\\u' + match.charCodeAt(0).toString(16);
4098 }
4099
4100 return match;
4101};
4102
4103var FORCED$3 = fails$5(function () {
4104 return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"' || $stringify('\uDEAD') !== '"\\udead"';
4105});
4106
4107if ($stringify) {
4108 // `JSON.stringify` method
4109 // https://tc39.es/ecma262/#sec-json.stringify
4110 // https://github.com/tc39/proposal-well-formed-stringify
4111 $$h({
4112 target: 'JSON',
4113 stat: true,
4114 forced: FORCED$3
4115 }, {
4116 // eslint-disable-next-line no-unused-vars -- required for `.length`
4117 stringify: function stringify(it, replacer, space) {
4118 var result = $stringify.apply(null, arguments);
4119 return typeof result == 'string' ? result.replace(re, fix) : result;
4120 }
4121 });
4122}
4123
4124var core = path$x; // eslint-disable-next-line es/no-json -- safe
4125
4126if (!core.JSON) core.JSON = {
4127 stringify: JSON.stringify
4128}; // eslint-disable-next-line no-unused-vars -- required for `.length`
4129
4130var stringify$3 = function stringify(it, replacer, space) {
4131 return core.JSON.stringify.apply(null, arguments);
4132};
4133
4134var parent$r = stringify$3;
4135var stringify$2 = parent$r;
4136
4137var stringify$1 = stringify$2;
4138
4139var $$g = _export;
4140var global$6 = global$k;
4141var userAgent$2 = engineUserAgent;
4142var slice = [].slice;
4143var MSIE = /MSIE .\./.test(userAgent$2); // <- dirty ie9- check
4144
4145var wrap = function (scheduler) {
4146 return function (handler, timeout
4147 /* , ...arguments */
4148 ) {
4149 var boundArgs = arguments.length > 2;
4150 var args = boundArgs ? slice.call(arguments, 2) : undefined;
4151 return scheduler(boundArgs ? function () {
4152 // eslint-disable-next-line no-new-func -- spec requirement
4153 (typeof handler == 'function' ? handler : Function(handler)).apply(this, args);
4154 } : handler, timeout);
4155 };
4156}; // ie9- setTimeout & setInterval additional parameters fix
4157// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
4158
4159
4160$$g({
4161 global: true,
4162 bind: true,
4163 forced: MSIE
4164}, {
4165 // `setTimeout` method
4166 // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
4167 setTimeout: wrap(global$6.setTimeout),
4168 // `setInterval` method
4169 // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval
4170 setInterval: wrap(global$6.setInterval)
4171});
4172
4173var path$c = path$x;
4174var setTimeout$2 = path$c.setTimeout;
4175
4176var setTimeout$1 = setTimeout$2;
4177
4178var toObject$3 = toObject$e;
4179var toAbsoluteIndex = toAbsoluteIndex$4;
4180var toLength$5 = toLength$c; // `Array.prototype.fill` method implementation
4181// https://tc39.es/ecma262/#sec-array.prototype.fill
4182
4183var arrayFill = function fill(value
4184/* , start = 0, end = @length */
4185) {
4186 var O = toObject$3(this);
4187 var length = toLength$5(O.length);
4188 var argumentsLength = arguments.length;
4189 var index = toAbsoluteIndex(argumentsLength > 1 ? arguments[1] : undefined, length);
4190 var end = argumentsLength > 2 ? arguments[2] : undefined;
4191 var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
4192
4193 while (endPos > index) O[index++] = value;
4194
4195 return O;
4196};
4197
4198var $$f = _export;
4199var fill$4 = arrayFill;
4200// https://tc39.es/ecma262/#sec-array.prototype.fill
4201
4202$$f({
4203 target: 'Array',
4204 proto: true
4205}, {
4206 fill: fill$4
4207}); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
4208
4209var entryVirtual$8 = entryVirtual$l;
4210var fill$3 = entryVirtual$8('Array').fill;
4211
4212var fill$2 = fill$3;
4213var ArrayPrototype$8 = Array.prototype;
4214
4215var fill_1 = function (it) {
4216 var own = it.fill;
4217 return it === ArrayPrototype$8 || it instanceof Array && own === ArrayPrototype$8.fill ? fill$2 : own;
4218};
4219
4220var parent$q = fill_1;
4221var fill$1 = parent$q;
4222
4223var fill = fill$1;
4224
4225/*! Hammer.JS - v2.0.17-rc - 2019-12-16
4226 * http://naver.github.io/egjs
4227 *
4228 * Forked By Naver egjs
4229 * Copyright (c) hammerjs
4230 * Licensed under the MIT license */
4231function _extends() {
4232 _extends = Object.assign || function (target) {
4233 for (var i = 1; i < arguments.length; i++) {
4234 var source = arguments[i];
4235
4236 for (var key in source) {
4237 if (Object.prototype.hasOwnProperty.call(source, key)) {
4238 target[key] = source[key];
4239 }
4240 }
4241 }
4242
4243 return target;
4244 };
4245
4246 return _extends.apply(this, arguments);
4247}
4248
4249function _inheritsLoose(subClass, superClass) {
4250 subClass.prototype = Object.create(superClass.prototype);
4251 subClass.prototype.constructor = subClass;
4252 subClass.__proto__ = superClass;
4253}
4254
4255function _assertThisInitialized$1(self) {
4256 if (self === void 0) {
4257 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
4258 }
4259
4260 return self;
4261}
4262/**
4263 * @private
4264 * extend object.
4265 * means that properties in dest will be overwritten by the ones in src.
4266 * @param {Object} target
4267 * @param {...Object} objects_to_assign
4268 * @returns {Object} target
4269 */
4270
4271
4272var assign;
4273
4274if (typeof Object.assign !== 'function') {
4275 assign = function assign(target) {
4276 if (target === undefined || target === null) {
4277 throw new TypeError('Cannot convert undefined or null to object');
4278 }
4279
4280 var output = Object(target);
4281
4282 for (var index = 1; index < arguments.length; index++) {
4283 var source = arguments[index];
4284
4285 if (source !== undefined && source !== null) {
4286 for (var nextKey in source) {
4287 if (source.hasOwnProperty(nextKey)) {
4288 output[nextKey] = source[nextKey];
4289 }
4290 }
4291 }
4292 }
4293
4294 return output;
4295 };
4296} else {
4297 assign = Object.assign;
4298}
4299
4300var assign$1 = assign;
4301var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
4302var TEST_ELEMENT = typeof document === "undefined" ? {
4303 style: {}
4304} : document.createElement('div');
4305var TYPE_FUNCTION = 'function';
4306var round = Math.round,
4307 abs$1 = Math.abs;
4308var now = Date.now;
4309/**
4310 * @private
4311 * get the prefixed property
4312 * @param {Object} obj
4313 * @param {String} property
4314 * @returns {String|Undefined} prefixed
4315 */
4316
4317function prefixed(obj, property) {
4318 var prefix;
4319 var prop;
4320 var camelProp = property[0].toUpperCase() + property.slice(1);
4321 var i = 0;
4322
4323 while (i < VENDOR_PREFIXES.length) {
4324 prefix = VENDOR_PREFIXES[i];
4325 prop = prefix ? prefix + camelProp : property;
4326
4327 if (prop in obj) {
4328 return prop;
4329 }
4330
4331 i++;
4332 }
4333
4334 return undefined;
4335}
4336/* eslint-disable no-new-func, no-nested-ternary */
4337
4338
4339var win;
4340
4341if (typeof window === "undefined") {
4342 // window is undefined in node.js
4343 win = {};
4344} else {
4345 win = window;
4346}
4347
4348var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
4349var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
4350
4351function getTouchActionProps() {
4352 if (!NATIVE_TOUCH_ACTION) {
4353 return false;
4354 }
4355
4356 var touchMap = {};
4357 var cssSupports = win.CSS && win.CSS.supports;
4358 ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
4359 // If css.supports is not supported but there is native touch-action assume it supports
4360 // all values. This is the case for IE 10 and 11.
4361 return touchMap[val] = cssSupports ? win.CSS.supports('touch-action', val) : true;
4362 });
4363 return touchMap;
4364}
4365
4366var TOUCH_ACTION_COMPUTE = 'compute';
4367var TOUCH_ACTION_AUTO = 'auto';
4368var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
4369
4370var TOUCH_ACTION_NONE = 'none';
4371var TOUCH_ACTION_PAN_X = 'pan-x';
4372var TOUCH_ACTION_PAN_Y = 'pan-y';
4373var TOUCH_ACTION_MAP = getTouchActionProps();
4374var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
4375var SUPPORT_TOUCH = ('ontouchstart' in win);
4376var SUPPORT_POINTER_EVENTS = prefixed(win, 'PointerEvent') !== undefined;
4377var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
4378var INPUT_TYPE_TOUCH = 'touch';
4379var INPUT_TYPE_PEN = 'pen';
4380var INPUT_TYPE_MOUSE = 'mouse';
4381var INPUT_TYPE_KINECT = 'kinect';
4382var COMPUTE_INTERVAL = 25;
4383var INPUT_START = 1;
4384var INPUT_MOVE = 2;
4385var INPUT_END = 4;
4386var INPUT_CANCEL = 8;
4387var DIRECTION_NONE = 1;
4388var DIRECTION_LEFT = 2;
4389var DIRECTION_RIGHT = 4;
4390var DIRECTION_UP = 8;
4391var DIRECTION_DOWN = 16;
4392var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
4393var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
4394var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
4395var PROPS_XY = ['x', 'y'];
4396var PROPS_CLIENT_XY = ['clientX', 'clientY'];
4397/**
4398 * @private
4399 * walk objects and arrays
4400 * @param {Object} obj
4401 * @param {Function} iterator
4402 * @param {Object} context
4403 */
4404
4405function each(obj, iterator, context) {
4406 var i;
4407
4408 if (!obj) {
4409 return;
4410 }
4411
4412 if (obj.forEach) {
4413 obj.forEach(iterator, context);
4414 } else if (obj.length !== undefined) {
4415 i = 0;
4416
4417 while (i < obj.length) {
4418 iterator.call(context, obj[i], i, obj);
4419 i++;
4420 }
4421 } else {
4422 for (i in obj) {
4423 obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
4424 }
4425 }
4426}
4427/**
4428 * @private
4429 * let a boolean value also be a function that must return a boolean
4430 * this first item in args will be used as the context
4431 * @param {Boolean|Function} val
4432 * @param {Array} [args]
4433 * @returns {Boolean}
4434 */
4435
4436
4437function boolOrFn(val, args) {
4438 if (typeof val === TYPE_FUNCTION) {
4439 return val.apply(args ? args[0] || undefined : undefined, args);
4440 }
4441
4442 return val;
4443}
4444/**
4445 * @private
4446 * small indexOf wrapper
4447 * @param {String} str
4448 * @param {String} find
4449 * @returns {Boolean} found
4450 */
4451
4452
4453function inStr(str, find) {
4454 return str.indexOf(find) > -1;
4455}
4456/**
4457 * @private
4458 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
4459 * @param {String} actions
4460 * @returns {*}
4461 */
4462
4463
4464function cleanTouchActions(actions) {
4465 // none
4466 if (inStr(actions, TOUCH_ACTION_NONE)) {
4467 return TOUCH_ACTION_NONE;
4468 }
4469
4470 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
4471 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
4472 // for different directions, e.g. horizontal pan but vertical swipe?)
4473 // we need none (as otherwise with pan-x pan-y combined none of these
4474 // recognizers will work, since the browser would handle all panning
4475
4476 if (hasPanX && hasPanY) {
4477 return TOUCH_ACTION_NONE;
4478 } // pan-x OR pan-y
4479
4480
4481 if (hasPanX || hasPanY) {
4482 return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
4483 } // manipulation
4484
4485
4486 if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
4487 return TOUCH_ACTION_MANIPULATION;
4488 }
4489
4490 return TOUCH_ACTION_AUTO;
4491}
4492/**
4493 * @private
4494 * Touch Action
4495 * sets the touchAction property or uses the js alternative
4496 * @param {Manager} manager
4497 * @param {String} value
4498 * @constructor
4499 */
4500
4501
4502var TouchAction = /*#__PURE__*/function () {
4503 function TouchAction(manager, value) {
4504 this.manager = manager;
4505 this.set(value);
4506 }
4507 /**
4508 * @private
4509 * set the touchAction value on the element or enable the polyfill
4510 * @param {String} value
4511 */
4512
4513
4514 var _proto = TouchAction.prototype;
4515
4516 _proto.set = function set(value) {
4517 // find out the touch-action by the event handlers
4518 if (value === TOUCH_ACTION_COMPUTE) {
4519 value = this.compute();
4520 }
4521
4522 if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
4523 this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
4524 }
4525
4526 this.actions = value.toLowerCase().trim();
4527 };
4528 /**
4529 * @private
4530 * just re-set the touchAction value
4531 */
4532
4533
4534 _proto.update = function update() {
4535 this.set(this.manager.options.touchAction);
4536 };
4537 /**
4538 * @private
4539 * compute the value for the touchAction property based on the recognizer's settings
4540 * @returns {String} value
4541 */
4542
4543
4544 _proto.compute = function compute() {
4545 var actions = [];
4546 each(this.manager.recognizers, function (recognizer) {
4547 if (boolOrFn(recognizer.options.enable, [recognizer])) {
4548 actions = actions.concat(recognizer.getTouchAction());
4549 }
4550 });
4551 return cleanTouchActions(actions.join(' '));
4552 };
4553 /**
4554 * @private
4555 * this method is called on each input cycle and provides the preventing of the browser behavior
4556 * @param {Object} input
4557 */
4558
4559
4560 _proto.preventDefaults = function preventDefaults(input) {
4561 var srcEvent = input.srcEvent;
4562 var direction = input.offsetDirection; // if the touch action did prevented once this session
4563
4564 if (this.manager.session.prevented) {
4565 srcEvent.preventDefault();
4566 return;
4567 }
4568
4569 var actions = this.actions;
4570 var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
4571 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
4572 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
4573
4574 if (hasNone) {
4575 // do not prevent defaults if this is a tap gesture
4576 var isTapPointer = input.pointers.length === 1;
4577 var isTapMovement = input.distance < 2;
4578 var isTapTouchTime = input.deltaTime < 250;
4579
4580 if (isTapPointer && isTapMovement && isTapTouchTime) {
4581 return;
4582 }
4583 }
4584
4585 if (hasPanX && hasPanY) {
4586 // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
4587 return;
4588 }
4589
4590 if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
4591 return this.preventSrc(srcEvent);
4592 }
4593 };
4594 /**
4595 * @private
4596 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
4597 * @param {Object} srcEvent
4598 */
4599
4600
4601 _proto.preventSrc = function preventSrc(srcEvent) {
4602 this.manager.session.prevented = true;
4603 srcEvent.preventDefault();
4604 };
4605
4606 return TouchAction;
4607}();
4608/**
4609 * @private
4610 * find if a node is in the given parent
4611 * @method hasParent
4612 * @param {HTMLElement} node
4613 * @param {HTMLElement} parent
4614 * @return {Boolean} found
4615 */
4616
4617
4618function hasParent(node, parent) {
4619 while (node) {
4620 if (node === parent) {
4621 return true;
4622 }
4623
4624 node = node.parentNode;
4625 }
4626
4627 return false;
4628}
4629/**
4630 * @private
4631 * get the center of all the pointers
4632 * @param {Array} pointers
4633 * @return {Object} center contains `x` and `y` properties
4634 */
4635
4636
4637function getCenter(pointers) {
4638 var pointersLength = pointers.length; // no need to loop when only one touch
4639
4640 if (pointersLength === 1) {
4641 return {
4642 x: round(pointers[0].clientX),
4643 y: round(pointers[0].clientY)
4644 };
4645 }
4646
4647 var x = 0;
4648 var y = 0;
4649 var i = 0;
4650
4651 while (i < pointersLength) {
4652 x += pointers[i].clientX;
4653 y += pointers[i].clientY;
4654 i++;
4655 }
4656
4657 return {
4658 x: round(x / pointersLength),
4659 y: round(y / pointersLength)
4660 };
4661}
4662/**
4663 * @private
4664 * create a simple clone from the input used for storage of firstInput and firstMultiple
4665 * @param {Object} input
4666 * @returns {Object} clonedInputData
4667 */
4668
4669
4670function simpleCloneInputData(input) {
4671 // make a simple copy of the pointers because we will get a reference if we don't
4672 // we only need clientXY for the calculations
4673 var pointers = [];
4674 var i = 0;
4675
4676 while (i < input.pointers.length) {
4677 pointers[i] = {
4678 clientX: round(input.pointers[i].clientX),
4679 clientY: round(input.pointers[i].clientY)
4680 };
4681 i++;
4682 }
4683
4684 return {
4685 timeStamp: now(),
4686 pointers: pointers,
4687 center: getCenter(pointers),
4688 deltaX: input.deltaX,
4689 deltaY: input.deltaY
4690 };
4691}
4692/**
4693 * @private
4694 * calculate the absolute distance between two points
4695 * @param {Object} p1 {x, y}
4696 * @param {Object} p2 {x, y}
4697 * @param {Array} [props] containing x and y keys
4698 * @return {Number} distance
4699 */
4700
4701
4702function getDistance(p1, p2, props) {
4703 if (!props) {
4704 props = PROPS_XY;
4705 }
4706
4707 var x = p2[props[0]] - p1[props[0]];
4708 var y = p2[props[1]] - p1[props[1]];
4709 return Math.sqrt(x * x + y * y);
4710}
4711/**
4712 * @private
4713 * calculate the angle between two coordinates
4714 * @param {Object} p1
4715 * @param {Object} p2
4716 * @param {Array} [props] containing x and y keys
4717 * @return {Number} angle
4718 */
4719
4720
4721function getAngle(p1, p2, props) {
4722 if (!props) {
4723 props = PROPS_XY;
4724 }
4725
4726 var x = p2[props[0]] - p1[props[0]];
4727 var y = p2[props[1]] - p1[props[1]];
4728 return Math.atan2(y, x) * 180 / Math.PI;
4729}
4730/**
4731 * @private
4732 * get the direction between two points
4733 * @param {Number} x
4734 * @param {Number} y
4735 * @return {Number} direction
4736 */
4737
4738
4739function getDirection(x, y) {
4740 if (x === y) {
4741 return DIRECTION_NONE;
4742 }
4743
4744 if (abs$1(x) >= abs$1(y)) {
4745 return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
4746 }
4747
4748 return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
4749}
4750
4751function computeDeltaXY(session, input) {
4752 var center = input.center; // let { offsetDelta:offset = {}, prevDelta = {}, prevInput = {} } = session;
4753 // jscs throwing error on defalut destructured values and without defaults tests fail
4754
4755 var offset = session.offsetDelta || {};
4756 var prevDelta = session.prevDelta || {};
4757 var prevInput = session.prevInput || {};
4758
4759 if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
4760 prevDelta = session.prevDelta = {
4761 x: prevInput.deltaX || 0,
4762 y: prevInput.deltaY || 0
4763 };
4764 offset = session.offsetDelta = {
4765 x: center.x,
4766 y: center.y
4767 };
4768 }
4769
4770 input.deltaX = prevDelta.x + (center.x - offset.x);
4771 input.deltaY = prevDelta.y + (center.y - offset.y);
4772}
4773/**
4774 * @private
4775 * calculate the velocity between two points. unit is in px per ms.
4776 * @param {Number} deltaTime
4777 * @param {Number} x
4778 * @param {Number} y
4779 * @return {Object} velocity `x` and `y`
4780 */
4781
4782
4783function getVelocity(deltaTime, x, y) {
4784 return {
4785 x: x / deltaTime || 0,
4786 y: y / deltaTime || 0
4787 };
4788}
4789/**
4790 * @private
4791 * calculate the scale factor between two pointersets
4792 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
4793 * @param {Array} start array of pointers
4794 * @param {Array} end array of pointers
4795 * @return {Number} scale
4796 */
4797
4798
4799function getScale(start, end) {
4800 return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
4801}
4802/**
4803 * @private
4804 * calculate the rotation degrees between two pointersets
4805 * @param {Array} start array of pointers
4806 * @param {Array} end array of pointers
4807 * @return {Number} rotation
4808 */
4809
4810
4811function getRotation(start, end) {
4812 return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
4813}
4814/**
4815 * @private
4816 * velocity is calculated every x ms
4817 * @param {Object} session
4818 * @param {Object} input
4819 */
4820
4821
4822function computeIntervalInputData(session, input) {
4823 var last = session.lastInterval || input;
4824 var deltaTime = input.timeStamp - last.timeStamp;
4825 var velocity;
4826 var velocityX;
4827 var velocityY;
4828 var direction;
4829
4830 if (input.eventType !== INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
4831 var deltaX = input.deltaX - last.deltaX;
4832 var deltaY = input.deltaY - last.deltaY;
4833 var v = getVelocity(deltaTime, deltaX, deltaY);
4834 velocityX = v.x;
4835 velocityY = v.y;
4836 velocity = abs$1(v.x) > abs$1(v.y) ? v.x : v.y;
4837 direction = getDirection(deltaX, deltaY);
4838 session.lastInterval = input;
4839 } else {
4840 // use latest velocity info if it doesn't overtake a minimum period
4841 velocity = last.velocity;
4842 velocityX = last.velocityX;
4843 velocityY = last.velocityY;
4844 direction = last.direction;
4845 }
4846
4847 input.velocity = velocity;
4848 input.velocityX = velocityX;
4849 input.velocityY = velocityY;
4850 input.direction = direction;
4851}
4852/**
4853* @private
4854 * extend the data with some usable properties like scale, rotate, velocity etc
4855 * @param {Object} manager
4856 * @param {Object} input
4857 */
4858
4859
4860function computeInputData(manager, input) {
4861 var session = manager.session;
4862 var pointers = input.pointers;
4863 var pointersLength = pointers.length; // store the first input to calculate the distance and direction
4864
4865 if (!session.firstInput) {
4866 session.firstInput = simpleCloneInputData(input);
4867 } // to compute scale and rotation we need to store the multiple touches
4868
4869
4870 if (pointersLength > 1 && !session.firstMultiple) {
4871 session.firstMultiple = simpleCloneInputData(input);
4872 } else if (pointersLength === 1) {
4873 session.firstMultiple = false;
4874 }
4875
4876 var firstInput = session.firstInput,
4877 firstMultiple = session.firstMultiple;
4878 var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
4879 var center = input.center = getCenter(pointers);
4880 input.timeStamp = now();
4881 input.deltaTime = input.timeStamp - firstInput.timeStamp;
4882 input.angle = getAngle(offsetCenter, center);
4883 input.distance = getDistance(offsetCenter, center);
4884 computeDeltaXY(session, input);
4885 input.offsetDirection = getDirection(input.deltaX, input.deltaY);
4886 var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
4887 input.overallVelocityX = overallVelocity.x;
4888 input.overallVelocityY = overallVelocity.y;
4889 input.overallVelocity = abs$1(overallVelocity.x) > abs$1(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
4890 input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
4891 input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
4892 input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
4893 computeIntervalInputData(session, input); // find the correct target
4894
4895 var target = manager.element;
4896 var srcEvent = input.srcEvent;
4897 var srcEventTarget;
4898
4899 if (srcEvent.composedPath) {
4900 srcEventTarget = srcEvent.composedPath()[0];
4901 } else if (srcEvent.path) {
4902 srcEventTarget = srcEvent.path[0];
4903 } else {
4904 srcEventTarget = srcEvent.target;
4905 }
4906
4907 if (hasParent(srcEventTarget, target)) {
4908 target = srcEventTarget;
4909 }
4910
4911 input.target = target;
4912}
4913/**
4914 * @private
4915 * handle input events
4916 * @param {Manager} manager
4917 * @param {String} eventType
4918 * @param {Object} input
4919 */
4920
4921
4922function inputHandler(manager, eventType, input) {
4923 var pointersLen = input.pointers.length;
4924 var changedPointersLen = input.changedPointers.length;
4925 var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
4926 var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
4927 input.isFirst = !!isFirst;
4928 input.isFinal = !!isFinal;
4929
4930 if (isFirst) {
4931 manager.session = {};
4932 } // source event is the normalized value of the domEvents
4933 // like 'touchstart, mouseup, pointerdown'
4934
4935
4936 input.eventType = eventType; // compute scale, rotation etc
4937
4938 computeInputData(manager, input); // emit secret event
4939
4940 manager.emit('hammer.input', input);
4941 manager.recognize(input);
4942 manager.session.prevInput = input;
4943}
4944/**
4945 * @private
4946 * split string on whitespace
4947 * @param {String} str
4948 * @returns {Array} words
4949 */
4950
4951
4952function splitStr(str) {
4953 return str.trim().split(/\s+/g);
4954}
4955/**
4956 * @private
4957 * addEventListener with multiple events at once
4958 * @param {EventTarget} target
4959 * @param {String} types
4960 * @param {Function} handler
4961 */
4962
4963
4964function addEventListeners(target, types, handler) {
4965 each(splitStr(types), function (type) {
4966 target.addEventListener(type, handler, false);
4967 });
4968}
4969/**
4970 * @private
4971 * removeEventListener with multiple events at once
4972 * @param {EventTarget} target
4973 * @param {String} types
4974 * @param {Function} handler
4975 */
4976
4977
4978function removeEventListeners(target, types, handler) {
4979 each(splitStr(types), function (type) {
4980 target.removeEventListener(type, handler, false);
4981 });
4982}
4983/**
4984 * @private
4985 * get the window object of an element
4986 * @param {HTMLElement} element
4987 * @returns {DocumentView|Window}
4988 */
4989
4990
4991function getWindowForElement(element) {
4992 var doc = element.ownerDocument || element;
4993 return doc.defaultView || doc.parentWindow || window;
4994}
4995/**
4996 * @private
4997 * create new input type manager
4998 * @param {Manager} manager
4999 * @param {Function} callback
5000 * @returns {Input}
5001 * @constructor
5002 */
5003
5004
5005var Input = /*#__PURE__*/function () {
5006 function Input(manager, callback) {
5007 var self = this;
5008 this.manager = manager;
5009 this.callback = callback;
5010 this.element = manager.element;
5011 this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager,
5012 // so when disabled the input events are completely bypassed.
5013
5014 this.domHandler = function (ev) {
5015 if (boolOrFn(manager.options.enable, [manager])) {
5016 self.handler(ev);
5017 }
5018 };
5019
5020 this.init();
5021 }
5022 /**
5023 * @private
5024 * should handle the inputEvent data and trigger the callback
5025 * @virtual
5026 */
5027
5028
5029 var _proto = Input.prototype;
5030
5031 _proto.handler = function handler() {};
5032 /**
5033 * @private
5034 * bind the events
5035 */
5036
5037
5038 _proto.init = function init() {
5039 this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
5040 this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
5041 this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
5042 };
5043 /**
5044 * @private
5045 * unbind the events
5046 */
5047
5048
5049 _proto.destroy = function destroy() {
5050 this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
5051 this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
5052 this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
5053 };
5054
5055 return Input;
5056}();
5057/**
5058 * @private
5059 * find if a array contains the object using indexOf or a simple polyFill
5060 * @param {Array} src
5061 * @param {String} find
5062 * @param {String} [findByKey]
5063 * @return {Boolean|Number} false when not found, or the index
5064 */
5065
5066
5067function inArray(src, find, findByKey) {
5068 if (src.indexOf && !findByKey) {
5069 return src.indexOf(find);
5070 } else {
5071 var i = 0;
5072
5073 while (i < src.length) {
5074 if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
5075 // do not use === here, test fails
5076 return i;
5077 }
5078
5079 i++;
5080 }
5081
5082 return -1;
5083 }
5084}
5085
5086var POINTER_INPUT_MAP = {
5087 pointerdown: INPUT_START,
5088 pointermove: INPUT_MOVE,
5089 pointerup: INPUT_END,
5090 pointercancel: INPUT_CANCEL,
5091 pointerout: INPUT_CANCEL
5092}; // in IE10 the pointer types is defined as an enum
5093
5094var IE10_POINTER_TYPE_ENUM = {
5095 2: INPUT_TYPE_TOUCH,
5096 3: INPUT_TYPE_PEN,
5097 4: INPUT_TYPE_MOUSE,
5098 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
5099
5100};
5101var POINTER_ELEMENT_EVENTS = 'pointerdown';
5102var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive
5103
5104if (win.MSPointerEvent && !win.PointerEvent) {
5105 POINTER_ELEMENT_EVENTS = 'MSPointerDown';
5106 POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
5107}
5108/**
5109 * @private
5110 * Pointer events input
5111 * @constructor
5112 * @extends Input
5113 */
5114
5115
5116var PointerEventInput = /*#__PURE__*/function (_Input) {
5117 _inheritsLoose(PointerEventInput, _Input);
5118
5119 function PointerEventInput() {
5120 var _this;
5121
5122 var proto = PointerEventInput.prototype;
5123 proto.evEl = POINTER_ELEMENT_EVENTS;
5124 proto.evWin = POINTER_WINDOW_EVENTS;
5125 _this = _Input.apply(this, arguments) || this;
5126 _this.store = _this.manager.session.pointerEvents = [];
5127 return _this;
5128 }
5129 /**
5130 * @private
5131 * handle mouse events
5132 * @param {Object} ev
5133 */
5134
5135
5136 var _proto = PointerEventInput.prototype;
5137
5138 _proto.handler = function handler(ev) {
5139 var store = this.store;
5140 var removePointer = false;
5141 var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
5142 var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
5143 var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
5144 var isTouch = pointerType === INPUT_TYPE_TOUCH; // get index of the event in the store
5145
5146 var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down
5147
5148 if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
5149 if (storeIndex < 0) {
5150 store.push(ev);
5151 storeIndex = store.length - 1;
5152 }
5153 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
5154 removePointer = true;
5155 } // it not found, so the pointer hasn't been down (so it's probably a hover)
5156
5157
5158 if (storeIndex < 0) {
5159 return;
5160 } // update the event in the store
5161
5162
5163 store[storeIndex] = ev;
5164 this.callback(this.manager, eventType, {
5165 pointers: store,
5166 changedPointers: [ev],
5167 pointerType: pointerType,
5168 srcEvent: ev
5169 });
5170
5171 if (removePointer) {
5172 // remove from the store
5173 store.splice(storeIndex, 1);
5174 }
5175 };
5176
5177 return PointerEventInput;
5178}(Input);
5179/**
5180 * @private
5181 * convert array-like objects to real arrays
5182 * @param {Object} obj
5183 * @returns {Array}
5184 */
5185
5186
5187function toArray(obj) {
5188 return Array.prototype.slice.call(obj, 0);
5189}
5190/**
5191 * @private
5192 * unique array with objects based on a key (like 'id') or just by the array's value
5193 * @param {Array} src [{id:1},{id:2},{id:1}]
5194 * @param {String} [key]
5195 * @param {Boolean} [sort=False]
5196 * @returns {Array} [{id:1},{id:2}]
5197 */
5198
5199
5200function uniqueArray(src, key, sort) {
5201 var results = [];
5202 var values = [];
5203 var i = 0;
5204
5205 while (i < src.length) {
5206 var val = key ? src[i][key] : src[i];
5207
5208 if (inArray(values, val) < 0) {
5209 results.push(src[i]);
5210 }
5211
5212 values[i] = val;
5213 i++;
5214 }
5215
5216 if (sort) {
5217 if (!key) {
5218 results = results.sort();
5219 } else {
5220 results = results.sort(function (a, b) {
5221 return a[key] > b[key];
5222 });
5223 }
5224 }
5225
5226 return results;
5227}
5228
5229var TOUCH_INPUT_MAP = {
5230 touchstart: INPUT_START,
5231 touchmove: INPUT_MOVE,
5232 touchend: INPUT_END,
5233 touchcancel: INPUT_CANCEL
5234};
5235var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
5236/**
5237 * @private
5238 * Multi-user touch events input
5239 * @constructor
5240 * @extends Input
5241 */
5242
5243var TouchInput = /*#__PURE__*/function (_Input) {
5244 _inheritsLoose(TouchInput, _Input);
5245
5246 function TouchInput() {
5247 var _this;
5248
5249 TouchInput.prototype.evTarget = TOUCH_TARGET_EVENTS;
5250 _this = _Input.apply(this, arguments) || this;
5251 _this.targetIds = {}; // this.evTarget = TOUCH_TARGET_EVENTS;
5252
5253 return _this;
5254 }
5255
5256 var _proto = TouchInput.prototype;
5257
5258 _proto.handler = function handler(ev) {
5259 var type = TOUCH_INPUT_MAP[ev.type];
5260 var touches = getTouches.call(this, ev, type);
5261
5262 if (!touches) {
5263 return;
5264 }
5265
5266 this.callback(this.manager, type, {
5267 pointers: touches[0],
5268 changedPointers: touches[1],
5269 pointerType: INPUT_TYPE_TOUCH,
5270 srcEvent: ev
5271 });
5272 };
5273
5274 return TouchInput;
5275}(Input);
5276
5277function getTouches(ev, type) {
5278 var allTouches = toArray(ev.touches);
5279 var targetIds = this.targetIds; // when there is only one touch, the process can be simplified
5280
5281 if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
5282 targetIds[allTouches[0].identifier] = true;
5283 return [allTouches, allTouches];
5284 }
5285
5286 var i;
5287 var targetTouches;
5288 var changedTouches = toArray(ev.changedTouches);
5289 var changedTargetTouches = [];
5290 var target = this.target; // get target touches from touches
5291
5292 targetTouches = allTouches.filter(function (touch) {
5293 return hasParent(touch.target, target);
5294 }); // collect touches
5295
5296 if (type === INPUT_START) {
5297 i = 0;
5298
5299 while (i < targetTouches.length) {
5300 targetIds[targetTouches[i].identifier] = true;
5301 i++;
5302 }
5303 } // filter changed touches to only contain touches that exist in the collected target ids
5304
5305
5306 i = 0;
5307
5308 while (i < changedTouches.length) {
5309 if (targetIds[changedTouches[i].identifier]) {
5310 changedTargetTouches.push(changedTouches[i]);
5311 } // cleanup removed touches
5312
5313
5314 if (type & (INPUT_END | INPUT_CANCEL)) {
5315 delete targetIds[changedTouches[i].identifier];
5316 }
5317
5318 i++;
5319 }
5320
5321 if (!changedTargetTouches.length) {
5322 return;
5323 }
5324
5325 return [// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
5326 uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches];
5327}
5328
5329var MOUSE_INPUT_MAP = {
5330 mousedown: INPUT_START,
5331 mousemove: INPUT_MOVE,
5332 mouseup: INPUT_END
5333};
5334var MOUSE_ELEMENT_EVENTS = 'mousedown';
5335var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
5336/**
5337 * @private
5338 * Mouse events input
5339 * @constructor
5340 * @extends Input
5341 */
5342
5343var MouseInput = /*#__PURE__*/function (_Input) {
5344 _inheritsLoose(MouseInput, _Input);
5345
5346 function MouseInput() {
5347 var _this;
5348
5349 var proto = MouseInput.prototype;
5350 proto.evEl = MOUSE_ELEMENT_EVENTS;
5351 proto.evWin = MOUSE_WINDOW_EVENTS;
5352 _this = _Input.apply(this, arguments) || this;
5353 _this.pressed = false; // mousedown state
5354
5355 return _this;
5356 }
5357 /**
5358 * @private
5359 * handle mouse events
5360 * @param {Object} ev
5361 */
5362
5363
5364 var _proto = MouseInput.prototype;
5365
5366 _proto.handler = function handler(ev) {
5367 var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down
5368
5369 if (eventType & INPUT_START && ev.button === 0) {
5370 this.pressed = true;
5371 }
5372
5373 if (eventType & INPUT_MOVE && ev.which !== 1) {
5374 eventType = INPUT_END;
5375 } // mouse must be down
5376
5377
5378 if (!this.pressed) {
5379 return;
5380 }
5381
5382 if (eventType & INPUT_END) {
5383 this.pressed = false;
5384 }
5385
5386 this.callback(this.manager, eventType, {
5387 pointers: [ev],
5388 changedPointers: [ev],
5389 pointerType: INPUT_TYPE_MOUSE,
5390 srcEvent: ev
5391 });
5392 };
5393
5394 return MouseInput;
5395}(Input);
5396/**
5397 * @private
5398 * Combined touch and mouse input
5399 *
5400 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
5401 * This because touch devices also emit mouse events while doing a touch.
5402 *
5403 * @constructor
5404 * @extends Input
5405 */
5406
5407
5408var DEDUP_TIMEOUT = 2500;
5409var DEDUP_DISTANCE = 25;
5410
5411function setLastTouch(eventData) {
5412 var _eventData$changedPoi = eventData.changedPointers,
5413 touch = _eventData$changedPoi[0];
5414
5415 if (touch.identifier === this.primaryTouch) {
5416 var lastTouch = {
5417 x: touch.clientX,
5418 y: touch.clientY
5419 };
5420 var lts = this.lastTouches;
5421 this.lastTouches.push(lastTouch);
5422
5423 var removeLastTouch = function removeLastTouch() {
5424 var i = lts.indexOf(lastTouch);
5425
5426 if (i > -1) {
5427 lts.splice(i, 1);
5428 }
5429 };
5430
5431 setTimeout(removeLastTouch, DEDUP_TIMEOUT);
5432 }
5433}
5434
5435function recordTouches(eventType, eventData) {
5436 if (eventType & INPUT_START) {
5437 this.primaryTouch = eventData.changedPointers[0].identifier;
5438 setLastTouch.call(this, eventData);
5439 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
5440 setLastTouch.call(this, eventData);
5441 }
5442}
5443
5444function isSyntheticEvent(eventData) {
5445 var x = eventData.srcEvent.clientX;
5446 var y = eventData.srcEvent.clientY;
5447
5448 for (var i = 0; i < this.lastTouches.length; i++) {
5449 var t = this.lastTouches[i];
5450 var dx = Math.abs(x - t.x);
5451 var dy = Math.abs(y - t.y);
5452
5453 if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
5454 return true;
5455 }
5456 }
5457
5458 return false;
5459}
5460
5461var TouchMouseInput = /*#__PURE__*/function () {
5462 var TouchMouseInput = /*#__PURE__*/function (_Input) {
5463 _inheritsLoose(TouchMouseInput, _Input);
5464
5465 function TouchMouseInput(_manager, callback) {
5466 var _this;
5467
5468 _this = _Input.call(this, _manager, callback) || this;
5469
5470 _this.handler = function (manager, inputEvent, inputData) {
5471 var isTouch = inputData.pointerType === INPUT_TYPE_TOUCH;
5472 var isMouse = inputData.pointerType === INPUT_TYPE_MOUSE;
5473
5474 if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
5475 return;
5476 } // when we're in a touch event, record touches to de-dupe synthetic mouse event
5477
5478
5479 if (isTouch) {
5480 recordTouches.call(_assertThisInitialized$1(_assertThisInitialized$1(_this)), inputEvent, inputData);
5481 } else if (isMouse && isSyntheticEvent.call(_assertThisInitialized$1(_assertThisInitialized$1(_this)), inputData)) {
5482 return;
5483 }
5484
5485 _this.callback(manager, inputEvent, inputData);
5486 };
5487
5488 _this.touch = new TouchInput(_this.manager, _this.handler);
5489 _this.mouse = new MouseInput(_this.manager, _this.handler);
5490 _this.primaryTouch = null;
5491 _this.lastTouches = [];
5492 return _this;
5493 }
5494 /**
5495 * @private
5496 * handle mouse and touch events
5497 * @param {Hammer} manager
5498 * @param {String} inputEvent
5499 * @param {Object} inputData
5500 */
5501
5502
5503 var _proto = TouchMouseInput.prototype;
5504 /**
5505 * @private
5506 * remove the event listeners
5507 */
5508
5509 _proto.destroy = function destroy() {
5510 this.touch.destroy();
5511 this.mouse.destroy();
5512 };
5513
5514 return TouchMouseInput;
5515 }(Input);
5516
5517 return TouchMouseInput;
5518}();
5519/**
5520 * @private
5521 * create new input type manager
5522 * called by the Manager constructor
5523 * @param {Hammer} manager
5524 * @returns {Input}
5525 */
5526
5527
5528function createInputInstance(manager) {
5529 var Type; // let inputClass = manager.options.inputClass;
5530
5531 var inputClass = manager.options.inputClass;
5532
5533 if (inputClass) {
5534 Type = inputClass;
5535 } else if (SUPPORT_POINTER_EVENTS) {
5536 Type = PointerEventInput;
5537 } else if (SUPPORT_ONLY_TOUCH) {
5538 Type = TouchInput;
5539 } else if (!SUPPORT_TOUCH) {
5540 Type = MouseInput;
5541 } else {
5542 Type = TouchMouseInput;
5543 }
5544
5545 return new Type(manager, inputHandler);
5546}
5547/**
5548 * @private
5549 * if the argument is an array, we want to execute the fn on each entry
5550 * if it aint an array we don't want to do a thing.
5551 * this is used by all the methods that accept a single and array argument.
5552 * @param {*|Array} arg
5553 * @param {String} fn
5554 * @param {Object} [context]
5555 * @returns {Boolean}
5556 */
5557
5558
5559function invokeArrayArg(arg, fn, context) {
5560 if (Array.isArray(arg)) {
5561 each(arg, context[fn], context);
5562 return true;
5563 }
5564
5565 return false;
5566}
5567
5568var STATE_POSSIBLE = 1;
5569var STATE_BEGAN = 2;
5570var STATE_CHANGED = 4;
5571var STATE_ENDED = 8;
5572var STATE_RECOGNIZED = STATE_ENDED;
5573var STATE_CANCELLED = 16;
5574var STATE_FAILED = 32;
5575/**
5576 * @private
5577 * get a unique id
5578 * @returns {number} uniqueId
5579 */
5580
5581var _uniqueId = 1;
5582
5583function uniqueId() {
5584 return _uniqueId++;
5585}
5586/**
5587 * @private
5588 * get a recognizer by name if it is bound to a manager
5589 * @param {Recognizer|String} otherRecognizer
5590 * @param {Recognizer} recognizer
5591 * @returns {Recognizer}
5592 */
5593
5594
5595function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
5596 var manager = recognizer.manager;
5597
5598 if (manager) {
5599 return manager.get(otherRecognizer);
5600 }
5601
5602 return otherRecognizer;
5603}
5604/**
5605 * @private
5606 * get a usable string, used as event postfix
5607 * @param {constant} state
5608 * @returns {String} state
5609 */
5610
5611
5612function stateStr(state) {
5613 if (state & STATE_CANCELLED) {
5614 return 'cancel';
5615 } else if (state & STATE_ENDED) {
5616 return 'end';
5617 } else if (state & STATE_CHANGED) {
5618 return 'move';
5619 } else if (state & STATE_BEGAN) {
5620 return 'start';
5621 }
5622
5623 return '';
5624}
5625/**
5626 * @private
5627 * Recognizer flow explained; *
5628 * All recognizers have the initial state of POSSIBLE when a input session starts.
5629 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
5630 * Example session for mouse-input: mousedown -> mousemove -> mouseup
5631 *
5632 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
5633 * which determines with state it should be.
5634 *
5635 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
5636 * POSSIBLE to give it another change on the next cycle.
5637 *
5638 * Possible
5639 * |
5640 * +-----+---------------+
5641 * | |
5642 * +-----+-----+ |
5643 * | | |
5644 * Failed Cancelled |
5645 * +-------+------+
5646 * | |
5647 * Recognized Began
5648 * |
5649 * Changed
5650 * |
5651 * Ended/Recognized
5652 */
5653
5654/**
5655 * @private
5656 * Recognizer
5657 * Every recognizer needs to extend from this class.
5658 * @constructor
5659 * @param {Object} options
5660 */
5661
5662
5663var Recognizer = /*#__PURE__*/function () {
5664 function Recognizer(options) {
5665 if (options === void 0) {
5666 options = {};
5667 }
5668
5669 this.options = _extends({
5670 enable: true
5671 }, options);
5672 this.id = uniqueId();
5673 this.manager = null; // default is enable true
5674
5675 this.state = STATE_POSSIBLE;
5676 this.simultaneous = {};
5677 this.requireFail = [];
5678 }
5679 /**
5680 * @private
5681 * set options
5682 * @param {Object} options
5683 * @return {Recognizer}
5684 */
5685
5686
5687 var _proto = Recognizer.prototype;
5688
5689 _proto.set = function set(options) {
5690 assign$1(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state
5691
5692 this.manager && this.manager.touchAction.update();
5693 return this;
5694 };
5695 /**
5696 * @private
5697 * recognize simultaneous with an other recognizer.
5698 * @param {Recognizer} otherRecognizer
5699 * @returns {Recognizer} this
5700 */
5701
5702
5703 _proto.recognizeWith = function recognizeWith(otherRecognizer) {
5704 if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
5705 return this;
5706 }
5707
5708 var simultaneous = this.simultaneous;
5709 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
5710
5711 if (!simultaneous[otherRecognizer.id]) {
5712 simultaneous[otherRecognizer.id] = otherRecognizer;
5713 otherRecognizer.recognizeWith(this);
5714 }
5715
5716 return this;
5717 };
5718 /**
5719 * @private
5720 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
5721 * @param {Recognizer} otherRecognizer
5722 * @returns {Recognizer} this
5723 */
5724
5725
5726 _proto.dropRecognizeWith = function dropRecognizeWith(otherRecognizer) {
5727 if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
5728 return this;
5729 }
5730
5731 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
5732 delete this.simultaneous[otherRecognizer.id];
5733 return this;
5734 };
5735 /**
5736 * @private
5737 * recognizer can only run when an other is failing
5738 * @param {Recognizer} otherRecognizer
5739 * @returns {Recognizer} this
5740 */
5741
5742
5743 _proto.requireFailure = function requireFailure(otherRecognizer) {
5744 if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
5745 return this;
5746 }
5747
5748 var requireFail = this.requireFail;
5749 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
5750
5751 if (inArray(requireFail, otherRecognizer) === -1) {
5752 requireFail.push(otherRecognizer);
5753 otherRecognizer.requireFailure(this);
5754 }
5755
5756 return this;
5757 };
5758 /**
5759 * @private
5760 * drop the requireFailure link. it does not remove the link on the other recognizer.
5761 * @param {Recognizer} otherRecognizer
5762 * @returns {Recognizer} this
5763 */
5764
5765
5766 _proto.dropRequireFailure = function dropRequireFailure(otherRecognizer) {
5767 if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
5768 return this;
5769 }
5770
5771 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
5772 var index = inArray(this.requireFail, otherRecognizer);
5773
5774 if (index > -1) {
5775 this.requireFail.splice(index, 1);
5776 }
5777
5778 return this;
5779 };
5780 /**
5781 * @private
5782 * has require failures boolean
5783 * @returns {boolean}
5784 */
5785
5786
5787 _proto.hasRequireFailures = function hasRequireFailures() {
5788 return this.requireFail.length > 0;
5789 };
5790 /**
5791 * @private
5792 * if the recognizer can recognize simultaneous with an other recognizer
5793 * @param {Recognizer} otherRecognizer
5794 * @returns {Boolean}
5795 */
5796
5797
5798 _proto.canRecognizeWith = function canRecognizeWith(otherRecognizer) {
5799 return !!this.simultaneous[otherRecognizer.id];
5800 };
5801 /**
5802 * @private
5803 * You should use `tryEmit` instead of `emit` directly to check
5804 * that all the needed recognizers has failed before emitting.
5805 * @param {Object} input
5806 */
5807
5808
5809 _proto.emit = function emit(input) {
5810 var self = this;
5811 var state = this.state;
5812
5813 function emit(event) {
5814 self.manager.emit(event, input);
5815 } // 'panstart' and 'panmove'
5816
5817
5818 if (state < STATE_ENDED) {
5819 emit(self.options.event + stateStr(state));
5820 }
5821
5822 emit(self.options.event); // simple 'eventName' events
5823
5824 if (input.additionalEvent) {
5825 // additional event(panleft, panright, pinchin, pinchout...)
5826 emit(input.additionalEvent);
5827 } // panend and pancancel
5828
5829
5830 if (state >= STATE_ENDED) {
5831 emit(self.options.event + stateStr(state));
5832 }
5833 };
5834 /**
5835 * @private
5836 * Check that all the require failure recognizers has failed,
5837 * if true, it emits a gesture event,
5838 * otherwise, setup the state to FAILED.
5839 * @param {Object} input
5840 */
5841
5842
5843 _proto.tryEmit = function tryEmit(input) {
5844 if (this.canEmit()) {
5845 return this.emit(input);
5846 } // it's failing anyway
5847
5848
5849 this.state = STATE_FAILED;
5850 };
5851 /**
5852 * @private
5853 * can we emit?
5854 * @returns {boolean}
5855 */
5856
5857
5858 _proto.canEmit = function canEmit() {
5859 var i = 0;
5860
5861 while (i < this.requireFail.length) {
5862 if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
5863 return false;
5864 }
5865
5866 i++;
5867 }
5868
5869 return true;
5870 };
5871 /**
5872 * @private
5873 * update the recognizer
5874 * @param {Object} inputData
5875 */
5876
5877
5878 _proto.recognize = function recognize(inputData) {
5879 // make a new copy of the inputData
5880 // so we can change the inputData without messing up the other recognizers
5881 var inputDataClone = assign$1({}, inputData); // is is enabled and allow recognizing?
5882
5883 if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
5884 this.reset();
5885 this.state = STATE_FAILED;
5886 return;
5887 } // reset when we've reached the end
5888
5889
5890 if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
5891 this.state = STATE_POSSIBLE;
5892 }
5893
5894 this.state = this.process(inputDataClone); // the recognizer has recognized a gesture
5895 // so trigger an event
5896
5897 if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
5898 this.tryEmit(inputDataClone);
5899 }
5900 };
5901 /**
5902 * @private
5903 * return the state of the recognizer
5904 * the actual recognizing happens in this method
5905 * @virtual
5906 * @param {Object} inputData
5907 * @returns {constant} STATE
5908 */
5909
5910 /* jshint ignore:start */
5911
5912
5913 _proto.process = function process(inputData) {};
5914 /* jshint ignore:end */
5915
5916 /**
5917 * @private
5918 * return the preferred touch-action
5919 * @virtual
5920 * @returns {Array}
5921 */
5922
5923
5924 _proto.getTouchAction = function getTouchAction() {};
5925 /**
5926 * @private
5927 * called when the gesture isn't allowed to recognize
5928 * like when another is being recognized or it is disabled
5929 * @virtual
5930 */
5931
5932
5933 _proto.reset = function reset() {};
5934
5935 return Recognizer;
5936}();
5937/**
5938 * @private
5939 * A tap is recognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
5940 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
5941 * a single tap.
5942 *
5943 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
5944 * multi-taps being recognized.
5945 * @constructor
5946 * @extends Recognizer
5947 */
5948
5949
5950var TapRecognizer = /*#__PURE__*/function (_Recognizer) {
5951 _inheritsLoose(TapRecognizer, _Recognizer);
5952
5953 function TapRecognizer(options) {
5954 var _this;
5955
5956 if (options === void 0) {
5957 options = {};
5958 }
5959
5960 _this = _Recognizer.call(this, _extends({
5961 event: 'tap',
5962 pointers: 1,
5963 taps: 1,
5964 interval: 300,
5965 // max time between the multi-tap taps
5966 time: 250,
5967 // max time of the pointer to be down (like finger on the screen)
5968 threshold: 9,
5969 // a minimal movement is ok, but keep it low
5970 posThreshold: 10
5971 }, options)) || this; // previous time and center,
5972 // used for tap counting
5973
5974 _this.pTime = false;
5975 _this.pCenter = false;
5976 _this._timer = null;
5977 _this._input = null;
5978 _this.count = 0;
5979 return _this;
5980 }
5981
5982 var _proto = TapRecognizer.prototype;
5983
5984 _proto.getTouchAction = function getTouchAction() {
5985 return [TOUCH_ACTION_MANIPULATION];
5986 };
5987
5988 _proto.process = function process(input) {
5989 var _this2 = this;
5990
5991 var options = this.options;
5992 var validPointers = input.pointers.length === options.pointers;
5993 var validMovement = input.distance < options.threshold;
5994 var validTouchTime = input.deltaTime < options.time;
5995 this.reset();
5996
5997 if (input.eventType & INPUT_START && this.count === 0) {
5998 return this.failTimeout();
5999 } // we only allow little movement
6000 // and we've reached an end event, so a tap is possible
6001
6002
6003 if (validMovement && validTouchTime && validPointers) {
6004 if (input.eventType !== INPUT_END) {
6005 return this.failTimeout();
6006 }
6007
6008 var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
6009 var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
6010 this.pTime = input.timeStamp;
6011 this.pCenter = input.center;
6012
6013 if (!validMultiTap || !validInterval) {
6014 this.count = 1;
6015 } else {
6016 this.count += 1;
6017 }
6018
6019 this._input = input; // if tap count matches we have recognized it,
6020 // else it has began recognizing...
6021
6022 var tapCount = this.count % options.taps;
6023
6024 if (tapCount === 0) {
6025 // no failing requirements, immediately trigger the tap event
6026 // or wait as long as the multitap interval to trigger
6027 if (!this.hasRequireFailures()) {
6028 return STATE_RECOGNIZED;
6029 } else {
6030 this._timer = setTimeout(function () {
6031 _this2.state = STATE_RECOGNIZED;
6032
6033 _this2.tryEmit();
6034 }, options.interval);
6035 return STATE_BEGAN;
6036 }
6037 }
6038 }
6039
6040 return STATE_FAILED;
6041 };
6042
6043 _proto.failTimeout = function failTimeout() {
6044 var _this3 = this;
6045
6046 this._timer = setTimeout(function () {
6047 _this3.state = STATE_FAILED;
6048 }, this.options.interval);
6049 return STATE_FAILED;
6050 };
6051
6052 _proto.reset = function reset() {
6053 clearTimeout(this._timer);
6054 };
6055
6056 _proto.emit = function emit() {
6057 if (this.state === STATE_RECOGNIZED) {
6058 this._input.tapCount = this.count;
6059 this.manager.emit(this.options.event, this._input);
6060 }
6061 };
6062
6063 return TapRecognizer;
6064}(Recognizer);
6065/**
6066 * @private
6067 * This recognizer is just used as a base for the simple attribute recognizers.
6068 * @constructor
6069 * @extends Recognizer
6070 */
6071
6072
6073var AttrRecognizer = /*#__PURE__*/function (_Recognizer) {
6074 _inheritsLoose(AttrRecognizer, _Recognizer);
6075
6076 function AttrRecognizer(options) {
6077 if (options === void 0) {
6078 options = {};
6079 }
6080
6081 return _Recognizer.call(this, _extends({
6082 pointers: 1
6083 }, options)) || this;
6084 }
6085 /**
6086 * @private
6087 * Used to check if it the recognizer receives valid input, like input.distance > 10.
6088 * @memberof AttrRecognizer
6089 * @param {Object} input
6090 * @returns {Boolean} recognized
6091 */
6092
6093
6094 var _proto = AttrRecognizer.prototype;
6095
6096 _proto.attrTest = function attrTest(input) {
6097 var optionPointers = this.options.pointers;
6098 return optionPointers === 0 || input.pointers.length === optionPointers;
6099 };
6100 /**
6101 * @private
6102 * Process the input and return the state for the recognizer
6103 * @memberof AttrRecognizer
6104 * @param {Object} input
6105 * @returns {*} State
6106 */
6107
6108
6109 _proto.process = function process(input) {
6110 var state = this.state;
6111 var eventType = input.eventType;
6112 var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
6113 var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED
6114
6115 if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
6116 return state | STATE_CANCELLED;
6117 } else if (isRecognized || isValid) {
6118 if (eventType & INPUT_END) {
6119 return state | STATE_ENDED;
6120 } else if (!(state & STATE_BEGAN)) {
6121 return STATE_BEGAN;
6122 }
6123
6124 return state | STATE_CHANGED;
6125 }
6126
6127 return STATE_FAILED;
6128 };
6129
6130 return AttrRecognizer;
6131}(Recognizer);
6132/**
6133 * @private
6134 * direction cons to string
6135 * @param {constant} direction
6136 * @returns {String}
6137 */
6138
6139
6140function directionStr(direction) {
6141 if (direction === DIRECTION_DOWN) {
6142 return 'down';
6143 } else if (direction === DIRECTION_UP) {
6144 return 'up';
6145 } else if (direction === DIRECTION_LEFT) {
6146 return 'left';
6147 } else if (direction === DIRECTION_RIGHT) {
6148 return 'right';
6149 }
6150
6151 return '';
6152}
6153/**
6154 * @private
6155 * Pan
6156 * Recognized when the pointer is down and moved in the allowed direction.
6157 * @constructor
6158 * @extends AttrRecognizer
6159 */
6160
6161
6162var PanRecognizer = /*#__PURE__*/function (_AttrRecognizer) {
6163 _inheritsLoose(PanRecognizer, _AttrRecognizer);
6164
6165 function PanRecognizer(options) {
6166 var _this;
6167
6168 if (options === void 0) {
6169 options = {};
6170 }
6171
6172 _this = _AttrRecognizer.call(this, _extends({
6173 event: 'pan',
6174 threshold: 10,
6175 pointers: 1,
6176 direction: DIRECTION_ALL
6177 }, options)) || this;
6178 _this.pX = null;
6179 _this.pY = null;
6180 return _this;
6181 }
6182
6183 var _proto = PanRecognizer.prototype;
6184
6185 _proto.getTouchAction = function getTouchAction() {
6186 var direction = this.options.direction;
6187 var actions = [];
6188
6189 if (direction & DIRECTION_HORIZONTAL) {
6190 actions.push(TOUCH_ACTION_PAN_Y);
6191 }
6192
6193 if (direction & DIRECTION_VERTICAL) {
6194 actions.push(TOUCH_ACTION_PAN_X);
6195 }
6196
6197 return actions;
6198 };
6199
6200 _proto.directionTest = function directionTest(input) {
6201 var options = this.options;
6202 var hasMoved = true;
6203 var distance = input.distance;
6204 var direction = input.direction;
6205 var x = input.deltaX;
6206 var y = input.deltaY; // lock to axis?
6207
6208 if (!(direction & options.direction)) {
6209 if (options.direction & DIRECTION_HORIZONTAL) {
6210 direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
6211 hasMoved = x !== this.pX;
6212 distance = Math.abs(input.deltaX);
6213 } else {
6214 direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
6215 hasMoved = y !== this.pY;
6216 distance = Math.abs(input.deltaY);
6217 }
6218 }
6219
6220 input.direction = direction;
6221 return hasMoved && distance > options.threshold && direction & options.direction;
6222 };
6223
6224 _proto.attrTest = function attrTest(input) {
6225 return AttrRecognizer.prototype.attrTest.call(this, input) && ( // replace with a super call
6226 this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
6227 };
6228
6229 _proto.emit = function emit(input) {
6230 this.pX = input.deltaX;
6231 this.pY = input.deltaY;
6232 var direction = directionStr(input.direction);
6233
6234 if (direction) {
6235 input.additionalEvent = this.options.event + direction;
6236 }
6237
6238 _AttrRecognizer.prototype.emit.call(this, input);
6239 };
6240
6241 return PanRecognizer;
6242}(AttrRecognizer);
6243/**
6244 * @private
6245 * Swipe
6246 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
6247 * @constructor
6248 * @extends AttrRecognizer
6249 */
6250
6251
6252var SwipeRecognizer = /*#__PURE__*/function (_AttrRecognizer) {
6253 _inheritsLoose(SwipeRecognizer, _AttrRecognizer);
6254
6255 function SwipeRecognizer(options) {
6256 if (options === void 0) {
6257 options = {};
6258 }
6259
6260 return _AttrRecognizer.call(this, _extends({
6261 event: 'swipe',
6262 threshold: 10,
6263 velocity: 0.3,
6264 direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
6265 pointers: 1
6266 }, options)) || this;
6267 }
6268
6269 var _proto = SwipeRecognizer.prototype;
6270
6271 _proto.getTouchAction = function getTouchAction() {
6272 return PanRecognizer.prototype.getTouchAction.call(this);
6273 };
6274
6275 _proto.attrTest = function attrTest(input) {
6276 var direction = this.options.direction;
6277 var velocity;
6278
6279 if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
6280 velocity = input.overallVelocity;
6281 } else if (direction & DIRECTION_HORIZONTAL) {
6282 velocity = input.overallVelocityX;
6283 } else if (direction & DIRECTION_VERTICAL) {
6284 velocity = input.overallVelocityY;
6285 }
6286
6287 return _AttrRecognizer.prototype.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers === this.options.pointers && abs$1(velocity) > this.options.velocity && input.eventType & INPUT_END;
6288 };
6289
6290 _proto.emit = function emit(input) {
6291 var direction = directionStr(input.offsetDirection);
6292
6293 if (direction) {
6294 this.manager.emit(this.options.event + direction, input);
6295 }
6296
6297 this.manager.emit(this.options.event, input);
6298 };
6299
6300 return SwipeRecognizer;
6301}(AttrRecognizer);
6302/**
6303 * @private
6304 * Pinch
6305 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
6306 * @constructor
6307 * @extends AttrRecognizer
6308 */
6309
6310
6311var PinchRecognizer = /*#__PURE__*/function (_AttrRecognizer) {
6312 _inheritsLoose(PinchRecognizer, _AttrRecognizer);
6313
6314 function PinchRecognizer(options) {
6315 if (options === void 0) {
6316 options = {};
6317 }
6318
6319 return _AttrRecognizer.call(this, _extends({
6320 event: 'pinch',
6321 threshold: 0,
6322 pointers: 2
6323 }, options)) || this;
6324 }
6325
6326 var _proto = PinchRecognizer.prototype;
6327
6328 _proto.getTouchAction = function getTouchAction() {
6329 return [TOUCH_ACTION_NONE];
6330 };
6331
6332 _proto.attrTest = function attrTest(input) {
6333 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
6334 };
6335
6336 _proto.emit = function emit(input) {
6337 if (input.scale !== 1) {
6338 var inOut = input.scale < 1 ? 'in' : 'out';
6339 input.additionalEvent = this.options.event + inOut;
6340 }
6341
6342 _AttrRecognizer.prototype.emit.call(this, input);
6343 };
6344
6345 return PinchRecognizer;
6346}(AttrRecognizer);
6347/**
6348 * @private
6349 * Rotate
6350 * Recognized when two or more pointer are moving in a circular motion.
6351 * @constructor
6352 * @extends AttrRecognizer
6353 */
6354
6355
6356var RotateRecognizer = /*#__PURE__*/function (_AttrRecognizer) {
6357 _inheritsLoose(RotateRecognizer, _AttrRecognizer);
6358
6359 function RotateRecognizer(options) {
6360 if (options === void 0) {
6361 options = {};
6362 }
6363
6364 return _AttrRecognizer.call(this, _extends({
6365 event: 'rotate',
6366 threshold: 0,
6367 pointers: 2
6368 }, options)) || this;
6369 }
6370
6371 var _proto = RotateRecognizer.prototype;
6372
6373 _proto.getTouchAction = function getTouchAction() {
6374 return [TOUCH_ACTION_NONE];
6375 };
6376
6377 _proto.attrTest = function attrTest(input) {
6378 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
6379 };
6380
6381 return RotateRecognizer;
6382}(AttrRecognizer);
6383/**
6384 * @private
6385 * Press
6386 * Recognized when the pointer is down for x ms without any movement.
6387 * @constructor
6388 * @extends Recognizer
6389 */
6390
6391
6392var PressRecognizer = /*#__PURE__*/function (_Recognizer) {
6393 _inheritsLoose(PressRecognizer, _Recognizer);
6394
6395 function PressRecognizer(options) {
6396 var _this;
6397
6398 if (options === void 0) {
6399 options = {};
6400 }
6401
6402 _this = _Recognizer.call(this, _extends({
6403 event: 'press',
6404 pointers: 1,
6405 time: 251,
6406 // minimal time of the pointer to be pressed
6407 threshold: 9
6408 }, options)) || this;
6409 _this._timer = null;
6410 _this._input = null;
6411 return _this;
6412 }
6413
6414 var _proto = PressRecognizer.prototype;
6415
6416 _proto.getTouchAction = function getTouchAction() {
6417 return [TOUCH_ACTION_AUTO];
6418 };
6419
6420 _proto.process = function process(input) {
6421 var _this2 = this;
6422
6423 var options = this.options;
6424 var validPointers = input.pointers.length === options.pointers;
6425 var validMovement = input.distance < options.threshold;
6426 var validTime = input.deltaTime > options.time;
6427 this._input = input; // we only allow little movement
6428 // and we've reached an end event, so a tap is possible
6429
6430 if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
6431 this.reset();
6432 } else if (input.eventType & INPUT_START) {
6433 this.reset();
6434 this._timer = setTimeout(function () {
6435 _this2.state = STATE_RECOGNIZED;
6436
6437 _this2.tryEmit();
6438 }, options.time);
6439 } else if (input.eventType & INPUT_END) {
6440 return STATE_RECOGNIZED;
6441 }
6442
6443 return STATE_FAILED;
6444 };
6445
6446 _proto.reset = function reset() {
6447 clearTimeout(this._timer);
6448 };
6449
6450 _proto.emit = function emit(input) {
6451 if (this.state !== STATE_RECOGNIZED) {
6452 return;
6453 }
6454
6455 if (input && input.eventType & INPUT_END) {
6456 this.manager.emit(this.options.event + "up", input);
6457 } else {
6458 this._input.timeStamp = now();
6459 this.manager.emit(this.options.event, this._input);
6460 }
6461 };
6462
6463 return PressRecognizer;
6464}(Recognizer);
6465
6466var defaults = {
6467 /**
6468 * @private
6469 * set if DOM events are being triggered.
6470 * But this is slower and unused by simple implementations, so disabled by default.
6471 * @type {Boolean}
6472 * @default false
6473 */
6474 domEvents: false,
6475
6476 /**
6477 * @private
6478 * The value for the touchAction property/fallback.
6479 * When set to `compute` it will magically set the correct value based on the added recognizers.
6480 * @type {String}
6481 * @default compute
6482 */
6483 touchAction: TOUCH_ACTION_COMPUTE,
6484
6485 /**
6486 * @private
6487 * @type {Boolean}
6488 * @default true
6489 */
6490 enable: true,
6491
6492 /**
6493 * @private
6494 * EXPERIMENTAL FEATURE -- can be removed/changed
6495 * Change the parent input target element.
6496 * If Null, then it is being set the to main element.
6497 * @type {Null|EventTarget}
6498 * @default null
6499 */
6500 inputTarget: null,
6501
6502 /**
6503 * @private
6504 * force an input class
6505 * @type {Null|Function}
6506 * @default null
6507 */
6508 inputClass: null,
6509
6510 /**
6511 * @private
6512 * Some CSS properties can be used to improve the working of Hammer.
6513 * Add them to this method and they will be set when creating a new Manager.
6514 * @namespace
6515 */
6516 cssProps: {
6517 /**
6518 * @private
6519 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
6520 * @type {String}
6521 * @default 'none'
6522 */
6523 userSelect: "none",
6524
6525 /**
6526 * @private
6527 * Disable the Windows Phone grippers when pressing an element.
6528 * @type {String}
6529 * @default 'none'
6530 */
6531 touchSelect: "none",
6532
6533 /**
6534 * @private
6535 * Disables the default callout shown when you touch and hold a touch target.
6536 * On iOS, when you touch and hold a touch target such as a link, Safari displays
6537 * a callout containing information about the link. This property allows you to disable that callout.
6538 * @type {String}
6539 * @default 'none'
6540 */
6541 touchCallout: "none",
6542
6543 /**
6544 * @private
6545 * Specifies whether zooming is enabled. Used by IE10>
6546 * @type {String}
6547 * @default 'none'
6548 */
6549 contentZooming: "none",
6550
6551 /**
6552 * @private
6553 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
6554 * @type {String}
6555 * @default 'none'
6556 */
6557 userDrag: "none",
6558
6559 /**
6560 * @private
6561 * Overrides the highlight color shown when the user taps a link or a JavaScript
6562 * clickable element in iOS. This property obeys the alpha value, if specified.
6563 * @type {String}
6564 * @default 'rgba(0,0,0,0)'
6565 */
6566 tapHighlightColor: "rgba(0,0,0,0)"
6567 }
6568};
6569/**
6570 * @private
6571 * Default recognizer setup when calling `Hammer()`
6572 * When creating a new Manager these will be skipped.
6573 * This is separated with other defaults because of tree-shaking.
6574 * @type {Array}
6575 */
6576
6577var preset = [[RotateRecognizer, {
6578 enable: false
6579}], [PinchRecognizer, {
6580 enable: false
6581}, ['rotate']], [SwipeRecognizer, {
6582 direction: DIRECTION_HORIZONTAL
6583}], [PanRecognizer, {
6584 direction: DIRECTION_HORIZONTAL
6585}, ['swipe']], [TapRecognizer], [TapRecognizer, {
6586 event: 'doubletap',
6587 taps: 2
6588}, ['tap']], [PressRecognizer]];
6589var STOP = 1;
6590var FORCED_STOP = 2;
6591/**
6592 * @private
6593 * add/remove the css properties as defined in manager.options.cssProps
6594 * @param {Manager} manager
6595 * @param {Boolean} add
6596 */
6597
6598function toggleCssProps(manager, add) {
6599 var element = manager.element;
6600
6601 if (!element.style) {
6602 return;
6603 }
6604
6605 var prop;
6606 each(manager.options.cssProps, function (value, name) {
6607 prop = prefixed(element.style, name);
6608
6609 if (add) {
6610 manager.oldCssProps[prop] = element.style[prop];
6611 element.style[prop] = value;
6612 } else {
6613 element.style[prop] = manager.oldCssProps[prop] || "";
6614 }
6615 });
6616
6617 if (!add) {
6618 manager.oldCssProps = {};
6619 }
6620}
6621/**
6622 * @private
6623 * trigger dom event
6624 * @param {String} event
6625 * @param {Object} data
6626 */
6627
6628
6629function triggerDomEvent(event, data) {
6630 var gestureEvent = document.createEvent("Event");
6631 gestureEvent.initEvent(event, true, true);
6632 gestureEvent.gesture = data;
6633 data.target.dispatchEvent(gestureEvent);
6634}
6635/**
6636* @private
6637 * Manager
6638 * @param {HTMLElement} element
6639 * @param {Object} [options]
6640 * @constructor
6641 */
6642
6643
6644var Manager = /*#__PURE__*/function () {
6645 function Manager(element, options) {
6646 var _this = this;
6647
6648 this.options = assign$1({}, defaults, options || {});
6649 this.options.inputTarget = this.options.inputTarget || element;
6650 this.handlers = {};
6651 this.session = {};
6652 this.recognizers = [];
6653 this.oldCssProps = {};
6654 this.element = element;
6655 this.input = createInputInstance(this);
6656 this.touchAction = new TouchAction(this, this.options.touchAction);
6657 toggleCssProps(this, true);
6658 each(this.options.recognizers, function (item) {
6659 var recognizer = _this.add(new item[0](item[1]));
6660
6661 item[2] && recognizer.recognizeWith(item[2]);
6662 item[3] && recognizer.requireFailure(item[3]);
6663 }, this);
6664 }
6665 /**
6666 * @private
6667 * set options
6668 * @param {Object} options
6669 * @returns {Manager}
6670 */
6671
6672
6673 var _proto = Manager.prototype;
6674
6675 _proto.set = function set(options) {
6676 assign$1(this.options, options); // Options that need a little more setup
6677
6678 if (options.touchAction) {
6679 this.touchAction.update();
6680 }
6681
6682 if (options.inputTarget) {
6683 // Clean up existing event listeners and reinitialize
6684 this.input.destroy();
6685 this.input.target = options.inputTarget;
6686 this.input.init();
6687 }
6688
6689 return this;
6690 };
6691 /**
6692 * @private
6693 * stop recognizing for this session.
6694 * This session will be discarded, when a new [input]start event is fired.
6695 * When forced, the recognizer cycle is stopped immediately.
6696 * @param {Boolean} [force]
6697 */
6698
6699
6700 _proto.stop = function stop(force) {
6701 this.session.stopped = force ? FORCED_STOP : STOP;
6702 };
6703 /**
6704 * @private
6705 * run the recognizers!
6706 * called by the inputHandler function on every movement of the pointers (touches)
6707 * it walks through all the recognizers and tries to detect the gesture that is being made
6708 * @param {Object} inputData
6709 */
6710
6711
6712 _proto.recognize = function recognize(inputData) {
6713 var session = this.session;
6714
6715 if (session.stopped) {
6716 return;
6717 } // run the touch-action polyfill
6718
6719
6720 this.touchAction.preventDefaults(inputData);
6721 var recognizer;
6722 var recognizers = this.recognizers; // this holds the recognizer that is being recognized.
6723 // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
6724 // if no recognizer is detecting a thing, it is set to `null`
6725
6726 var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized
6727 // or when we're in a new session
6728
6729 if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
6730 session.curRecognizer = null;
6731 curRecognizer = null;
6732 }
6733
6734 var i = 0;
6735
6736 while (i < recognizers.length) {
6737 recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one.
6738 // 1. allow if the session is NOT forced stopped (see the .stop() method)
6739 // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
6740 // that is being recognized.
6741 // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
6742 // this can be setup with the `recognizeWith()` method on the recognizer.
6743
6744 if (session.stopped !== FORCED_STOP && ( // 1
6745 !curRecognizer || recognizer === curRecognizer || // 2
6746 recognizer.canRecognizeWith(curRecognizer))) {
6747 // 3
6748 recognizer.recognize(inputData);
6749 } else {
6750 recognizer.reset();
6751 } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
6752 // current active recognizer. but only if we don't already have an active recognizer
6753
6754
6755 if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
6756 session.curRecognizer = recognizer;
6757 curRecognizer = recognizer;
6758 }
6759
6760 i++;
6761 }
6762 };
6763 /**
6764 * @private
6765 * get a recognizer by its event name.
6766 * @param {Recognizer|String} recognizer
6767 * @returns {Recognizer|Null}
6768 */
6769
6770
6771 _proto.get = function get(recognizer) {
6772 if (recognizer instanceof Recognizer) {
6773 return recognizer;
6774 }
6775
6776 var recognizers = this.recognizers;
6777
6778 for (var i = 0; i < recognizers.length; i++) {
6779 if (recognizers[i].options.event === recognizer) {
6780 return recognizers[i];
6781 }
6782 }
6783
6784 return null;
6785 };
6786 /**
6787 * @private add a recognizer to the manager
6788 * existing recognizers with the same event name will be removed
6789 * @param {Recognizer} recognizer
6790 * @returns {Recognizer|Manager}
6791 */
6792
6793
6794 _proto.add = function add(recognizer) {
6795 if (invokeArrayArg(recognizer, "add", this)) {
6796 return this;
6797 } // remove existing
6798
6799
6800 var existing = this.get(recognizer.options.event);
6801
6802 if (existing) {
6803 this.remove(existing);
6804 }
6805
6806 this.recognizers.push(recognizer);
6807 recognizer.manager = this;
6808 this.touchAction.update();
6809 return recognizer;
6810 };
6811 /**
6812 * @private
6813 * remove a recognizer by name or instance
6814 * @param {Recognizer|String} recognizer
6815 * @returns {Manager}
6816 */
6817
6818
6819 _proto.remove = function remove(recognizer) {
6820 if (invokeArrayArg(recognizer, "remove", this)) {
6821 return this;
6822 }
6823
6824 var targetRecognizer = this.get(recognizer); // let's make sure this recognizer exists
6825
6826 if (recognizer) {
6827 var recognizers = this.recognizers;
6828 var index = inArray(recognizers, targetRecognizer);
6829
6830 if (index !== -1) {
6831 recognizers.splice(index, 1);
6832 this.touchAction.update();
6833 }
6834 }
6835
6836 return this;
6837 };
6838 /**
6839 * @private
6840 * bind event
6841 * @param {String} events
6842 * @param {Function} handler
6843 * @returns {EventEmitter} this
6844 */
6845
6846
6847 _proto.on = function on(events, handler) {
6848 if (events === undefined || handler === undefined) {
6849 return this;
6850 }
6851
6852 var handlers = this.handlers;
6853 each(splitStr(events), function (event) {
6854 handlers[event] = handlers[event] || [];
6855 handlers[event].push(handler);
6856 });
6857 return this;
6858 };
6859 /**
6860 * @private unbind event, leave emit blank to remove all handlers
6861 * @param {String} events
6862 * @param {Function} [handler]
6863 * @returns {EventEmitter} this
6864 */
6865
6866
6867 _proto.off = function off(events, handler) {
6868 if (events === undefined) {
6869 return this;
6870 }
6871
6872 var handlers = this.handlers;
6873 each(splitStr(events), function (event) {
6874 if (!handler) {
6875 delete handlers[event];
6876 } else {
6877 handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
6878 }
6879 });
6880 return this;
6881 };
6882 /**
6883 * @private emit event to the listeners
6884 * @param {String} event
6885 * @param {Object} data
6886 */
6887
6888
6889 _proto.emit = function emit(event, data) {
6890 // we also want to trigger dom events
6891 if (this.options.domEvents) {
6892 triggerDomEvent(event, data);
6893 } // no handlers, so skip it all
6894
6895
6896 var handlers = this.handlers[event] && this.handlers[event].slice();
6897
6898 if (!handlers || !handlers.length) {
6899 return;
6900 }
6901
6902 data.type = event;
6903
6904 data.preventDefault = function () {
6905 data.srcEvent.preventDefault();
6906 };
6907
6908 var i = 0;
6909
6910 while (i < handlers.length) {
6911 handlers[i](data);
6912 i++;
6913 }
6914 };
6915 /**
6916 * @private
6917 * destroy the manager and unbinds all events
6918 * it doesn't unbind dom events, that is the user own responsibility
6919 */
6920
6921
6922 _proto.destroy = function destroy() {
6923 this.element && toggleCssProps(this, false);
6924 this.handlers = {};
6925 this.session = {};
6926 this.input.destroy();
6927 this.element = null;
6928 };
6929
6930 return Manager;
6931}();
6932
6933var SINGLE_TOUCH_INPUT_MAP = {
6934 touchstart: INPUT_START,
6935 touchmove: INPUT_MOVE,
6936 touchend: INPUT_END,
6937 touchcancel: INPUT_CANCEL
6938};
6939var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
6940var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
6941/**
6942 * @private
6943 * Touch events input
6944 * @constructor
6945 * @extends Input
6946 */
6947
6948var SingleTouchInput = /*#__PURE__*/function (_Input) {
6949 _inheritsLoose(SingleTouchInput, _Input);
6950
6951 function SingleTouchInput() {
6952 var _this;
6953
6954 var proto = SingleTouchInput.prototype;
6955 proto.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
6956 proto.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
6957 _this = _Input.apply(this, arguments) || this;
6958 _this.started = false;
6959 return _this;
6960 }
6961
6962 var _proto = SingleTouchInput.prototype;
6963
6964 _proto.handler = function handler(ev) {
6965 var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events?
6966
6967 if (type === INPUT_START) {
6968 this.started = true;
6969 }
6970
6971 if (!this.started) {
6972 return;
6973 }
6974
6975 var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state
6976
6977 if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
6978 this.started = false;
6979 }
6980
6981 this.callback(this.manager, type, {
6982 pointers: touches[0],
6983 changedPointers: touches[1],
6984 pointerType: INPUT_TYPE_TOUCH,
6985 srcEvent: ev
6986 });
6987 };
6988
6989 return SingleTouchInput;
6990}(Input);
6991
6992function normalizeSingleTouches(ev, type) {
6993 var all = toArray(ev.touches);
6994 var changed = toArray(ev.changedTouches);
6995
6996 if (type & (INPUT_END | INPUT_CANCEL)) {
6997 all = uniqueArray(all.concat(changed), 'identifier', true);
6998 }
6999
7000 return [all, changed];
7001}
7002/**
7003 * @private
7004 * wrap a method with a deprecation warning and stack trace
7005 * @param {Function} method
7006 * @param {String} name
7007 * @param {String} message
7008 * @returns {Function} A new function wrapping the supplied method.
7009 */
7010
7011
7012function deprecate(method, name, message) {
7013 var deprecationMessage = "DEPRECATED METHOD: " + name + "\n" + message + " AT \n";
7014 return function () {
7015 var e = new Error('get-stack-trace');
7016 var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
7017 var log = window.console && (window.console.warn || window.console.log);
7018
7019 if (log) {
7020 log.call(window.console, deprecationMessage, stack);
7021 }
7022
7023 return method.apply(this, arguments);
7024 };
7025}
7026/**
7027 * @private
7028 * extend object.
7029 * means that properties in dest will be overwritten by the ones in src.
7030 * @param {Object} dest
7031 * @param {Object} src
7032 * @param {Boolean} [merge=false]
7033 * @returns {Object} dest
7034 */
7035
7036
7037var extend = deprecate(function (dest, src, merge) {
7038 var keys = Object.keys(src);
7039 var i = 0;
7040
7041 while (i < keys.length) {
7042 if (!merge || merge && dest[keys[i]] === undefined) {
7043 dest[keys[i]] = src[keys[i]];
7044 }
7045
7046 i++;
7047 }
7048
7049 return dest;
7050}, 'extend', 'Use `assign`.');
7051/**
7052 * @private
7053 * merge the values from src in the dest.
7054 * means that properties that exist in dest will not be overwritten by src
7055 * @param {Object} dest
7056 * @param {Object} src
7057 * @returns {Object} dest
7058 */
7059
7060var merge$2 = deprecate(function (dest, src) {
7061 return extend(dest, src, true);
7062}, 'merge', 'Use `assign`.');
7063/**
7064 * @private
7065 * simple class inheritance
7066 * @param {Function} child
7067 * @param {Function} base
7068 * @param {Object} [properties]
7069 */
7070
7071function inherit(child, base, properties) {
7072 var baseP = base.prototype;
7073 var childP;
7074 childP = child.prototype = Object.create(baseP);
7075 childP.constructor = child;
7076 childP._super = baseP;
7077
7078 if (properties) {
7079 assign$1(childP, properties);
7080 }
7081}
7082/**
7083 * @private
7084 * simple function bind
7085 * @param {Function} fn
7086 * @param {Object} context
7087 * @returns {Function}
7088 */
7089
7090
7091function bindFn(fn, context) {
7092 return function boundFn() {
7093 return fn.apply(context, arguments);
7094 };
7095}
7096/**
7097 * @private
7098 * Simple way to create a manager with a default set of recognizers.
7099 * @param {HTMLElement} element
7100 * @param {Object} [options]
7101 * @constructor
7102 */
7103
7104
7105var Hammer$2 = /*#__PURE__*/function () {
7106 var Hammer =
7107 /**
7108 * @private
7109 * @const {string}
7110 */
7111 function Hammer(element, options) {
7112 if (options === void 0) {
7113 options = {};
7114 }
7115
7116 return new Manager(element, _extends({
7117 recognizers: preset.concat()
7118 }, options));
7119 };
7120
7121 Hammer.VERSION = "2.0.17-rc";
7122 Hammer.DIRECTION_ALL = DIRECTION_ALL;
7123 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
7124 Hammer.DIRECTION_LEFT = DIRECTION_LEFT;
7125 Hammer.DIRECTION_RIGHT = DIRECTION_RIGHT;
7126 Hammer.DIRECTION_UP = DIRECTION_UP;
7127 Hammer.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL;
7128 Hammer.DIRECTION_VERTICAL = DIRECTION_VERTICAL;
7129 Hammer.DIRECTION_NONE = DIRECTION_NONE;
7130 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
7131 Hammer.INPUT_START = INPUT_START;
7132 Hammer.INPUT_MOVE = INPUT_MOVE;
7133 Hammer.INPUT_END = INPUT_END;
7134 Hammer.INPUT_CANCEL = INPUT_CANCEL;
7135 Hammer.STATE_POSSIBLE = STATE_POSSIBLE;
7136 Hammer.STATE_BEGAN = STATE_BEGAN;
7137 Hammer.STATE_CHANGED = STATE_CHANGED;
7138 Hammer.STATE_ENDED = STATE_ENDED;
7139 Hammer.STATE_RECOGNIZED = STATE_RECOGNIZED;
7140 Hammer.STATE_CANCELLED = STATE_CANCELLED;
7141 Hammer.STATE_FAILED = STATE_FAILED;
7142 Hammer.Manager = Manager;
7143 Hammer.Input = Input;
7144 Hammer.TouchAction = TouchAction;
7145 Hammer.TouchInput = TouchInput;
7146 Hammer.MouseInput = MouseInput;
7147 Hammer.PointerEventInput = PointerEventInput;
7148 Hammer.TouchMouseInput = TouchMouseInput;
7149 Hammer.SingleTouchInput = SingleTouchInput;
7150 Hammer.Recognizer = Recognizer;
7151 Hammer.AttrRecognizer = AttrRecognizer;
7152 Hammer.Tap = TapRecognizer;
7153 Hammer.Pan = PanRecognizer;
7154 Hammer.Swipe = SwipeRecognizer;
7155 Hammer.Pinch = PinchRecognizer;
7156 Hammer.Rotate = RotateRecognizer;
7157 Hammer.Press = PressRecognizer;
7158 Hammer.on = addEventListeners;
7159 Hammer.off = removeEventListeners;
7160 Hammer.each = each;
7161 Hammer.merge = merge$2;
7162 Hammer.extend = extend;
7163 Hammer.bindFn = bindFn;
7164 Hammer.assign = assign$1;
7165 Hammer.inherit = inherit;
7166 Hammer.bindFn = bindFn;
7167 Hammer.prefixed = prefixed;
7168 Hammer.toArray = toArray;
7169 Hammer.inArray = inArray;
7170 Hammer.uniqueArray = uniqueArray;
7171 Hammer.splitStr = splitStr;
7172 Hammer.boolOrFn = boolOrFn;
7173 Hammer.hasParent = hasParent;
7174 Hammer.addEventListeners = addEventListeners;
7175 Hammer.removeEventListeners = removeEventListeners;
7176 Hammer.defaults = assign$1({}, defaults, {
7177 preset: preset
7178 });
7179 return Hammer;
7180}(); // style loader but by script tag, not by the loader.
7181var RealHammer = Hammer$2;
7182
7183function _createForOfIteratorHelper$8(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$8(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
7184
7185function _unsupportedIterableToArray$8(o, minLen) { var _context21; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$8(o, minLen); var n = slice$1(_context21 = Object.prototype.toString.call(o)).call(_context21, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$8(o, minLen); }
7186
7187function _arrayLikeToArray$8(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
7188/**
7189 * Use this symbol to delete properies in deepObjectAssign.
7190 */
7191
7192var DELETE = symbol("DELETE");
7193/**
7194 * Pure version of deepObjectAssign, it doesn't modify any of it's arguments.
7195 *
7196 * @param base - The base object that fullfils the whole interface T.
7197 * @param updates - Updates that may change or delete props.
7198 *
7199 * @returns A brand new instance with all the supplied objects deeply merged.
7200 */
7201
7202
7203function pureDeepObjectAssign(base) {
7204 var _context;
7205
7206 for (var _len = arguments.length, updates = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
7207 updates[_key - 1] = arguments[_key];
7208 }
7209
7210 return deepObjectAssign.apply(void 0, concat(_context = [{}, base]).call(_context, updates));
7211}
7212/**
7213 * Deep version of object assign with additional deleting by the DELETE symbol.
7214 *
7215 * @param values - Objects to be deeply merged.
7216 *
7217 * @returns The first object from values.
7218 */
7219
7220
7221function deepObjectAssign() {
7222 var merged = deepObjectAssignNonentry.apply(void 0, arguments);
7223 stripDelete(merged);
7224 return merged;
7225}
7226/**
7227 * Deep version of object assign with additional deleting by the DELETE symbol.
7228 *
7229 * @remarks
7230 * This doesn't strip the DELETE symbols so they may end up in the final object.
7231 *
7232 * @param values - Objects to be deeply merged.
7233 *
7234 * @returns The first object from values.
7235 */
7236
7237
7238function deepObjectAssignNonentry() {
7239 for (var _len2 = arguments.length, values = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
7240 values[_key2] = arguments[_key2];
7241 }
7242
7243 if (values.length < 2) {
7244 return values[0];
7245 } else if (values.length > 2) {
7246 var _context2;
7247
7248 return deepObjectAssignNonentry.apply(void 0, concat(_context2 = [deepObjectAssign(values[0], values[1])]).call(_context2, _toConsumableArray(slice$1(values).call(values, 2))));
7249 }
7250
7251 var a = values[0];
7252 var b = values[1];
7253
7254 var _iterator = _createForOfIteratorHelper$8(ownKeys$5(b)),
7255 _step;
7256
7257 try {
7258 for (_iterator.s(); !(_step = _iterator.n()).done;) {
7259 var prop = _step.value;
7260 if (!Object.prototype.propertyIsEnumerable.call(b, prop)) ;else if (b[prop] === DELETE) {
7261 delete a[prop];
7262 } else if (a[prop] !== null && b[prop] !== null && _typeof(a[prop]) === "object" && _typeof(b[prop]) === "object" && !isArray$2(a[prop]) && !isArray$2(b[prop])) {
7263 a[prop] = deepObjectAssignNonentry(a[prop], b[prop]);
7264 } else {
7265 a[prop] = clone(b[prop]);
7266 }
7267 }
7268 } catch (err) {
7269 _iterator.e(err);
7270 } finally {
7271 _iterator.f();
7272 }
7273
7274 return a;
7275}
7276/**
7277 * Deep clone given object or array. In case of primitive simply return.
7278 *
7279 * @param a - Anything.
7280 *
7281 * @returns Deep cloned object/array or unchanged a.
7282 */
7283
7284
7285function clone(a) {
7286 if (isArray$2(a)) {
7287 return map$3(a).call(a, function (value) {
7288 return clone(value);
7289 });
7290 } else if (_typeof(a) === "object" && a !== null) {
7291 return deepObjectAssignNonentry({}, a);
7292 } else {
7293 return a;
7294 }
7295}
7296/**
7297 * Strip DELETE from given object.
7298 *
7299 * @param a - Object which may contain DELETE but won't after this is executed.
7300 */
7301
7302
7303function stripDelete(a) {
7304 for (var _i = 0, _Object$keys = keys$4(a); _i < _Object$keys.length; _i++) {
7305 var prop = _Object$keys[_i];
7306
7307 if (a[prop] === DELETE) {
7308 delete a[prop];
7309 } else if (_typeof(a[prop]) === "object" && a[prop] !== null) {
7310 stripDelete(a[prop]);
7311 }
7312 }
7313}
7314/**
7315 * Seedable, fast and reasonably good (not crypto but more than okay for our
7316 * needs) random number generator.
7317 *
7318 * @remarks
7319 * Adapted from {@link https://web.archive.org/web/20110429100736/http://baagoe.com:80/en/RandomMusings/javascript}.
7320 * Original algorithm created by Johannes Baagøe \<baagoe\@baagoe.com\> in 2010.
7321 */
7322
7323/**
7324 * Create a seeded pseudo random generator based on Alea by Johannes Baagøe.
7325 *
7326 * @param seed - All supplied arguments will be used as a seed. In case nothing
7327 * is supplied the current time will be used to seed the generator.
7328 *
7329 * @returns A ready to use seeded generator.
7330 */
7331
7332
7333function Alea() {
7334 for (var _len3 = arguments.length, seed = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
7335 seed[_key3] = arguments[_key3];
7336 }
7337
7338 return AleaImplementation(seed.length ? seed : [now$1()]);
7339}
7340/**
7341 * An implementation of [[Alea]] without user input validation.
7342 *
7343 * @param seed - The data that will be used to seed the generator.
7344 *
7345 * @returns A ready to use seeded generator.
7346 */
7347
7348
7349function AleaImplementation(seed) {
7350 var _mashSeed = mashSeed(seed),
7351 _mashSeed2 = _slicedToArray(_mashSeed, 3),
7352 s0 = _mashSeed2[0],
7353 s1 = _mashSeed2[1],
7354 s2 = _mashSeed2[2];
7355
7356 var c = 1;
7357
7358 var random = function random() {
7359 var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
7360
7361 s0 = s1;
7362 s1 = s2;
7363 return s2 = t - (c = t | 0);
7364 };
7365
7366 random.uint32 = function () {
7367 return random() * 0x100000000;
7368 }; // 2^32
7369
7370
7371 random.fract53 = function () {
7372 return random() + (random() * 0x200000 | 0) * 1.1102230246251565e-16;
7373 }; // 2^-53
7374
7375
7376 random.algorithm = "Alea";
7377 random.seed = seed;
7378 random.version = "0.9";
7379 return random;
7380}
7381/**
7382 * Turn arbitrary data into values [[AleaImplementation]] can use to generate
7383 * random numbers.
7384 *
7385 * @param seed - Arbitrary data that will be used as the seed.
7386 *
7387 * @returns Three numbers to use as initial values for [[AleaImplementation]].
7388 */
7389
7390
7391function mashSeed() {
7392 var mash = Mash();
7393 var s0 = mash(" ");
7394 var s1 = mash(" ");
7395 var s2 = mash(" ");
7396
7397 for (var i = 0; i < arguments.length; i++) {
7398 s0 -= mash(i < 0 || arguments.length <= i ? undefined : arguments[i]);
7399
7400 if (s0 < 0) {
7401 s0 += 1;
7402 }
7403
7404 s1 -= mash(i < 0 || arguments.length <= i ? undefined : arguments[i]);
7405
7406 if (s1 < 0) {
7407 s1 += 1;
7408 }
7409
7410 s2 -= mash(i < 0 || arguments.length <= i ? undefined : arguments[i]);
7411
7412 if (s2 < 0) {
7413 s2 += 1;
7414 }
7415 }
7416
7417 return [s0, s1, s2];
7418}
7419/**
7420 * Create a new mash function.
7421 *
7422 * @returns A nonpure function that takes arbitrary [[Mashable]] data and turns
7423 * them into numbers.
7424 */
7425
7426
7427function Mash() {
7428 var n = 0xefc8249d;
7429 return function (data) {
7430 var string = data.toString();
7431
7432 for (var i = 0; i < string.length; i++) {
7433 n += string.charCodeAt(i);
7434 var h = 0.02519603282416938 * n;
7435 n = h >>> 0;
7436 h -= n;
7437 h *= n;
7438 n = h >>> 0;
7439 h -= n;
7440 n += h * 0x100000000; // 2^32
7441 }
7442
7443 return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
7444 };
7445}
7446/**
7447 * Setup a mock hammer.js object, for unit testing.
7448 *
7449 * Inspiration: https://github.com/uber/deck.gl/pull/658
7450 *
7451 * @returns {{on: noop, off: noop, destroy: noop, emit: noop, get: get}}
7452 */
7453
7454
7455function hammerMock() {
7456 var noop = function noop() {};
7457
7458 return {
7459 on: noop,
7460 off: noop,
7461 destroy: noop,
7462 emit: noop,
7463 get: function get() {
7464 return {
7465 set: noop
7466 };
7467 }
7468 };
7469}
7470
7471var Hammer = typeof window !== "undefined" ? window.Hammer || RealHammer : function () {
7472 // hammer.js is only available in a browser, not in node.js. Replacing it with a mock object.
7473 return hammerMock();
7474};
7475/**
7476 * Turn an element into an clickToUse element.
7477 * When not active, the element has a transparent overlay. When the overlay is
7478 * clicked, the mode is changed to active.
7479 * When active, the element is displayed with a blue border around it, and
7480 * the interactive contents of the element can be used. When clicked outside
7481 * the element, the elements mode is changed to inactive.
7482 *
7483 * @param {Element} container
7484 * @class Activator
7485 */
7486
7487function Activator(container) {
7488 var _this = this,
7489 _context3;
7490
7491 this._cleanupQueue = [];
7492 this.active = false;
7493 this._dom = {
7494 container: container,
7495 overlay: document.createElement("div")
7496 };
7497
7498 this._dom.overlay.classList.add("vis-overlay");
7499
7500 this._dom.container.appendChild(this._dom.overlay);
7501
7502 this._cleanupQueue.push(function () {
7503 _this._dom.overlay.parentNode.removeChild(_this._dom.overlay);
7504 });
7505
7506 var hammer = Hammer(this._dom.overlay);
7507 hammer.on("tap", bind$6(_context3 = this._onTapOverlay).call(_context3, this));
7508
7509 this._cleanupQueue.push(function () {
7510 hammer.destroy(); // FIXME: cleaning up hammer instances doesn't work (Timeline not removed
7511 // from memory)
7512 }); // block all touch events (except tap)
7513
7514
7515 var events = ["tap", "doubletap", "press", "pinch", "pan", "panstart", "panmove", "panend"];
7516
7517 forEach$2(events).call(events, function (event) {
7518 hammer.on(event, function (event) {
7519 event.srcEvent.stopPropagation();
7520 });
7521 }); // attach a click event to the window, in order to deactivate when clicking outside the timeline
7522
7523
7524 if (document && document.body) {
7525 this._onClick = function (event) {
7526 if (!_hasParent(event.target, container)) {
7527 _this.deactivate();
7528 }
7529 };
7530
7531 document.body.addEventListener("click", this._onClick);
7532
7533 this._cleanupQueue.push(function () {
7534 document.body.removeEventListener("click", _this._onClick);
7535 });
7536 } // prepare escape key listener for deactivating when active
7537
7538
7539 this._escListener = function (event) {
7540 if ("key" in event ? event.key === "Escape" : event.keyCode === 27
7541 /* the keyCode is for IE11 */
7542 ) {
7543 _this.deactivate();
7544 }
7545 };
7546} // turn into an event emitter
7547
7548
7549Emitter(Activator.prototype); // The currently active activator
7550
7551Activator.current = null;
7552/**
7553 * Destroy the activator. Cleans up all created DOM and event listeners
7554 */
7555
7556Activator.prototype.destroy = function () {
7557 var _context4, _context5;
7558
7559 this.deactivate();
7560
7561 var _iterator2 = _createForOfIteratorHelper$8(reverse(_context4 = splice(_context5 = this._cleanupQueue).call(_context5, 0)).call(_context4)),
7562 _step2;
7563
7564 try {
7565 for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
7566 var callback = _step2.value;
7567 callback();
7568 }
7569 } catch (err) {
7570 _iterator2.e(err);
7571 } finally {
7572 _iterator2.f();
7573 }
7574};
7575/**
7576 * Activate the element
7577 * Overlay is hidden, element is decorated with a blue shadow border
7578 */
7579
7580
7581Activator.prototype.activate = function () {
7582 // we allow only one active activator at a time
7583 if (Activator.current) {
7584 Activator.current.deactivate();
7585 }
7586
7587 Activator.current = this;
7588 this.active = true;
7589 this._dom.overlay.style.display = "none";
7590
7591 this._dom.container.classList.add("vis-active");
7592
7593 this.emit("change");
7594 this.emit("activate"); // ugly hack: bind ESC after emitting the events, as the Network rebinds all
7595 // keyboard events on a 'change' event
7596
7597 document.body.addEventListener("keydown", this._escListener);
7598};
7599/**
7600 * Deactivate the element
7601 * Overlay is displayed on top of the element
7602 */
7603
7604
7605Activator.prototype.deactivate = function () {
7606 this.active = false;
7607 this._dom.overlay.style.display = "block";
7608
7609 this._dom.container.classList.remove("vis-active");
7610
7611 document.body.removeEventListener("keydown", this._escListener);
7612 this.emit("change");
7613 this.emit("deactivate");
7614};
7615/**
7616 * Handle a tap event: activate the container
7617 *
7618 * @param {Event} event The event
7619 * @private
7620 */
7621
7622
7623Activator.prototype._onTapOverlay = function (event) {
7624 // activate the container
7625 this.activate();
7626 event.srcEvent.stopPropagation();
7627};
7628/**
7629 * Test whether the element has the requested parent element somewhere in
7630 * its chain of parent nodes.
7631 *
7632 * @param {HTMLElement} element
7633 * @param {HTMLElement} parent
7634 * @returns {boolean} Returns true when the parent is found somewhere in the
7635 * chain of parent nodes.
7636 * @private
7637 */
7638
7639
7640function _hasParent(element, parent) {
7641 while (element) {
7642 if (element === parent) {
7643 return true;
7644 }
7645
7646 element = element.parentNode;
7647 }
7648
7649 return false;
7650} // utility functions
7651
7652var fullHexRE = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
7653var shortHexRE = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
7654var rgbRE = /^rgb\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *\)$/i;
7655var rgbaRE = /^rgba\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *([01]|0?\.\d+) *\)$/i;
7656/**
7657 * Remove everything in the DOM object.
7658 *
7659 * @param DOMobject - Node whose child nodes will be recursively deleted.
7660 */
7661
7662
7663function recursiveDOMDelete(DOMobject) {
7664 if (DOMobject) {
7665 while (DOMobject.hasChildNodes() === true) {
7666 var child = DOMobject.firstChild;
7667
7668 if (child) {
7669 recursiveDOMDelete(child);
7670 DOMobject.removeChild(child);
7671 }
7672 }
7673 }
7674}
7675/**
7676 * Test whether given object is a string.
7677 *
7678 * @param value - Input value of unknown type.
7679 *
7680 * @returns True if string, false otherwise.
7681 */
7682
7683
7684function isString(value) {
7685 return value instanceof String || typeof value === "string";
7686}
7687/**
7688 * Test whether given object is a object (not primitive or null).
7689 *
7690 * @param value - Input value of unknown type.
7691 *
7692 * @returns True if not null object, false otherwise.
7693 */
7694
7695
7696function isObject$6(value) {
7697 return _typeof(value) === "object" && value !== null;
7698}
7699/**
7700 * Copy property from b to a if property present in a.
7701 * If property in b explicitly set to null, delete it if `allowDeletion` set.
7702 *
7703 * Internal helper routine, should not be exported. Not added to `exports` for that reason.
7704 *
7705 * @param a - Target object.
7706 * @param b - Source object.
7707 * @param prop - Name of property to copy from b to a.
7708 * @param allowDeletion - If true, delete property in a if explicitly set to null in b.
7709 */
7710
7711
7712function copyOrDelete(a, b, prop, allowDeletion) {
7713 var doDeletion = false;
7714
7715 if (allowDeletion === true) {
7716 doDeletion = b[prop] === null && a[prop] !== undefined;
7717 }
7718
7719 if (doDeletion) {
7720 delete a[prop];
7721 } else {
7722 a[prop] = b[prop]; // Remember, this is a reference copy!
7723 }
7724}
7725/**
7726 * Fill an object with a possibly partially defined other object.
7727 *
7728 * Only copies values for the properties already present in a.
7729 * That means an object is not created on a property if only the b object has it.
7730 *
7731 * @param a - The object that will have it's properties updated.
7732 * @param b - The object with property updates.
7733 * @param allowDeletion - If true, delete properties in a that are explicitly set to null in b.
7734 */
7735
7736
7737function fillIfDefined(a, b) {
7738 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7739
7740 // NOTE: iteration of properties of a
7741 // NOTE: prototype properties iterated over as well
7742 for (var prop in a) {
7743 if (b[prop] !== undefined) {
7744 if (b[prop] === null || _typeof(b[prop]) !== "object") {
7745 // Note: typeof null === 'object'
7746 copyOrDelete(a, b, prop, allowDeletion);
7747 } else {
7748 var aProp = a[prop];
7749 var bProp = b[prop];
7750
7751 if (isObject$6(aProp) && isObject$6(bProp)) {
7752 fillIfDefined(aProp, bProp, allowDeletion);
7753 }
7754 }
7755 }
7756 }
7757}
7758/**
7759 * Extend object a with selected properties of object b.
7760 * Only properties with defined values are copied.
7761 *
7762 * @remarks
7763 * Previous version of this routine implied that multiple source objects could
7764 * be used; however, the implementation was **wrong**. Since multiple (\>1)
7765 * sources weren't used anywhere in the `vis.js` code, this has been removed
7766 *
7767 * @param props - Names of first-level properties to copy over.
7768 * @param a - Target object.
7769 * @param b - Source object.
7770 * @param allowDeletion - If true, delete property in a if explicitly set to null in b.
7771 *
7772 * @returns Argument a.
7773 */
7774
7775
7776function selectiveDeepExtend(props, a, b) {
7777 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7778
7779 // TODO: add support for Arrays to deepExtend
7780 if (isArray$2(b)) {
7781 throw new TypeError("Arrays are not supported by deepExtend");
7782 }
7783
7784 for (var p = 0; p < props.length; p++) {
7785 var prop = props[p];
7786
7787 if (Object.prototype.hasOwnProperty.call(b, prop)) {
7788 if (b[prop] && b[prop].constructor === Object) {
7789 if (a[prop] === undefined) {
7790 a[prop] = {};
7791 }
7792
7793 if (a[prop].constructor === Object) {
7794 deepExtend(a[prop], b[prop], false, allowDeletion);
7795 } else {
7796 copyOrDelete(a, b, prop, allowDeletion);
7797 }
7798 } else if (isArray$2(b[prop])) {
7799 throw new TypeError("Arrays are not supported by deepExtend");
7800 } else {
7801 copyOrDelete(a, b, prop, allowDeletion);
7802 }
7803 }
7804 }
7805
7806 return a;
7807}
7808/**
7809 * Extend object `a` with properties of object `b`, ignoring properties which
7810 * are explicitly specified to be excluded.
7811 *
7812 * @remarks
7813 * The properties of `b` are considered for copying. Properties which are
7814 * themselves objects are are also extended. Only properties with defined
7815 * values are copied.
7816 *
7817 * @param propsToExclude - Names of properties which should *not* be copied.
7818 * @param a - Object to extend.
7819 * @param b - Object to take properties from for extension.
7820 * @param allowDeletion - If true, delete properties in a that are explicitly
7821 * set to null in b.
7822 *
7823 * @returns Argument a.
7824 */
7825
7826
7827function selectiveNotDeepExtend(propsToExclude, a, b) {
7828 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7829
7830 // TODO: add support for Arrays to deepExtend
7831 // NOTE: array properties have an else-below; apparently, there is a problem here.
7832 if (isArray$2(b)) {
7833 throw new TypeError("Arrays are not supported by deepExtend");
7834 }
7835
7836 for (var prop in b) {
7837 if (!Object.prototype.hasOwnProperty.call(b, prop)) {
7838 continue;
7839 } // Handle local properties only
7840
7841
7842 if (includes(propsToExclude).call(propsToExclude, prop)) {
7843 continue;
7844 } // In exclusion list, skip
7845
7846
7847 if (b[prop] && b[prop].constructor === Object) {
7848 if (a[prop] === undefined) {
7849 a[prop] = {};
7850 }
7851
7852 if (a[prop].constructor === Object) {
7853 deepExtend(a[prop], b[prop]); // NOTE: allowDeletion not propagated!
7854 } else {
7855 copyOrDelete(a, b, prop, allowDeletion);
7856 }
7857 } else if (isArray$2(b[prop])) {
7858 a[prop] = [];
7859
7860 for (var i = 0; i < b[prop].length; i++) {
7861 a[prop].push(b[prop][i]);
7862 }
7863 } else {
7864 copyOrDelete(a, b, prop, allowDeletion);
7865 }
7866 }
7867
7868 return a;
7869}
7870/**
7871 * Deep extend an object a with the properties of object b.
7872 *
7873 * @param a - Target object.
7874 * @param b - Source object.
7875 * @param protoExtend - If true, the prototype values will also be extended.
7876 * (That is the options objects that inherit from others will also get the
7877 * inherited options).
7878 * @param allowDeletion - If true, the values of fields that are null will be deleted.
7879 *
7880 * @returns Argument a.
7881 */
7882
7883
7884function deepExtend(a, b) {
7885 var protoExtend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7886 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7887
7888 for (var prop in b) {
7889 if (Object.prototype.hasOwnProperty.call(b, prop) || protoExtend === true) {
7890 if (_typeof(b[prop]) === "object" && b[prop] !== null && getPrototypeOf$3(b[prop]) === Object.prototype) {
7891 if (a[prop] === undefined) {
7892 a[prop] = deepExtend({}, b[prop], protoExtend); // NOTE: allowDeletion not propagated!
7893 } else if (_typeof(a[prop]) === "object" && a[prop] !== null && getPrototypeOf$3(a[prop]) === Object.prototype) {
7894 deepExtend(a[prop], b[prop], protoExtend); // NOTE: allowDeletion not propagated!
7895 } else {
7896 copyOrDelete(a, b, prop, allowDeletion);
7897 }
7898 } else if (isArray$2(b[prop])) {
7899 var _context6;
7900
7901 a[prop] = slice$1(_context6 = b[prop]).call(_context6);
7902 } else {
7903 copyOrDelete(a, b, prop, allowDeletion);
7904 }
7905 }
7906 }
7907
7908 return a;
7909}
7910/**
7911 * Used to extend an array and copy it. This is used to propagate paths recursively.
7912 *
7913 * @param arr - First part.
7914 * @param newValue - The value to be aadded into the array.
7915 *
7916 * @returns A new array with all items from arr and newValue (which is last).
7917 */
7918
7919
7920function copyAndExtendArray(arr, newValue) {
7921 var _context7;
7922
7923 return concat(_context7 = []).call(_context7, _toConsumableArray(arr), [newValue]);
7924}
7925/**
7926 * Used to extend an array and copy it. This is used to propagate paths recursively.
7927 *
7928 * @param arr - The array to be copied.
7929 *
7930 * @returns Shallow copy of arr.
7931 */
7932
7933
7934function copyArray(arr) {
7935 return slice$1(arr).call(arr);
7936}
7937/**
7938 * Retrieve the absolute left value of a DOM element.
7939 *
7940 * @param elem - A dom element, for example a div.
7941 *
7942 * @returns The absolute left position of this element in the browser page.
7943 */
7944
7945
7946function getAbsoluteLeft(elem) {
7947 return elem.getBoundingClientRect().left;
7948}
7949/**
7950 * Retrieve the absolute top value of a DOM element.
7951 *
7952 * @param elem - A dom element, for example a div.
7953 *
7954 * @returns The absolute top position of this element in the browser page.
7955 */
7956
7957
7958function getAbsoluteTop(elem) {
7959 return elem.getBoundingClientRect().top;
7960}
7961/**
7962 * For each method for both arrays and objects.
7963 * In case of an array, the built-in Array.forEach() is applied (**No, it's not!**).
7964 * In case of an Object, the method loops over all properties of the object.
7965 *
7966 * @param object - An Object or Array to be iterated over.
7967 * @param callback - Array.forEach-like callback.
7968 */
7969
7970
7971function forEach$1(object, callback) {
7972 if (isArray$2(object)) {
7973 // array
7974 var len = object.length;
7975
7976 for (var i = 0; i < len; i++) {
7977 callback(object[i], i, object);
7978 }
7979 } else {
7980 // object
7981 for (var key in object) {
7982 if (Object.prototype.hasOwnProperty.call(object, key)) {
7983 callback(object[key], key, object);
7984 }
7985 }
7986 }
7987}
7988/**
7989 * Add and event listener. Works for all browsers.
7990 *
7991 * @param element - The element to bind the event listener to.
7992 * @param action - Same as Element.addEventListener(action, —, —).
7993 * @param listener - Same as Element.addEventListener(—, listener, —).
7994 * @param useCapture - Same as Element.addEventListener(—, —, useCapture).
7995 */
7996
7997
7998function addEventListener(element, action, listener, useCapture) {
7999 if (element.addEventListener) {
8000 var _context8;
8001
8002 if (useCapture === undefined) {
8003 useCapture = false;
8004 }
8005
8006 if (action === "mousewheel" && includes(_context8 = navigator.userAgent).call(_context8, "Firefox")) {
8007 action = "DOMMouseScroll"; // For Firefox
8008 }
8009
8010 element.addEventListener(action, listener, useCapture);
8011 } else {
8012 // @TODO: IE types? Does anyone care?
8013 element.attachEvent("on" + action, listener); // IE browsers
8014 }
8015}
8016/**
8017 * Remove an event listener from an element.
8018 *
8019 * @param element - The element to bind the event listener to.
8020 * @param action - Same as Element.removeEventListener(action, —, —).
8021 * @param listener - Same as Element.removeEventListener(—, listener, —).
8022 * @param useCapture - Same as Element.removeEventListener(—, —, useCapture).
8023 */
8024
8025
8026function removeEventListener(element, action, listener, useCapture) {
8027 if (element.removeEventListener) {
8028 var _context9;
8029
8030 // non-IE browsers
8031 if (useCapture === undefined) {
8032 useCapture = false;
8033 }
8034
8035 if (action === "mousewheel" && includes(_context9 = navigator.userAgent).call(_context9, "Firefox")) {
8036 action = "DOMMouseScroll"; // For Firefox
8037 }
8038
8039 element.removeEventListener(action, listener, useCapture);
8040 } else {
8041 // @TODO: IE types? Does anyone care?
8042 element.detachEvent("on" + action, listener); // IE browsers
8043 }
8044}
8045/**
8046 * Convert hex color string into RGB color object.
8047 *
8048 * @remarks
8049 * {@link http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb}
8050 *
8051 * @param hex - Hex color string (3 or 6 digits, with or without #).
8052 *
8053 * @returns RGB color object.
8054 */
8055
8056function hexToRGB(hex) {
8057 var result;
8058
8059 switch (hex.length) {
8060 case 3:
8061 case 4:
8062 result = shortHexRE.exec(hex);
8063 return result ? {
8064 r: _parseInt(result[1] + result[1], 16),
8065 g: _parseInt(result[2] + result[2], 16),
8066 b: _parseInt(result[3] + result[3], 16)
8067 } : null;
8068
8069 case 6:
8070 case 7:
8071 result = fullHexRE.exec(hex);
8072 return result ? {
8073 r: _parseInt(result[1], 16),
8074 g: _parseInt(result[2], 16),
8075 b: _parseInt(result[3], 16)
8076 } : null;
8077
8078 default:
8079 return null;
8080 }
8081}
8082/**
8083 * This function takes string color in hex or RGB format and adds the opacity, RGBA is passed through unchanged.
8084 *
8085 * @param color - The color string (hex, RGB, RGBA).
8086 * @param opacity - The new opacity.
8087 *
8088 * @returns RGBA string, for example 'rgba(255, 0, 127, 0.3)'.
8089 */
8090
8091
8092function overrideOpacity(color, opacity) {
8093 if (includes(color).call(color, "rgba")) {
8094 return color;
8095 } else if (includes(color).call(color, "rgb")) {
8096 var rgb = color.substr(indexOf(color).call(color, "(") + 1).replace(")", "").split(",");
8097 return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + opacity + ")";
8098 } else {
8099 var _rgb = hexToRGB(color);
8100
8101 if (_rgb == null) {
8102 return color;
8103 } else {
8104 return "rgba(" + _rgb.r + "," + _rgb.g + "," + _rgb.b + "," + opacity + ")";
8105 }
8106 }
8107}
8108/**
8109 * Convert RGB \<0, 255\> into hex color string.
8110 *
8111 * @param red - Red channel.
8112 * @param green - Green channel.
8113 * @param blue - Blue channel.
8114 *
8115 * @returns Hex color string (for example: '#0acdc0').
8116 */
8117
8118
8119function RGBToHex(red, green, blue) {
8120 var _context10;
8121
8122 return "#" + slice$1(_context10 = ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16)).call(_context10, 1);
8123}
8124/**
8125 * Parse a color property into an object with border, background, and highlight colors.
8126 *
8127 * @param inputColor - Shorthand color string or input color object.
8128 * @param defaultColor - Full color object to fill in missing values in inputColor.
8129 *
8130 * @returns Color object.
8131 */
8132
8133
8134function parseColor(inputColor, defaultColor) {
8135 if (isString(inputColor)) {
8136 var colorStr = inputColor;
8137
8138 if (isValidRGB(colorStr)) {
8139 var _context11;
8140
8141 var rgb = map$3(_context11 = colorStr.substr(4).substr(0, colorStr.length - 5).split(",")).call(_context11, function (value) {
8142 return _parseInt(value);
8143 });
8144
8145 colorStr = RGBToHex(rgb[0], rgb[1], rgb[2]);
8146 }
8147
8148 if (isValidHex(colorStr) === true) {
8149 var hsv = hexToHSV(colorStr);
8150 var lighterColorHSV = {
8151 h: hsv.h,
8152 s: hsv.s * 0.8,
8153 v: Math.min(1, hsv.v * 1.02)
8154 };
8155 var darkerColorHSV = {
8156 h: hsv.h,
8157 s: Math.min(1, hsv.s * 1.25),
8158 v: hsv.v * 0.8
8159 };
8160 var darkerColorHex = HSVToHex(darkerColorHSV.h, darkerColorHSV.s, darkerColorHSV.v);
8161 var lighterColorHex = HSVToHex(lighterColorHSV.h, lighterColorHSV.s, lighterColorHSV.v);
8162 return {
8163 background: colorStr,
8164 border: darkerColorHex,
8165 highlight: {
8166 background: lighterColorHex,
8167 border: darkerColorHex
8168 },
8169 hover: {
8170 background: lighterColorHex,
8171 border: darkerColorHex
8172 }
8173 };
8174 } else {
8175 return {
8176 background: colorStr,
8177 border: colorStr,
8178 highlight: {
8179 background: colorStr,
8180 border: colorStr
8181 },
8182 hover: {
8183 background: colorStr,
8184 border: colorStr
8185 }
8186 };
8187 }
8188 } else {
8189 if (defaultColor) {
8190 var color = {
8191 background: inputColor.background || defaultColor.background,
8192 border: inputColor.border || defaultColor.border,
8193 highlight: isString(inputColor.highlight) ? {
8194 border: inputColor.highlight,
8195 background: inputColor.highlight
8196 } : {
8197 background: inputColor.highlight && inputColor.highlight.background || defaultColor.highlight.background,
8198 border: inputColor.highlight && inputColor.highlight.border || defaultColor.highlight.border
8199 },
8200 hover: isString(inputColor.hover) ? {
8201 border: inputColor.hover,
8202 background: inputColor.hover
8203 } : {
8204 border: inputColor.hover && inputColor.hover.border || defaultColor.hover.border,
8205 background: inputColor.hover && inputColor.hover.background || defaultColor.hover.background
8206 }
8207 };
8208 return color;
8209 } else {
8210 var _color = {
8211 background: inputColor.background || undefined,
8212 border: inputColor.border || undefined,
8213 highlight: isString(inputColor.highlight) ? {
8214 border: inputColor.highlight,
8215 background: inputColor.highlight
8216 } : {
8217 background: inputColor.highlight && inputColor.highlight.background || undefined,
8218 border: inputColor.highlight && inputColor.highlight.border || undefined
8219 },
8220 hover: isString(inputColor.hover) ? {
8221 border: inputColor.hover,
8222 background: inputColor.hover
8223 } : {
8224 border: inputColor.hover && inputColor.hover.border || undefined,
8225 background: inputColor.hover && inputColor.hover.background || undefined
8226 }
8227 };
8228 return _color;
8229 }
8230 }
8231}
8232/**
8233 * Convert RGB \<0, 255\> into HSV object.
8234 *
8235 * @remarks
8236 * {@link http://www.javascripter.net/faq/rgb2hsv.htm}
8237 *
8238 * @param red - Red channel.
8239 * @param green - Green channel.
8240 * @param blue - Blue channel.
8241 *
8242 * @returns HSV color object.
8243 */
8244
8245
8246function RGBToHSV(red, green, blue) {
8247 red = red / 255;
8248 green = green / 255;
8249 blue = blue / 255;
8250 var minRGB = Math.min(red, Math.min(green, blue));
8251 var maxRGB = Math.max(red, Math.max(green, blue)); // Black-gray-white
8252
8253 if (minRGB === maxRGB) {
8254 return {
8255 h: 0,
8256 s: 0,
8257 v: minRGB
8258 };
8259 } // Colors other than black-gray-white:
8260
8261
8262 var d = red === minRGB ? green - blue : blue === minRGB ? red - green : blue - red;
8263 var h = red === minRGB ? 3 : blue === minRGB ? 1 : 5;
8264 var hue = 60 * (h - d / (maxRGB - minRGB)) / 360;
8265 var saturation = (maxRGB - minRGB) / maxRGB;
8266 var value = maxRGB;
8267 return {
8268 h: hue,
8269 s: saturation,
8270 v: value
8271 };
8272}
8273/**
8274 * Convert HSV \<0, 1\> into RGB color object.
8275 *
8276 * @remarks
8277 * {@link https://gist.github.com/mjijackson/5311256}
8278 *
8279 * @param h - Hue.
8280 * @param s - Saturation.
8281 * @param v - Value.
8282 *
8283 * @returns RGB color object.
8284 */
8285
8286
8287function HSVToRGB(h, s, v) {
8288 var r;
8289 var g;
8290 var b;
8291 var i = Math.floor(h * 6);
8292 var f = h * 6 - i;
8293 var p = v * (1 - s);
8294 var q = v * (1 - f * s);
8295 var t = v * (1 - (1 - f) * s);
8296
8297 switch (i % 6) {
8298 case 0:
8299 r = v, g = t, b = p;
8300 break;
8301
8302 case 1:
8303 r = q, g = v, b = p;
8304 break;
8305
8306 case 2:
8307 r = p, g = v, b = t;
8308 break;
8309
8310 case 3:
8311 r = p, g = q, b = v;
8312 break;
8313
8314 case 4:
8315 r = t, g = p, b = v;
8316 break;
8317
8318 case 5:
8319 r = v, g = p, b = q;
8320 break;
8321 }
8322
8323 return {
8324 r: Math.floor(r * 255),
8325 g: Math.floor(g * 255),
8326 b: Math.floor(b * 255)
8327 };
8328}
8329/**
8330 * Convert HSV \<0, 1\> into hex color string.
8331 *
8332 * @param h - Hue.
8333 * @param s - Saturation.
8334 * @param v - Value.
8335 *
8336 * @returns Hex color string.
8337 */
8338
8339
8340function HSVToHex(h, s, v) {
8341 var rgb = HSVToRGB(h, s, v);
8342 return RGBToHex(rgb.r, rgb.g, rgb.b);
8343}
8344/**
8345 * Convert hex color string into HSV \<0, 1\>.
8346 *
8347 * @param hex - Hex color string.
8348 *
8349 * @returns HSV color object.
8350 */
8351
8352
8353function hexToHSV(hex) {
8354 var rgb = hexToRGB(hex);
8355
8356 if (!rgb) {
8357 throw new TypeError("'".concat(hex, "' is not a valid color."));
8358 }
8359
8360 return RGBToHSV(rgb.r, rgb.g, rgb.b);
8361}
8362/**
8363 * Validate hex color string.
8364 *
8365 * @param hex - Unknown string that may contain a color.
8366 *
8367 * @returns True if the string is valid, false otherwise.
8368 */
8369
8370
8371function isValidHex(hex) {
8372 var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
8373 return isOk;
8374}
8375/**
8376 * Validate RGB color string.
8377 *
8378 * @param rgb - Unknown string that may contain a color.
8379 *
8380 * @returns True if the string is valid, false otherwise.
8381 */
8382
8383
8384function isValidRGB(rgb) {
8385 return rgbRE.test(rgb);
8386}
8387/**
8388 * Validate RGBA color string.
8389 *
8390 * @param rgba - Unknown string that may contain a color.
8391 *
8392 * @returns True if the string is valid, false otherwise.
8393 */
8394
8395
8396function isValidRGBA(rgba) {
8397 return rgbaRE.test(rgba);
8398}
8399/**
8400 * This recursively redirects the prototype of JSON objects to the referenceObject.
8401 * This is used for default options.
8402 *
8403 * @param referenceObject - The original object.
8404 *
8405 * @returns The Element if the referenceObject is an Element, or a new object inheriting from the referenceObject.
8406 */
8407
8408
8409function bridgeObject(referenceObject) {
8410 if (referenceObject === null || _typeof(referenceObject) !== "object") {
8411 return null;
8412 }
8413
8414 if (referenceObject instanceof Element) {
8415 // Avoid bridging DOM objects
8416 return referenceObject;
8417 }
8418
8419 var objectTo = create$4(referenceObject);
8420
8421 for (var i in referenceObject) {
8422 if (Object.prototype.hasOwnProperty.call(referenceObject, i)) {
8423 if (_typeof(referenceObject[i]) == "object") {
8424 objectTo[i] = bridgeObject(referenceObject[i]);
8425 }
8426 }
8427 }
8428
8429 return objectTo;
8430}
8431/**
8432 * This is used to set the options of subobjects in the options object.
8433 *
8434 * A requirement of these subobjects is that they have an 'enabled' element
8435 * which is optional for the user but mandatory for the program.
8436 *
8437 * The added value here of the merge is that option 'enabled' is set as required.
8438 *
8439 * @param mergeTarget - Either this.options or the options used for the groups.
8440 * @param options - Options.
8441 * @param option - Option key in the options argument.
8442 * @param globalOptions - Global options, passed in to determine value of option 'enabled'.
8443 */
8444
8445
8446function mergeOptions(mergeTarget, options, option) {
8447 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
8448
8449 // Local helpers
8450 var isPresent = function isPresent(obj) {
8451 return obj !== null && obj !== undefined;
8452 };
8453
8454 var isObject = function isObject(obj) {
8455 return obj !== null && _typeof(obj) === "object";
8456 }; // https://stackoverflow.com/a/34491287/1223531
8457
8458
8459 var isEmpty = function isEmpty(obj) {
8460 for (var x in obj) {
8461 if (Object.prototype.hasOwnProperty.call(obj, x)) {
8462 return false;
8463 }
8464 }
8465
8466 return true;
8467 }; // Guards
8468
8469
8470 if (!isObject(mergeTarget)) {
8471 throw new Error("Parameter mergeTarget must be an object");
8472 }
8473
8474 if (!isObject(options)) {
8475 throw new Error("Parameter options must be an object");
8476 }
8477
8478 if (!isPresent(option)) {
8479 throw new Error("Parameter option must have a value");
8480 }
8481
8482 if (!isObject(globalOptions)) {
8483 throw new Error("Parameter globalOptions must be an object");
8484 } //
8485 // Actual merge routine, separated from main logic
8486 // Only a single level of options is merged. Deeper levels are ref'd. This may actually be an issue.
8487 //
8488
8489
8490 var doMerge = function doMerge(target, options, option) {
8491 if (!isObject(target[option])) {
8492 target[option] = {};
8493 }
8494
8495 var src = options[option];
8496 var dst = target[option];
8497
8498 for (var prop in src) {
8499 if (Object.prototype.hasOwnProperty.call(src, prop)) {
8500 dst[prop] = src[prop];
8501 }
8502 }
8503 }; // Local initialization
8504
8505
8506 var srcOption = options[option];
8507 var globalPassed = isObject(globalOptions) && !isEmpty(globalOptions);
8508 var globalOption = globalPassed ? globalOptions[option] : undefined;
8509 var globalEnabled = globalOption ? globalOption.enabled : undefined; /////////////////////////////////////////
8510 // Main routine
8511 /////////////////////////////////////////
8512
8513 if (srcOption === undefined) {
8514 return; // Nothing to do
8515 }
8516
8517 if (typeof srcOption === "boolean") {
8518 if (!isObject(mergeTarget[option])) {
8519 mergeTarget[option] = {};
8520 }
8521
8522 mergeTarget[option].enabled = srcOption;
8523 return;
8524 }
8525
8526 if (srcOption === null && !isObject(mergeTarget[option])) {
8527 // If possible, explicit copy from globals
8528 if (isPresent(globalOption)) {
8529 mergeTarget[option] = create$4(globalOption);
8530 } else {
8531 return; // Nothing to do
8532 }
8533 }
8534
8535 if (!isObject(srcOption)) {
8536 return;
8537 } //
8538 // Ensure that 'enabled' is properly set. It is required internally
8539 // Note that the value from options will always overwrite the existing value
8540 //
8541
8542
8543 var enabled = true; // default value
8544
8545 if (srcOption.enabled !== undefined) {
8546 enabled = srcOption.enabled;
8547 } else {
8548 // Take from globals, if present
8549 if (globalEnabled !== undefined) {
8550 enabled = globalOption.enabled;
8551 }
8552 }
8553
8554 doMerge(mergeTarget, options, option);
8555 mergeTarget[option].enabled = enabled;
8556}
8557/*
8558 * Easing Functions.
8559 * Only considering the t value for the range [0, 1] => [0, 1].
8560 *
8561 * Inspiration: from http://gizma.com/easing/
8562 * https://gist.github.com/gre/1650294
8563 */
8564
8565
8566var easingFunctions = {
8567 /**
8568 * Provides no easing and no acceleration.
8569 *
8570 * @param t - Time.
8571 *
8572 * @returns Value at time t.
8573 */
8574 linear: function linear(t) {
8575 return t;
8576 },
8577
8578 /**
8579 * Accelerate from zero velocity.
8580 *
8581 * @param t - Time.
8582 *
8583 * @returns Value at time t.
8584 */
8585 easeInQuad: function easeInQuad(t) {
8586 return t * t;
8587 },
8588
8589 /**
8590 * Decelerate to zero velocity.
8591 *
8592 * @param t - Time.
8593 *
8594 * @returns Value at time t.
8595 */
8596 easeOutQuad: function easeOutQuad(t) {
8597 return t * (2 - t);
8598 },
8599
8600 /**
8601 * Accelerate until halfway, then decelerate.
8602 *
8603 * @param t - Time.
8604 *
8605 * @returns Value at time t.
8606 */
8607 easeInOutQuad: function easeInOutQuad(t) {
8608 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
8609 },
8610
8611 /**
8612 * Accelerate from zero velocity.
8613 *
8614 * @param t - Time.
8615 *
8616 * @returns Value at time t.
8617 */
8618 easeInCubic: function easeInCubic(t) {
8619 return t * t * t;
8620 },
8621
8622 /**
8623 * Decelerate to zero velocity.
8624 *
8625 * @param t - Time.
8626 *
8627 * @returns Value at time t.
8628 */
8629 easeOutCubic: function easeOutCubic(t) {
8630 return --t * t * t + 1;
8631 },
8632
8633 /**
8634 * Accelerate until halfway, then decelerate.
8635 *
8636 * @param t - Time.
8637 *
8638 * @returns Value at time t.
8639 */
8640 easeInOutCubic: function easeInOutCubic(t) {
8641 return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
8642 },
8643
8644 /**
8645 * Accelerate from zero velocity.
8646 *
8647 * @param t - Time.
8648 *
8649 * @returns Value at time t.
8650 */
8651 easeInQuart: function easeInQuart(t) {
8652 return t * t * t * t;
8653 },
8654
8655 /**
8656 * Decelerate to zero velocity.
8657 *
8658 * @param t - Time.
8659 *
8660 * @returns Value at time t.
8661 */
8662 easeOutQuart: function easeOutQuart(t) {
8663 return 1 - --t * t * t * t;
8664 },
8665
8666 /**
8667 * Accelerate until halfway, then decelerate.
8668 *
8669 * @param t - Time.
8670 *
8671 * @returns Value at time t.
8672 */
8673 easeInOutQuart: function easeInOutQuart(t) {
8674 return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
8675 },
8676
8677 /**
8678 * Accelerate from zero velocity.
8679 *
8680 * @param t - Time.
8681 *
8682 * @returns Value at time t.
8683 */
8684 easeInQuint: function easeInQuint(t) {
8685 return t * t * t * t * t;
8686 },
8687
8688 /**
8689 * Decelerate to zero velocity.
8690 *
8691 * @param t - Time.
8692 *
8693 * @returns Value at time t.
8694 */
8695 easeOutQuint: function easeOutQuint(t) {
8696 return 1 + --t * t * t * t * t;
8697 },
8698
8699 /**
8700 * Accelerate until halfway, then decelerate.
8701 *
8702 * @param t - Time.
8703 *
8704 * @returns Value at time t.
8705 */
8706 easeInOutQuint: function easeInOutQuint(t) {
8707 return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
8708 }
8709};
8710// It works only for single property objects,
8711// otherwise it combines all of the types in a union.
8712// export function topMost<K1 extends string, V1> (
8713// pile: Record<K1, undefined | V1>[],
8714// accessors: K1 | [K1]
8715// ): undefined | V1
8716// export function topMost<K1 extends string, K2 extends string, V1, V2> (
8717// pile: Record<K1, undefined | V1 | Record<K2, undefined | V2>>[],
8718// accessors: [K1, K2]
8719// ): undefined | V1 | V2
8720// export function topMost<K1 extends string, K2 extends string, K3 extends string, V1, V2, V3> (
8721// pile: Record<K1, undefined | V1 | Record<K2, undefined | V2 | Record<K3, undefined | V3>>>[],
8722// accessors: [K1, K2, K3]
8723// ): undefined | V1 | V2 | V3
8724
8725/**
8726 * Get the top most property value from a pile of objects.
8727 *
8728 * @param pile - Array of objects, no required format.
8729 * @param accessors - Array of property names.
8730 * For example `object['foo']['bar']` → `['foo', 'bar']`.
8731 *
8732 * @returns Value of the property with given accessors path from the first pile item where it's not undefined.
8733 */
8734
8735
8736function topMost(pile, accessors) {
8737 var candidate;
8738
8739 if (!isArray$2(accessors)) {
8740 accessors = [accessors];
8741 }
8742
8743 var _iterator3 = _createForOfIteratorHelper$8(pile),
8744 _step3;
8745
8746 try {
8747 for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
8748 var member = _step3.value;
8749
8750 if (member) {
8751 candidate = member[accessors[0]];
8752
8753 for (var i = 1; i < accessors.length; i++) {
8754 if (candidate) {
8755 candidate = candidate[accessors[i]];
8756 }
8757 }
8758
8759 if (typeof candidate !== "undefined") {
8760 break;
8761 }
8762 }
8763 }
8764 } catch (err) {
8765 _iterator3.e(err);
8766 } finally {
8767 _iterator3.f();
8768 }
8769
8770 return candidate;
8771}
8772
8773var htmlColors = {
8774 black: "#000000",
8775 navy: "#000080",
8776 darkblue: "#00008B",
8777 mediumblue: "#0000CD",
8778 blue: "#0000FF",
8779 darkgreen: "#006400",
8780 green: "#008000",
8781 teal: "#008080",
8782 darkcyan: "#008B8B",
8783 deepskyblue: "#00BFFF",
8784 darkturquoise: "#00CED1",
8785 mediumspringgreen: "#00FA9A",
8786 lime: "#00FF00",
8787 springgreen: "#00FF7F",
8788 aqua: "#00FFFF",
8789 cyan: "#00FFFF",
8790 midnightblue: "#191970",
8791 dodgerblue: "#1E90FF",
8792 lightseagreen: "#20B2AA",
8793 forestgreen: "#228B22",
8794 seagreen: "#2E8B57",
8795 darkslategray: "#2F4F4F",
8796 limegreen: "#32CD32",
8797 mediumseagreen: "#3CB371",
8798 turquoise: "#40E0D0",
8799 royalblue: "#4169E1",
8800 steelblue: "#4682B4",
8801 darkslateblue: "#483D8B",
8802 mediumturquoise: "#48D1CC",
8803 indigo: "#4B0082",
8804 darkolivegreen: "#556B2F",
8805 cadetblue: "#5F9EA0",
8806 cornflowerblue: "#6495ED",
8807 mediumaquamarine: "#66CDAA",
8808 dimgray: "#696969",
8809 slateblue: "#6A5ACD",
8810 olivedrab: "#6B8E23",
8811 slategray: "#708090",
8812 lightslategray: "#778899",
8813 mediumslateblue: "#7B68EE",
8814 lawngreen: "#7CFC00",
8815 chartreuse: "#7FFF00",
8816 aquamarine: "#7FFFD4",
8817 maroon: "#800000",
8818 purple: "#800080",
8819 olive: "#808000",
8820 gray: "#808080",
8821 skyblue: "#87CEEB",
8822 lightskyblue: "#87CEFA",
8823 blueviolet: "#8A2BE2",
8824 darkred: "#8B0000",
8825 darkmagenta: "#8B008B",
8826 saddlebrown: "#8B4513",
8827 darkseagreen: "#8FBC8F",
8828 lightgreen: "#90EE90",
8829 mediumpurple: "#9370D8",
8830 darkviolet: "#9400D3",
8831 palegreen: "#98FB98",
8832 darkorchid: "#9932CC",
8833 yellowgreen: "#9ACD32",
8834 sienna: "#A0522D",
8835 brown: "#A52A2A",
8836 darkgray: "#A9A9A9",
8837 lightblue: "#ADD8E6",
8838 greenyellow: "#ADFF2F",
8839 paleturquoise: "#AFEEEE",
8840 lightsteelblue: "#B0C4DE",
8841 powderblue: "#B0E0E6",
8842 firebrick: "#B22222",
8843 darkgoldenrod: "#B8860B",
8844 mediumorchid: "#BA55D3",
8845 rosybrown: "#BC8F8F",
8846 darkkhaki: "#BDB76B",
8847 silver: "#C0C0C0",
8848 mediumvioletred: "#C71585",
8849 indianred: "#CD5C5C",
8850 peru: "#CD853F",
8851 chocolate: "#D2691E",
8852 tan: "#D2B48C",
8853 lightgrey: "#D3D3D3",
8854 palevioletred: "#D87093",
8855 thistle: "#D8BFD8",
8856 orchid: "#DA70D6",
8857 goldenrod: "#DAA520",
8858 crimson: "#DC143C",
8859 gainsboro: "#DCDCDC",
8860 plum: "#DDA0DD",
8861 burlywood: "#DEB887",
8862 lightcyan: "#E0FFFF",
8863 lavender: "#E6E6FA",
8864 darksalmon: "#E9967A",
8865 violet: "#EE82EE",
8866 palegoldenrod: "#EEE8AA",
8867 lightcoral: "#F08080",
8868 khaki: "#F0E68C",
8869 aliceblue: "#F0F8FF",
8870 honeydew: "#F0FFF0",
8871 azure: "#F0FFFF",
8872 sandybrown: "#F4A460",
8873 wheat: "#F5DEB3",
8874 beige: "#F5F5DC",
8875 whitesmoke: "#F5F5F5",
8876 mintcream: "#F5FFFA",
8877 ghostwhite: "#F8F8FF",
8878 salmon: "#FA8072",
8879 antiquewhite: "#FAEBD7",
8880 linen: "#FAF0E6",
8881 lightgoldenrodyellow: "#FAFAD2",
8882 oldlace: "#FDF5E6",
8883 red: "#FF0000",
8884 fuchsia: "#FF00FF",
8885 magenta: "#FF00FF",
8886 deeppink: "#FF1493",
8887 orangered: "#FF4500",
8888 tomato: "#FF6347",
8889 hotpink: "#FF69B4",
8890 coral: "#FF7F50",
8891 darkorange: "#FF8C00",
8892 lightsalmon: "#FFA07A",
8893 orange: "#FFA500",
8894 lightpink: "#FFB6C1",
8895 pink: "#FFC0CB",
8896 gold: "#FFD700",
8897 peachpuff: "#FFDAB9",
8898 navajowhite: "#FFDEAD",
8899 moccasin: "#FFE4B5",
8900 bisque: "#FFE4C4",
8901 mistyrose: "#FFE4E1",
8902 blanchedalmond: "#FFEBCD",
8903 papayawhip: "#FFEFD5",
8904 lavenderblush: "#FFF0F5",
8905 seashell: "#FFF5EE",
8906 cornsilk: "#FFF8DC",
8907 lemonchiffon: "#FFFACD",
8908 floralwhite: "#FFFAF0",
8909 snow: "#FFFAFA",
8910 yellow: "#FFFF00",
8911 lightyellow: "#FFFFE0",
8912 ivory: "#FFFFF0",
8913 white: "#FFFFFF"
8914};
8915/**
8916 * @param {number} [pixelRatio=1]
8917 */
8918
8919var ColorPicker = /*#__PURE__*/function () {
8920 /**
8921 * @param {number} [pixelRatio=1]
8922 */
8923 function ColorPicker() {
8924 var pixelRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
8925
8926 _classCallCheck(this, ColorPicker);
8927
8928 this.pixelRatio = pixelRatio;
8929 this.generated = false;
8930 this.centerCoordinates = {
8931 x: 289 / 2,
8932 y: 289 / 2
8933 };
8934 this.r = 289 * 0.49;
8935 this.color = {
8936 r: 255,
8937 g: 255,
8938 b: 255,
8939 a: 1.0
8940 };
8941 this.hueCircle = undefined;
8942 this.initialColor = {
8943 r: 255,
8944 g: 255,
8945 b: 255,
8946 a: 1.0
8947 };
8948 this.previousColor = undefined;
8949 this.applied = false; // bound by
8950
8951 this.updateCallback = function () {};
8952
8953 this.closeCallback = function () {}; // create all DOM elements
8954
8955
8956 this._create();
8957 }
8958 /**
8959 * this inserts the colorPicker into a div from the DOM
8960 *
8961 * @param {Element} container
8962 */
8963
8964
8965 _createClass(ColorPicker, [{
8966 key: "insertTo",
8967 value: function insertTo(container) {
8968 if (this.hammer !== undefined) {
8969 this.hammer.destroy();
8970 this.hammer = undefined;
8971 }
8972
8973 this.container = container;
8974 this.container.appendChild(this.frame);
8975
8976 this._bindHammer();
8977
8978 this._setSize();
8979 }
8980 /**
8981 * the callback is executed on apply and save. Bind it to the application
8982 *
8983 * @param {Function} callback
8984 */
8985
8986 }, {
8987 key: "setUpdateCallback",
8988 value: function setUpdateCallback(callback) {
8989 if (typeof callback === "function") {
8990 this.updateCallback = callback;
8991 } else {
8992 throw new Error("Function attempted to set as colorPicker update callback is not a function.");
8993 }
8994 }
8995 /**
8996 * the callback is executed on apply and save. Bind it to the application
8997 *
8998 * @param {Function} callback
8999 */
9000
9001 }, {
9002 key: "setCloseCallback",
9003 value: function setCloseCallback(callback) {
9004 if (typeof callback === "function") {
9005 this.closeCallback = callback;
9006 } else {
9007 throw new Error("Function attempted to set as colorPicker closing callback is not a function.");
9008 }
9009 }
9010 /**
9011 *
9012 * @param {string} color
9013 * @returns {string}
9014 * @private
9015 */
9016
9017 }, {
9018 key: "_isColorString",
9019 value: function _isColorString(color) {
9020 if (typeof color === "string") {
9021 return htmlColors[color];
9022 }
9023 }
9024 /**
9025 * Set the color of the colorPicker
9026 * Supported formats:
9027 * 'red' --> HTML color string
9028 * '#ffffff' --> hex string
9029 * 'rgb(255,255,255)' --> rgb string
9030 * 'rgba(255,255,255,1.0)' --> rgba string
9031 * {r:255,g:255,b:255} --> rgb object
9032 * {r:255,g:255,b:255,a:1.0} --> rgba object
9033 *
9034 * @param {string | object} color
9035 * @param {boolean} [setInitial=true]
9036 */
9037
9038 }, {
9039 key: "setColor",
9040 value: function setColor(color) {
9041 var setInitial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
9042
9043 if (color === "none") {
9044 return;
9045 }
9046
9047 var rgba; // if a html color shorthand is used, convert to hex
9048
9049 var htmlColor = this._isColorString(color);
9050
9051 if (htmlColor !== undefined) {
9052 color = htmlColor;
9053 } // check format
9054
9055
9056 if (isString(color) === true) {
9057 if (isValidRGB(color) === true) {
9058 var rgbaArray = color.substr(4).substr(0, color.length - 5).split(",");
9059 rgba = {
9060 r: rgbaArray[0],
9061 g: rgbaArray[1],
9062 b: rgbaArray[2],
9063 a: 1.0
9064 };
9065 } else if (isValidRGBA(color) === true) {
9066 var _rgbaArray = color.substr(5).substr(0, color.length - 6).split(",");
9067
9068 rgba = {
9069 r: _rgbaArray[0],
9070 g: _rgbaArray[1],
9071 b: _rgbaArray[2],
9072 a: _rgbaArray[3]
9073 };
9074 } else if (isValidHex(color) === true) {
9075 var rgbObj = hexToRGB(color);
9076 rgba = {
9077 r: rgbObj.r,
9078 g: rgbObj.g,
9079 b: rgbObj.b,
9080 a: 1.0
9081 };
9082 }
9083 } else {
9084 if (color instanceof Object) {
9085 if (color.r !== undefined && color.g !== undefined && color.b !== undefined) {
9086 var alpha = color.a !== undefined ? color.a : "1.0";
9087 rgba = {
9088 r: color.r,
9089 g: color.g,
9090 b: color.b,
9091 a: alpha
9092 };
9093 }
9094 }
9095 } // set color
9096
9097
9098 if (rgba === undefined) {
9099 throw new Error("Unknown color passed to the colorPicker. Supported are strings: rgb, hex, rgba. Object: rgb ({r:r,g:g,b:b,[a:a]}). Supplied: " + stringify$1(color));
9100 } else {
9101 this._setColor(rgba, setInitial);
9102 }
9103 }
9104 /**
9105 * this shows the color picker.
9106 * The hue circle is constructed once and stored.
9107 */
9108
9109 }, {
9110 key: "show",
9111 value: function show() {
9112 if (this.closeCallback !== undefined) {
9113 this.closeCallback();
9114 this.closeCallback = undefined;
9115 }
9116
9117 this.applied = false;
9118 this.frame.style.display = "block";
9119
9120 this._generateHueCircle();
9121 } // ------------------------------------------ PRIVATE ----------------------------- //
9122
9123 /**
9124 * Hide the picker. Is called by the cancel button.
9125 * Optional boolean to store the previous color for easy access later on.
9126 *
9127 * @param {boolean} [storePrevious=true]
9128 * @private
9129 */
9130
9131 }, {
9132 key: "_hide",
9133 value: function _hide() {
9134 var _this2 = this;
9135
9136 var storePrevious = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
9137
9138 // store the previous color for next time;
9139 if (storePrevious === true) {
9140 this.previousColor = assign$2({}, this.color);
9141 }
9142
9143 if (this.applied === true) {
9144 this.updateCallback(this.initialColor);
9145 }
9146
9147 this.frame.style.display = "none"; // call the closing callback, restoring the onclick method.
9148 // this is in a setTimeout because it will trigger the show again before the click is done.
9149
9150 setTimeout$1(function () {
9151 if (_this2.closeCallback !== undefined) {
9152 _this2.closeCallback();
9153
9154 _this2.closeCallback = undefined;
9155 }
9156 }, 0);
9157 }
9158 /**
9159 * bound to the save button. Saves and hides.
9160 *
9161 * @private
9162 */
9163
9164 }, {
9165 key: "_save",
9166 value: function _save() {
9167 this.updateCallback(this.color);
9168 this.applied = false;
9169
9170 this._hide();
9171 }
9172 /**
9173 * Bound to apply button. Saves but does not close. Is undone by the cancel button.
9174 *
9175 * @private
9176 */
9177
9178 }, {
9179 key: "_apply",
9180 value: function _apply() {
9181 this.applied = true;
9182 this.updateCallback(this.color);
9183
9184 this._updatePicker(this.color);
9185 }
9186 /**
9187 * load the color from the previous session.
9188 *
9189 * @private
9190 */
9191
9192 }, {
9193 key: "_loadLast",
9194 value: function _loadLast() {
9195 if (this.previousColor !== undefined) {
9196 this.setColor(this.previousColor, false);
9197 } else {
9198 alert("There is no last color to load...");
9199 }
9200 }
9201 /**
9202 * set the color, place the picker
9203 *
9204 * @param {object} rgba
9205 * @param {boolean} [setInitial=true]
9206 * @private
9207 */
9208
9209 }, {
9210 key: "_setColor",
9211 value: function _setColor(rgba) {
9212 var setInitial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
9213
9214 // store the initial color
9215 if (setInitial === true) {
9216 this.initialColor = assign$2({}, rgba);
9217 }
9218
9219 this.color = rgba;
9220 var hsv = RGBToHSV(rgba.r, rgba.g, rgba.b);
9221 var angleConvert = 2 * Math.PI;
9222 var radius = this.r * hsv.s;
9223 var x = this.centerCoordinates.x + radius * Math.sin(angleConvert * hsv.h);
9224 var y = this.centerCoordinates.y + radius * Math.cos(angleConvert * hsv.h);
9225 this.colorPickerSelector.style.left = x - 0.5 * this.colorPickerSelector.clientWidth + "px";
9226 this.colorPickerSelector.style.top = y - 0.5 * this.colorPickerSelector.clientHeight + "px";
9227
9228 this._updatePicker(rgba);
9229 }
9230 /**
9231 * bound to opacity control
9232 *
9233 * @param {number} value
9234 * @private
9235 */
9236
9237 }, {
9238 key: "_setOpacity",
9239 value: function _setOpacity(value) {
9240 this.color.a = value / 100;
9241
9242 this._updatePicker(this.color);
9243 }
9244 /**
9245 * bound to brightness control
9246 *
9247 * @param {number} value
9248 * @private
9249 */
9250
9251 }, {
9252 key: "_setBrightness",
9253 value: function _setBrightness(value) {
9254 var hsv = RGBToHSV(this.color.r, this.color.g, this.color.b);
9255 hsv.v = value / 100;
9256 var rgba = HSVToRGB(hsv.h, hsv.s, hsv.v);
9257 rgba["a"] = this.color.a;
9258 this.color = rgba;
9259
9260 this._updatePicker();
9261 }
9262 /**
9263 * update the color picker. A black circle overlays the hue circle to mimic the brightness decreasing.
9264 *
9265 * @param {object} rgba
9266 * @private
9267 */
9268
9269 }, {
9270 key: "_updatePicker",
9271 value: function _updatePicker() {
9272 var rgba = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.color;
9273 var hsv = RGBToHSV(rgba.r, rgba.g, rgba.b);
9274 var ctx = this.colorPickerCanvas.getContext("2d");
9275
9276 if (this.pixelRation === undefined) {
9277 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
9278 }
9279
9280 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); // clear the canvas
9281
9282 var w = this.colorPickerCanvas.clientWidth;
9283 var h = this.colorPickerCanvas.clientHeight;
9284 ctx.clearRect(0, 0, w, h);
9285 ctx.putImageData(this.hueCircle, 0, 0);
9286 ctx.fillStyle = "rgba(0,0,0," + (1 - hsv.v) + ")";
9287 ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
9288
9289 fill(ctx).call(ctx);
9290
9291 this.brightnessRange.value = 100 * hsv.v;
9292 this.opacityRange.value = 100 * rgba.a;
9293 this.initialColorDiv.style.backgroundColor = "rgba(" + this.initialColor.r + "," + this.initialColor.g + "," + this.initialColor.b + "," + this.initialColor.a + ")";
9294 this.newColorDiv.style.backgroundColor = "rgba(" + this.color.r + "," + this.color.g + "," + this.color.b + "," + this.color.a + ")";
9295 }
9296 /**
9297 * used by create to set the size of the canvas.
9298 *
9299 * @private
9300 */
9301
9302 }, {
9303 key: "_setSize",
9304 value: function _setSize() {
9305 this.colorPickerCanvas.style.width = "100%";
9306 this.colorPickerCanvas.style.height = "100%";
9307 this.colorPickerCanvas.width = 289 * this.pixelRatio;
9308 this.colorPickerCanvas.height = 289 * this.pixelRatio;
9309 }
9310 /**
9311 * create all dom elements
9312 * TODO: cleanup, lots of similar dom elements
9313 *
9314 * @private
9315 */
9316
9317 }, {
9318 key: "_create",
9319 value: function _create() {
9320 var _context16, _context17, _context18, _context19;
9321
9322 this.frame = document.createElement("div");
9323 this.frame.className = "vis-color-picker";
9324 this.colorPickerDiv = document.createElement("div");
9325 this.colorPickerSelector = document.createElement("div");
9326 this.colorPickerSelector.className = "vis-selector";
9327 this.colorPickerDiv.appendChild(this.colorPickerSelector);
9328 this.colorPickerCanvas = document.createElement("canvas");
9329 this.colorPickerDiv.appendChild(this.colorPickerCanvas);
9330
9331 if (!this.colorPickerCanvas.getContext) {
9332 var noCanvas = document.createElement("DIV");
9333 noCanvas.style.color = "red";
9334 noCanvas.style.fontWeight = "bold";
9335 noCanvas.style.padding = "10px";
9336 noCanvas.innerText = "Error: your browser does not support HTML canvas";
9337 this.colorPickerCanvas.appendChild(noCanvas);
9338 } else {
9339 var ctx = this.colorPickerCanvas.getContext("2d");
9340 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
9341 this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
9342 }
9343
9344 this.colorPickerDiv.className = "vis-color";
9345 this.opacityDiv = document.createElement("div");
9346 this.opacityDiv.className = "vis-opacity";
9347 this.brightnessDiv = document.createElement("div");
9348 this.brightnessDiv.className = "vis-brightness";
9349 this.arrowDiv = document.createElement("div");
9350 this.arrowDiv.className = "vis-arrow";
9351 this.opacityRange = document.createElement("input");
9352
9353 try {
9354 this.opacityRange.type = "range"; // Not supported on IE9
9355
9356 this.opacityRange.min = "0";
9357 this.opacityRange.max = "100";
9358 } catch (err) {// TODO: Add some error handling.
9359 }
9360
9361 this.opacityRange.value = "100";
9362 this.opacityRange.className = "vis-range";
9363 this.brightnessRange = document.createElement("input");
9364
9365 try {
9366 this.brightnessRange.type = "range"; // Not supported on IE9
9367
9368 this.brightnessRange.min = "0";
9369 this.brightnessRange.max = "100";
9370 } catch (err) {// TODO: Add some error handling.
9371 }
9372
9373 this.brightnessRange.value = "100";
9374 this.brightnessRange.className = "vis-range";
9375 this.opacityDiv.appendChild(this.opacityRange);
9376 this.brightnessDiv.appendChild(this.brightnessRange);
9377 var me = this;
9378
9379 this.opacityRange.onchange = function () {
9380 me._setOpacity(this.value);
9381 };
9382
9383 this.opacityRange.oninput = function () {
9384 me._setOpacity(this.value);
9385 };
9386
9387 this.brightnessRange.onchange = function () {
9388 me._setBrightness(this.value);
9389 };
9390
9391 this.brightnessRange.oninput = function () {
9392 me._setBrightness(this.value);
9393 };
9394
9395 this.brightnessLabel = document.createElement("div");
9396 this.brightnessLabel.className = "vis-label vis-brightness";
9397 this.brightnessLabel.innerText = "brightness:";
9398 this.opacityLabel = document.createElement("div");
9399 this.opacityLabel.className = "vis-label vis-opacity";
9400 this.opacityLabel.innerText = "opacity:";
9401 this.newColorDiv = document.createElement("div");
9402 this.newColorDiv.className = "vis-new-color";
9403 this.newColorDiv.innerText = "new";
9404 this.initialColorDiv = document.createElement("div");
9405 this.initialColorDiv.className = "vis-initial-color";
9406 this.initialColorDiv.innerText = "initial";
9407 this.cancelButton = document.createElement("div");
9408 this.cancelButton.className = "vis-button vis-cancel";
9409 this.cancelButton.innerText = "cancel";
9410 this.cancelButton.onclick = bind$6(_context16 = this._hide).call(_context16, this, false);
9411 this.applyButton = document.createElement("div");
9412 this.applyButton.className = "vis-button vis-apply";
9413 this.applyButton.innerText = "apply";
9414 this.applyButton.onclick = bind$6(_context17 = this._apply).call(_context17, this);
9415 this.saveButton = document.createElement("div");
9416 this.saveButton.className = "vis-button vis-save";
9417 this.saveButton.innerText = "save";
9418 this.saveButton.onclick = bind$6(_context18 = this._save).call(_context18, this);
9419 this.loadButton = document.createElement("div");
9420 this.loadButton.className = "vis-button vis-load";
9421 this.loadButton.innerText = "load last";
9422 this.loadButton.onclick = bind$6(_context19 = this._loadLast).call(_context19, this);
9423 this.frame.appendChild(this.colorPickerDiv);
9424 this.frame.appendChild(this.arrowDiv);
9425 this.frame.appendChild(this.brightnessLabel);
9426 this.frame.appendChild(this.brightnessDiv);
9427 this.frame.appendChild(this.opacityLabel);
9428 this.frame.appendChild(this.opacityDiv);
9429 this.frame.appendChild(this.newColorDiv);
9430 this.frame.appendChild(this.initialColorDiv);
9431 this.frame.appendChild(this.cancelButton);
9432 this.frame.appendChild(this.applyButton);
9433 this.frame.appendChild(this.saveButton);
9434 this.frame.appendChild(this.loadButton);
9435 }
9436 /**
9437 * bind hammer to the color picker
9438 *
9439 * @private
9440 */
9441
9442 }, {
9443 key: "_bindHammer",
9444 value: function _bindHammer() {
9445 var _this3 = this;
9446
9447 this.drag = {};
9448 this.pinch = {};
9449 this.hammer = new Hammer(this.colorPickerCanvas);
9450 this.hammer.get("pinch").set({
9451 enable: true
9452 });
9453 this.hammer.on("hammer.input", function (event) {
9454 if (event.isFirst) {
9455 _this3._moveSelector(event);
9456 }
9457 });
9458 this.hammer.on("tap", function (event) {
9459 _this3._moveSelector(event);
9460 });
9461 this.hammer.on("panstart", function (event) {
9462 _this3._moveSelector(event);
9463 });
9464 this.hammer.on("panmove", function (event) {
9465 _this3._moveSelector(event);
9466 });
9467 this.hammer.on("panend", function (event) {
9468 _this3._moveSelector(event);
9469 });
9470 }
9471 /**
9472 * generate the hue circle. This is relatively heavy (200ms) and is done only once on the first time it is shown.
9473 *
9474 * @private
9475 */
9476
9477 }, {
9478 key: "_generateHueCircle",
9479 value: function _generateHueCircle() {
9480 if (this.generated === false) {
9481 var ctx = this.colorPickerCanvas.getContext("2d");
9482
9483 if (this.pixelRation === undefined) {
9484 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
9485 }
9486
9487 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); // clear the canvas
9488
9489 var w = this.colorPickerCanvas.clientWidth;
9490 var h = this.colorPickerCanvas.clientHeight;
9491 ctx.clearRect(0, 0, w, h); // draw hue circle
9492
9493 var x, y, hue, sat;
9494 this.centerCoordinates = {
9495 x: w * 0.5,
9496 y: h * 0.5
9497 };
9498 this.r = 0.49 * w;
9499 var angleConvert = 2 * Math.PI / 360;
9500 var hfac = 1 / 360;
9501 var sfac = 1 / this.r;
9502 var rgb;
9503
9504 for (hue = 0; hue < 360; hue++) {
9505 for (sat = 0; sat < this.r; sat++) {
9506 x = this.centerCoordinates.x + sat * Math.sin(angleConvert * hue);
9507 y = this.centerCoordinates.y + sat * Math.cos(angleConvert * hue);
9508 rgb = HSVToRGB(hue * hfac, sat * sfac, 1);
9509 ctx.fillStyle = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
9510 ctx.fillRect(x - 0.5, y - 0.5, 2, 2);
9511 }
9512 }
9513
9514 ctx.strokeStyle = "rgba(0,0,0,1)";
9515 ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
9516 ctx.stroke();
9517 this.hueCircle = ctx.getImageData(0, 0, w, h);
9518 }
9519
9520 this.generated = true;
9521 }
9522 /**
9523 * move the selector. This is called by hammer functions.
9524 *
9525 * @param {Event} event The event
9526 * @private
9527 */
9528
9529 }, {
9530 key: "_moveSelector",
9531 value: function _moveSelector(event) {
9532 var rect = this.colorPickerDiv.getBoundingClientRect();
9533 var left = event.center.x - rect.left;
9534 var top = event.center.y - rect.top;
9535 var centerY = 0.5 * this.colorPickerDiv.clientHeight;
9536 var centerX = 0.5 * this.colorPickerDiv.clientWidth;
9537 var x = left - centerX;
9538 var y = top - centerY;
9539 var angle = Math.atan2(x, y);
9540 var radius = 0.98 * Math.min(Math.sqrt(x * x + y * y), centerX);
9541 var newTop = Math.cos(angle) * radius + centerY;
9542 var newLeft = Math.sin(angle) * radius + centerX;
9543 this.colorPickerSelector.style.top = newTop - 0.5 * this.colorPickerSelector.clientHeight + "px";
9544 this.colorPickerSelector.style.left = newLeft - 0.5 * this.colorPickerSelector.clientWidth + "px"; // set color
9545
9546 var h = angle / (2 * Math.PI);
9547 h = h < 0 ? h + 1 : h;
9548 var s = radius / this.r;
9549 var hsv = RGBToHSV(this.color.r, this.color.g, this.color.b);
9550 hsv.h = h;
9551 hsv.s = s;
9552 var rgba = HSVToRGB(hsv.h, hsv.s, hsv.v);
9553 rgba["a"] = this.color.a;
9554 this.color = rgba; // update previews
9555
9556 this.initialColorDiv.style.backgroundColor = "rgba(" + this.initialColor.r + "," + this.initialColor.g + "," + this.initialColor.b + "," + this.initialColor.a + ")";
9557 this.newColorDiv.style.backgroundColor = "rgba(" + this.color.r + "," + this.color.g + "," + this.color.b + "," + this.color.a + ")";
9558 }
9559 }]);
9560
9561 return ColorPicker;
9562}();
9563/**
9564 * Wrap given text (last argument) in HTML elements (all preceding arguments).
9565 *
9566 * @param {...any} rest - List of tag names followed by inner text.
9567 *
9568 * @returns An element or a text node.
9569 */
9570
9571
9572function wrapInTag() {
9573 for (var _len5 = arguments.length, rest = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
9574 rest[_key5] = arguments[_key5];
9575 }
9576
9577 if (rest.length < 1) {
9578 throw new TypeError("Invalid arguments.");
9579 } else if (rest.length === 1) {
9580 return document.createTextNode(rest[0]);
9581 } else {
9582 var element = document.createElement(rest[0]);
9583 element.appendChild(wrapInTag.apply(void 0, _toConsumableArray(slice$1(rest).call(rest, 1))));
9584 return element;
9585 }
9586}
9587/**
9588 * The way this works is for all properties of this.possible options, you can supply the property name in any form to list the options.
9589 * Boolean options are recognised as Boolean
9590 * Number options should be written as array: [default value, min value, max value, stepsize]
9591 * Colors should be written as array: ['color', '#ffffff']
9592 * Strings with should be written as array: [option1, option2, option3, ..]
9593 *
9594 * The options are matched with their counterparts in each of the modules and the values used in the configuration are
9595 */
9596
9597
9598var Configurator = /*#__PURE__*/function () {
9599 /**
9600 * @param {object} parentModule | the location where parentModule.setOptions() can be called
9601 * @param {object} defaultContainer | the default container of the module
9602 * @param {object} configureOptions | the fully configured and predefined options set found in allOptions.js
9603 * @param {number} pixelRatio | canvas pixel ratio
9604 * @param {Function} hideOption | custom logic to dynamically hide options
9605 */
9606 function Configurator(parentModule, defaultContainer, configureOptions) {
9607 var pixelRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
9608 var hideOption = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : function () {
9609 return false;
9610 };
9611
9612 _classCallCheck(this, Configurator);
9613
9614 this.parent = parentModule;
9615 this.changedOptions = [];
9616 this.container = defaultContainer;
9617 this.allowCreation = false;
9618 this.hideOption = hideOption;
9619 this.options = {};
9620 this.initialized = false;
9621 this.popupCounter = 0;
9622 this.defaultOptions = {
9623 enabled: false,
9624 filter: true,
9625 container: undefined,
9626 showButton: true
9627 };
9628
9629 assign$2(this.options, this.defaultOptions);
9630
9631 this.configureOptions = configureOptions;
9632 this.moduleOptions = {};
9633 this.domElements = [];
9634 this.popupDiv = {};
9635 this.popupLimit = 5;
9636 this.popupHistory = {};
9637 this.colorPicker = new ColorPicker(pixelRatio);
9638 this.wrapper = undefined;
9639 }
9640 /**
9641 * refresh all options.
9642 * Because all modules parse their options by themselves, we just use their options. We copy them here.
9643 *
9644 * @param {object} options
9645 */
9646
9647
9648 _createClass(Configurator, [{
9649 key: "setOptions",
9650 value: function setOptions(options) {
9651 if (options !== undefined) {
9652 // reset the popup history because the indices may have been changed.
9653 this.popupHistory = {};
9654
9655 this._removePopup();
9656
9657 var enabled = true;
9658
9659 if (typeof options === "string") {
9660 this.options.filter = options;
9661 } else if (isArray$2(options)) {
9662 this.options.filter = options.join();
9663 } else if (_typeof(options) === "object") {
9664 if (options == null) {
9665 throw new TypeError("options cannot be null");
9666 }
9667
9668 if (options.container !== undefined) {
9669 this.options.container = options.container;
9670 }
9671
9672 if (filter(options) !== undefined) {
9673 this.options.filter = filter(options);
9674 }
9675
9676 if (options.showButton !== undefined) {
9677 this.options.showButton = options.showButton;
9678 }
9679
9680 if (options.enabled !== undefined) {
9681 enabled = options.enabled;
9682 }
9683 } else if (typeof options === "boolean") {
9684 this.options.filter = true;
9685 enabled = options;
9686 } else if (typeof options === "function") {
9687 this.options.filter = options;
9688 enabled = true;
9689 }
9690
9691 if (filter(this.options) === false) {
9692 enabled = false;
9693 }
9694
9695 this.options.enabled = enabled;
9696 }
9697
9698 this._clean();
9699 }
9700 /**
9701 *
9702 * @param {object} moduleOptions
9703 */
9704
9705 }, {
9706 key: "setModuleOptions",
9707 value: function setModuleOptions(moduleOptions) {
9708 this.moduleOptions = moduleOptions;
9709
9710 if (this.options.enabled === true) {
9711 this._clean();
9712
9713 if (this.options.container !== undefined) {
9714 this.container = this.options.container;
9715 }
9716
9717 this._create();
9718 }
9719 }
9720 /**
9721 * Create all DOM elements
9722 *
9723 * @private
9724 */
9725
9726 }, {
9727 key: "_create",
9728 value: function _create() {
9729 this._clean();
9730
9731 this.changedOptions = [];
9732
9733 var filter$1 = filter(this.options);
9734
9735 var counter = 0;
9736 var show = false;
9737
9738 for (var _option in this.configureOptions) {
9739 if (Object.prototype.hasOwnProperty.call(this.configureOptions, _option)) {
9740 this.allowCreation = false;
9741 show = false;
9742
9743 if (typeof filter$1 === "function") {
9744 show = filter$1(_option, []);
9745 show = show || this._handleObject(this.configureOptions[_option], [_option], true);
9746 } else if (filter$1 === true || indexOf(filter$1).call(filter$1, _option) !== -1) {
9747 show = true;
9748 }
9749
9750 if (show !== false) {
9751 this.allowCreation = true; // linebreak between categories
9752
9753 if (counter > 0) {
9754 this._makeItem([]);
9755 } // a header for the category
9756
9757
9758 this._makeHeader(_option); // get the sub options
9759
9760
9761 this._handleObject(this.configureOptions[_option], [_option]);
9762 }
9763
9764 counter++;
9765 }
9766 }
9767
9768 this._makeButton();
9769
9770 this._push(); //~ this.colorPicker.insertTo(this.container);
9771
9772 }
9773 /**
9774 * draw all DOM elements on the screen
9775 *
9776 * @private
9777 */
9778
9779 }, {
9780 key: "_push",
9781 value: function _push() {
9782 this.wrapper = document.createElement("div");
9783 this.wrapper.className = "vis-configuration-wrapper";
9784 this.container.appendChild(this.wrapper);
9785
9786 for (var i = 0; i < this.domElements.length; i++) {
9787 this.wrapper.appendChild(this.domElements[i]);
9788 }
9789
9790 this._showPopupIfNeeded();
9791 }
9792 /**
9793 * delete all DOM elements
9794 *
9795 * @private
9796 */
9797
9798 }, {
9799 key: "_clean",
9800 value: function _clean() {
9801 for (var i = 0; i < this.domElements.length; i++) {
9802 this.wrapper.removeChild(this.domElements[i]);
9803 }
9804
9805 if (this.wrapper !== undefined) {
9806 this.container.removeChild(this.wrapper);
9807 this.wrapper = undefined;
9808 }
9809
9810 this.domElements = [];
9811
9812 this._removePopup();
9813 }
9814 /**
9815 * get the value from the actualOptions if it exists
9816 *
9817 * @param {Array} path | where to look for the actual option
9818 * @returns {*}
9819 * @private
9820 */
9821
9822 }, {
9823 key: "_getValue",
9824 value: function _getValue(path) {
9825 var base = this.moduleOptions;
9826
9827 for (var i = 0; i < path.length; i++) {
9828 if (base[path[i]] !== undefined) {
9829 base = base[path[i]];
9830 } else {
9831 base = undefined;
9832 break;
9833 }
9834 }
9835
9836 return base;
9837 }
9838 /**
9839 * all option elements are wrapped in an item
9840 *
9841 * @param {Array} path | where to look for the actual option
9842 * @param {Array.<Element>} domElements
9843 * @returns {number}
9844 * @private
9845 */
9846
9847 }, {
9848 key: "_makeItem",
9849 value: function _makeItem(path) {
9850 if (this.allowCreation === true) {
9851 var item = document.createElement("div");
9852 item.className = "vis-configuration vis-config-item vis-config-s" + path.length;
9853
9854 for (var _len6 = arguments.length, domElements = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
9855 domElements[_key6 - 1] = arguments[_key6];
9856 }
9857
9858 forEach$2(domElements).call(domElements, function (element) {
9859 item.appendChild(element);
9860 });
9861
9862 this.domElements.push(item);
9863 return this.domElements.length;
9864 }
9865
9866 return 0;
9867 }
9868 /**
9869 * header for major subjects
9870 *
9871 * @param {string} name
9872 * @private
9873 */
9874
9875 }, {
9876 key: "_makeHeader",
9877 value: function _makeHeader(name) {
9878 var div = document.createElement("div");
9879 div.className = "vis-configuration vis-config-header";
9880 div.innerText = name;
9881
9882 this._makeItem([], div);
9883 }
9884 /**
9885 * make a label, if it is an object label, it gets different styling.
9886 *
9887 * @param {string} name
9888 * @param {Array} path | where to look for the actual option
9889 * @param {string} objectLabel
9890 * @returns {HTMLElement}
9891 * @private
9892 */
9893
9894 }, {
9895 key: "_makeLabel",
9896 value: function _makeLabel(name, path) {
9897 var objectLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
9898 var div = document.createElement("div");
9899 div.className = "vis-configuration vis-config-label vis-config-s" + path.length;
9900
9901 if (objectLabel === true) {
9902 while (div.firstChild) {
9903 div.removeChild(div.firstChild);
9904 }
9905
9906 div.appendChild(wrapInTag("i", "b", name));
9907 } else {
9908 div.innerText = name + ":";
9909 }
9910
9911 return div;
9912 }
9913 /**
9914 * make a dropdown list for multiple possible string optoins
9915 *
9916 * @param {Array.<number>} arr
9917 * @param {number} value
9918 * @param {Array} path | where to look for the actual option
9919 * @private
9920 */
9921
9922 }, {
9923 key: "_makeDropdown",
9924 value: function _makeDropdown(arr, value, path) {
9925 var select = document.createElement("select");
9926 select.className = "vis-configuration vis-config-select";
9927 var selectedValue = 0;
9928
9929 if (value !== undefined) {
9930 if (indexOf(arr).call(arr, value) !== -1) {
9931 selectedValue = indexOf(arr).call(arr, value);
9932 }
9933 }
9934
9935 for (var i = 0; i < arr.length; i++) {
9936 var _option2 = document.createElement("option");
9937
9938 _option2.value = arr[i];
9939
9940 if (i === selectedValue) {
9941 _option2.selected = "selected";
9942 }
9943
9944 _option2.innerText = arr[i];
9945 select.appendChild(_option2);
9946 }
9947
9948 var me = this;
9949
9950 select.onchange = function () {
9951 me._update(this.value, path);
9952 };
9953
9954 var label = this._makeLabel(path[path.length - 1], path);
9955
9956 this._makeItem(path, label, select);
9957 }
9958 /**
9959 * make a range object for numeric options
9960 *
9961 * @param {Array.<number>} arr
9962 * @param {number} value
9963 * @param {Array} path | where to look for the actual option
9964 * @private
9965 */
9966
9967 }, {
9968 key: "_makeRange",
9969 value: function _makeRange(arr, value, path) {
9970 var defaultValue = arr[0];
9971 var min = arr[1];
9972 var max = arr[2];
9973 var step = arr[3];
9974 var range = document.createElement("input");
9975 range.className = "vis-configuration vis-config-range";
9976
9977 try {
9978 range.type = "range"; // not supported on IE9
9979
9980 range.min = min;
9981 range.max = max;
9982 } catch (err) {// TODO: Add some error handling.
9983 }
9984
9985 range.step = step; // set up the popup settings in case they are needed.
9986
9987 var popupString = "";
9988 var popupValue = 0;
9989
9990 if (value !== undefined) {
9991 var factor = 1.2;
9992
9993 if (value < 0 && value * factor < min) {
9994 range.min = Math.ceil(value * factor);
9995 popupValue = range.min;
9996 popupString = "range increased";
9997 } else if (value / factor < min) {
9998 range.min = Math.ceil(value / factor);
9999 popupValue = range.min;
10000 popupString = "range increased";
10001 }
10002
10003 if (value * factor > max && max !== 1) {
10004 range.max = Math.ceil(value * factor);
10005 popupValue = range.max;
10006 popupString = "range increased";
10007 }
10008
10009 range.value = value;
10010 } else {
10011 range.value = defaultValue;
10012 }
10013
10014 var input = document.createElement("input");
10015 input.className = "vis-configuration vis-config-rangeinput";
10016 input.value = range.value;
10017 var me = this;
10018
10019 range.onchange = function () {
10020 input.value = this.value;
10021
10022 me._update(Number(this.value), path);
10023 };
10024
10025 range.oninput = function () {
10026 input.value = this.value;
10027 };
10028
10029 var label = this._makeLabel(path[path.length - 1], path);
10030
10031 var itemIndex = this._makeItem(path, label, range, input); // if a popup is needed AND it has not been shown for this value, show it.
10032
10033
10034 if (popupString !== "" && this.popupHistory[itemIndex] !== popupValue) {
10035 this.popupHistory[itemIndex] = popupValue;
10036
10037 this._setupPopup(popupString, itemIndex);
10038 }
10039 }
10040 /**
10041 * make a button object
10042 *
10043 * @private
10044 */
10045
10046 }, {
10047 key: "_makeButton",
10048 value: function _makeButton() {
10049 var _this4 = this;
10050
10051 if (this.options.showButton === true) {
10052 var generateButton = document.createElement("div");
10053 generateButton.className = "vis-configuration vis-config-button";
10054 generateButton.innerText = "generate options";
10055
10056 generateButton.onclick = function () {
10057 _this4._printOptions();
10058 };
10059
10060 generateButton.onmouseover = function () {
10061 generateButton.className = "vis-configuration vis-config-button hover";
10062 };
10063
10064 generateButton.onmouseout = function () {
10065 generateButton.className = "vis-configuration vis-config-button";
10066 };
10067
10068 this.optionsContainer = document.createElement("div");
10069 this.optionsContainer.className = "vis-configuration vis-config-option-container";
10070 this.domElements.push(this.optionsContainer);
10071 this.domElements.push(generateButton);
10072 }
10073 }
10074 /**
10075 * prepare the popup
10076 *
10077 * @param {string} string
10078 * @param {number} index
10079 * @private
10080 */
10081
10082 }, {
10083 key: "_setupPopup",
10084 value: function _setupPopup(string, index) {
10085 var _this5 = this;
10086
10087 if (this.initialized === true && this.allowCreation === true && this.popupCounter < this.popupLimit) {
10088 var div = document.createElement("div");
10089 div.id = "vis-configuration-popup";
10090 div.className = "vis-configuration-popup";
10091 div.innerText = string;
10092
10093 div.onclick = function () {
10094 _this5._removePopup();
10095 };
10096
10097 this.popupCounter += 1;
10098 this.popupDiv = {
10099 html: div,
10100 index: index
10101 };
10102 }
10103 }
10104 /**
10105 * remove the popup from the dom
10106 *
10107 * @private
10108 */
10109
10110 }, {
10111 key: "_removePopup",
10112 value: function _removePopup() {
10113 if (this.popupDiv.html !== undefined) {
10114 this.popupDiv.html.parentNode.removeChild(this.popupDiv.html);
10115 clearTimeout(this.popupDiv.hideTimeout);
10116 clearTimeout(this.popupDiv.deleteTimeout);
10117 this.popupDiv = {};
10118 }
10119 }
10120 /**
10121 * Show the popup if it is needed.
10122 *
10123 * @private
10124 */
10125
10126 }, {
10127 key: "_showPopupIfNeeded",
10128 value: function _showPopupIfNeeded() {
10129 var _this6 = this;
10130
10131 if (this.popupDiv.html !== undefined) {
10132 var correspondingElement = this.domElements[this.popupDiv.index];
10133 var rect = correspondingElement.getBoundingClientRect();
10134 this.popupDiv.html.style.left = rect.left + "px";
10135 this.popupDiv.html.style.top = rect.top - 30 + "px"; // 30 is the height;
10136
10137 document.body.appendChild(this.popupDiv.html);
10138 this.popupDiv.hideTimeout = setTimeout$1(function () {
10139 _this6.popupDiv.html.style.opacity = 0;
10140 }, 1500);
10141 this.popupDiv.deleteTimeout = setTimeout$1(function () {
10142 _this6._removePopup();
10143 }, 1800);
10144 }
10145 }
10146 /**
10147 * make a checkbox for boolean options.
10148 *
10149 * @param {number} defaultValue
10150 * @param {number} value
10151 * @param {Array} path | where to look for the actual option
10152 * @private
10153 */
10154
10155 }, {
10156 key: "_makeCheckbox",
10157 value: function _makeCheckbox(defaultValue, value, path) {
10158 var checkbox = document.createElement("input");
10159 checkbox.type = "checkbox";
10160 checkbox.className = "vis-configuration vis-config-checkbox";
10161 checkbox.checked = defaultValue;
10162
10163 if (value !== undefined) {
10164 checkbox.checked = value;
10165
10166 if (value !== defaultValue) {
10167 if (_typeof(defaultValue) === "object") {
10168 if (value !== defaultValue.enabled) {
10169 this.changedOptions.push({
10170 path: path,
10171 value: value
10172 });
10173 }
10174 } else {
10175 this.changedOptions.push({
10176 path: path,
10177 value: value
10178 });
10179 }
10180 }
10181 }
10182
10183 var me = this;
10184
10185 checkbox.onchange = function () {
10186 me._update(this.checked, path);
10187 };
10188
10189 var label = this._makeLabel(path[path.length - 1], path);
10190
10191 this._makeItem(path, label, checkbox);
10192 }
10193 /**
10194 * make a text input field for string options.
10195 *
10196 * @param {number} defaultValue
10197 * @param {number} value
10198 * @param {Array} path | where to look for the actual option
10199 * @private
10200 */
10201
10202 }, {
10203 key: "_makeTextInput",
10204 value: function _makeTextInput(defaultValue, value, path) {
10205 var checkbox = document.createElement("input");
10206 checkbox.type = "text";
10207 checkbox.className = "vis-configuration vis-config-text";
10208 checkbox.value = value;
10209
10210 if (value !== defaultValue) {
10211 this.changedOptions.push({
10212 path: path,
10213 value: value
10214 });
10215 }
10216
10217 var me = this;
10218
10219 checkbox.onchange = function () {
10220 me._update(this.value, path);
10221 };
10222
10223 var label = this._makeLabel(path[path.length - 1], path);
10224
10225 this._makeItem(path, label, checkbox);
10226 }
10227 /**
10228 * make a color field with a color picker for color fields
10229 *
10230 * @param {Array.<number>} arr
10231 * @param {number} value
10232 * @param {Array} path | where to look for the actual option
10233 * @private
10234 */
10235
10236 }, {
10237 key: "_makeColorField",
10238 value: function _makeColorField(arr, value, path) {
10239 var _this7 = this;
10240
10241 var defaultColor = arr[1];
10242 var div = document.createElement("div");
10243 value = value === undefined ? defaultColor : value;
10244
10245 if (value !== "none") {
10246 div.className = "vis-configuration vis-config-colorBlock";
10247 div.style.backgroundColor = value;
10248 } else {
10249 div.className = "vis-configuration vis-config-colorBlock none";
10250 }
10251
10252 value = value === undefined ? defaultColor : value;
10253
10254 div.onclick = function () {
10255 _this7._showColorPicker(value, div, path);
10256 };
10257
10258 var label = this._makeLabel(path[path.length - 1], path);
10259
10260 this._makeItem(path, label, div);
10261 }
10262 /**
10263 * used by the color buttons to call the color picker.
10264 *
10265 * @param {number} value
10266 * @param {HTMLElement} div
10267 * @param {Array} path | where to look for the actual option
10268 * @private
10269 */
10270
10271 }, {
10272 key: "_showColorPicker",
10273 value: function _showColorPicker(value, div, path) {
10274 var _this8 = this;
10275
10276 // clear the callback from this div
10277 div.onclick = function () {};
10278
10279 this.colorPicker.insertTo(div);
10280 this.colorPicker.show();
10281 this.colorPicker.setColor(value);
10282 this.colorPicker.setUpdateCallback(function (color) {
10283 var colorString = "rgba(" + color.r + "," + color.g + "," + color.b + "," + color.a + ")";
10284 div.style.backgroundColor = colorString;
10285
10286 _this8._update(colorString, path);
10287 }); // on close of the colorpicker, restore the callback.
10288
10289 this.colorPicker.setCloseCallback(function () {
10290 div.onclick = function () {
10291 _this8._showColorPicker(value, div, path);
10292 };
10293 });
10294 }
10295 /**
10296 * parse an object and draw the correct items
10297 *
10298 * @param {object} obj
10299 * @param {Array} [path=[]] | where to look for the actual option
10300 * @param {boolean} [checkOnly=false]
10301 * @returns {boolean}
10302 * @private
10303 */
10304
10305 }, {
10306 key: "_handleObject",
10307 value: function _handleObject(obj) {
10308 var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
10309 var checkOnly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
10310 var show = false;
10311
10312 var filter$1 = filter(this.options);
10313
10314 var visibleInSet = false;
10315
10316 for (var subObj in obj) {
10317 if (Object.prototype.hasOwnProperty.call(obj, subObj)) {
10318 show = true;
10319 var item = obj[subObj];
10320 var newPath = copyAndExtendArray(path, subObj);
10321
10322 if (typeof filter$1 === "function") {
10323 show = filter$1(subObj, path); // if needed we must go deeper into the object.
10324
10325 if (show === false) {
10326 if (!isArray$2(item) && typeof item !== "string" && typeof item !== "boolean" && item instanceof Object) {
10327 this.allowCreation = false;
10328 show = this._handleObject(item, newPath, true);
10329 this.allowCreation = checkOnly === false;
10330 }
10331 }
10332 }
10333
10334 if (show !== false) {
10335 visibleInSet = true;
10336
10337 var value = this._getValue(newPath);
10338
10339 if (isArray$2(item)) {
10340 this._handleArray(item, value, newPath);
10341 } else if (typeof item === "string") {
10342 this._makeTextInput(item, value, newPath);
10343 } else if (typeof item === "boolean") {
10344 this._makeCheckbox(item, value, newPath);
10345 } else if (item instanceof Object) {
10346 // skip the options that are not enabled
10347 if (!this.hideOption(path, subObj, this.moduleOptions)) {
10348 // initially collapse options with an disabled enabled option.
10349 if (item.enabled !== undefined) {
10350 var enabledPath = copyAndExtendArray(newPath, "enabled");
10351
10352 var enabledValue = this._getValue(enabledPath);
10353
10354 if (enabledValue === true) {
10355 var label = this._makeLabel(subObj, newPath, true);
10356
10357 this._makeItem(newPath, label);
10358
10359 visibleInSet = this._handleObject(item, newPath) || visibleInSet;
10360 } else {
10361 this._makeCheckbox(item, enabledValue, newPath);
10362 }
10363 } else {
10364 var _label = this._makeLabel(subObj, newPath, true);
10365
10366 this._makeItem(newPath, _label);
10367
10368 visibleInSet = this._handleObject(item, newPath) || visibleInSet;
10369 }
10370 }
10371 } else {
10372 console.error("dont know how to handle", item, subObj, newPath);
10373 }
10374 }
10375 }
10376 }
10377
10378 return visibleInSet;
10379 }
10380 /**
10381 * handle the array type of option
10382 *
10383 * @param {Array.<number>} arr
10384 * @param {number} value
10385 * @param {Array} path | where to look for the actual option
10386 * @private
10387 */
10388
10389 }, {
10390 key: "_handleArray",
10391 value: function _handleArray(arr, value, path) {
10392 if (typeof arr[0] === "string" && arr[0] === "color") {
10393 this._makeColorField(arr, value, path);
10394
10395 if (arr[1] !== value) {
10396 this.changedOptions.push({
10397 path: path,
10398 value: value
10399 });
10400 }
10401 } else if (typeof arr[0] === "string") {
10402 this._makeDropdown(arr, value, path);
10403
10404 if (arr[0] !== value) {
10405 this.changedOptions.push({
10406 path: path,
10407 value: value
10408 });
10409 }
10410 } else if (typeof arr[0] === "number") {
10411 this._makeRange(arr, value, path);
10412
10413 if (arr[0] !== value) {
10414 this.changedOptions.push({
10415 path: path,
10416 value: Number(value)
10417 });
10418 }
10419 }
10420 }
10421 /**
10422 * called to update the network with the new settings.
10423 *
10424 * @param {number} value
10425 * @param {Array} path | where to look for the actual option
10426 * @private
10427 */
10428
10429 }, {
10430 key: "_update",
10431 value: function _update(value, path) {
10432 var options = this._constructOptions(value, path);
10433
10434 if (this.parent.body && this.parent.body.emitter && this.parent.body.emitter.emit) {
10435 this.parent.body.emitter.emit("configChange", options);
10436 }
10437
10438 this.initialized = true;
10439 this.parent.setOptions(options);
10440 }
10441 /**
10442 *
10443 * @param {string | boolean} value
10444 * @param {Array.<string>} path
10445 * @param {{}} optionsObj
10446 * @returns {{}}
10447 * @private
10448 */
10449
10450 }, {
10451 key: "_constructOptions",
10452 value: function _constructOptions(value, path) {
10453 var optionsObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
10454 var pointer = optionsObj; // when dropdown boxes can be string or boolean, we typecast it into correct types
10455
10456 value = value === "true" ? true : value;
10457 value = value === "false" ? false : value;
10458
10459 for (var i = 0; i < path.length; i++) {
10460 if (path[i] !== "global") {
10461 if (pointer[path[i]] === undefined) {
10462 pointer[path[i]] = {};
10463 }
10464
10465 if (i !== path.length - 1) {
10466 pointer = pointer[path[i]];
10467 } else {
10468 pointer[path[i]] = value;
10469 }
10470 }
10471 }
10472
10473 return optionsObj;
10474 }
10475 /**
10476 * @private
10477 */
10478
10479 }, {
10480 key: "_printOptions",
10481 value: function _printOptions() {
10482 var options = this.getOptions();
10483
10484 while (this.optionsContainer.firstChild) {
10485 this.optionsContainer.removeChild(this.optionsContainer.firstChild);
10486 }
10487
10488 this.optionsContainer.appendChild(wrapInTag("pre", "const options = " + stringify$1(options, null, 2)));
10489 }
10490 /**
10491 *
10492 * @returns {{}} options
10493 */
10494
10495 }, {
10496 key: "getOptions",
10497 value: function getOptions() {
10498 var options = {};
10499
10500 for (var i = 0; i < this.changedOptions.length; i++) {
10501 this._constructOptions(this.changedOptions[i].value, this.changedOptions[i].path, options);
10502 }
10503
10504 return options;
10505 }
10506 }]);
10507
10508 return Configurator;
10509}();
10510/**
10511 * Popup is a class to create a popup window with some text
10512 */
10513
10514
10515var Popup = /*#__PURE__*/function () {
10516 /**
10517 * @param {Element} container The container object.
10518 * @param {string} overflowMethod How the popup should act to overflowing ('flip' or 'cap')
10519 */
10520 function Popup(container, overflowMethod) {
10521 _classCallCheck(this, Popup);
10522
10523 this.container = container;
10524 this.overflowMethod = overflowMethod || "cap";
10525 this.x = 0;
10526 this.y = 0;
10527 this.padding = 5;
10528 this.hidden = false; // create the frame
10529
10530 this.frame = document.createElement("div");
10531 this.frame.className = "vis-tooltip";
10532 this.container.appendChild(this.frame);
10533 }
10534 /**
10535 * @param {number} x Horizontal position of the popup window
10536 * @param {number} y Vertical position of the popup window
10537 */
10538
10539
10540 _createClass(Popup, [{
10541 key: "setPosition",
10542 value: function setPosition(x, y) {
10543 this.x = _parseInt(x);
10544 this.y = _parseInt(y);
10545 }
10546 /**
10547 * Set the content for the popup window. This can be HTML code or text.
10548 *
10549 * @param {string | Element} content
10550 */
10551
10552 }, {
10553 key: "setText",
10554 value: function setText(content) {
10555 if (content instanceof Element) {
10556 while (this.frame.firstChild) {
10557 this.frame.removeChild(this.frame.firstChild);
10558 }
10559
10560 this.frame.appendChild(content);
10561 } else {
10562 // String containing literal text, element has to be used for HTML due to
10563 // XSS risks associated with innerHTML (i.e. prevent XSS by accident).
10564 this.frame.innerText = content;
10565 }
10566 }
10567 /**
10568 * Show the popup window
10569 *
10570 * @param {boolean} [doShow] Show or hide the window
10571 */
10572
10573 }, {
10574 key: "show",
10575 value: function show(doShow) {
10576 if (doShow === undefined) {
10577 doShow = true;
10578 }
10579
10580 if (doShow === true) {
10581 var height = this.frame.clientHeight;
10582 var width = this.frame.clientWidth;
10583 var maxHeight = this.frame.parentNode.clientHeight;
10584 var maxWidth = this.frame.parentNode.clientWidth;
10585 var left = 0,
10586 top = 0;
10587
10588 if (this.overflowMethod == "flip") {
10589 var isLeft = false,
10590 isTop = true; // Where around the position it's located
10591
10592 if (this.y - height < this.padding) {
10593 isTop = false;
10594 }
10595
10596 if (this.x + width > maxWidth - this.padding) {
10597 isLeft = true;
10598 }
10599
10600 if (isLeft) {
10601 left = this.x - width;
10602 } else {
10603 left = this.x;
10604 }
10605
10606 if (isTop) {
10607 top = this.y - height;
10608 } else {
10609 top = this.y;
10610 }
10611 } else {
10612 top = this.y - height;
10613
10614 if (top + height + this.padding > maxHeight) {
10615 top = maxHeight - height - this.padding;
10616 }
10617
10618 if (top < this.padding) {
10619 top = this.padding;
10620 }
10621
10622 left = this.x;
10623
10624 if (left + width + this.padding > maxWidth) {
10625 left = maxWidth - width - this.padding;
10626 }
10627
10628 if (left < this.padding) {
10629 left = this.padding;
10630 }
10631 }
10632
10633 this.frame.style.left = left + "px";
10634 this.frame.style.top = top + "px";
10635 this.frame.style.visibility = "visible";
10636 this.hidden = false;
10637 } else {
10638 this.hide();
10639 }
10640 }
10641 /**
10642 * Hide the popup window
10643 */
10644
10645 }, {
10646 key: "hide",
10647 value: function hide() {
10648 this.hidden = true;
10649 this.frame.style.left = "0";
10650 this.frame.style.top = "0";
10651 this.frame.style.visibility = "hidden";
10652 }
10653 /**
10654 * Remove the popup window
10655 */
10656
10657 }, {
10658 key: "destroy",
10659 value: function destroy() {
10660 this.frame.parentNode.removeChild(this.frame); // Remove element from DOM
10661 }
10662 }]);
10663
10664 return Popup;
10665}();
10666
10667var errorFound = false;
10668var allOptions$1;
10669var VALIDATOR_PRINT_STYLE = "background: #FFeeee; color: #dd0000";
10670/**
10671 * Used to validate options.
10672 */
10673
10674var Validator = /*#__PURE__*/function () {
10675 function Validator() {
10676 _classCallCheck(this, Validator);
10677 }
10678
10679 _createClass(Validator, null, [{
10680 key: "validate",
10681 value:
10682 /**
10683 * Main function to be called
10684 *
10685 * @param {object} options
10686 * @param {object} referenceOptions
10687 * @param {object} subObject
10688 * @returns {boolean}
10689 * @static
10690 */
10691 function validate(options, referenceOptions, subObject) {
10692 errorFound = false;
10693 allOptions$1 = referenceOptions;
10694 var usedOptions = referenceOptions;
10695
10696 if (subObject !== undefined) {
10697 usedOptions = referenceOptions[subObject];
10698 }
10699
10700 Validator.parse(options, usedOptions, []);
10701 return errorFound;
10702 }
10703 /**
10704 * Will traverse an object recursively and check every value
10705 *
10706 * @param {object} options
10707 * @param {object} referenceOptions
10708 * @param {Array} path | where to look for the actual option
10709 * @static
10710 */
10711
10712 }, {
10713 key: "parse",
10714 value: function parse(options, referenceOptions, path) {
10715 for (var _option3 in options) {
10716 if (Object.prototype.hasOwnProperty.call(options, _option3)) {
10717 Validator.check(_option3, options, referenceOptions, path);
10718 }
10719 }
10720 }
10721 /**
10722 * Check every value. If the value is an object, call the parse function on that object.
10723 *
10724 * @param {string} option
10725 * @param {object} options
10726 * @param {object} referenceOptions
10727 * @param {Array} path | where to look for the actual option
10728 * @static
10729 */
10730
10731 }, {
10732 key: "check",
10733 value: function check(option, options, referenceOptions, path) {
10734 if (referenceOptions[option] === undefined && referenceOptions.__any__ === undefined) {
10735 Validator.getSuggestion(option, referenceOptions, path);
10736 return;
10737 }
10738
10739 var referenceOption = option;
10740 var is_object = true;
10741
10742 if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {
10743 // NOTE: This only triggers if the __any__ is in the top level of the options object.
10744 // THAT'S A REALLY BAD PLACE TO ALLOW IT!!!!
10745 // TODO: Examine if needed, remove if possible
10746 // __any__ is a wildcard. Any value is accepted and will be further analysed by reference.
10747 referenceOption = "__any__"; // if the any-subgroup is not a predefined object in the configurator,
10748 // we do not look deeper into the object.
10749
10750 is_object = Validator.getType(options[option]) === "object";
10751 }
10752
10753 var refOptionObj = referenceOptions[referenceOption];
10754
10755 if (is_object && refOptionObj.__type__ !== undefined) {
10756 refOptionObj = refOptionObj.__type__;
10757 }
10758
10759 Validator.checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path);
10760 }
10761 /**
10762 *
10763 * @param {string} option | the option property
10764 * @param {object} options | The supplied options object
10765 * @param {object} referenceOptions | The reference options containing all options and their allowed formats
10766 * @param {string} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
10767 * @param {string} refOptionObj | This is the type object from the reference options
10768 * @param {Array} path | where in the object is the option
10769 * @static
10770 */
10771
10772 }, {
10773 key: "checkFields",
10774 value: function checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path) {
10775 var log = function log(message) {
10776 console.error("%c" + message + Validator.printLocation(path, option), VALIDATOR_PRINT_STYLE);
10777 };
10778
10779 var optionType = Validator.getType(options[option]);
10780 var refOptionType = refOptionObj[optionType];
10781
10782 if (refOptionType !== undefined) {
10783 // if the type is correct, we check if it is supposed to be one of a few select values
10784 if (Validator.getType(refOptionType) === "array" && indexOf(refOptionType).call(refOptionType, options[option]) === -1) {
10785 log('Invalid option detected in "' + option + '".' + " Allowed values are:" + Validator.print(refOptionType) + ' not "' + options[option] + '". ');
10786 errorFound = true;
10787 } else if (optionType === "object" && referenceOption !== "__any__") {
10788 path = copyAndExtendArray(path, option);
10789 Validator.parse(options[option], referenceOptions[referenceOption], path);
10790 }
10791 } else if (refOptionObj["any"] === undefined) {
10792 // type of the field is incorrect and the field cannot be any
10793 log('Invalid type received for "' + option + '". Expected: ' + Validator.print(keys$4(refOptionObj)) + ". Received [" + optionType + '] "' + options[option] + '"');
10794 errorFound = true;
10795 }
10796 }
10797 /**
10798 *
10799 * @param {object | boolean | number | string | Array.<number> | Date | Node | Moment | undefined | null} object
10800 * @returns {string}
10801 * @static
10802 */
10803
10804 }, {
10805 key: "getType",
10806 value: function getType(object) {
10807 var type = _typeof(object);
10808
10809 if (type === "object") {
10810 if (object === null) {
10811 return "null";
10812 }
10813
10814 if (object instanceof Boolean) {
10815 return "boolean";
10816 }
10817
10818 if (object instanceof Number) {
10819 return "number";
10820 }
10821
10822 if (object instanceof String) {
10823 return "string";
10824 }
10825
10826 if (isArray$2(object)) {
10827 return "array";
10828 }
10829
10830 if (object instanceof Date) {
10831 return "date";
10832 }
10833
10834 if (object.nodeType !== undefined) {
10835 return "dom";
10836 }
10837
10838 if (object._isAMomentObject === true) {
10839 return "moment";
10840 }
10841
10842 return "object";
10843 } else if (type === "number") {
10844 return "number";
10845 } else if (type === "boolean") {
10846 return "boolean";
10847 } else if (type === "string") {
10848 return "string";
10849 } else if (type === undefined) {
10850 return "undefined";
10851 }
10852
10853 return type;
10854 }
10855 /**
10856 * @param {string} option
10857 * @param {object} options
10858 * @param {Array.<string>} path
10859 * @static
10860 */
10861
10862 }, {
10863 key: "getSuggestion",
10864 value: function getSuggestion(option, options, path) {
10865 var localSearch = Validator.findInOptions(option, options, path, false);
10866 var globalSearch = Validator.findInOptions(option, allOptions$1, [], true);
10867 var localSearchThreshold = 8;
10868 var globalSearchThreshold = 4;
10869 var msg;
10870
10871 if (localSearch.indexMatch !== undefined) {
10872 msg = " in " + Validator.printLocation(localSearch.path, option, "") + 'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n';
10873 } else if (globalSearch.distance <= globalSearchThreshold && localSearch.distance > globalSearch.distance) {
10874 msg = " in " + Validator.printLocation(localSearch.path, option, "") + "Perhaps it was misplaced? Matching option found at: " + Validator.printLocation(globalSearch.path, globalSearch.closestMatch, "");
10875 } else if (localSearch.distance <= localSearchThreshold) {
10876 msg = '. Did you mean "' + localSearch.closestMatch + '"?' + Validator.printLocation(localSearch.path, option);
10877 } else {
10878 msg = ". Did you mean one of these: " + Validator.print(keys$4(options)) + Validator.printLocation(path, option);
10879 }
10880
10881 console.error('%cUnknown option detected: "' + option + '"' + msg, VALIDATOR_PRINT_STYLE);
10882 errorFound = true;
10883 }
10884 /**
10885 * traverse the options in search for a match.
10886 *
10887 * @param {string} option
10888 * @param {object} options
10889 * @param {Array} path | where to look for the actual option
10890 * @param {boolean} [recursive=false]
10891 * @returns {{closestMatch: string, path: Array, distance: number}}
10892 * @static
10893 */
10894
10895 }, {
10896 key: "findInOptions",
10897 value: function findInOptions(option, options, path) {
10898 var recursive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
10899 var min = 1e9;
10900 var closestMatch = "";
10901 var closestMatchPath = [];
10902 var lowerCaseOption = option.toLowerCase();
10903 var indexMatch = undefined;
10904
10905 for (var op in options) {
10906 var distance = void 0;
10907
10908 if (options[op].__type__ !== undefined && recursive === true) {
10909 var result = Validator.findInOptions(option, options[op], copyAndExtendArray(path, op));
10910
10911 if (min > result.distance) {
10912 closestMatch = result.closestMatch;
10913 closestMatchPath = result.path;
10914 min = result.distance;
10915 indexMatch = result.indexMatch;
10916 }
10917 } else {
10918 var _context20;
10919
10920 if (indexOf(_context20 = op.toLowerCase()).call(_context20, lowerCaseOption) !== -1) {
10921 indexMatch = op;
10922 }
10923
10924 distance = Validator.levenshteinDistance(option, op);
10925
10926 if (min > distance) {
10927 closestMatch = op;
10928 closestMatchPath = copyArray(path);
10929 min = distance;
10930 }
10931 }
10932 }
10933
10934 return {
10935 closestMatch: closestMatch,
10936 path: closestMatchPath,
10937 distance: min,
10938 indexMatch: indexMatch
10939 };
10940 }
10941 /**
10942 * @param {Array.<string>} path
10943 * @param {object} option
10944 * @param {string} prefix
10945 * @returns {string}
10946 * @static
10947 */
10948
10949 }, {
10950 key: "printLocation",
10951 value: function printLocation(path, option) {
10952 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "Problem value found at: \n";
10953 var str = "\n\n" + prefix + "options = {\n";
10954
10955 for (var i = 0; i < path.length; i++) {
10956 for (var j = 0; j < i + 1; j++) {
10957 str += " ";
10958 }
10959
10960 str += path[i] + ": {\n";
10961 }
10962
10963 for (var _j = 0; _j < path.length + 1; _j++) {
10964 str += " ";
10965 }
10966
10967 str += option + "\n";
10968
10969 for (var _i3 = 0; _i3 < path.length + 1; _i3++) {
10970 for (var _j2 = 0; _j2 < path.length - _i3; _j2++) {
10971 str += " ";
10972 }
10973
10974 str += "}\n";
10975 }
10976
10977 return str + "\n\n";
10978 }
10979 /**
10980 * @param {object} options
10981 * @returns {string}
10982 * @static
10983 */
10984
10985 }, {
10986 key: "print",
10987 value: function print(options) {
10988 return stringify$1(options).replace(/(")|(\[)|(\])|(,"__type__")/g, "").replace(/(,)/g, ", ");
10989 }
10990 /**
10991 * Compute the edit distance between the two given strings
10992 * http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
10993 *
10994 * Copyright (c) 2011 Andrei Mackenzie
10995 *
10996 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10997 *
10998 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10999 *
11000 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11001 *
11002 * @param {string} a
11003 * @param {string} b
11004 * @returns {Array.<Array.<number>>}}
11005 * @static
11006 */
11007
11008 }, {
11009 key: "levenshteinDistance",
11010 value: function levenshteinDistance(a, b) {
11011 if (a.length === 0) return b.length;
11012 if (b.length === 0) return a.length;
11013 var matrix = []; // increment along the first column of each row
11014
11015 var i;
11016
11017 for (i = 0; i <= b.length; i++) {
11018 matrix[i] = [i];
11019 } // increment each column in the first row
11020
11021
11022 var j;
11023
11024 for (j = 0; j <= a.length; j++) {
11025 matrix[0][j] = j;
11026 } // Fill in the rest of the matrix
11027
11028
11029 for (i = 1; i <= b.length; i++) {
11030 for (j = 1; j <= a.length; j++) {
11031 if (b.charAt(i - 1) == a.charAt(j - 1)) {
11032 matrix[i][j] = matrix[i - 1][j - 1];
11033 } else {
11034 matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
11035 Math.min(matrix[i][j - 1] + 1, // insertion
11036 matrix[i - 1][j] + 1)); // deletion
11037 }
11038 }
11039 }
11040
11041 return matrix[b.length][a.length];
11042 }
11043 }]);
11044
11045 return Validator;
11046}();
11047
11048var Activator$1 = Activator;
11049var Configurator$1 = Configurator;
11050var Hammer$1 = Hammer;
11051var Popup$1 = Popup;
11052var VALIDATOR_PRINT_STYLE$1 = VALIDATOR_PRINT_STYLE;
11053var Validator$1 = Validator;
11054
11055/* eslint-disable no-prototype-builtins */
11056
11057/* eslint-disable no-unused-vars */
11058
11059/* eslint-disable no-var */
11060
11061/**
11062 * Parse a text source containing data in DOT language into a JSON object.
11063 * The object contains two lists: one with nodes and one with edges.
11064 *
11065 * DOT language reference: http://www.graphviz.org/doc/info/lang.html
11066 *
11067 * DOT language attributes: http://graphviz.org/content/attrs
11068 *
11069 * @param {string} data Text containing a graph in DOT-notation
11070 * @returns {object} graph An object containing two parameters:
11071 * {Object[]} nodes
11072 * {Object[]} edges
11073 *
11074 * -------------------------------------------
11075 * TODO
11076 * ====
11077 *
11078 * For label handling, this is an incomplete implementation. From docs (quote #3015):
11079 *
11080 * > the escape sequences "\n", "\l" and "\r" divide the label into lines, centered,
11081 * > left-justified, and right-justified, respectively.
11082 *
11083 * Source: http://www.graphviz.org/content/attrs#kescString
11084 *
11085 * > As another aid for readability, dot allows double-quoted strings to span multiple physical
11086 * > lines using the standard C convention of a backslash immediately preceding a newline
11087 * > character
11088 * > In addition, double-quoted strings can be concatenated using a '+' operator.
11089 * > As HTML strings can contain newline characters, which are used solely for formatting,
11090 * > the language does not allow escaped newlines or concatenation operators to be used
11091 * > within them.
11092 *
11093 * - Currently, only '\\n' is handled
11094 * - Note that text explicitly says 'labels'; the dot parser currently handles escape
11095 * sequences in **all** strings.
11096 */
11097function parseDOT(data) {
11098 dot = data;
11099 return parseGraph();
11100} // mapping of attributes from DOT (the keys) to vis.js (the values)
11101
11102var NODE_ATTR_MAPPING = {
11103 fontsize: "font.size",
11104 fontcolor: "font.color",
11105 labelfontcolor: "font.color",
11106 fontname: "font.face",
11107 color: ["color.border", "color.background"],
11108 fillcolor: "color.background",
11109 tooltip: "title",
11110 labeltooltip: "title"
11111};
11112
11113var EDGE_ATTR_MAPPING = create$4(NODE_ATTR_MAPPING);
11114
11115EDGE_ATTR_MAPPING.color = "color.color";
11116EDGE_ATTR_MAPPING.style = "dashes"; // token types enumeration
11117
11118var TOKENTYPE = {
11119 NULL: 0,
11120 DELIMITER: 1,
11121 IDENTIFIER: 2,
11122 UNKNOWN: 3
11123}; // map with all delimiters
11124
11125var DELIMITERS = {
11126 "{": true,
11127 "}": true,
11128 "[": true,
11129 "]": true,
11130 ";": true,
11131 "=": true,
11132 ",": true,
11133 "->": true,
11134 "--": true
11135};
11136var dot = ""; // current dot file
11137
11138var index$1 = 0; // current index in dot file
11139
11140var c = ""; // current token character in expr
11141
11142var token = ""; // current token
11143
11144var tokenType = TOKENTYPE.NULL; // type of the token
11145
11146/**
11147 * Get the first character from the dot file.
11148 * The character is stored into the char c. If the end of the dot file is
11149 * reached, the function puts an empty string in c.
11150 */
11151
11152function first() {
11153 index$1 = 0;
11154 c = dot.charAt(0);
11155}
11156/**
11157 * Get the next character from the dot file.
11158 * The character is stored into the char c. If the end of the dot file is
11159 * reached, the function puts an empty string in c.
11160 */
11161
11162
11163function next() {
11164 index$1++;
11165 c = dot.charAt(index$1);
11166}
11167/**
11168 * Preview the next character from the dot file.
11169 *
11170 * @returns {string} cNext
11171 */
11172
11173
11174function nextPreview() {
11175 return dot.charAt(index$1 + 1);
11176}
11177/**
11178 * Test whether given character is alphabetic or numeric ( a-zA-Z_0-9.:# )
11179 *
11180 * @param {string} c
11181 * @returns {boolean} isAlphaNumeric
11182 */
11183
11184
11185function isAlphaNumeric(c) {
11186 var charCode = c.charCodeAt(0);
11187
11188 if (charCode < 47) {
11189 // #.
11190 return charCode === 35 || charCode === 46;
11191 }
11192
11193 if (charCode < 59) {
11194 // 0-9 and :
11195 return charCode > 47;
11196 }
11197
11198 if (charCode < 91) {
11199 // A-Z
11200 return charCode > 64;
11201 }
11202
11203 if (charCode < 96) {
11204 // _
11205 return charCode === 95;
11206 }
11207
11208 if (charCode < 123) {
11209 // a-z
11210 return charCode > 96;
11211 }
11212
11213 return false;
11214}
11215/**
11216 * Merge all options of object b into object b
11217 *
11218 * @param {object} a
11219 * @param {object} b
11220 * @returns {object} a
11221 */
11222
11223
11224function merge$1(a, b) {
11225 if (!a) {
11226 a = {};
11227 }
11228
11229 if (b) {
11230 for (var name in b) {
11231 if (b.hasOwnProperty(name)) {
11232 a[name] = b[name];
11233 }
11234 }
11235 }
11236
11237 return a;
11238}
11239/**
11240 * Set a value in an object, where the provided parameter name can be a
11241 * path with nested parameters. For example:
11242 *
11243 * var obj = {a: 2};
11244 * setValue(obj, 'b.c', 3); // obj = {a: 2, b: {c: 3}}
11245 *
11246 * @param {object} obj
11247 * @param {string} path A parameter name or dot-separated parameter path,
11248 * like "color.highlight.border".
11249 * @param {*} value
11250 */
11251
11252
11253function setValue(obj, path, value) {
11254 var keys = path.split(".");
11255 var o = obj;
11256
11257 while (keys.length) {
11258 var key = keys.shift();
11259
11260 if (keys.length) {
11261 // this isn't the end point
11262 if (!o[key]) {
11263 o[key] = {};
11264 }
11265
11266 o = o[key];
11267 } else {
11268 // this is the end point
11269 o[key] = value;
11270 }
11271 }
11272}
11273/**
11274 * Add a node to a graph object. If there is already a node with
11275 * the same id, their attributes will be merged.
11276 *
11277 * @param {object} graph
11278 * @param {object} node
11279 */
11280
11281
11282function addNode(graph, node) {
11283 var i, len;
11284 var current = null; // find root graph (in case of subgraph)
11285
11286 var graphs = [graph]; // list with all graphs from current graph to root graph
11287
11288 var root = graph;
11289
11290 while (root.parent) {
11291 graphs.push(root.parent);
11292 root = root.parent;
11293 } // find existing node (at root level) by its id
11294
11295
11296 if (root.nodes) {
11297 for (i = 0, len = root.nodes.length; i < len; i++) {
11298 if (node.id === root.nodes[i].id) {
11299 current = root.nodes[i];
11300 break;
11301 }
11302 }
11303 }
11304
11305 if (!current) {
11306 // this is a new node
11307 current = {
11308 id: node.id
11309 };
11310
11311 if (graph.node) {
11312 // clone default attributes
11313 current.attr = merge$1(current.attr, graph.node);
11314 }
11315 } // add node to this (sub)graph and all its parent graphs
11316
11317
11318 for (i = graphs.length - 1; i >= 0; i--) {
11319 var _context;
11320
11321 var g = graphs[i];
11322
11323 if (!g.nodes) {
11324 g.nodes = [];
11325 }
11326
11327 if (indexOf(_context = g.nodes).call(_context, current) === -1) {
11328 g.nodes.push(current);
11329 }
11330 } // merge attributes
11331
11332
11333 if (node.attr) {
11334 current.attr = merge$1(current.attr, node.attr);
11335 }
11336}
11337/**
11338 * Add an edge to a graph object
11339 *
11340 * @param {object} graph
11341 * @param {object} edge
11342 */
11343
11344
11345function addEdge(graph, edge) {
11346 if (!graph.edges) {
11347 graph.edges = [];
11348 }
11349
11350 graph.edges.push(edge);
11351
11352 if (graph.edge) {
11353 var attr = merge$1({}, graph.edge); // clone default attributes
11354
11355 edge.attr = merge$1(attr, edge.attr); // merge attributes
11356 }
11357}
11358/**
11359 * Create an edge to a graph object
11360 *
11361 * @param {object} graph
11362 * @param {string | number | object} from
11363 * @param {string | number | object} to
11364 * @param {string} type
11365 * @param {object | null} attr
11366 * @returns {object} edge
11367 */
11368
11369
11370function createEdge(graph, from, to, type, attr) {
11371 var edge = {
11372 from: from,
11373 to: to,
11374 type: type
11375 };
11376
11377 if (graph.edge) {
11378 edge.attr = merge$1({}, graph.edge); // clone default attributes
11379 }
11380
11381 edge.attr = merge$1(edge.attr || {}, attr); // merge attributes
11382 // Move arrows attribute from attr to edge temporally created in
11383 // parseAttributeList().
11384
11385 if (attr != null) {
11386 if (attr.hasOwnProperty("arrows") && attr["arrows"] != null) {
11387 edge["arrows"] = {
11388 to: {
11389 enabled: true,
11390 type: attr.arrows.type
11391 }
11392 };
11393 attr["arrows"] = null;
11394 }
11395 }
11396
11397 return edge;
11398}
11399/**
11400 * Get next token in the current dot file.
11401 * The token and token type are available as token and tokenType
11402 */
11403
11404
11405function getToken() {
11406 tokenType = TOKENTYPE.NULL;
11407 token = ""; // skip over whitespaces
11408
11409 while (c === " " || c === "\t" || c === "\n" || c === "\r") {
11410 // space, tab, enter
11411 next();
11412 }
11413
11414 do {
11415 var isComment = false; // skip comment
11416
11417 if (c === "#") {
11418 // find the previous non-space character
11419 var i = index$1 - 1;
11420
11421 while (dot.charAt(i) === " " || dot.charAt(i) === "\t") {
11422 i--;
11423 }
11424
11425 if (dot.charAt(i) === "\n" || dot.charAt(i) === "") {
11426 // the # is at the start of a line, this is indeed a line comment
11427 while (c != "" && c != "\n") {
11428 next();
11429 }
11430
11431 isComment = true;
11432 }
11433 }
11434
11435 if (c === "/" && nextPreview() === "/") {
11436 // skip line comment
11437 while (c != "" && c != "\n") {
11438 next();
11439 }
11440
11441 isComment = true;
11442 }
11443
11444 if (c === "/" && nextPreview() === "*") {
11445 // skip block comment
11446 while (c != "") {
11447 if (c === "*" && nextPreview() === "/") {
11448 // end of block comment found. skip these last two characters
11449 next();
11450 next();
11451 break;
11452 } else {
11453 next();
11454 }
11455 }
11456
11457 isComment = true;
11458 } // skip over whitespaces
11459
11460
11461 while (c === " " || c === "\t" || c === "\n" || c === "\r") {
11462 // space, tab, enter
11463 next();
11464 }
11465 } while (isComment); // check for end of dot file
11466
11467
11468 if (c === "") {
11469 // token is still empty
11470 tokenType = TOKENTYPE.DELIMITER;
11471 return;
11472 } // check for delimiters consisting of 2 characters
11473
11474
11475 var c2 = c + nextPreview();
11476
11477 if (DELIMITERS[c2]) {
11478 tokenType = TOKENTYPE.DELIMITER;
11479 token = c2;
11480 next();
11481 next();
11482 return;
11483 } // check for delimiters consisting of 1 character
11484
11485
11486 if (DELIMITERS[c]) {
11487 tokenType = TOKENTYPE.DELIMITER;
11488 token = c;
11489 next();
11490 return;
11491 } // check for an identifier (number or string)
11492 // TODO: more precise parsing of numbers/strings (and the port separator ':')
11493
11494
11495 if (isAlphaNumeric(c) || c === "-") {
11496 token += c;
11497 next();
11498
11499 while (isAlphaNumeric(c)) {
11500 token += c;
11501 next();
11502 }
11503
11504 if (token === "false") {
11505 token = false; // convert to boolean
11506 } else if (token === "true") {
11507 token = true; // convert to boolean
11508 } else if (!isNaN(Number(token))) {
11509 token = Number(token); // convert to number
11510 }
11511
11512 tokenType = TOKENTYPE.IDENTIFIER;
11513 return;
11514 } // check for a string enclosed by double quotes
11515
11516
11517 if (c === '"') {
11518 next();
11519
11520 while (c != "" && (c != '"' || c === '"' && nextPreview() === '"')) {
11521 if (c === '"') {
11522 // skip the escape character
11523 token += c;
11524 next();
11525 } else if (c === "\\" && nextPreview() === "n") {
11526 // Honor a newline escape sequence
11527 token += "\n";
11528 next();
11529 } else {
11530 token += c;
11531 }
11532
11533 next();
11534 }
11535
11536 if (c != '"') {
11537 throw newSyntaxError('End of string " expected');
11538 }
11539
11540 next();
11541 tokenType = TOKENTYPE.IDENTIFIER;
11542 return;
11543 } // something unknown is found, wrong characters, a syntax error
11544
11545
11546 tokenType = TOKENTYPE.UNKNOWN;
11547
11548 while (c != "") {
11549 token += c;
11550 next();
11551 }
11552
11553 throw new SyntaxError('Syntax error in part "' + chop(token, 30) + '"');
11554}
11555/**
11556 * Parse a graph.
11557 *
11558 * @returns {object} graph
11559 */
11560
11561
11562function parseGraph() {
11563 var graph = {};
11564 first();
11565 getToken(); // optional strict keyword
11566
11567 if (token === "strict") {
11568 graph.strict = true;
11569 getToken();
11570 } // graph or digraph keyword
11571
11572
11573 if (token === "graph" || token === "digraph") {
11574 graph.type = token;
11575 getToken();
11576 } // optional graph id
11577
11578
11579 if (tokenType === TOKENTYPE.IDENTIFIER) {
11580 graph.id = token;
11581 getToken();
11582 } // open angle bracket
11583
11584
11585 if (token != "{") {
11586 throw newSyntaxError("Angle bracket { expected");
11587 }
11588
11589 getToken(); // statements
11590
11591 parseStatements(graph); // close angle bracket
11592
11593 if (token != "}") {
11594 throw newSyntaxError("Angle bracket } expected");
11595 }
11596
11597 getToken(); // end of file
11598
11599 if (token !== "") {
11600 throw newSyntaxError("End of file expected");
11601 }
11602
11603 getToken(); // remove temporary default options
11604
11605 delete graph.node;
11606 delete graph.edge;
11607 delete graph.graph;
11608 return graph;
11609}
11610/**
11611 * Parse a list with statements.
11612 *
11613 * @param {object} graph
11614 */
11615
11616
11617function parseStatements(graph) {
11618 while (token !== "" && token != "}") {
11619 parseStatement(graph);
11620
11621 if (token === ";") {
11622 getToken();
11623 }
11624 }
11625}
11626/**
11627 * Parse a single statement. Can be a an attribute statement, node
11628 * statement, a series of node statements and edge statements, or a
11629 * parameter.
11630 *
11631 * @param {object} graph
11632 */
11633
11634
11635function parseStatement(graph) {
11636 // parse subgraph
11637 var subgraph = parseSubgraph(graph);
11638
11639 if (subgraph) {
11640 // edge statements
11641 parseEdge(graph, subgraph);
11642 return;
11643 } // parse an attribute statement
11644
11645
11646 var attr = parseAttributeStatement(graph);
11647
11648 if (attr) {
11649 return;
11650 } // parse node
11651
11652
11653 if (tokenType != TOKENTYPE.IDENTIFIER) {
11654 throw newSyntaxError("Identifier expected");
11655 }
11656
11657 var id = token; // id can be a string or a number
11658
11659 getToken();
11660
11661 if (token === "=") {
11662 // id statement
11663 getToken();
11664
11665 if (tokenType != TOKENTYPE.IDENTIFIER) {
11666 throw newSyntaxError("Identifier expected");
11667 }
11668
11669 graph[id] = token;
11670 getToken(); // TODO: implement comma separated list with "a_list: ID=ID [','] [a_list] "
11671 } else {
11672 parseNodeStatement(graph, id);
11673 }
11674}
11675/**
11676 * Parse a subgraph
11677 *
11678 * @param {object} graph parent graph object
11679 * @returns {object | null} subgraph
11680 */
11681
11682
11683function parseSubgraph(graph) {
11684 var subgraph = null; // optional subgraph keyword
11685
11686 if (token === "subgraph") {
11687 subgraph = {};
11688 subgraph.type = "subgraph";
11689 getToken(); // optional graph id
11690
11691 if (tokenType === TOKENTYPE.IDENTIFIER) {
11692 subgraph.id = token;
11693 getToken();
11694 }
11695 } // open angle bracket
11696
11697
11698 if (token === "{") {
11699 getToken();
11700
11701 if (!subgraph) {
11702 subgraph = {};
11703 }
11704
11705 subgraph.parent = graph;
11706 subgraph.node = graph.node;
11707 subgraph.edge = graph.edge;
11708 subgraph.graph = graph.graph; // statements
11709
11710 parseStatements(subgraph); // close angle bracket
11711
11712 if (token != "}") {
11713 throw newSyntaxError("Angle bracket } expected");
11714 }
11715
11716 getToken(); // remove temporary default options
11717
11718 delete subgraph.node;
11719 delete subgraph.edge;
11720 delete subgraph.graph;
11721 delete subgraph.parent; // register at the parent graph
11722
11723 if (!graph.subgraphs) {
11724 graph.subgraphs = [];
11725 }
11726
11727 graph.subgraphs.push(subgraph);
11728 }
11729
11730 return subgraph;
11731}
11732/**
11733 * parse an attribute statement like "node [shape=circle fontSize=16]".
11734 * Available keywords are 'node', 'edge', 'graph'.
11735 * The previous list with default attributes will be replaced
11736 *
11737 * @param {object} graph
11738 * @returns {string | null} keyword Returns the name of the parsed attribute
11739 * (node, edge, graph), or null if nothing
11740 * is parsed.
11741 */
11742
11743
11744function parseAttributeStatement(graph) {
11745 // attribute statements
11746 if (token === "node") {
11747 getToken(); // node attributes
11748
11749 graph.node = parseAttributeList();
11750 return "node";
11751 } else if (token === "edge") {
11752 getToken(); // edge attributes
11753
11754 graph.edge = parseAttributeList();
11755 return "edge";
11756 } else if (token === "graph") {
11757 getToken(); // graph attributes
11758
11759 graph.graph = parseAttributeList();
11760 return "graph";
11761 }
11762
11763 return null;
11764}
11765/**
11766 * parse a node statement
11767 *
11768 * @param {object} graph
11769 * @param {string | number} id
11770 */
11771
11772
11773function parseNodeStatement(graph, id) {
11774 // node statement
11775 var node = {
11776 id: id
11777 };
11778 var attr = parseAttributeList();
11779
11780 if (attr) {
11781 node.attr = attr;
11782 }
11783
11784 addNode(graph, node); // edge statements
11785
11786 parseEdge(graph, id);
11787}
11788/**
11789 * Parse an edge or a series of edges
11790 *
11791 * @param {object} graph
11792 * @param {string | number} from Id of the from node
11793 */
11794
11795
11796function parseEdge(graph, from) {
11797 while (token === "->" || token === "--") {
11798 var to;
11799 var type = token;
11800 getToken();
11801 var subgraph = parseSubgraph(graph);
11802
11803 if (subgraph) {
11804 to = subgraph;
11805 } else {
11806 if (tokenType != TOKENTYPE.IDENTIFIER) {
11807 throw newSyntaxError("Identifier or subgraph expected");
11808 }
11809
11810 to = token;
11811 addNode(graph, {
11812 id: to
11813 });
11814 getToken();
11815 } // parse edge attributes
11816
11817
11818 var attr = parseAttributeList(); // create edge
11819
11820 var edge = createEdge(graph, from, to, type, attr);
11821 addEdge(graph, edge);
11822 from = to;
11823 }
11824}
11825/**
11826 * Parse a set with attributes,
11827 * for example [label="1.000", shape=solid]
11828 *
11829 * @returns {object | null} attr
11830 */
11831
11832
11833function parseAttributeList() {
11834 var i;
11835 var attr = null; // edge styles of dot and vis
11836
11837 var edgeStyles = {
11838 dashed: true,
11839 solid: false,
11840 dotted: [1, 5]
11841 };
11842 /**
11843 * Define arrow types.
11844 * vis currently supports types defined in 'arrowTypes'.
11845 * Details of arrow shapes are described in
11846 * http://www.graphviz.org/content/arrow-shapes
11847 */
11848
11849 var arrowTypes = {
11850 dot: "circle",
11851 box: "box",
11852 crow: "crow",
11853 curve: "curve",
11854 icurve: "inv_curve",
11855 normal: "triangle",
11856 inv: "inv_triangle",
11857 diamond: "diamond",
11858 tee: "bar",
11859 vee: "vee"
11860 };
11861 /**
11862 * 'attr_list' contains attributes for checking if some of them are affected
11863 * later. For instance, both of 'arrowhead' and 'dir' (edge style defined
11864 * in DOT) make changes to 'arrows' attribute in vis.
11865 */
11866
11867 var attr_list = new Array();
11868 var attr_names = new Array(); // used for checking the case.
11869 // parse attributes
11870
11871 while (token === "[") {
11872 getToken();
11873 attr = {};
11874
11875 while (token !== "" && token != "]") {
11876 if (tokenType != TOKENTYPE.IDENTIFIER) {
11877 throw newSyntaxError("Attribute name expected");
11878 }
11879
11880 var name = token;
11881 getToken();
11882
11883 if (token != "=") {
11884 throw newSyntaxError("Equal sign = expected");
11885 }
11886
11887 getToken();
11888
11889 if (tokenType != TOKENTYPE.IDENTIFIER) {
11890 throw newSyntaxError("Attribute value expected");
11891 }
11892
11893 var value = token; // convert from dot style to vis
11894
11895 if (name === "style") {
11896 value = edgeStyles[value];
11897 }
11898
11899 var arrowType;
11900
11901 if (name === "arrowhead") {
11902 arrowType = arrowTypes[value];
11903 name = "arrows";
11904 value = {
11905 to: {
11906 enabled: true,
11907 type: arrowType
11908 }
11909 };
11910 }
11911
11912 if (name === "arrowtail") {
11913 arrowType = arrowTypes[value];
11914 name = "arrows";
11915 value = {
11916 from: {
11917 enabled: true,
11918 type: arrowType
11919 }
11920 };
11921 }
11922
11923 attr_list.push({
11924 attr: attr,
11925 name: name,
11926 value: value
11927 });
11928 attr_names.push(name);
11929 getToken();
11930
11931 if (token == ",") {
11932 getToken();
11933 }
11934 }
11935
11936 if (token != "]") {
11937 throw newSyntaxError("Bracket ] expected");
11938 }
11939
11940 getToken();
11941 }
11942 /**
11943 * As explained in [1], graphviz has limitations for combination of
11944 * arrow[head|tail] and dir. If attribute list includes 'dir',
11945 * following cases just be supported.
11946 * 1. both or none + arrowhead, arrowtail
11947 * 2. forward + arrowhead (arrowtail is not affedted)
11948 * 3. back + arrowtail (arrowhead is not affected)
11949 * [1] https://www.graphviz.org/doc/info/attrs.html#h:undir_note
11950 */
11951
11952
11953 if (includes(attr_names).call(attr_names, "dir")) {
11954 var idx = {}; // get index of 'arrows' and 'dir'
11955
11956 idx.arrows = {};
11957
11958 for (i = 0; i < attr_list.length; i++) {
11959 if (attr_list[i].name === "arrows") {
11960 if (attr_list[i].value.to != null) {
11961 idx.arrows.to = i;
11962 } else if (attr_list[i].value.from != null) {
11963 idx.arrows.from = i;
11964 } else {
11965 throw newSyntaxError("Invalid value of arrows");
11966 }
11967 } else if (attr_list[i].name === "dir") {
11968 idx.dir = i;
11969 }
11970 } // first, add default arrow shape if it is not assigned to avoid error
11971
11972
11973 var dir_type = attr_list[idx.dir].value;
11974
11975 if (!includes(attr_names).call(attr_names, "arrows")) {
11976 if (dir_type === "both") {
11977 attr_list.push({
11978 attr: attr_list[idx.dir].attr,
11979 name: "arrows",
11980 value: {
11981 to: {
11982 enabled: true
11983 }
11984 }
11985 });
11986 idx.arrows.to = attr_list.length - 1;
11987 attr_list.push({
11988 attr: attr_list[idx.dir].attr,
11989 name: "arrows",
11990 value: {
11991 from: {
11992 enabled: true
11993 }
11994 }
11995 });
11996 idx.arrows.from = attr_list.length - 1;
11997 } else if (dir_type === "forward") {
11998 attr_list.push({
11999 attr: attr_list[idx.dir].attr,
12000 name: "arrows",
12001 value: {
12002 to: {
12003 enabled: true
12004 }
12005 }
12006 });
12007 idx.arrows.to = attr_list.length - 1;
12008 } else if (dir_type === "back") {
12009 attr_list.push({
12010 attr: attr_list[idx.dir].attr,
12011 name: "arrows",
12012 value: {
12013 from: {
12014 enabled: true
12015 }
12016 }
12017 });
12018 idx.arrows.from = attr_list.length - 1;
12019 } else if (dir_type === "none") {
12020 attr_list.push({
12021 attr: attr_list[idx.dir].attr,
12022 name: "arrows",
12023 value: ""
12024 });
12025 idx.arrows.to = attr_list.length - 1;
12026 } else {
12027 throw newSyntaxError('Invalid dir type "' + dir_type + '"');
12028 }
12029 }
12030
12031 var from_type;
12032 var to_type; // update 'arrows' attribute from 'dir'.
12033
12034 if (dir_type === "both") {
12035 // both of shapes of 'from' and 'to' are given
12036 if (idx.arrows.to && idx.arrows.from) {
12037 to_type = attr_list[idx.arrows.to].value.to.type;
12038 from_type = attr_list[idx.arrows.from].value.from.type;
12039 attr_list[idx.arrows.to] = {
12040 attr: attr_list[idx.arrows.to].attr,
12041 name: attr_list[idx.arrows.to].name,
12042 value: {
12043 to: {
12044 enabled: true,
12045 type: to_type
12046 },
12047 from: {
12048 enabled: true,
12049 type: from_type
12050 }
12051 }
12052 };
12053
12054 splice(attr_list).call(attr_list, idx.arrows.from, 1); // shape of 'to' is assigned and use default to 'from'
12055
12056 } else if (idx.arrows.to) {
12057 to_type = attr_list[idx.arrows.to].value.to.type;
12058 from_type = "arrow";
12059 attr_list[idx.arrows.to] = {
12060 attr: attr_list[idx.arrows.to].attr,
12061 name: attr_list[idx.arrows.to].name,
12062 value: {
12063 to: {
12064 enabled: true,
12065 type: to_type
12066 },
12067 from: {
12068 enabled: true,
12069 type: from_type
12070 }
12071 }
12072 }; // only shape of 'from' is assigned and use default for 'to'
12073 } else if (idx.arrows.from) {
12074 to_type = "arrow";
12075 from_type = attr_list[idx.arrows.from].value.from.type;
12076 attr_list[idx.arrows.from] = {
12077 attr: attr_list[idx.arrows.from].attr,
12078 name: attr_list[idx.arrows.from].name,
12079 value: {
12080 to: {
12081 enabled: true,
12082 type: to_type
12083 },
12084 from: {
12085 enabled: true,
12086 type: from_type
12087 }
12088 }
12089 };
12090 }
12091 } else if (dir_type === "back") {
12092 // given both of shapes, but use only 'from'
12093 if (idx.arrows.to && idx.arrows.from) {
12094 to_type = "";
12095 from_type = attr_list[idx.arrows.from].value.from.type;
12096 attr_list[idx.arrows.from] = {
12097 attr: attr_list[idx.arrows.from].attr,
12098 name: attr_list[idx.arrows.from].name,
12099 value: {
12100 to: {
12101 enabled: true,
12102 type: to_type
12103 },
12104 from: {
12105 enabled: true,
12106 type: from_type
12107 }
12108 }
12109 }; // given shape of 'to', but does not use it
12110 } else if (idx.arrows.to) {
12111 to_type = "";
12112 from_type = "arrow";
12113 idx.arrows.from = idx.arrows.to;
12114 attr_list[idx.arrows.from] = {
12115 attr: attr_list[idx.arrows.from].attr,
12116 name: attr_list[idx.arrows.from].name,
12117 value: {
12118 to: {
12119 enabled: true,
12120 type: to_type
12121 },
12122 from: {
12123 enabled: true,
12124 type: from_type
12125 }
12126 }
12127 }; // assign given 'from' shape
12128 } else if (idx.arrows.from) {
12129 to_type = "";
12130 from_type = attr_list[idx.arrows.from].value.from.type;
12131 attr_list[idx.arrows.to] = {
12132 attr: attr_list[idx.arrows.from].attr,
12133 name: attr_list[idx.arrows.from].name,
12134 value: {
12135 to: {
12136 enabled: true,
12137 type: to_type
12138 },
12139 from: {
12140 enabled: true,
12141 type: from_type
12142 }
12143 }
12144 };
12145 }
12146
12147 attr_list[idx.arrows.from] = {
12148 attr: attr_list[idx.arrows.from].attr,
12149 name: attr_list[idx.arrows.from].name,
12150 value: {
12151 from: {
12152 enabled: true,
12153 type: attr_list[idx.arrows.from].value.from.type
12154 }
12155 }
12156 };
12157 } else if (dir_type === "none") {
12158 var idx_arrow;
12159
12160 if (idx.arrows.to) {
12161 idx_arrow = idx.arrows.to;
12162 } else {
12163 idx_arrow = idx.arrows.from;
12164 }
12165
12166 attr_list[idx_arrow] = {
12167 attr: attr_list[idx_arrow].attr,
12168 name: attr_list[idx_arrow].name,
12169 value: ""
12170 };
12171 } else if (dir_type === "forward") {
12172 // given both of shapes, but use only 'to'
12173 if (idx.arrows.to && idx.arrows.from) {
12174 to_type = attr_list[idx.arrows.to].value.to.type;
12175 from_type = "";
12176 attr_list[idx.arrows.to] = {
12177 attr: attr_list[idx.arrows.to].attr,
12178 name: attr_list[idx.arrows.to].name,
12179 value: {
12180 to: {
12181 enabled: true,
12182 type: to_type
12183 },
12184 from: {
12185 enabled: true,
12186 type: from_type
12187 }
12188 }
12189 }; // assign given 'to' shape
12190 } else if (idx.arrows.to) {
12191 to_type = attr_list[idx.arrows.to].value.to.type;
12192 from_type = "";
12193 attr_list[idx.arrows.to] = {
12194 attr: attr_list[idx.arrows.to].attr,
12195 name: attr_list[idx.arrows.to].name,
12196 value: {
12197 to: {
12198 enabled: true,
12199 type: to_type
12200 },
12201 from: {
12202 enabled: true,
12203 type: from_type
12204 }
12205 }
12206 }; // given shape of 'from', but does not use it
12207 } else if (idx.arrows.from) {
12208 to_type = "arrow";
12209 from_type = "";
12210 idx.arrows.to = idx.arrows.from;
12211 attr_list[idx.arrows.to] = {
12212 attr: attr_list[idx.arrows.to].attr,
12213 name: attr_list[idx.arrows.to].name,
12214 value: {
12215 to: {
12216 enabled: true,
12217 type: to_type
12218 },
12219 from: {
12220 enabled: true,
12221 type: from_type
12222 }
12223 }
12224 };
12225 }
12226
12227 attr_list[idx.arrows.to] = {
12228 attr: attr_list[idx.arrows.to].attr,
12229 name: attr_list[idx.arrows.to].name,
12230 value: {
12231 to: {
12232 enabled: true,
12233 type: attr_list[idx.arrows.to].value.to.type
12234 }
12235 }
12236 };
12237 } else {
12238 throw newSyntaxError('Invalid dir type "' + dir_type + '"');
12239 } // remove 'dir' attribute no need anymore
12240
12241
12242 splice(attr_list).call(attr_list, idx.dir, 1);
12243 } // parse 'penwidth'
12244
12245
12246 var nof_attr_list;
12247
12248 if (includes(attr_names).call(attr_names, "penwidth")) {
12249 var tmp_attr_list = [];
12250 nof_attr_list = attr_list.length;
12251
12252 for (i = 0; i < nof_attr_list; i++) {
12253 // exclude 'width' from attr_list if 'penwidth' exists
12254 if (attr_list[i].name !== "width") {
12255 if (attr_list[i].name === "penwidth") {
12256 attr_list[i].name = "width";
12257 }
12258
12259 tmp_attr_list.push(attr_list[i]);
12260 }
12261 }
12262
12263 attr_list = tmp_attr_list;
12264 }
12265
12266 nof_attr_list = attr_list.length;
12267
12268 for (i = 0; i < nof_attr_list; i++) {
12269 setValue(attr_list[i].attr, attr_list[i].name, attr_list[i].value);
12270 }
12271
12272 return attr;
12273}
12274/**
12275 * Create a syntax error with extra information on current token and index.
12276 *
12277 * @param {string} message
12278 * @returns {SyntaxError} err
12279 */
12280
12281
12282function newSyntaxError(message) {
12283 return new SyntaxError(message + ', got "' + chop(token, 30) + '" (char ' + index$1 + ")");
12284}
12285/**
12286 * Chop off text after a maximum length
12287 *
12288 * @param {string} text
12289 * @param {number} maxLength
12290 * @returns {string}
12291 */
12292
12293
12294function chop(text, maxLength) {
12295 return text.length <= maxLength ? text : text.substr(0, 27) + "...";
12296}
12297/**
12298 * Execute a function fn for each pair of elements in two arrays
12299 *
12300 * @param {Array | *} array1
12301 * @param {Array | *} array2
12302 * @param {Function} fn
12303 */
12304
12305
12306function forEach2(array1, array2, fn) {
12307 if (isArray$2(array1)) {
12308 forEach$2(array1).call(array1, function (elem1) {
12309 if (isArray$2(array2)) {
12310 forEach$2(array2).call(array2, function (elem2) {
12311 fn(elem1, elem2);
12312 });
12313 } else {
12314 fn(elem1, array2);
12315 }
12316 });
12317 } else {
12318 if (isArray$2(array2)) {
12319 forEach$2(array2).call(array2, function (elem2) {
12320 fn(array1, elem2);
12321 });
12322 } else {
12323 fn(array1, array2);
12324 }
12325 }
12326}
12327/**
12328 * Set a nested property on an object
12329 * When nested objects are missing, they will be created.
12330 * For example setProp({}, 'font.color', 'red') will return {font: {color: 'red'}}
12331 *
12332 * @param {object} object
12333 * @param {string} path A dot separated string like 'font.color'
12334 * @param {*} value Value for the property
12335 * @returns {object} Returns the original object, allows for chaining.
12336 */
12337
12338
12339function setProp(object, path, value) {
12340 var names = path.split(".");
12341 var prop = names.pop(); // traverse over the nested objects
12342
12343 var obj = object;
12344
12345 for (var i = 0; i < names.length; i++) {
12346 var name = names[i];
12347
12348 if (!(name in obj)) {
12349 obj[name] = {};
12350 }
12351
12352 obj = obj[name];
12353 } // set the property value
12354
12355
12356 obj[prop] = value;
12357 return object;
12358}
12359/**
12360 * Convert an object with DOT attributes to their vis.js equivalents.
12361 *
12362 * @param {object} attr Object with DOT attributes
12363 * @param {object} mapping
12364 * @returns {object} Returns an object with vis.js attributes
12365 */
12366
12367
12368function convertAttr(attr, mapping) {
12369 var converted = {};
12370
12371 for (var prop in attr) {
12372 if (attr.hasOwnProperty(prop)) {
12373 var visProp = mapping[prop];
12374
12375 if (isArray$2(visProp)) {
12376 forEach$2(visProp).call(visProp, function (visPropI) {
12377 setProp(converted, visPropI, attr[prop]);
12378 });
12379 } else if (typeof visProp === "string") {
12380 setProp(converted, visProp, attr[prop]);
12381 } else {
12382 setProp(converted, prop, attr[prop]);
12383 }
12384 }
12385 }
12386
12387 return converted;
12388}
12389/**
12390 * Convert a string containing a graph in DOT language into a map containing
12391 * with nodes and edges in the format of graph.
12392 *
12393 * @param {string} data Text containing a graph in DOT-notation
12394 * @returns {object} graphData
12395 */
12396
12397
12398function DOTToGraph(data) {
12399 // parse the DOT file
12400 var dotData = parseDOT(data);
12401 var graphData = {
12402 nodes: [],
12403 edges: [],
12404 options: {}
12405 }; // copy the nodes
12406
12407 if (dotData.nodes) {
12408 var _context2;
12409
12410 forEach$2(_context2 = dotData.nodes).call(_context2, function (dotNode) {
12411 var graphNode = {
12412 id: dotNode.id,
12413 label: String(dotNode.label || dotNode.id)
12414 };
12415 merge$1(graphNode, convertAttr(dotNode.attr, NODE_ATTR_MAPPING));
12416
12417 if (graphNode.image) {
12418 graphNode.shape = "image";
12419 }
12420
12421 graphData.nodes.push(graphNode);
12422 });
12423 } // copy the edges
12424
12425
12426 if (dotData.edges) {
12427 var _context3;
12428
12429 /**
12430 * Convert an edge in DOT format to an edge with VisGraph format
12431 *
12432 * @param {object} dotEdge
12433 * @returns {object} graphEdge
12434 */
12435 var convertEdge = function convertEdge(dotEdge) {
12436 var graphEdge = {
12437 from: dotEdge.from,
12438 to: dotEdge.to
12439 };
12440 merge$1(graphEdge, convertAttr(dotEdge.attr, EDGE_ATTR_MAPPING)); // Add arrows attribute to default styled arrow.
12441 // The reason why default style is not added in parseAttributeList() is
12442 // because only default is cleared before here.
12443
12444 if (graphEdge.arrows == null && dotEdge.type === "->") {
12445 graphEdge.arrows = "to";
12446 }
12447
12448 return graphEdge;
12449 };
12450
12451 forEach$2(_context3 = dotData.edges).call(_context3, function (dotEdge) {
12452 var from, to;
12453
12454 if (dotEdge.from instanceof Object) {
12455 from = dotEdge.from.nodes;
12456 } else {
12457 from = {
12458 id: dotEdge.from
12459 };
12460 }
12461
12462 if (dotEdge.to instanceof Object) {
12463 to = dotEdge.to.nodes;
12464 } else {
12465 to = {
12466 id: dotEdge.to
12467 };
12468 }
12469
12470 if (dotEdge.from instanceof Object && dotEdge.from.edges) {
12471 var _context4;
12472
12473 forEach$2(_context4 = dotEdge.from.edges).call(_context4, function (subEdge) {
12474 var graphEdge = convertEdge(subEdge);
12475 graphData.edges.push(graphEdge);
12476 });
12477 }
12478
12479 forEach2(from, to, function (from, to) {
12480 var subEdge = createEdge(graphData, from.id, to.id, dotEdge.type, dotEdge.attr);
12481 var graphEdge = convertEdge(subEdge);
12482 graphData.edges.push(graphEdge);
12483 });
12484
12485 if (dotEdge.to instanceof Object && dotEdge.to.edges) {
12486 var _context5;
12487
12488 forEach$2(_context5 = dotEdge.to.edges).call(_context5, function (subEdge) {
12489 var graphEdge = convertEdge(subEdge);
12490 graphData.edges.push(graphEdge);
12491 });
12492 }
12493 });
12494 } // copy the options
12495
12496
12497 if (dotData.attr) {
12498 graphData.options = dotData.attr;
12499 }
12500
12501 return graphData;
12502}
12503/* eslint-enable no-var */
12504
12505/* eslint-enable no-unused-vars */
12506
12507/* eslint-enable no-prototype-builtins */
12508
12509var dotparser = /*#__PURE__*/Object.freeze({
12510 __proto__: null,
12511 parseDOT: parseDOT,
12512 DOTToGraph: DOTToGraph
12513});
12514
12515/**
12516 * Convert Gephi to Vis.
12517 *
12518 * @param gephiJSON - The parsed JSON data in Gephi format.
12519 * @param optionsObj - Additional options.
12520 *
12521 * @returns The converted data ready to be used in Vis.
12522 */
12523function parseGephi(gephiJSON, optionsObj) {
12524 var _context;
12525
12526 var options = {
12527 edges: {
12528 inheritColor: false
12529 },
12530 nodes: {
12531 fixed: false,
12532 parseColor: false
12533 }
12534 };
12535
12536 if (optionsObj != null) {
12537 if (optionsObj.fixed != null) {
12538 options.nodes.fixed = optionsObj.fixed;
12539 }
12540
12541 if (optionsObj.parseColor != null) {
12542 options.nodes.parseColor = optionsObj.parseColor;
12543 }
12544
12545 if (optionsObj.inheritColor != null) {
12546 options.edges.inheritColor = optionsObj.inheritColor;
12547 }
12548 }
12549
12550 var gEdges = gephiJSON.edges;
12551
12552 var vEdges = map$3(gEdges).call(gEdges, function (gEdge) {
12553 var vEdge = {
12554 from: gEdge.source,
12555 id: gEdge.id,
12556 to: gEdge.target
12557 };
12558
12559 if (gEdge.attributes != null) {
12560 vEdge.attributes = gEdge.attributes;
12561 }
12562
12563 if (gEdge.label != null) {
12564 vEdge.label = gEdge.label;
12565 }
12566
12567 if (gEdge.attributes != null && gEdge.attributes.title != null) {
12568 vEdge.title = gEdge.attributes.title;
12569 }
12570
12571 if (gEdge.type === "Directed") {
12572 vEdge.arrows = "to";
12573 } // edge['value'] = gEdge.attributes != null ? gEdge.attributes.Weight : undefined;
12574 // edge['width'] = edge['value'] != null ? undefined : edgegEdge.size;
12575
12576
12577 if (gEdge.color && options.edges.inheritColor === false) {
12578 vEdge.color = gEdge.color;
12579 }
12580
12581 return vEdge;
12582 });
12583
12584 var vNodes = map$3(_context = gephiJSON.nodes).call(_context, function (gNode) {
12585 var vNode = {
12586 id: gNode.id,
12587 fixed: options.nodes.fixed && gNode.x != null && gNode.y != null
12588 };
12589
12590 if (gNode.attributes != null) {
12591 vNode.attributes = gNode.attributes;
12592 }
12593
12594 if (gNode.label != null) {
12595 vNode.label = gNode.label;
12596 }
12597
12598 if (gNode.size != null) {
12599 vNode.size = gNode.size;
12600 }
12601
12602 if (gNode.attributes != null && gNode.attributes.title != null) {
12603 vNode.title = gNode.attributes.title;
12604 }
12605
12606 if (gNode.title != null) {
12607 vNode.title = gNode.title;
12608 }
12609
12610 if (gNode.x != null) {
12611 vNode.x = gNode.x;
12612 }
12613
12614 if (gNode.y != null) {
12615 vNode.y = gNode.y;
12616 }
12617
12618 if (gNode.color != null) {
12619 if (options.nodes.parseColor === true) {
12620 vNode.color = gNode.color;
12621 } else {
12622 vNode.color = {
12623 background: gNode.color,
12624 border: gNode.color,
12625 highlight: {
12626 background: gNode.color,
12627 border: gNode.color
12628 },
12629 hover: {
12630 background: gNode.color,
12631 border: gNode.color
12632 }
12633 };
12634 }
12635 }
12636
12637 return vNode;
12638 });
12639
12640 return {
12641 nodes: vNodes,
12642 edges: vEdges
12643 };
12644}
12645
12646var gephiParser = /*#__PURE__*/Object.freeze({
12647 __proto__: null,
12648 parseGephi: parseGephi
12649});
12650
12651// English
12652var en = {
12653 addDescription: "Click in an empty space to place a new node.",
12654 addEdge: "Add Edge",
12655 addNode: "Add Node",
12656 back: "Back",
12657 close: "Close",
12658 createEdgeError: "Cannot link edges to a cluster.",
12659 del: "Delete selected",
12660 deleteClusterError: "Clusters cannot be deleted.",
12661 edgeDescription: "Click on a node and drag the edge to another node to connect them.",
12662 edit: "Edit",
12663 editClusterError: "Clusters cannot be edited.",
12664 editEdge: "Edit Edge",
12665 editEdgeDescription: "Click on the control points and drag them to a node to connect to it.",
12666 editNode: "Edit Node"
12667}; // German
12668
12669var de = {
12670 addDescription: "Klicke auf eine freie Stelle, um einen neuen Knoten zu plazieren.",
12671 addEdge: "Kante hinzuf\xFCgen",
12672 addNode: "Knoten hinzuf\xFCgen",
12673 back: "Zur\xFCck",
12674 close: "Schließen",
12675 createEdgeError: "Es ist nicht m\xF6glich, Kanten mit Clustern zu verbinden.",
12676 del: "L\xF6sche Auswahl",
12677 deleteClusterError: "Cluster k\xF6nnen nicht gel\xF6scht werden.",
12678 edgeDescription: "Klicke auf einen Knoten und ziehe die Kante zu einem anderen Knoten, um diese zu verbinden.",
12679 edit: "Editieren",
12680 editClusterError: "Cluster k\xF6nnen nicht editiert werden.",
12681 editEdge: "Kante editieren",
12682 editEdgeDescription: "Klicke auf die Verbindungspunkte und ziehe diese auf einen Knoten, um sie zu verbinden.",
12683 editNode: "Knoten editieren"
12684}; // Spanish
12685
12686var es = {
12687 addDescription: "Haga clic en un lugar vac\xEDo para colocar un nuevo nodo.",
12688 addEdge: "A\xF1adir arista",
12689 addNode: "A\xF1adir nodo",
12690 back: "Atr\xE1s",
12691 close: "Cerrar",
12692 createEdgeError: "No se puede conectar una arista a un grupo.",
12693 del: "Eliminar selecci\xF3n",
12694 deleteClusterError: "No es posible eliminar grupos.",
12695 edgeDescription: "Haga clic en un nodo y arrastre la arista hacia otro nodo para conectarlos.",
12696 edit: "Editar",
12697 editClusterError: "No es posible editar grupos.",
12698 editEdge: "Editar arista",
12699 editEdgeDescription: "Haga clic en un punto de control y arrastrelo a un nodo para conectarlo.",
12700 editNode: "Editar nodo"
12701}; //Italiano
12702
12703var it = {
12704 addDescription: "Clicca per aggiungere un nuovo nodo",
12705 addEdge: "Aggiungi un vertice",
12706 addNode: "Aggiungi un nodo",
12707 back: "Indietro",
12708 close: "Chiudere",
12709 createEdgeError: "Non si possono collegare vertici ad un cluster",
12710 del: "Cancella la selezione",
12711 deleteClusterError: "I cluster non possono essere cancellati",
12712 edgeDescription: "Clicca su un nodo e trascinalo ad un altro nodo per connetterli.",
12713 edit: "Modifica",
12714 editClusterError: "I clusters non possono essere modificati.",
12715 editEdge: "Modifica il vertice",
12716 editEdgeDescription: "Clicca sui Punti di controllo e trascinali ad un nodo per connetterli.",
12717 editNode: "Modifica il nodo"
12718}; // Dutch
12719
12720var nl = {
12721 addDescription: "Klik op een leeg gebied om een nieuwe node te maken.",
12722 addEdge: "Link toevoegen",
12723 addNode: "Node toevoegen",
12724 back: "Terug",
12725 close: "Sluiten",
12726 createEdgeError: "Kan geen link maken naar een cluster.",
12727 del: "Selectie verwijderen",
12728 deleteClusterError: "Clusters kunnen niet worden verwijderd.",
12729 edgeDescription: "Klik op een node en sleep de link naar een andere node om ze te verbinden.",
12730 edit: "Wijzigen",
12731 editClusterError: "Clusters kunnen niet worden aangepast.",
12732 editEdge: "Link wijzigen",
12733 editEdgeDescription: "Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.",
12734 editNode: "Node wijzigen"
12735}; // Portuguese Brazil
12736
12737var pt = {
12738 addDescription: "Clique em um espaço em branco para adicionar um novo nó",
12739 addEdge: "Adicionar aresta",
12740 addNode: "Adicionar nó",
12741 back: "Voltar",
12742 close: "Fechar",
12743 createEdgeError: "Não foi possível linkar arestas a um cluster.",
12744 del: "Remover selecionado",
12745 deleteClusterError: "Clusters não puderam ser removidos.",
12746 edgeDescription: "Clique em um nó e arraste a aresta até outro nó para conectá-los",
12747 edit: "Editar",
12748 editClusterError: "Clusters não puderam ser editados.",
12749 editEdge: "Editar aresta",
12750 editEdgeDescription: "Clique nos pontos de controle e os arraste para um nó para conectá-los",
12751 editNode: "Editar nó"
12752}; // Russian
12753
12754var ru = {
12755 addDescription: "Кликните в свободное место, чтобы добавить новый узел.",
12756 addEdge: "Добавить ребро",
12757 addNode: "Добавить узел",
12758 back: "Назад",
12759 close: "Закрывать",
12760 createEdgeError: "Невозможно соединить ребра в кластер.",
12761 del: "Удалить выбранное",
12762 deleteClusterError: "Кластеры не могут быть удалены",
12763 edgeDescription: "Кликните на узел и протяните ребро к другому узлу, чтобы соединить их.",
12764 edit: "Редактировать",
12765 editClusterError: "Кластеры недоступны для редактирования.",
12766 editEdge: "Редактировать ребро",
12767 editEdgeDescription: "Кликните на контрольные точки и перетащите их в узел, чтобы подключиться к нему.",
12768 editNode: "Редактировать узел"
12769}; // Chinese
12770
12771var cn = {
12772 addDescription: "单击空白处放置新节点。",
12773 addEdge: "添加连接线",
12774 addNode: "添加节点",
12775 back: "返回",
12776 close: "關閉",
12777 createEdgeError: "无法将连接线连接到群集。",
12778 del: "删除选定",
12779 deleteClusterError: "无法删除群集。",
12780 edgeDescription: "单击某个节点并将该连接线拖动到另一个节点以连接它们。",
12781 edit: "编辑",
12782 editClusterError: "无法编辑群集。",
12783 editEdge: "编辑连接线",
12784 editEdgeDescription: "单击控制节点并将它们拖到节点上连接。",
12785 editNode: "编辑节点"
12786}; // Ukrainian
12787
12788var uk = {
12789 addDescription: "Kлікніть на вільне місце, щоб додати новий вузол.",
12790 addEdge: "Додати край",
12791 addNode: "Додати вузол",
12792 back: "Назад",
12793 close: "Закрити",
12794 createEdgeError: "Не можливо об'єднати краї в групу.",
12795 del: "Видалити обране",
12796 deleteClusterError: "Групи не можуть бути видалені.",
12797 edgeDescription: "Клікніть на вузол і перетягніть край до іншого вузла, щоб їх з'єднати.",
12798 edit: "Редагувати",
12799 editClusterError: "Групи недоступні для редагування.",
12800 editEdge: "Редагувати край",
12801 editEdgeDescription: "Клікніть на контрольні точки і перетягніть їх у вузол, щоб підключитися до нього.",
12802 editNode: "Редагувати вузол"
12803}; // French
12804
12805var fr = {
12806 addDescription: "Cliquez dans un endroit vide pour placer un nœud.",
12807 addEdge: "Ajouter un lien",
12808 addNode: "Ajouter un nœud",
12809 back: "Retour",
12810 close: "Fermer",
12811 createEdgeError: "Impossible de créer un lien vers un cluster.",
12812 del: "Effacer la sélection",
12813 deleteClusterError: "Les clusters ne peuvent pas être effacés.",
12814 edgeDescription: "Cliquez sur un nœud et glissez le lien vers un autre nœud pour les connecter.",
12815 edit: "Éditer",
12816 editClusterError: "Les clusters ne peuvent pas être édités.",
12817 editEdge: "Éditer le lien",
12818 editEdgeDescription: "Cliquez sur les points de contrôle et glissez-les pour connecter un nœud.",
12819 editNode: "Éditer le nœud"
12820}; // Czech
12821
12822var cs = {
12823 addDescription: "Kluknutím do prázdného prostoru můžete přidat nový vrchol.",
12824 addEdge: "Přidat hranu",
12825 addNode: "Přidat vrchol",
12826 back: "Zpět",
12827 close: "Zavřít",
12828 createEdgeError: "Nelze připojit hranu ke shluku.",
12829 del: "Smazat výběr",
12830 deleteClusterError: "Nelze mazat shluky.",
12831 edgeDescription: "Přetažením z jednoho vrcholu do druhého můžete spojit tyto vrcholy novou hranou.",
12832 edit: "Upravit",
12833 editClusterError: "Nelze upravovat shluky.",
12834 editEdge: "Upravit hranu",
12835 editEdgeDescription: "Přetažením kontrolního vrcholu hrany ji můžete připojit k jinému vrcholu.",
12836 editNode: "Upravit vrchol"
12837};
12838
12839var locales = /*#__PURE__*/Object.freeze({
12840 __proto__: null,
12841 en: en,
12842 de: de,
12843 es: es,
12844 it: it,
12845 nl: nl,
12846 pt: pt,
12847 ru: ru,
12848 cn: cn,
12849 uk: uk,
12850 fr: fr,
12851 cs: cs
12852});
12853
12854/**
12855 * Normalizes language code into the format used internally.
12856 *
12857 * @param locales - All the available locales.
12858 * @param rawCode - The original code as supplied by the user.
12859 *
12860 * @returns Language code in the format language-COUNTRY or language, eventually
12861 * fallbacks to en.
12862 */
12863function normalizeLanguageCode(locales, rawCode) {
12864 try {
12865 var _rawCode$split = rawCode.split(/[-_ /]/, 2),
12866 _rawCode$split2 = _slicedToArray(_rawCode$split, 2),
12867 rawLanguage = _rawCode$split2[0],
12868 rawCountry = _rawCode$split2[1];
12869
12870 var language = rawLanguage != null ? rawLanguage.toLowerCase() : null;
12871 var country = rawCountry != null ? rawCountry.toUpperCase() : null;
12872
12873 if (language && country) {
12874 var code = language + "-" + country;
12875
12876 if (Object.prototype.hasOwnProperty.call(locales, code)) {
12877 return code;
12878 } else {
12879 var _context;
12880
12881 console.warn(concat(_context = "Unknown variant ".concat(country, " of language ")).call(_context, language, "."));
12882 }
12883 }
12884
12885 if (language) {
12886 var _code = language;
12887
12888 if (Object.prototype.hasOwnProperty.call(locales, _code)) {
12889 return _code;
12890 } else {
12891 console.warn("Unknown language ".concat(language));
12892 }
12893 }
12894
12895 console.warn("Unknown locale ".concat(rawCode, ", falling back to English."));
12896 return "en";
12897 } catch (error) {
12898 console.error(error);
12899 console.warn("Unexpected error while normalizing locale ".concat(rawCode, ", falling back to English."));
12900 return "en";
12901 }
12902}
12903
12904/**
12905 * Associates a canvas to a given image, containing a number of renderings
12906 * of the image at various sizes.
12907 *
12908 * This technique is known as 'mipmapping'.
12909 *
12910 * NOTE: Images can also be of type 'data:svg+xml`. This code also works
12911 * for svg, but the mipmapping may not be necessary.
12912 *
12913 * @param {Image} image
12914 */
12915var CachedImage = /*#__PURE__*/function () {
12916 /**
12917 * @ignore
12918 */
12919 function CachedImage() {
12920 _classCallCheck(this, CachedImage);
12921
12922 this.NUM_ITERATIONS = 4; // Number of items in the coordinates array
12923
12924 this.image = new Image();
12925 this.canvas = document.createElement("canvas");
12926 }
12927 /**
12928 * Called when the image has been successfully loaded.
12929 */
12930
12931
12932 _createClass(CachedImage, [{
12933 key: "init",
12934 value: function init() {
12935 if (this.initialized()) return;
12936 this.src = this.image.src; // For same interface with Image
12937
12938 var w = this.image.width;
12939 var h = this.image.height; // Ease external access
12940
12941 this.width = w;
12942 this.height = h;
12943 var h2 = Math.floor(h / 2);
12944 var h4 = Math.floor(h / 4);
12945 var h8 = Math.floor(h / 8);
12946 var h16 = Math.floor(h / 16);
12947 var w2 = Math.floor(w / 2);
12948 var w4 = Math.floor(w / 4);
12949 var w8 = Math.floor(w / 8);
12950 var w16 = Math.floor(w / 16); // Make canvas as small as possible
12951
12952 this.canvas.width = 3 * w4;
12953 this.canvas.height = h2; // Coordinates and sizes of images contained in the canvas
12954 // Values per row: [top x, left y, width, height]
12955
12956 this.coordinates = [[0, 0, w2, h2], [w2, 0, w4, h4], [w2, h4, w8, h8], [5 * w8, h4, w16, h16]];
12957
12958 this._fillMipMap();
12959 }
12960 /**
12961 * @returns {boolean} true if init() has been called, false otherwise.
12962 */
12963
12964 }, {
12965 key: "initialized",
12966 value: function initialized() {
12967 return this.coordinates !== undefined;
12968 }
12969 /**
12970 * Redraw main image in various sizes to the context.
12971 *
12972 * The rationale behind this is to reduce artefacts due to interpolation
12973 * at differing zoom levels.
12974 *
12975 * Source: http://stackoverflow.com/q/18761404/1223531
12976 *
12977 * This methods takes the resizing out of the drawing loop, in order to
12978 * reduce performance overhead.
12979 *
12980 * TODO: The code assumes that a 2D context can always be gotten. This is
12981 * not necessarily true! OTOH, if not true then usage of this class
12982 * is senseless.
12983 *
12984 * @private
12985 */
12986
12987 }, {
12988 key: "_fillMipMap",
12989 value: function _fillMipMap() {
12990 var ctx = this.canvas.getContext("2d"); // First zoom-level comes from the image
12991
12992 var to = this.coordinates[0];
12993 ctx.drawImage(this.image, to[0], to[1], to[2], to[3]); // The rest are copy actions internal to the canvas/context
12994
12995 for (var iterations = 1; iterations < this.NUM_ITERATIONS; iterations++) {
12996 var from = this.coordinates[iterations - 1];
12997 var _to = this.coordinates[iterations];
12998 ctx.drawImage(this.canvas, from[0], from[1], from[2], from[3], _to[0], _to[1], _to[2], _to[3]);
12999 }
13000 }
13001 /**
13002 * Draw the image, using the mipmap if necessary.
13003 *
13004 * MipMap is only used if param factor > 2; otherwise, original bitmap
13005 * is resized. This is also used to skip mipmap usage, e.g. by setting factor = 1
13006 *
13007 * Credits to 'Alex de Mulder' for original implementation.
13008 *
13009 * @param {CanvasRenderingContext2D} ctx context on which to draw zoomed image
13010 * @param {Float} factor scale factor at which to draw
13011 * @param {number} left
13012 * @param {number} top
13013 * @param {number} width
13014 * @param {number} height
13015 */
13016
13017 }, {
13018 key: "drawImageAtPosition",
13019 value: function drawImageAtPosition(ctx, factor, left, top, width, height) {
13020 if (!this.initialized()) return; //can't draw image yet not intialized
13021
13022 if (factor > 2) {
13023 // Determine which zoomed image to use
13024 factor *= 0.5;
13025 var iterations = 0;
13026
13027 while (factor > 2 && iterations < this.NUM_ITERATIONS) {
13028 factor *= 0.5;
13029 iterations += 1;
13030 }
13031
13032 if (iterations >= this.NUM_ITERATIONS) {
13033 iterations = this.NUM_ITERATIONS - 1;
13034 } //console.log("iterations: " + iterations);
13035
13036
13037 var from = this.coordinates[iterations];
13038 ctx.drawImage(this.canvas, from[0], from[1], from[2], from[3], left, top, width, height);
13039 } else {
13040 // Draw image directly
13041 ctx.drawImage(this.image, left, top, width, height);
13042 }
13043 }
13044 }]);
13045
13046 return CachedImage;
13047}();
13048
13049/**
13050 * This callback is a callback that accepts an Image.
13051 *
13052 * @callback ImageCallback
13053 * @param {Image} image
13054 */
13055
13056/**
13057 * This class loads images and keeps them stored.
13058 *
13059 * @param {ImageCallback} callback
13060 */
13061
13062var Images = /*#__PURE__*/function () {
13063 /**
13064 * @param {ImageCallback} callback
13065 */
13066 function Images(callback) {
13067 _classCallCheck(this, Images);
13068
13069 this.images = {};
13070 this.imageBroken = {};
13071 this.callback = callback;
13072 }
13073 /**
13074 * @param {string} url The original Url that failed to load, if the broken image is successfully loaded it will be added to the cache using this Url as the key so that subsequent requests for this Url will return the broken image
13075 * @param {string} brokenUrl Url the broken image to try and load
13076 * @param {Image} imageToLoadBrokenUrlOn The image object
13077 */
13078
13079
13080 _createClass(Images, [{
13081 key: "_tryloadBrokenUrl",
13082 value: function _tryloadBrokenUrl(url, brokenUrl, imageToLoadBrokenUrlOn) {
13083 //If these parameters aren't specified then exit the function because nothing constructive can be done
13084 if (url === undefined || imageToLoadBrokenUrlOn === undefined) return;
13085
13086 if (brokenUrl === undefined) {
13087 console.warn("No broken url image defined");
13088 return;
13089 } //Clear the old subscription to the error event and put a new in place that only handle errors in loading the brokenImageUrl
13090
13091
13092 imageToLoadBrokenUrlOn.image.onerror = function () {
13093 console.error("Could not load brokenImage:", brokenUrl); // cache item will contain empty image, this should be OK for default
13094 }; //Set the source of the image to the brokenUrl, this is actually what kicks off the loading of the broken image
13095
13096
13097 imageToLoadBrokenUrlOn.image.src = brokenUrl;
13098 }
13099 /**
13100 *
13101 * @param {vis.Image} imageToRedrawWith
13102 * @private
13103 */
13104
13105 }, {
13106 key: "_redrawWithImage",
13107 value: function _redrawWithImage(imageToRedrawWith) {
13108 if (this.callback) {
13109 this.callback(imageToRedrawWith);
13110 }
13111 }
13112 /**
13113 * @param {string} url Url of the image
13114 * @param {string} brokenUrl Url of an image to use if the url image is not found
13115 * @returns {Image} img The image object
13116 */
13117
13118 }, {
13119 key: "load",
13120 value: function load(url, brokenUrl) {
13121 var _this = this;
13122
13123 //Try and get the image from the cache, if successful then return the cached image
13124 var cachedImage = this.images[url];
13125 if (cachedImage) return cachedImage; //Create a new image
13126
13127 var img = new CachedImage(); // Need to add to cache here, otherwise final return will spawn different copies of the same image,
13128 // Also, there will be multiple loads of the same image.
13129
13130 this.images[url] = img; //Subscribe to the event that is raised if the image loads successfully
13131
13132 img.image.onload = function () {
13133 // Properly init the cached item and then request a redraw
13134 _this._fixImageCoordinates(img.image);
13135
13136 img.init();
13137
13138 _this._redrawWithImage(img);
13139 }; //Subscribe to the event that is raised if the image fails to load
13140
13141
13142 img.image.onerror = function () {
13143 console.error("Could not load image:", url); //Try and load the image specified by the brokenUrl using
13144
13145 _this._tryloadBrokenUrl(url, brokenUrl, img);
13146 }; //Set the source of the image to the url, this is what actually kicks off the loading of the image
13147
13148
13149 img.image.src = url; //Return the new image
13150
13151 return img;
13152 }
13153 /**
13154 * IE11 fix -- thanks dponch!
13155 *
13156 * Local helper function
13157 *
13158 * @param {vis.Image} imageToCache
13159 * @private
13160 */
13161
13162 }, {
13163 key: "_fixImageCoordinates",
13164 value: function _fixImageCoordinates(imageToCache) {
13165 if (imageToCache.width === 0) {
13166 document.body.appendChild(imageToCache);
13167 imageToCache.width = imageToCache.offsetWidth;
13168 imageToCache.height = imageToCache.offsetHeight;
13169 document.body.removeChild(imageToCache);
13170 }
13171 }
13172 }]);
13173
13174 return Images;
13175}();
13176
13177var internalMetadata = {exports: {}};
13178
13179var fails$4 = fails$m;
13180var freezing = !fails$4(function () {
13181 // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- required for testing
13182 return Object.isExtensible(Object.preventExtensions({}));
13183});
13184
13185var $$e = _export;
13186var hiddenKeys = hiddenKeys$6;
13187var isObject$5 = isObject$j;
13188var has$1 = has$c;
13189var defineProperty$2 = objectDefineProperty.f;
13190var getOwnPropertyNamesModule = objectGetOwnPropertyNames;
13191var getOwnPropertyNamesExternalModule = objectGetOwnPropertyNamesExternal;
13192var uid = uid$4;
13193var FREEZING = freezing;
13194var REQUIRED = false;
13195var METADATA = uid('meta');
13196var id$1 = 0; // eslint-disable-next-line es/no-object-isextensible -- safe
13197
13198var isExtensible$1 = Object.isExtensible || function () {
13199 return true;
13200};
13201
13202var setMetadata = function (it) {
13203 defineProperty$2(it, METADATA, {
13204 value: {
13205 objectID: 'O' + id$1++,
13206 // object ID
13207 weakData: {} // weak collections IDs
13208
13209 }
13210 });
13211};
13212
13213var fastKey$1 = function (it, create) {
13214 // return a primitive with prefix
13215 if (!isObject$5(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
13216
13217 if (!has$1(it, METADATA)) {
13218 // can't set metadata to uncaught frozen object
13219 if (!isExtensible$1(it)) return 'F'; // not necessary to add metadata
13220
13221 if (!create) return 'E'; // add missing metadata
13222
13223 setMetadata(it); // return object ID
13224 }
13225
13226 return it[METADATA].objectID;
13227};
13228
13229var getWeakData$1 = function (it, create) {
13230 if (!has$1(it, METADATA)) {
13231 // can't set metadata to uncaught frozen object
13232 if (!isExtensible$1(it)) return true; // not necessary to add metadata
13233
13234 if (!create) return false; // add missing metadata
13235
13236 setMetadata(it); // return the store of weak collections IDs
13237 }
13238
13239 return it[METADATA].weakData;
13240}; // add metadata on freeze-family methods calling
13241
13242
13243var onFreeze = function (it) {
13244 if (FREEZING && REQUIRED && isExtensible$1(it) && !has$1(it, METADATA)) setMetadata(it);
13245 return it;
13246};
13247
13248var enable = function () {
13249 meta.enable = function () {
13250 /* empty */
13251 };
13252
13253 REQUIRED = true;
13254 var getOwnPropertyNames = getOwnPropertyNamesModule.f;
13255 var splice = [].splice;
13256 var test = {};
13257 test[METADATA] = 1; // prevent exposing of metadata key
13258
13259 if (getOwnPropertyNames(test).length) {
13260 getOwnPropertyNamesModule.f = function (it) {
13261 var result = getOwnPropertyNames(it);
13262
13263 for (var i = 0, length = result.length; i < length; i++) {
13264 if (result[i] === METADATA) {
13265 splice.call(result, i, 1);
13266 break;
13267 }
13268 }
13269
13270 return result;
13271 };
13272
13273 $$e({
13274 target: 'Object',
13275 stat: true,
13276 forced: true
13277 }, {
13278 getOwnPropertyNames: getOwnPropertyNamesExternalModule.f
13279 });
13280 }
13281};
13282
13283var meta = internalMetadata.exports = {
13284 enable: enable,
13285 fastKey: fastKey$1,
13286 getWeakData: getWeakData$1,
13287 onFreeze: onFreeze
13288};
13289hiddenKeys[METADATA] = true;
13290
13291var anObject$4 = anObject$d;
13292var isArrayIteratorMethod = isArrayIteratorMethod$2;
13293var toLength$4 = toLength$c;
13294var bind$3 = functionBindContext;
13295var getIteratorMethod$1 = getIteratorMethod$7;
13296var iteratorClose = iteratorClose$2;
13297
13298var Result = function (stopped, result) {
13299 this.stopped = stopped;
13300 this.result = result;
13301};
13302
13303var iterate$3 = function (iterable, unboundFunction, options) {
13304 var that = options && options.that;
13305 var AS_ENTRIES = !!(options && options.AS_ENTRIES);
13306 var IS_ITERATOR = !!(options && options.IS_ITERATOR);
13307 var INTERRUPTED = !!(options && options.INTERRUPTED);
13308 var fn = bind$3(unboundFunction, that, 1 + AS_ENTRIES + INTERRUPTED);
13309 var iterator, iterFn, index, length, result, next, step;
13310
13311 var stop = function (condition) {
13312 if (iterator) iteratorClose(iterator);
13313 return new Result(true, condition);
13314 };
13315
13316 var callFn = function (value) {
13317 if (AS_ENTRIES) {
13318 anObject$4(value);
13319 return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);
13320 }
13321
13322 return INTERRUPTED ? fn(value, stop) : fn(value);
13323 };
13324
13325 if (IS_ITERATOR) {
13326 iterator = iterable;
13327 } else {
13328 iterFn = getIteratorMethod$1(iterable);
13329 if (typeof iterFn != 'function') throw TypeError('Target is not iterable'); // optimisation for array iterators
13330
13331 if (isArrayIteratorMethod(iterFn)) {
13332 for (index = 0, length = toLength$4(iterable.length); length > index; index++) {
13333 result = callFn(iterable[index]);
13334 if (result && result instanceof Result) return result;
13335 }
13336
13337 return new Result(false);
13338 }
13339
13340 iterator = iterFn.call(iterable);
13341 }
13342
13343 next = iterator.next;
13344
13345 while (!(step = next.call(iterator)).done) {
13346 try {
13347 result = callFn(step.value);
13348 } catch (error) {
13349 iteratorClose(iterator);
13350 throw error;
13351 }
13352
13353 if (typeof result == 'object' && result && result instanceof Result) return result;
13354 }
13355
13356 return new Result(false);
13357};
13358
13359var anInstance$3 = function (it, Constructor, name) {
13360 if (!(it instanceof Constructor)) {
13361 throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
13362 }
13363
13364 return it;
13365};
13366
13367var $$d = _export;
13368var global$5 = global$k;
13369var InternalMetadataModule$1 = internalMetadata.exports;
13370var fails$3 = fails$m;
13371var createNonEnumerableProperty = createNonEnumerableProperty$9;
13372var iterate$2 = iterate$3;
13373var anInstance$2 = anInstance$3;
13374var isObject$4 = isObject$j;
13375var setToStringTag = setToStringTag$5;
13376var defineProperty$1 = objectDefineProperty.f;
13377var forEach = arrayIteration.forEach;
13378var DESCRIPTORS$2 = descriptors;
13379var InternalStateModule$2 = internalState;
13380var setInternalState$2 = InternalStateModule$2.set;
13381var internalStateGetterFor$2 = InternalStateModule$2.getterFor;
13382
13383var collection$3 = function (CONSTRUCTOR_NAME, wrapper, common) {
13384 var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1;
13385 var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1;
13386 var ADDER = IS_MAP ? 'set' : 'add';
13387 var NativeConstructor = global$5[CONSTRUCTOR_NAME];
13388 var NativePrototype = NativeConstructor && NativeConstructor.prototype;
13389 var exported = {};
13390 var Constructor;
13391
13392 if (!DESCRIPTORS$2 || typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails$3(function () {
13393 new NativeConstructor().entries().next();
13394 }))) {
13395 // create collection constructor
13396 Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
13397 InternalMetadataModule$1.enable();
13398 } else {
13399 Constructor = wrapper(function (target, iterable) {
13400 setInternalState$2(anInstance$2(target, Constructor, CONSTRUCTOR_NAME), {
13401 type: CONSTRUCTOR_NAME,
13402 collection: new NativeConstructor()
13403 });
13404 if (iterable != undefined) iterate$2(iterable, target[ADDER], {
13405 that: target,
13406 AS_ENTRIES: IS_MAP
13407 });
13408 });
13409 var getInternalState = internalStateGetterFor$2(CONSTRUCTOR_NAME);
13410 forEach(['add', 'clear', 'delete', 'forEach', 'get', 'has', 'set', 'keys', 'values', 'entries'], function (KEY) {
13411 var IS_ADDER = KEY == 'add' || KEY == 'set';
13412
13413 if (KEY in NativePrototype && !(IS_WEAK && KEY == 'clear')) {
13414 createNonEnumerableProperty(Constructor.prototype, KEY, function (a, b) {
13415 var collection = getInternalState(this).collection;
13416 if (!IS_ADDER && IS_WEAK && !isObject$4(a)) return KEY == 'get' ? undefined : false;
13417 var result = collection[KEY](a === 0 ? 0 : a, b);
13418 return IS_ADDER ? this : result;
13419 });
13420 }
13421 });
13422 IS_WEAK || defineProperty$1(Constructor.prototype, 'size', {
13423 configurable: true,
13424 get: function () {
13425 return getInternalState(this).collection.size;
13426 }
13427 });
13428 }
13429
13430 setToStringTag(Constructor, CONSTRUCTOR_NAME, false, true);
13431 exported[CONSTRUCTOR_NAME] = Constructor;
13432 $$d({
13433 global: true,
13434 forced: true
13435 }, exported);
13436 if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
13437 return Constructor;
13438};
13439
13440var redefine = redefine$3;
13441
13442var redefineAll$3 = function (target, src, options) {
13443 for (var key in src) {
13444 if (options && options.unsafe && target[key]) target[key] = src[key];else redefine(target, key, src[key], options);
13445 }
13446
13447 return target;
13448};
13449
13450var getBuiltIn$1 = getBuiltIn$8;
13451var definePropertyModule = objectDefineProperty;
13452var wellKnownSymbol = wellKnownSymbol$j;
13453var DESCRIPTORS$1 = descriptors;
13454var SPECIES = wellKnownSymbol('species');
13455
13456var setSpecies$1 = function (CONSTRUCTOR_NAME) {
13457 var Constructor = getBuiltIn$1(CONSTRUCTOR_NAME);
13458 var defineProperty = definePropertyModule.f;
13459
13460 if (DESCRIPTORS$1 && Constructor && !Constructor[SPECIES]) {
13461 defineProperty(Constructor, SPECIES, {
13462 configurable: true,
13463 get: function () {
13464 return this;
13465 }
13466 });
13467 }
13468};
13469
13470var defineProperty = objectDefineProperty.f;
13471var create$3 = objectCreate;
13472var redefineAll$2 = redefineAll$3;
13473var bind$2 = functionBindContext;
13474var anInstance$1 = anInstance$3;
13475var iterate$1 = iterate$3;
13476var defineIterator = defineIterator$3;
13477var setSpecies = setSpecies$1;
13478var DESCRIPTORS = descriptors;
13479var fastKey = internalMetadata.exports.fastKey;
13480var InternalStateModule$1 = internalState;
13481var setInternalState$1 = InternalStateModule$1.set;
13482var internalStateGetterFor$1 = InternalStateModule$1.getterFor;
13483var collectionStrong$2 = {
13484 getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
13485 var C = wrapper(function (that, iterable) {
13486 anInstance$1(that, C, CONSTRUCTOR_NAME);
13487 setInternalState$1(that, {
13488 type: CONSTRUCTOR_NAME,
13489 index: create$3(null),
13490 first: undefined,
13491 last: undefined,
13492 size: 0
13493 });
13494 if (!DESCRIPTORS) that.size = 0;
13495 if (iterable != undefined) iterate$1(iterable, that[ADDER], {
13496 that: that,
13497 AS_ENTRIES: IS_MAP
13498 });
13499 });
13500 var getInternalState = internalStateGetterFor$1(CONSTRUCTOR_NAME);
13501
13502 var define = function (that, key, value) {
13503 var state = getInternalState(that);
13504 var entry = getEntry(that, key);
13505 var previous, index; // change existing entry
13506
13507 if (entry) {
13508 entry.value = value; // create new entry
13509 } else {
13510 state.last = entry = {
13511 index: index = fastKey(key, true),
13512 key: key,
13513 value: value,
13514 previous: previous = state.last,
13515 next: undefined,
13516 removed: false
13517 };
13518 if (!state.first) state.first = entry;
13519 if (previous) previous.next = entry;
13520 if (DESCRIPTORS) state.size++;else that.size++; // add to index
13521
13522 if (index !== 'F') state.index[index] = entry;
13523 }
13524
13525 return that;
13526 };
13527
13528 var getEntry = function (that, key) {
13529 var state = getInternalState(that); // fast case
13530
13531 var index = fastKey(key);
13532 var entry;
13533 if (index !== 'F') return state.index[index]; // frozen object case
13534
13535 for (entry = state.first; entry; entry = entry.next) {
13536 if (entry.key == key) return entry;
13537 }
13538 };
13539
13540 redefineAll$2(C.prototype, {
13541 // `{ Map, Set }.prototype.clear()` methods
13542 // https://tc39.es/ecma262/#sec-map.prototype.clear
13543 // https://tc39.es/ecma262/#sec-set.prototype.clear
13544 clear: function clear() {
13545 var that = this;
13546 var state = getInternalState(that);
13547 var data = state.index;
13548 var entry = state.first;
13549
13550 while (entry) {
13551 entry.removed = true;
13552 if (entry.previous) entry.previous = entry.previous.next = undefined;
13553 delete data[entry.index];
13554 entry = entry.next;
13555 }
13556
13557 state.first = state.last = undefined;
13558 if (DESCRIPTORS) state.size = 0;else that.size = 0;
13559 },
13560 // `{ Map, Set }.prototype.delete(key)` methods
13561 // https://tc39.es/ecma262/#sec-map.prototype.delete
13562 // https://tc39.es/ecma262/#sec-set.prototype.delete
13563 'delete': function (key) {
13564 var that = this;
13565 var state = getInternalState(that);
13566 var entry = getEntry(that, key);
13567
13568 if (entry) {
13569 var next = entry.next;
13570 var prev = entry.previous;
13571 delete state.index[entry.index];
13572 entry.removed = true;
13573 if (prev) prev.next = next;
13574 if (next) next.previous = prev;
13575 if (state.first == entry) state.first = next;
13576 if (state.last == entry) state.last = prev;
13577 if (DESCRIPTORS) state.size--;else that.size--;
13578 }
13579
13580 return !!entry;
13581 },
13582 // `{ Map, Set }.prototype.forEach(callbackfn, thisArg = undefined)` methods
13583 // https://tc39.es/ecma262/#sec-map.prototype.foreach
13584 // https://tc39.es/ecma262/#sec-set.prototype.foreach
13585 forEach: function forEach(callbackfn
13586 /* , that = undefined */
13587 ) {
13588 var state = getInternalState(this);
13589 var boundFunction = bind$2(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
13590 var entry;
13591
13592 while (entry = entry ? entry.next : state.first) {
13593 boundFunction(entry.value, entry.key, this); // revert to the last existing entry
13594
13595 while (entry && entry.removed) entry = entry.previous;
13596 }
13597 },
13598 // `{ Map, Set}.prototype.has(key)` methods
13599 // https://tc39.es/ecma262/#sec-map.prototype.has
13600 // https://tc39.es/ecma262/#sec-set.prototype.has
13601 has: function has(key) {
13602 return !!getEntry(this, key);
13603 }
13604 });
13605 redefineAll$2(C.prototype, IS_MAP ? {
13606 // `Map.prototype.get(key)` method
13607 // https://tc39.es/ecma262/#sec-map.prototype.get
13608 get: function get(key) {
13609 var entry = getEntry(this, key);
13610 return entry && entry.value;
13611 },
13612 // `Map.prototype.set(key, value)` method
13613 // https://tc39.es/ecma262/#sec-map.prototype.set
13614 set: function set(key, value) {
13615 return define(this, key === 0 ? 0 : key, value);
13616 }
13617 } : {
13618 // `Set.prototype.add(value)` method
13619 // https://tc39.es/ecma262/#sec-set.prototype.add
13620 add: function add(value) {
13621 return define(this, value = value === 0 ? 0 : value, value);
13622 }
13623 });
13624 if (DESCRIPTORS) defineProperty(C.prototype, 'size', {
13625 get: function () {
13626 return getInternalState(this).size;
13627 }
13628 });
13629 return C;
13630 },
13631 setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) {
13632 var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator';
13633 var getInternalCollectionState = internalStateGetterFor$1(CONSTRUCTOR_NAME);
13634 var getInternalIteratorState = internalStateGetterFor$1(ITERATOR_NAME); // `{ Map, Set }.prototype.{ keys, values, entries, @@iterator }()` methods
13635 // https://tc39.es/ecma262/#sec-map.prototype.entries
13636 // https://tc39.es/ecma262/#sec-map.prototype.keys
13637 // https://tc39.es/ecma262/#sec-map.prototype.values
13638 // https://tc39.es/ecma262/#sec-map.prototype-@@iterator
13639 // https://tc39.es/ecma262/#sec-set.prototype.entries
13640 // https://tc39.es/ecma262/#sec-set.prototype.keys
13641 // https://tc39.es/ecma262/#sec-set.prototype.values
13642 // https://tc39.es/ecma262/#sec-set.prototype-@@iterator
13643
13644 defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) {
13645 setInternalState$1(this, {
13646 type: ITERATOR_NAME,
13647 target: iterated,
13648 state: getInternalCollectionState(iterated),
13649 kind: kind,
13650 last: undefined
13651 });
13652 }, function () {
13653 var state = getInternalIteratorState(this);
13654 var kind = state.kind;
13655 var entry = state.last; // revert to the last existing entry
13656
13657 while (entry && entry.removed) entry = entry.previous; // get next entry
13658
13659
13660 if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) {
13661 // or finish the iteration
13662 state.target = undefined;
13663 return {
13664 value: undefined,
13665 done: true
13666 };
13667 } // return step by kind
13668
13669
13670 if (kind == 'keys') return {
13671 value: entry.key,
13672 done: false
13673 };
13674 if (kind == 'values') return {
13675 value: entry.value,
13676 done: false
13677 };
13678 return {
13679 value: [entry.key, entry.value],
13680 done: false
13681 };
13682 }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); // `{ Map, Set }.prototype[@@species]` accessors
13683 // https://tc39.es/ecma262/#sec-get-map-@@species
13684 // https://tc39.es/ecma262/#sec-get-set-@@species
13685
13686 setSpecies(CONSTRUCTOR_NAME);
13687 }
13688};
13689
13690var collection$2 = collection$3;
13691var collectionStrong$1 = collectionStrong$2; // `Map` constructor
13692// https://tc39.es/ecma262/#sec-map-objects
13693
13694collection$2('Map', function (init) {
13695 return function Map() {
13696 return init(this, arguments.length ? arguments[0] : undefined);
13697 };
13698}, collectionStrong$1);
13699
13700var path$b = path$x;
13701var map$2 = path$b.Map;
13702
13703var parent$p = map$2;
13704var map$1 = parent$p;
13705
13706var map = map$1;
13707
13708/**
13709 * This class can store groups and options specific for groups.
13710 */
13711var Groups = /*#__PURE__*/function () {
13712 /**
13713 * @ignore
13714 */
13715 function Groups() {
13716 _classCallCheck(this, Groups);
13717
13718 this.clear();
13719 this._defaultIndex = 0;
13720 this._groupIndex = 0;
13721 this._defaultGroups = [{
13722 border: "#2B7CE9",
13723 background: "#97C2FC",
13724 highlight: {
13725 border: "#2B7CE9",
13726 background: "#D2E5FF"
13727 },
13728 hover: {
13729 border: "#2B7CE9",
13730 background: "#D2E5FF"
13731 }
13732 }, // 0: blue
13733 {
13734 border: "#FFA500",
13735 background: "#FFFF00",
13736 highlight: {
13737 border: "#FFA500",
13738 background: "#FFFFA3"
13739 },
13740 hover: {
13741 border: "#FFA500",
13742 background: "#FFFFA3"
13743 }
13744 }, // 1: yellow
13745 {
13746 border: "#FA0A10",
13747 background: "#FB7E81",
13748 highlight: {
13749 border: "#FA0A10",
13750 background: "#FFAFB1"
13751 },
13752 hover: {
13753 border: "#FA0A10",
13754 background: "#FFAFB1"
13755 }
13756 }, // 2: red
13757 {
13758 border: "#41A906",
13759 background: "#7BE141",
13760 highlight: {
13761 border: "#41A906",
13762 background: "#A1EC76"
13763 },
13764 hover: {
13765 border: "#41A906",
13766 background: "#A1EC76"
13767 }
13768 }, // 3: green
13769 {
13770 border: "#E129F0",
13771 background: "#EB7DF4",
13772 highlight: {
13773 border: "#E129F0",
13774 background: "#F0B3F5"
13775 },
13776 hover: {
13777 border: "#E129F0",
13778 background: "#F0B3F5"
13779 }
13780 }, // 4: magenta
13781 {
13782 border: "#7C29F0",
13783 background: "#AD85E4",
13784 highlight: {
13785 border: "#7C29F0",
13786 background: "#D3BDF0"
13787 },
13788 hover: {
13789 border: "#7C29F0",
13790 background: "#D3BDF0"
13791 }
13792 }, // 5: purple
13793 {
13794 border: "#C37F00",
13795 background: "#FFA807",
13796 highlight: {
13797 border: "#C37F00",
13798 background: "#FFCA66"
13799 },
13800 hover: {
13801 border: "#C37F00",
13802 background: "#FFCA66"
13803 }
13804 }, // 6: orange
13805 {
13806 border: "#4220FB",
13807 background: "#6E6EFD",
13808 highlight: {
13809 border: "#4220FB",
13810 background: "#9B9BFD"
13811 },
13812 hover: {
13813 border: "#4220FB",
13814 background: "#9B9BFD"
13815 }
13816 }, // 7: darkblue
13817 {
13818 border: "#FD5A77",
13819 background: "#FFC0CB",
13820 highlight: {
13821 border: "#FD5A77",
13822 background: "#FFD1D9"
13823 },
13824 hover: {
13825 border: "#FD5A77",
13826 background: "#FFD1D9"
13827 }
13828 }, // 8: pink
13829 {
13830 border: "#4AD63A",
13831 background: "#C2FABC",
13832 highlight: {
13833 border: "#4AD63A",
13834 background: "#E6FFE3"
13835 },
13836 hover: {
13837 border: "#4AD63A",
13838 background: "#E6FFE3"
13839 }
13840 }, // 9: mint
13841 {
13842 border: "#990000",
13843 background: "#EE0000",
13844 highlight: {
13845 border: "#BB0000",
13846 background: "#FF3333"
13847 },
13848 hover: {
13849 border: "#BB0000",
13850 background: "#FF3333"
13851 }
13852 }, // 10:bright red
13853 {
13854 border: "#FF6000",
13855 background: "#FF6000",
13856 highlight: {
13857 border: "#FF6000",
13858 background: "#FF6000"
13859 },
13860 hover: {
13861 border: "#FF6000",
13862 background: "#FF6000"
13863 }
13864 }, // 12: real orange
13865 {
13866 border: "#97C2FC",
13867 background: "#2B7CE9",
13868 highlight: {
13869 border: "#D2E5FF",
13870 background: "#2B7CE9"
13871 },
13872 hover: {
13873 border: "#D2E5FF",
13874 background: "#2B7CE9"
13875 }
13876 }, // 13: blue
13877 {
13878 border: "#399605",
13879 background: "#255C03",
13880 highlight: {
13881 border: "#399605",
13882 background: "#255C03"
13883 },
13884 hover: {
13885 border: "#399605",
13886 background: "#255C03"
13887 }
13888 }, // 14: green
13889 {
13890 border: "#B70054",
13891 background: "#FF007E",
13892 highlight: {
13893 border: "#B70054",
13894 background: "#FF007E"
13895 },
13896 hover: {
13897 border: "#B70054",
13898 background: "#FF007E"
13899 }
13900 }, // 15: magenta
13901 {
13902 border: "#AD85E4",
13903 background: "#7C29F0",
13904 highlight: {
13905 border: "#D3BDF0",
13906 background: "#7C29F0"
13907 },
13908 hover: {
13909 border: "#D3BDF0",
13910 background: "#7C29F0"
13911 }
13912 }, // 16: purple
13913 {
13914 border: "#4557FA",
13915 background: "#000EA1",
13916 highlight: {
13917 border: "#6E6EFD",
13918 background: "#000EA1"
13919 },
13920 hover: {
13921 border: "#6E6EFD",
13922 background: "#000EA1"
13923 }
13924 }, // 17: darkblue
13925 {
13926 border: "#FFC0CB",
13927 background: "#FD5A77",
13928 highlight: {
13929 border: "#FFD1D9",
13930 background: "#FD5A77"
13931 },
13932 hover: {
13933 border: "#FFD1D9",
13934 background: "#FD5A77"
13935 }
13936 }, // 18: pink
13937 {
13938 border: "#C2FABC",
13939 background: "#74D66A",
13940 highlight: {
13941 border: "#E6FFE3",
13942 background: "#74D66A"
13943 },
13944 hover: {
13945 border: "#E6FFE3",
13946 background: "#74D66A"
13947 }
13948 }, // 19: mint
13949 {
13950 border: "#EE0000",
13951 background: "#990000",
13952 highlight: {
13953 border: "#FF3333",
13954 background: "#BB0000"
13955 },
13956 hover: {
13957 border: "#FF3333",
13958 background: "#BB0000"
13959 }
13960 } // 20:bright red
13961 ];
13962 this.options = {};
13963 this.defaultOptions = {
13964 useDefaultGroups: true
13965 };
13966
13967 assign$2(this.options, this.defaultOptions);
13968 }
13969 /**
13970 *
13971 * @param {object} options
13972 */
13973
13974
13975 _createClass(Groups, [{
13976 key: "setOptions",
13977 value: function setOptions(options) {
13978 var optionFields = ["useDefaultGroups"];
13979
13980 if (options !== undefined) {
13981 for (var groupName in options) {
13982 if (Object.prototype.hasOwnProperty.call(options, groupName)) {
13983 if (indexOf(optionFields).call(optionFields, groupName) === -1) {
13984 var group = options[groupName];
13985 this.add(groupName, group);
13986 }
13987 }
13988 }
13989 }
13990 }
13991 /**
13992 * Clear all groups
13993 */
13994
13995 }, {
13996 key: "clear",
13997 value: function clear() {
13998 this._groups = new map();
13999 this._groupNames = [];
14000 }
14001 /**
14002 * Get group options of a groupname.
14003 * If groupname is not found, a new group may be created.
14004 *
14005 * @param {*} groupname Can be a number, string, Date, etc.
14006 * @param {boolean} [shouldCreate=true] If true, create a new group
14007 * @returns {object} The found or created group
14008 */
14009
14010 }, {
14011 key: "get",
14012 value: function get(groupname) {
14013 var shouldCreate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
14014
14015 var group = this._groups.get(groupname);
14016
14017 if (group === undefined && shouldCreate) {
14018 if (this.options.useDefaultGroups === false && this._groupNames.length > 0) {
14019 // create new group
14020 var index = this._groupIndex % this._groupNames.length;
14021 ++this._groupIndex;
14022 group = {};
14023 group.color = this._groups.get(this._groupNames[index]);
14024
14025 this._groups.set(groupname, group);
14026 } else {
14027 // create new group
14028 var _index = this._defaultIndex % this._defaultGroups.length;
14029
14030 this._defaultIndex++;
14031 group = {};
14032 group.color = this._defaultGroups[_index];
14033
14034 this._groups.set(groupname, group);
14035 }
14036 }
14037
14038 return group;
14039 }
14040 /**
14041 * Add custom group style.
14042 *
14043 * @param {string} groupName - The name of the group, a new group will be
14044 * created if a group with the same name doesn't exist, otherwise the old
14045 * groups style will be overwritten.
14046 * @param {object} style - An object containing borderColor, backgroundColor,
14047 * etc.
14048 * @returns {object} The created group object.
14049 */
14050
14051 }, {
14052 key: "add",
14053 value: function add(groupName, style) {
14054 // Only push group name once to prevent duplicates which would consume more
14055 // RAM and also skew the distribution towards more often updated groups,
14056 // neither of which is desirable.
14057 if (!this._groups.has(groupName)) {
14058 this._groupNames.push(groupName);
14059 }
14060
14061 this._groups.set(groupName, style);
14062
14063 return style;
14064 }
14065 }]);
14066
14067 return Groups;
14068}();
14069
14070var $$c = _export; // `Number.isNaN` method
14071// https://tc39.es/ecma262/#sec-number.isnan
14072
14073$$c({
14074 target: 'Number',
14075 stat: true
14076}, {
14077 isNaN: function isNaN(number) {
14078 // eslint-disable-next-line no-self-compare -- NaN check
14079 return number != number;
14080 }
14081});
14082
14083var path$a = path$x;
14084var isNan$2 = path$a.Number.isNaN;
14085
14086var parent$o = isNan$2;
14087var isNan$1 = parent$o;
14088
14089var isNan = isNan$1;
14090
14091var global$4 = global$k;
14092var globalIsFinite = global$4.isFinite; // `Number.isFinite` method
14093// https://tc39.es/ecma262/#sec-number.isfinite
14094// eslint-disable-next-line es/no-number-isfinite -- safe
14095
14096var numberIsFinite$1 = Number.isFinite || function isFinite(it) {
14097 return typeof it == 'number' && globalIsFinite(it);
14098};
14099
14100var $$b = _export;
14101var numberIsFinite = numberIsFinite$1; // `Number.isFinite` method
14102// https://tc39.es/ecma262/#sec-number.isfinite
14103
14104$$b({
14105 target: 'Number',
14106 stat: true
14107}, {
14108 isFinite: numberIsFinite
14109});
14110
14111var path$9 = path$x;
14112var _isFinite$2 = path$9.Number.isFinite;
14113
14114var parent$n = _isFinite$2;
14115var _isFinite$1 = parent$n;
14116
14117var _isFinite = _isFinite$1;
14118
14119var $$a = _export;
14120var $some = arrayIteration.some;
14121var arrayMethodIsStrict$3 = arrayMethodIsStrict$6;
14122var STRICT_METHOD$3 = arrayMethodIsStrict$3('some'); // `Array.prototype.some` method
14123// https://tc39.es/ecma262/#sec-array.prototype.some
14124
14125$$a({
14126 target: 'Array',
14127 proto: true,
14128 forced: !STRICT_METHOD$3
14129}, {
14130 some: function some(callbackfn
14131 /* , thisArg */
14132 ) {
14133 return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
14134 }
14135});
14136
14137var entryVirtual$7 = entryVirtual$l;
14138var some$3 = entryVirtual$7('Array').some;
14139
14140var some$2 = some$3;
14141var ArrayPrototype$7 = Array.prototype;
14142
14143var some_1 = function (it) {
14144 var own = it.some;
14145 return it === ArrayPrototype$7 || it instanceof Array && own === ArrayPrototype$7.some ? some$2 : own;
14146};
14147
14148var parent$m = some_1;
14149var some$1 = parent$m;
14150
14151var some = some$1;
14152
14153var $$9 = _export;
14154var getBuiltIn = getBuiltIn$8;
14155var aFunction$3 = aFunction$6;
14156var anObject$3 = anObject$d;
14157var isObject$3 = isObject$j;
14158var create$2 = objectCreate;
14159var bind$1 = functionBind;
14160var fails$2 = fails$m;
14161var nativeConstruct = getBuiltIn('Reflect', 'construct'); // `Reflect.construct` method
14162// https://tc39.es/ecma262/#sec-reflect.construct
14163// MS Edge supports only 2 arguments and argumentsList argument is optional
14164// FF Nightly sets third argument as `new.target`, but does not create `this` from it
14165
14166var NEW_TARGET_BUG = fails$2(function () {
14167 function F() {
14168 /* empty */
14169 }
14170
14171 return !(nativeConstruct(function () {
14172 /* empty */
14173 }, [], F) instanceof F);
14174});
14175var ARGS_BUG = !fails$2(function () {
14176 nativeConstruct(function () {
14177 /* empty */
14178 });
14179});
14180var FORCED$2 = NEW_TARGET_BUG || ARGS_BUG;
14181$$9({
14182 target: 'Reflect',
14183 stat: true,
14184 forced: FORCED$2,
14185 sham: FORCED$2
14186}, {
14187 construct: function construct(Target, args
14188 /* , newTarget */
14189 ) {
14190 aFunction$3(Target);
14191 anObject$3(args);
14192 var newTarget = arguments.length < 3 ? Target : aFunction$3(arguments[2]);
14193 if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget);
14194
14195 if (Target == newTarget) {
14196 // w/o altered newTarget, optimization for 0-4 arguments
14197 switch (args.length) {
14198 case 0:
14199 return new Target();
14200
14201 case 1:
14202 return new Target(args[0]);
14203
14204 case 2:
14205 return new Target(args[0], args[1]);
14206
14207 case 3:
14208 return new Target(args[0], args[1], args[2]);
14209
14210 case 4:
14211 return new Target(args[0], args[1], args[2], args[3]);
14212 } // w/o altered newTarget, lot of arguments case
14213
14214
14215 var $args = [null];
14216 $args.push.apply($args, args);
14217 return new (bind$1.apply(Target, $args))();
14218 } // with altered newTarget, not support built-in constructors
14219
14220
14221 var proto = newTarget.prototype;
14222 var instance = create$2(isObject$3(proto) ? proto : Object.prototype);
14223 var result = Function.apply.call(Target, instance, args);
14224 return isObject$3(result) ? result : instance;
14225 }
14226});
14227
14228var path$8 = path$x;
14229var construct$2 = path$8.Reflect.construct;
14230
14231var parent$l = construct$2;
14232var construct$1 = parent$l;
14233
14234var construct = construct$1;
14235
14236function _assertThisInitialized(self) {
14237 if (self === void 0) {
14238 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
14239 }
14240
14241 return self;
14242}
14243
14244var parent$k = create$5;
14245var create$1 = parent$k;
14246
14247var create = create$1;
14248
14249var $$8 = _export;
14250var setPrototypeOf$4 = objectSetPrototypeOf; // `Object.setPrototypeOf` method
14251// https://tc39.es/ecma262/#sec-object.setprototypeof
14252
14253$$8({
14254 target: 'Object',
14255 stat: true
14256}, {
14257 setPrototypeOf: setPrototypeOf$4
14258});
14259
14260var path$7 = path$x;
14261var setPrototypeOf$3 = path$7.Object.setPrototypeOf;
14262
14263var parent$j = setPrototypeOf$3;
14264var setPrototypeOf$2 = parent$j;
14265
14266var parent$i = setPrototypeOf$2;
14267var setPrototypeOf$1 = parent$i;
14268
14269var setPrototypeOf = setPrototypeOf$1;
14270
14271function _setPrototypeOf(o, p) {
14272 _setPrototypeOf = setPrototypeOf || function _setPrototypeOf(o, p) {
14273 o.__proto__ = p;
14274 return o;
14275 };
14276
14277 return _setPrototypeOf(o, p);
14278}
14279
14280function _inherits(subClass, superClass) {
14281 if (typeof superClass !== "function" && superClass !== null) {
14282 throw new TypeError("Super expression must either be null or a function");
14283 }
14284
14285 subClass.prototype = create(superClass && superClass.prototype, {
14286 constructor: {
14287 value: subClass,
14288 writable: true,
14289 configurable: true
14290 }
14291 });
14292 if (superClass) _setPrototypeOf(subClass, superClass);
14293}
14294
14295function _possibleConstructorReturn(self, call) {
14296 if (call && (_typeof(call) === "object" || typeof call === "function")) {
14297 return call;
14298 } else if (call !== void 0) {
14299 throw new TypeError("Derived constructors may only return object or undefined");
14300 }
14301
14302 return _assertThisInitialized(self);
14303}
14304
14305var parent$h = getPrototypeOf$4;
14306var getPrototypeOf$2 = parent$h;
14307
14308var getPrototypeOf$1 = getPrototypeOf$2;
14309
14310function _getPrototypeOf(o) {
14311 _getPrototypeOf = setPrototypeOf ? getPrototypeOf$1 : function _getPrototypeOf(o) {
14312 return o.__proto__ || getPrototypeOf$1(o);
14313 };
14314 return _getPrototypeOf(o);
14315}
14316
14317var runtime = {exports: {}};
14318
14319/**
14320 * Copyright (c) 2014-present, Facebook, Inc.
14321 *
14322 * This source code is licensed under the MIT license found in the
14323 * LICENSE file in the root directory of this source tree.
14324 */
14325
14326(function (module) {
14327 var runtime = function (exports) {
14328
14329 var Op = Object.prototype;
14330 var hasOwn = Op.hasOwnProperty;
14331 var undefined$1; // More compressible than void 0.
14332
14333 var $Symbol = typeof Symbol === "function" ? Symbol : {};
14334 var iteratorSymbol = $Symbol.iterator || "@@iterator";
14335 var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
14336 var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
14337
14338 function define(obj, key, value) {
14339 Object.defineProperty(obj, key, {
14340 value: value,
14341 enumerable: true,
14342 configurable: true,
14343 writable: true
14344 });
14345 return obj[key];
14346 }
14347
14348 try {
14349 // IE 8 has a broken Object.defineProperty that only works on DOM objects.
14350 define({}, "");
14351 } catch (err) {
14352 define = function (obj, key, value) {
14353 return obj[key] = value;
14354 };
14355 }
14356
14357 function wrap(innerFn, outerFn, self, tryLocsList) {
14358 // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
14359 var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
14360 var generator = Object.create(protoGenerator.prototype);
14361 var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
14362 // .throw, and .return methods.
14363
14364 generator._invoke = makeInvokeMethod(innerFn, self, context);
14365 return generator;
14366 }
14367
14368 exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
14369 // record like context.tryEntries[i].completion. This interface could
14370 // have been (and was previously) designed to take a closure to be
14371 // invoked without arguments, but in all the cases we care about we
14372 // already have an existing method we want to call, so there's no need
14373 // to create a new function object. We can even get away with assuming
14374 // the method takes exactly one argument, since that happens to be true
14375 // in every case, so we don't have to touch the arguments object. The
14376 // only additional allocation required is the completion record, which
14377 // has a stable shape and so hopefully should be cheap to allocate.
14378
14379 function tryCatch(fn, obj, arg) {
14380 try {
14381 return {
14382 type: "normal",
14383 arg: fn.call(obj, arg)
14384 };
14385 } catch (err) {
14386 return {
14387 type: "throw",
14388 arg: err
14389 };
14390 }
14391 }
14392
14393 var GenStateSuspendedStart = "suspendedStart";
14394 var GenStateSuspendedYield = "suspendedYield";
14395 var GenStateExecuting = "executing";
14396 var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
14397 // breaking out of the dispatch switch statement.
14398
14399 var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
14400 // .constructor.prototype properties for functions that return Generator
14401 // objects. For full spec compliance, you may wish to configure your
14402 // minifier not to mangle the names of these two functions.
14403
14404 function Generator() {}
14405
14406 function GeneratorFunction() {}
14407
14408 function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
14409 // don't natively support it.
14410
14411
14412 var IteratorPrototype = {};
14413
14414 IteratorPrototype[iteratorSymbol] = function () {
14415 return this;
14416 };
14417
14418 var getProto = Object.getPrototypeOf;
14419 var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
14420
14421 if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
14422 // This environment has a native %IteratorPrototype%; use it instead
14423 // of the polyfill.
14424 IteratorPrototype = NativeIteratorPrototype;
14425 }
14426
14427 var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
14428 GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
14429 GeneratorFunctionPrototype.constructor = GeneratorFunction;
14430 GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the
14431 // Iterator interface in terms of a single ._invoke method.
14432
14433 function defineIteratorMethods(prototype) {
14434 ["next", "throw", "return"].forEach(function (method) {
14435 define(prototype, method, function (arg) {
14436 return this._invoke(method, arg);
14437 });
14438 });
14439 }
14440
14441 exports.isGeneratorFunction = function (genFun) {
14442 var ctor = typeof genFun === "function" && genFun.constructor;
14443 return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
14444 // do is to check its .name property.
14445 (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
14446 };
14447
14448 exports.mark = function (genFun) {
14449 if (Object.setPrototypeOf) {
14450 Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
14451 } else {
14452 genFun.__proto__ = GeneratorFunctionPrototype;
14453 define(genFun, toStringTagSymbol, "GeneratorFunction");
14454 }
14455
14456 genFun.prototype = Object.create(Gp);
14457 return genFun;
14458 }; // Within the body of any async function, `await x` is transformed to
14459 // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
14460 // `hasOwn.call(value, "__await")` to determine if the yielded value is
14461 // meant to be awaited.
14462
14463
14464 exports.awrap = function (arg) {
14465 return {
14466 __await: arg
14467 };
14468 };
14469
14470 function AsyncIterator(generator, PromiseImpl) {
14471 function invoke(method, arg, resolve, reject) {
14472 var record = tryCatch(generator[method], generator, arg);
14473
14474 if (record.type === "throw") {
14475 reject(record.arg);
14476 } else {
14477 var result = record.arg;
14478 var value = result.value;
14479
14480 if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
14481 return PromiseImpl.resolve(value.__await).then(function (value) {
14482 invoke("next", value, resolve, reject);
14483 }, function (err) {
14484 invoke("throw", err, resolve, reject);
14485 });
14486 }
14487
14488 return PromiseImpl.resolve(value).then(function (unwrapped) {
14489 // When a yielded Promise is resolved, its final value becomes
14490 // the .value of the Promise<{value,done}> result for the
14491 // current iteration.
14492 result.value = unwrapped;
14493 resolve(result);
14494 }, function (error) {
14495 // If a rejected Promise was yielded, throw the rejection back
14496 // into the async generator function so it can be handled there.
14497 return invoke("throw", error, resolve, reject);
14498 });
14499 }
14500 }
14501
14502 var previousPromise;
14503
14504 function enqueue(method, arg) {
14505 function callInvokeWithMethodAndArg() {
14506 return new PromiseImpl(function (resolve, reject) {
14507 invoke(method, arg, resolve, reject);
14508 });
14509 }
14510
14511 return previousPromise = // If enqueue has been called before, then we want to wait until
14512 // all previous Promises have been resolved before calling invoke,
14513 // so that results are always delivered in the correct order. If
14514 // enqueue has not been called before, then it is important to
14515 // call invoke immediately, without waiting on a callback to fire,
14516 // so that the async generator function has the opportunity to do
14517 // any necessary setup in a predictable way. This predictability
14518 // is why the Promise constructor synchronously invokes its
14519 // executor callback, and why async functions synchronously
14520 // execute code before the first await. Since we implement simple
14521 // async functions in terms of async generators, it is especially
14522 // important to get this right, even though it requires care.
14523 previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
14524 // invocations of the iterator.
14525 callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
14526 } // Define the unified helper method that is used to implement .next,
14527 // .throw, and .return (see defineIteratorMethods).
14528
14529
14530 this._invoke = enqueue;
14531 }
14532
14533 defineIteratorMethods(AsyncIterator.prototype);
14534
14535 AsyncIterator.prototype[asyncIteratorSymbol] = function () {
14536 return this;
14537 };
14538
14539 exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
14540 // AsyncIterator objects; they just return a Promise for the value of
14541 // the final result produced by the iterator.
14542
14543 exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
14544 if (PromiseImpl === void 0) PromiseImpl = Promise;
14545 var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
14546 return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
14547 : iter.next().then(function (result) {
14548 return result.done ? result.value : iter.next();
14549 });
14550 };
14551
14552 function makeInvokeMethod(innerFn, self, context) {
14553 var state = GenStateSuspendedStart;
14554 return function invoke(method, arg) {
14555 if (state === GenStateExecuting) {
14556 throw new Error("Generator is already running");
14557 }
14558
14559 if (state === GenStateCompleted) {
14560 if (method === "throw") {
14561 throw arg;
14562 } // Be forgiving, per 25.3.3.3.3 of the spec:
14563 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
14564
14565
14566 return doneResult();
14567 }
14568
14569 context.method = method;
14570 context.arg = arg;
14571
14572 while (true) {
14573 var delegate = context.delegate;
14574
14575 if (delegate) {
14576 var delegateResult = maybeInvokeDelegate(delegate, context);
14577
14578 if (delegateResult) {
14579 if (delegateResult === ContinueSentinel) continue;
14580 return delegateResult;
14581 }
14582 }
14583
14584 if (context.method === "next") {
14585 // Setting context._sent for legacy support of Babel's
14586 // function.sent implementation.
14587 context.sent = context._sent = context.arg;
14588 } else if (context.method === "throw") {
14589 if (state === GenStateSuspendedStart) {
14590 state = GenStateCompleted;
14591 throw context.arg;
14592 }
14593
14594 context.dispatchException(context.arg);
14595 } else if (context.method === "return") {
14596 context.abrupt("return", context.arg);
14597 }
14598
14599 state = GenStateExecuting;
14600 var record = tryCatch(innerFn, self, context);
14601
14602 if (record.type === "normal") {
14603 // If an exception is thrown from innerFn, we leave state ===
14604 // GenStateExecuting and loop back for another invocation.
14605 state = context.done ? GenStateCompleted : GenStateSuspendedYield;
14606
14607 if (record.arg === ContinueSentinel) {
14608 continue;
14609 }
14610
14611 return {
14612 value: record.arg,
14613 done: context.done
14614 };
14615 } else if (record.type === "throw") {
14616 state = GenStateCompleted; // Dispatch the exception by looping back around to the
14617 // context.dispatchException(context.arg) call above.
14618
14619 context.method = "throw";
14620 context.arg = record.arg;
14621 }
14622 }
14623 };
14624 } // Call delegate.iterator[context.method](context.arg) and handle the
14625 // result, either by returning a { value, done } result from the
14626 // delegate iterator, or by modifying context.method and context.arg,
14627 // setting context.delegate to null, and returning the ContinueSentinel.
14628
14629
14630 function maybeInvokeDelegate(delegate, context) {
14631 var method = delegate.iterator[context.method];
14632
14633 if (method === undefined$1) {
14634 // A .throw or .return when the delegate iterator has no .throw
14635 // method always terminates the yield* loop.
14636 context.delegate = null;
14637
14638 if (context.method === "throw") {
14639 // Note: ["return"] must be used for ES3 parsing compatibility.
14640 if (delegate.iterator["return"]) {
14641 // If the delegate iterator has a return method, give it a
14642 // chance to clean up.
14643 context.method = "return";
14644 context.arg = undefined$1;
14645 maybeInvokeDelegate(delegate, context);
14646
14647 if (context.method === "throw") {
14648 // If maybeInvokeDelegate(context) changed context.method from
14649 // "return" to "throw", let that override the TypeError below.
14650 return ContinueSentinel;
14651 }
14652 }
14653
14654 context.method = "throw";
14655 context.arg = new TypeError("The iterator does not provide a 'throw' method");
14656 }
14657
14658 return ContinueSentinel;
14659 }
14660
14661 var record = tryCatch(method, delegate.iterator, context.arg);
14662
14663 if (record.type === "throw") {
14664 context.method = "throw";
14665 context.arg = record.arg;
14666 context.delegate = null;
14667 return ContinueSentinel;
14668 }
14669
14670 var info = record.arg;
14671
14672 if (!info) {
14673 context.method = "throw";
14674 context.arg = new TypeError("iterator result is not an object");
14675 context.delegate = null;
14676 return ContinueSentinel;
14677 }
14678
14679 if (info.done) {
14680 // Assign the result of the finished delegate to the temporary
14681 // variable specified by delegate.resultName (see delegateYield).
14682 context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
14683
14684 context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
14685 // exception, let the outer generator proceed normally. If
14686 // context.method was "next", forget context.arg since it has been
14687 // "consumed" by the delegate iterator. If context.method was
14688 // "return", allow the original .return call to continue in the
14689 // outer generator.
14690
14691 if (context.method !== "return") {
14692 context.method = "next";
14693 context.arg = undefined$1;
14694 }
14695 } else {
14696 // Re-yield the result returned by the delegate method.
14697 return info;
14698 } // The delegate iterator is finished, so forget it and continue with
14699 // the outer generator.
14700
14701
14702 context.delegate = null;
14703 return ContinueSentinel;
14704 } // Define Generator.prototype.{next,throw,return} in terms of the
14705 // unified ._invoke helper method.
14706
14707
14708 defineIteratorMethods(Gp);
14709 define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the
14710 // @@iterator function is called on it. Some browsers' implementations of the
14711 // iterator prototype chain incorrectly implement this, causing the Generator
14712 // object to not be returned from this call. This ensures that doesn't happen.
14713 // See https://github.com/facebook/regenerator/issues/274 for more details.
14714
14715 Gp[iteratorSymbol] = function () {
14716 return this;
14717 };
14718
14719 Gp.toString = function () {
14720 return "[object Generator]";
14721 };
14722
14723 function pushTryEntry(locs) {
14724 var entry = {
14725 tryLoc: locs[0]
14726 };
14727
14728 if (1 in locs) {
14729 entry.catchLoc = locs[1];
14730 }
14731
14732 if (2 in locs) {
14733 entry.finallyLoc = locs[2];
14734 entry.afterLoc = locs[3];
14735 }
14736
14737 this.tryEntries.push(entry);
14738 }
14739
14740 function resetTryEntry(entry) {
14741 var record = entry.completion || {};
14742 record.type = "normal";
14743 delete record.arg;
14744 entry.completion = record;
14745 }
14746
14747 function Context(tryLocsList) {
14748 // The root entry object (effectively a try statement without a catch
14749 // or a finally block) gives us a place to store values thrown from
14750 // locations where there is no enclosing try statement.
14751 this.tryEntries = [{
14752 tryLoc: "root"
14753 }];
14754 tryLocsList.forEach(pushTryEntry, this);
14755 this.reset(true);
14756 }
14757
14758 exports.keys = function (object) {
14759 var keys = [];
14760
14761 for (var key in object) {
14762 keys.push(key);
14763 }
14764
14765 keys.reverse(); // Rather than returning an object with a next method, we keep
14766 // things simple and return the next function itself.
14767
14768 return function next() {
14769 while (keys.length) {
14770 var key = keys.pop();
14771
14772 if (key in object) {
14773 next.value = key;
14774 next.done = false;
14775 return next;
14776 }
14777 } // To avoid creating an additional object, we just hang the .value
14778 // and .done properties off the next function object itself. This
14779 // also ensures that the minifier will not anonymize the function.
14780
14781
14782 next.done = true;
14783 return next;
14784 };
14785 };
14786
14787 function values(iterable) {
14788 if (iterable) {
14789 var iteratorMethod = iterable[iteratorSymbol];
14790
14791 if (iteratorMethod) {
14792 return iteratorMethod.call(iterable);
14793 }
14794
14795 if (typeof iterable.next === "function") {
14796 return iterable;
14797 }
14798
14799 if (!isNaN(iterable.length)) {
14800 var i = -1,
14801 next = function next() {
14802 while (++i < iterable.length) {
14803 if (hasOwn.call(iterable, i)) {
14804 next.value = iterable[i];
14805 next.done = false;
14806 return next;
14807 }
14808 }
14809
14810 next.value = undefined$1;
14811 next.done = true;
14812 return next;
14813 };
14814
14815 return next.next = next;
14816 }
14817 } // Return an iterator with no values.
14818
14819
14820 return {
14821 next: doneResult
14822 };
14823 }
14824
14825 exports.values = values;
14826
14827 function doneResult() {
14828 return {
14829 value: undefined$1,
14830 done: true
14831 };
14832 }
14833
14834 Context.prototype = {
14835 constructor: Context,
14836 reset: function (skipTempReset) {
14837 this.prev = 0;
14838 this.next = 0; // Resetting context._sent for legacy support of Babel's
14839 // function.sent implementation.
14840
14841 this.sent = this._sent = undefined$1;
14842 this.done = false;
14843 this.delegate = null;
14844 this.method = "next";
14845 this.arg = undefined$1;
14846 this.tryEntries.forEach(resetTryEntry);
14847
14848 if (!skipTempReset) {
14849 for (var name in this) {
14850 // Not sure about the optimal order of these conditions:
14851 if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
14852 this[name] = undefined$1;
14853 }
14854 }
14855 }
14856 },
14857 stop: function () {
14858 this.done = true;
14859 var rootEntry = this.tryEntries[0];
14860 var rootRecord = rootEntry.completion;
14861
14862 if (rootRecord.type === "throw") {
14863 throw rootRecord.arg;
14864 }
14865
14866 return this.rval;
14867 },
14868 dispatchException: function (exception) {
14869 if (this.done) {
14870 throw exception;
14871 }
14872
14873 var context = this;
14874
14875 function handle(loc, caught) {
14876 record.type = "throw";
14877 record.arg = exception;
14878 context.next = loc;
14879
14880 if (caught) {
14881 // If the dispatched exception was caught by a catch block,
14882 // then let that catch block handle the exception normally.
14883 context.method = "next";
14884 context.arg = undefined$1;
14885 }
14886
14887 return !!caught;
14888 }
14889
14890 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
14891 var entry = this.tryEntries[i];
14892 var record = entry.completion;
14893
14894 if (entry.tryLoc === "root") {
14895 // Exception thrown outside of any try block that could handle
14896 // it, so set the completion value of the entire function to
14897 // throw the exception.
14898 return handle("end");
14899 }
14900
14901 if (entry.tryLoc <= this.prev) {
14902 var hasCatch = hasOwn.call(entry, "catchLoc");
14903 var hasFinally = hasOwn.call(entry, "finallyLoc");
14904
14905 if (hasCatch && hasFinally) {
14906 if (this.prev < entry.catchLoc) {
14907 return handle(entry.catchLoc, true);
14908 } else if (this.prev < entry.finallyLoc) {
14909 return handle(entry.finallyLoc);
14910 }
14911 } else if (hasCatch) {
14912 if (this.prev < entry.catchLoc) {
14913 return handle(entry.catchLoc, true);
14914 }
14915 } else if (hasFinally) {
14916 if (this.prev < entry.finallyLoc) {
14917 return handle(entry.finallyLoc);
14918 }
14919 } else {
14920 throw new Error("try statement without catch or finally");
14921 }
14922 }
14923 }
14924 },
14925 abrupt: function (type, arg) {
14926 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
14927 var entry = this.tryEntries[i];
14928
14929 if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
14930 var finallyEntry = entry;
14931 break;
14932 }
14933 }
14934
14935 if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
14936 // Ignore the finally entry if control is not jumping to a
14937 // location outside the try/catch block.
14938 finallyEntry = null;
14939 }
14940
14941 var record = finallyEntry ? finallyEntry.completion : {};
14942 record.type = type;
14943 record.arg = arg;
14944
14945 if (finallyEntry) {
14946 this.method = "next";
14947 this.next = finallyEntry.finallyLoc;
14948 return ContinueSentinel;
14949 }
14950
14951 return this.complete(record);
14952 },
14953 complete: function (record, afterLoc) {
14954 if (record.type === "throw") {
14955 throw record.arg;
14956 }
14957
14958 if (record.type === "break" || record.type === "continue") {
14959 this.next = record.arg;
14960 } else if (record.type === "return") {
14961 this.rval = this.arg = record.arg;
14962 this.method = "return";
14963 this.next = "end";
14964 } else if (record.type === "normal" && afterLoc) {
14965 this.next = afterLoc;
14966 }
14967
14968 return ContinueSentinel;
14969 },
14970 finish: function (finallyLoc) {
14971 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
14972 var entry = this.tryEntries[i];
14973
14974 if (entry.finallyLoc === finallyLoc) {
14975 this.complete(entry.completion, entry.afterLoc);
14976 resetTryEntry(entry);
14977 return ContinueSentinel;
14978 }
14979 }
14980 },
14981 "catch": function (tryLoc) {
14982 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
14983 var entry = this.tryEntries[i];
14984
14985 if (entry.tryLoc === tryLoc) {
14986 var record = entry.completion;
14987
14988 if (record.type === "throw") {
14989 var thrown = record.arg;
14990 resetTryEntry(entry);
14991 }
14992
14993 return thrown;
14994 }
14995 } // The context.catch method must only be called with a location
14996 // argument that corresponds to a known catch block.
14997
14998
14999 throw new Error("illegal catch attempt");
15000 },
15001 delegateYield: function (iterable, resultName, nextLoc) {
15002 this.delegate = {
15003 iterator: values(iterable),
15004 resultName: resultName,
15005 nextLoc: nextLoc
15006 };
15007
15008 if (this.method === "next") {
15009 // Deliberately forget the last sent value so that we don't
15010 // accidentally pass it on to the delegate.
15011 this.arg = undefined$1;
15012 }
15013
15014 return ContinueSentinel;
15015 }
15016 }; // Regardless of whether this script is executing as a CommonJS module
15017 // or not, return the runtime object so that we can declare the variable
15018 // regeneratorRuntime in the outer scope, which allows this module to be
15019 // injected easily by `bin/regenerator --include-runtime script.js`.
15020
15021 return exports;
15022 }( // If this script is executing as a CommonJS module, use module.exports
15023 // as the regeneratorRuntime namespace. Otherwise create a new empty
15024 // object. Either way, the resulting object will be used to initialize
15025 // the regeneratorRuntime variable at the top of this file.
15026 module.exports );
15027
15028 try {
15029 regeneratorRuntime = runtime;
15030 } catch (accidentalStrictMode) {
15031 // This module should not be running in strict mode, so the above
15032 // assignment should always work unless something is misconfigured. Just
15033 // in case runtime.js accidentally runs in strict mode, we can escape
15034 // strict mode using a global Function call. This could conceivably fail
15035 // if a Content Security Policy forbids using Function, but in that case
15036 // the proper solution is to fix the accidental strict mode problem. If
15037 // you've misconfigured your bundler to force strict mode and applied a
15038 // CSP to forbid Function, and you're not willing to fix either of those
15039 // problems, please detail your unique predicament in a GitHub issue.
15040 Function("r", "regeneratorRuntime = r")(runtime);
15041 }
15042})(runtime);
15043
15044var regenerator = runtime.exports;
15045
15046var aFunction$2 = aFunction$6;
15047var toObject$2 = toObject$e;
15048var IndexedObject = indexedObject;
15049var toLength$3 = toLength$c; // `Array.prototype.{ reduce, reduceRight }` methods implementation
15050
15051var createMethod = function (IS_RIGHT) {
15052 return function (that, callbackfn, argumentsLength, memo) {
15053 aFunction$2(callbackfn);
15054 var O = toObject$2(that);
15055 var self = IndexedObject(O);
15056 var length = toLength$3(O.length);
15057 var index = IS_RIGHT ? length - 1 : 0;
15058 var i = IS_RIGHT ? -1 : 1;
15059 if (argumentsLength < 2) while (true) {
15060 if (index in self) {
15061 memo = self[index];
15062 index += i;
15063 break;
15064 }
15065
15066 index += i;
15067
15068 if (IS_RIGHT ? index < 0 : length <= index) {
15069 throw TypeError('Reduce of empty array with no initial value');
15070 }
15071 }
15072
15073 for (; IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {
15074 memo = callbackfn(memo, self[index], index, O);
15075 }
15076
15077 return memo;
15078 };
15079};
15080
15081var arrayReduce = {
15082 // `Array.prototype.reduce` method
15083 // https://tc39.es/ecma262/#sec-array.prototype.reduce
15084 left: createMethod(false),
15085 // `Array.prototype.reduceRight` method
15086 // https://tc39.es/ecma262/#sec-array.prototype.reduceright
15087 right: createMethod(true)
15088};
15089
15090var classof$3 = classofRaw$1;
15091var global$3 = global$k;
15092var engineIsNode = classof$3(global$3.process) == 'process';
15093
15094var $$7 = _export;
15095var $reduce = arrayReduce.left;
15096var arrayMethodIsStrict$2 = arrayMethodIsStrict$6;
15097var CHROME_VERSION = engineV8Version;
15098var IS_NODE = engineIsNode;
15099var STRICT_METHOD$2 = arrayMethodIsStrict$2('reduce'); // Chrome 80-82 has a critical bug
15100// https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
15101
15102var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83; // `Array.prototype.reduce` method
15103// https://tc39.es/ecma262/#sec-array.prototype.reduce
15104
15105$$7({
15106 target: 'Array',
15107 proto: true,
15108 forced: !STRICT_METHOD$2 || CHROME_BUG
15109}, {
15110 reduce: function reduce(callbackfn
15111 /* , initialValue */
15112 ) {
15113 return $reduce(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
15114 }
15115});
15116
15117var entryVirtual$6 = entryVirtual$l;
15118var reduce$3 = entryVirtual$6('Array').reduce;
15119
15120var reduce$2 = reduce$3;
15121var ArrayPrototype$6 = Array.prototype;
15122
15123var reduce_1 = function (it) {
15124 var own = it.reduce;
15125 return it === ArrayPrototype$6 || it instanceof Array && own === ArrayPrototype$6.reduce ? reduce$2 : own;
15126};
15127
15128var parent$g = reduce_1;
15129var reduce$1 = parent$g;
15130
15131var reduce = reduce$1;
15132
15133var isArray = isArray$c;
15134var toLength$2 = toLength$c;
15135var bind = functionBindContext; // `FlattenIntoArray` abstract operation
15136// https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
15137
15138var flattenIntoArray$1 = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {
15139 var targetIndex = start;
15140 var sourceIndex = 0;
15141 var mapFn = mapper ? bind(mapper, thisArg, 3) : false;
15142 var element;
15143
15144 while (sourceIndex < sourceLen) {
15145 if (sourceIndex in source) {
15146 element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
15147
15148 if (depth > 0 && isArray(element)) {
15149 targetIndex = flattenIntoArray$1(target, original, element, toLength$2(element.length), targetIndex, depth - 1) - 1;
15150 } else {
15151 if (targetIndex >= 0x1FFFFFFFFFFFFF) throw TypeError('Exceed the acceptable array length');
15152 target[targetIndex] = element;
15153 }
15154
15155 targetIndex++;
15156 }
15157
15158 sourceIndex++;
15159 }
15160
15161 return targetIndex;
15162};
15163
15164var flattenIntoArray_1 = flattenIntoArray$1;
15165
15166var $$6 = _export;
15167var flattenIntoArray = flattenIntoArray_1;
15168var toObject$1 = toObject$e;
15169var toLength$1 = toLength$c;
15170var aFunction$1 = aFunction$6;
15171var arraySpeciesCreate = arraySpeciesCreate$4; // `Array.prototype.flatMap` method
15172// https://tc39.es/ecma262/#sec-array.prototype.flatmap
15173
15174$$6({
15175 target: 'Array',
15176 proto: true
15177}, {
15178 flatMap: function flatMap(callbackfn
15179 /* , thisArg */
15180 ) {
15181 var O = toObject$1(this);
15182 var sourceLen = toLength$1(O.length);
15183 var A;
15184 aFunction$1(callbackfn);
15185 A = arraySpeciesCreate(O, 0);
15186 A.length = flattenIntoArray(A, O, O, sourceLen, 0, 1, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
15187 return A;
15188 }
15189});
15190
15191var entryVirtual$5 = entryVirtual$l;
15192var flatMap$3 = entryVirtual$5('Array').flatMap;
15193
15194var flatMap$2 = flatMap$3;
15195var ArrayPrototype$5 = Array.prototype;
15196
15197var flatMap_1 = function (it) {
15198 var own = it.flatMap;
15199 return it === ArrayPrototype$5 || it instanceof Array && own === ArrayPrototype$5.flatMap ? flatMap$2 : own;
15200};
15201
15202var parent$f = flatMap_1;
15203var flatMap$1 = parent$f;
15204
15205var flatMap = flatMap$1;
15206
15207var collection$1 = collection$3;
15208var collectionStrong = collectionStrong$2; // `Set` constructor
15209// https://tc39.es/ecma262/#sec-set-objects
15210
15211collection$1('Set', function (init) {
15212 return function Set() {
15213 return init(this, arguments.length ? arguments[0] : undefined);
15214 };
15215}, collectionStrong);
15216
15217var path$6 = path$x;
15218var set$2 = path$6.Set;
15219
15220var parent$e = set$2;
15221var set$1 = parent$e;
15222
15223var set = set$1;
15224
15225var iterator = iterator$3;
15226
15227var anObject$2 = anObject$d;
15228var getIteratorMethod = getIteratorMethod$7;
15229
15230var getIterator$4 = function (it) {
15231 var iteratorMethod = getIteratorMethod(it);
15232
15233 if (typeof iteratorMethod != 'function') {
15234 throw TypeError(String(it) + ' is not iterable');
15235 }
15236
15237 return anObject$2(iteratorMethod.call(it));
15238};
15239
15240var getIterator$3 = getIterator$4;
15241var getIterator_1 = getIterator$3;
15242
15243var parent$d = getIterator_1;
15244var getIterator$2 = parent$d;
15245
15246var parent$c = getIterator$2;
15247var getIterator$1 = parent$c;
15248
15249var getIterator = getIterator$1;
15250
15251var floor = Math.floor;
15252
15253var mergeSort = function (array, comparefn) {
15254 var length = array.length;
15255 var middle = floor(length / 2);
15256 return length < 8 ? insertionSort(array, comparefn) : merge(mergeSort(array.slice(0, middle), comparefn), mergeSort(array.slice(middle), comparefn), comparefn);
15257};
15258
15259var insertionSort = function (array, comparefn) {
15260 var length = array.length;
15261 var i = 1;
15262 var element, j;
15263
15264 while (i < length) {
15265 j = i;
15266 element = array[i];
15267
15268 while (j && comparefn(array[j - 1], element) > 0) {
15269 array[j] = array[--j];
15270 }
15271
15272 if (j !== i++) array[j] = element;
15273 }
15274
15275 return array;
15276};
15277
15278var merge = function (left, right, comparefn) {
15279 var llength = left.length;
15280 var rlength = right.length;
15281 var lindex = 0;
15282 var rindex = 0;
15283 var result = [];
15284
15285 while (lindex < llength || rindex < rlength) {
15286 if (lindex < llength && rindex < rlength) {
15287 result.push(comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]);
15288 } else {
15289 result.push(lindex < llength ? left[lindex++] : right[rindex++]);
15290 }
15291 }
15292
15293 return result;
15294};
15295
15296var arraySort = mergeSort;
15297
15298var userAgent$1 = engineUserAgent;
15299var firefox = userAgent$1.match(/firefox\/(\d+)/i);
15300var engineFfVersion = !!firefox && +firefox[1];
15301
15302var UA = engineUserAgent;
15303var engineIsIeOrEdge = /MSIE|Trident/.test(UA);
15304
15305var userAgent = engineUserAgent;
15306var webkit = userAgent.match(/AppleWebKit\/(\d+)\./);
15307var engineWebkitVersion = !!webkit && +webkit[1];
15308
15309var $$5 = _export;
15310var aFunction = aFunction$6;
15311var toObject = toObject$e;
15312var toLength = toLength$c;
15313var toString$1 = toString$9;
15314var fails$1 = fails$m;
15315var internalSort = arraySort;
15316var arrayMethodIsStrict$1 = arrayMethodIsStrict$6;
15317var FF = engineFfVersion;
15318var IE_OR_EDGE = engineIsIeOrEdge;
15319var V8 = engineV8Version;
15320var WEBKIT = engineWebkitVersion;
15321var test = [];
15322var nativeSort = test.sort; // IE8-
15323
15324var FAILS_ON_UNDEFINED = fails$1(function () {
15325 test.sort(undefined);
15326}); // V8 bug
15327
15328var FAILS_ON_NULL = fails$1(function () {
15329 test.sort(null);
15330}); // Old WebKit
15331
15332var STRICT_METHOD$1 = arrayMethodIsStrict$1('sort');
15333var STABLE_SORT = !fails$1(function () {
15334 // feature detection can be too slow, so check engines versions
15335 if (V8) return V8 < 70;
15336 if (FF && FF > 3) return;
15337 if (IE_OR_EDGE) return true;
15338 if (WEBKIT) return WEBKIT < 603;
15339 var result = '';
15340 var code, chr, value, index; // generate an array with more 512 elements (Chakra and old V8 fails only in this case)
15341
15342 for (code = 65; code < 76; code++) {
15343 chr = String.fromCharCode(code);
15344
15345 switch (code) {
15346 case 66:
15347 case 69:
15348 case 70:
15349 case 72:
15350 value = 3;
15351 break;
15352
15353 case 68:
15354 case 71:
15355 value = 4;
15356 break;
15357
15358 default:
15359 value = 2;
15360 }
15361
15362 for (index = 0; index < 47; index++) {
15363 test.push({
15364 k: chr + index,
15365 v: value
15366 });
15367 }
15368 }
15369
15370 test.sort(function (a, b) {
15371 return b.v - a.v;
15372 });
15373
15374 for (index = 0; index < test.length; index++) {
15375 chr = test[index].k.charAt(0);
15376 if (result.charAt(result.length - 1) !== chr) result += chr;
15377 }
15378
15379 return result !== 'DGBEFHACIJK';
15380});
15381var FORCED$1 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD$1 || !STABLE_SORT;
15382
15383var getSortCompare = function (comparefn) {
15384 return function (x, y) {
15385 if (y === undefined) return -1;
15386 if (x === undefined) return 1;
15387 if (comparefn !== undefined) return +comparefn(x, y) || 0;
15388 return toString$1(x) > toString$1(y) ? 1 : -1;
15389 };
15390}; // `Array.prototype.sort` method
15391// https://tc39.es/ecma262/#sec-array.prototype.sort
15392
15393
15394$$5({
15395 target: 'Array',
15396 proto: true,
15397 forced: FORCED$1
15398}, {
15399 sort: function sort(comparefn) {
15400 if (comparefn !== undefined) aFunction(comparefn);
15401 var array = toObject(this);
15402 if (STABLE_SORT) return comparefn === undefined ? nativeSort.call(array) : nativeSort.call(array, comparefn);
15403 var items = [];
15404 var arrayLength = toLength(array.length);
15405 var itemsLength, index;
15406
15407 for (index = 0; index < arrayLength; index++) {
15408 if (index in array) items.push(array[index]);
15409 }
15410
15411 items = internalSort(items, getSortCompare(comparefn));
15412 itemsLength = items.length;
15413 index = 0;
15414
15415 while (index < itemsLength) array[index] = items[index++];
15416
15417 while (index < arrayLength) delete array[index++];
15418
15419 return array;
15420 }
15421});
15422
15423var entryVirtual$4 = entryVirtual$l;
15424var sort$3 = entryVirtual$4('Array').sort;
15425
15426var sort$2 = sort$3;
15427var ArrayPrototype$4 = Array.prototype;
15428
15429var sort_1 = function (it) {
15430 var own = it.sort;
15431 return it === ArrayPrototype$4 || it instanceof Array && own === ArrayPrototype$4.sort ? sort$2 : own;
15432};
15433
15434var parent$b = sort_1;
15435var sort$1 = parent$b;
15436
15437var sort = sort$1;
15438
15439var entryVirtual$3 = entryVirtual$l;
15440var keys$3 = entryVirtual$3('Array').keys;
15441
15442var parent$a = keys$3;
15443var keys$2 = parent$a;
15444
15445var keys$1 = keys$2;
15446var classof$2 = classof$a;
15447var ArrayPrototype$3 = Array.prototype;
15448var DOMIterables$2 = {
15449 DOMTokenList: true,
15450 NodeList: true
15451};
15452
15453var keys_1 = function (it) {
15454 var own = it.keys;
15455 return it === ArrayPrototype$3 || it instanceof Array && own === ArrayPrototype$3.keys // eslint-disable-next-line no-prototype-builtins -- safe
15456 || DOMIterables$2.hasOwnProperty(classof$2(it)) ? keys$1 : own;
15457};
15458
15459var keys = keys_1;
15460
15461var entryVirtual$2 = entryVirtual$l;
15462var values$3 = entryVirtual$2('Array').values;
15463
15464var parent$9 = values$3;
15465var values$2 = parent$9;
15466
15467var values$1 = values$2;
15468var classof$1 = classof$a;
15469var ArrayPrototype$2 = Array.prototype;
15470var DOMIterables$1 = {
15471 DOMTokenList: true,
15472 NodeList: true
15473};
15474
15475var values_1 = function (it) {
15476 var own = it.values;
15477 return it === ArrayPrototype$2 || it instanceof Array && own === ArrayPrototype$2.values // eslint-disable-next-line no-prototype-builtins -- safe
15478 || DOMIterables$1.hasOwnProperty(classof$1(it)) ? values$1 : own;
15479};
15480
15481var values = values_1;
15482
15483var entryVirtual$1 = entryVirtual$l;
15484var entries$3 = entryVirtual$1('Array').entries;
15485
15486var parent$8 = entries$3;
15487var entries$2 = parent$8;
15488
15489var entries$1 = entries$2;
15490var classof = classof$a;
15491var ArrayPrototype$1 = Array.prototype;
15492var DOMIterables = {
15493 DOMTokenList: true,
15494 NodeList: true
15495};
15496
15497var entries_1 = function (it) {
15498 var own = it.entries;
15499 return it === ArrayPrototype$1 || it instanceof Array && own === ArrayPrototype$1.entries // eslint-disable-next-line no-prototype-builtins -- safe
15500 || DOMIterables.hasOwnProperty(classof(it)) ? entries$1 : own;
15501};
15502
15503var entries = entries_1;
15504
15505// Unique ID creation requires a high quality random # generator. In the browser we therefore
15506// require the crypto API and do not support built-in fallback to lower quality random number
15507// generators (like Math.random()).
15508var getRandomValues;
15509var rnds8 = new Uint8Array(16);
15510function rng() {
15511 // lazy load so that environments that need to polyfill have a chance to do so
15512 if (!getRandomValues) {
15513 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
15514 // find the complete implementation of crypto (msCrypto) on IE11.
15515 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
15516
15517 if (!getRandomValues) {
15518 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
15519 }
15520 }
15521
15522 return getRandomValues(rnds8);
15523}
15524
15525var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
15526
15527function validate(uuid) {
15528 return typeof uuid === 'string' && REGEX.test(uuid);
15529}
15530
15531/**
15532 * Convert array of 16 byte values to UUID string format of the form:
15533 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
15534 */
15535
15536var byteToHex = [];
15537
15538for (var i = 0; i < 256; ++i) {
15539 byteToHex.push((i + 0x100).toString(16).substr(1));
15540}
15541
15542function stringify(arr) {
15543 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; // Note: Be careful editing this code! It's been tuned for performance
15544 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
15545
15546 var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
15547 // of the following:
15548 // - One or more input array values don't map to a hex octet (leading to
15549 // "undefined" in the uuid)
15550 // - Invalid input values for the RFC `version` or `variant` fields
15551
15552 if (!validate(uuid)) {
15553 throw TypeError('Stringified UUID is invalid');
15554 }
15555
15556 return uuid;
15557}
15558
15559function v4(options, buf, offset) {
15560 options = options || {};
15561 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
15562
15563 rnds[6] = rnds[6] & 0x0f | 0x40;
15564 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
15565
15566 if (buf) {
15567 offset = offset || 0;
15568
15569 for (var i = 0; i < 16; ++i) {
15570 buf[offset + i] = rnds[i];
15571 }
15572
15573 return buf;
15574 }
15575
15576 return stringify(rnds);
15577}
15578
15579function ownKeys$4(object, enumerableOnly) { var keys = keys$4(object); if (getOwnPropertySymbols) { var symbols = getOwnPropertySymbols(object); if (enumerableOnly) { symbols = filter(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$2(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
15580
15581function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { var _context32; forEach$2(_context32 = ownKeys$4(Object(source), true)).call(_context32, function (key) { _defineProperty(target, key, source[key]); }); } else if (getOwnPropertyDescriptors) { defineProperties(target, getOwnPropertyDescriptors(source)); } else { var _context33; forEach$2(_context33 = ownKeys$4(Object(source))).call(_context33, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$2(source, key)); }); } } return target; }
15582
15583function _createSuper$t(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$t(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
15584
15585function _isNativeReflectConstruct$t() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
15586
15587function _createForOfIteratorHelper$7(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$7(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
15588
15589function _unsupportedIterableToArray$7(o, minLen) { var _context31; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$7(o, minLen); var n = slice$1(_context31 = Object.prototype.toString.call(o)).call(_context31, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$7(o, minLen); }
15590
15591function _arrayLikeToArray$7(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
15592/**
15593 * Create new data pipe.
15594 *
15595 * @param from - The source data set or data view.
15596 *
15597 * @remarks
15598 * Example usage:
15599 * ```typescript
15600 * interface AppItem {
15601 * whoami: string;
15602 * appData: unknown;
15603 * visData: VisItem;
15604 * }
15605 * interface VisItem {
15606 * id: number;
15607 * label: string;
15608 * color: string;
15609 * x: number;
15610 * y: number;
15611 * }
15612 *
15613 * const ds1 = new DataSet<AppItem, "whoami">([], { fieldId: "whoami" });
15614 * const ds2 = new DataSet<VisItem, "id">();
15615 *
15616 * const pipe = createNewDataPipeFrom(ds1)
15617 * .filter((item): boolean => item.enabled === true)
15618 * .map<VisItem, "id">((item): VisItem => item.visData)
15619 * .to(ds2);
15620 *
15621 * pipe.start();
15622 * ```
15623 *
15624 * @returns A factory whose methods can be used to configure the pipe.
15625 */
15626
15627function createNewDataPipeFrom(from) {
15628 return new DataPipeUnderConstruction(from);
15629}
15630/**
15631 * Internal implementation of the pipe. This should be accessible only through
15632 * `createNewDataPipeFrom` from the outside.
15633 *
15634 * @typeParam SI - Source item type.
15635 * @typeParam SP - Source item type's id property name.
15636 * @typeParam TI - Target item type.
15637 * @typeParam TP - Target item type's id property name.
15638 */
15639
15640
15641var SimpleDataPipe = /*#__PURE__*/function () {
15642 /**
15643 * Create a new data pipe.
15644 *
15645 * @param _source - The data set or data view that will be observed.
15646 * @param _transformers - An array of transforming functions to be used to
15647 * filter or transform the items in the pipe.
15648 * @param _target - The data set or data view that will receive the items.
15649 */
15650 function SimpleDataPipe(_source, _transformers, _target) {
15651 var _context, _context2, _context3;
15652
15653 _classCallCheck(this, SimpleDataPipe);
15654
15655 this._source = _source;
15656 this._transformers = _transformers;
15657 this._target = _target;
15658 /**
15659 * Bound listeners for use with `DataInterface['on' | 'off']`.
15660 */
15661
15662 this._listeners = {
15663 add: bind$6(_context = this._add).call(_context, this),
15664 remove: bind$6(_context2 = this._remove).call(_context2, this),
15665 update: bind$6(_context3 = this._update).call(_context3, this)
15666 };
15667 }
15668 /** @inheritDoc */
15669
15670
15671 _createClass(SimpleDataPipe, [{
15672 key: "all",
15673 value: function all() {
15674 this._target.update(this._transformItems(this._source.get()));
15675
15676 return this;
15677 }
15678 /** @inheritDoc */
15679
15680 }, {
15681 key: "start",
15682 value: function start() {
15683 this._source.on("add", this._listeners.add);
15684
15685 this._source.on("remove", this._listeners.remove);
15686
15687 this._source.on("update", this._listeners.update);
15688
15689 return this;
15690 }
15691 /** @inheritDoc */
15692
15693 }, {
15694 key: "stop",
15695 value: function stop() {
15696 this._source.off("add", this._listeners.add);
15697
15698 this._source.off("remove", this._listeners.remove);
15699
15700 this._source.off("update", this._listeners.update);
15701
15702 return this;
15703 }
15704 /**
15705 * Apply the transformers to the items.
15706 *
15707 * @param items - The items to be transformed.
15708 *
15709 * @returns The transformed items.
15710 */
15711
15712 }, {
15713 key: "_transformItems",
15714 value: function _transformItems(items) {
15715 var _context4;
15716
15717 return reduce(_context4 = this._transformers).call(_context4, function (items, transform) {
15718 return transform(items);
15719 }, items);
15720 }
15721 /**
15722 * Handle an add event.
15723 *
15724 * @param _name - Ignored.
15725 * @param payload - The payload containing the ids of the added items.
15726 */
15727
15728 }, {
15729 key: "_add",
15730 value: function _add(_name, payload) {
15731 if (payload == null) {
15732 return;
15733 }
15734
15735 this._target.add(this._transformItems(this._source.get(payload.items)));
15736 }
15737 /**
15738 * Handle an update event.
15739 *
15740 * @param _name - Ignored.
15741 * @param payload - The payload containing the ids of the updated items.
15742 */
15743
15744 }, {
15745 key: "_update",
15746 value: function _update(_name, payload) {
15747 if (payload == null) {
15748 return;
15749 }
15750
15751 this._target.update(this._transformItems(this._source.get(payload.items)));
15752 }
15753 /**
15754 * Handle a remove event.
15755 *
15756 * @param _name - Ignored.
15757 * @param payload - The payload containing the data of the removed items.
15758 */
15759
15760 }, {
15761 key: "_remove",
15762 value: function _remove(_name, payload) {
15763 if (payload == null) {
15764 return;
15765 }
15766
15767 this._target.remove(this._transformItems(payload.oldData));
15768 }
15769 }]);
15770
15771 return SimpleDataPipe;
15772}();
15773/**
15774 * Internal implementation of the pipe factory. This should be accessible
15775 * only through `createNewDataPipeFrom` from the outside.
15776 *
15777 * @typeParam TI - Target item type.
15778 * @typeParam TP - Target item type's id property name.
15779 */
15780
15781
15782var DataPipeUnderConstruction = /*#__PURE__*/function () {
15783 /**
15784 * Create a new data pipe factory. This is an internal constructor that
15785 * should never be called from outside of this file.
15786 *
15787 * @param _source - The source data set or data view for this pipe.
15788 */
15789 function DataPipeUnderConstruction(_source) {
15790 _classCallCheck(this, DataPipeUnderConstruction);
15791
15792 this._source = _source;
15793 /**
15794 * Array transformers used to transform items within the pipe. This is typed
15795 * as any for the sake of simplicity.
15796 */
15797
15798 this._transformers = [];
15799 }
15800 /**
15801 * Filter the items.
15802 *
15803 * @param callback - A filtering function that returns true if given item
15804 * should be piped and false if not.
15805 *
15806 * @returns This factory for further configuration.
15807 */
15808
15809
15810 _createClass(DataPipeUnderConstruction, [{
15811 key: "filter",
15812 value: function filter$1(callback) {
15813 this._transformers.push(function (input) {
15814 return filter(input).call(input, callback);
15815 });
15816
15817 return this;
15818 }
15819 /**
15820 * Map each source item to a new type.
15821 *
15822 * @param callback - A mapping function that takes a source item and returns
15823 * corresponding mapped item.
15824 *
15825 * @typeParam TI - Target item type.
15826 * @typeParam TP - Target item type's id property name.
15827 *
15828 * @returns This factory for further configuration.
15829 */
15830
15831 }, {
15832 key: "map",
15833 value: function map(callback) {
15834 this._transformers.push(function (input) {
15835 return map$3(input).call(input, callback);
15836 });
15837
15838 return this;
15839 }
15840 /**
15841 * Map each source item to zero or more items of a new type.
15842 *
15843 * @param callback - A mapping function that takes a source item and returns
15844 * an array of corresponding mapped items.
15845 *
15846 * @typeParam TI - Target item type.
15847 * @typeParam TP - Target item type's id property name.
15848 *
15849 * @returns This factory for further configuration.
15850 */
15851
15852 }, {
15853 key: "flatMap",
15854 value: function flatMap$1(callback) {
15855 this._transformers.push(function (input) {
15856 return flatMap(input).call(input, callback);
15857 });
15858
15859 return this;
15860 }
15861 /**
15862 * Connect this pipe to given data set.
15863 *
15864 * @param target - The data set that will receive the items from this pipe.
15865 *
15866 * @returns The pipe connected between given data sets and performing
15867 * configured transformation on the processed items.
15868 */
15869
15870 }, {
15871 key: "to",
15872 value: function to(target) {
15873 return new SimpleDataPipe(this._source, this._transformers, target);
15874 }
15875 }]);
15876
15877 return DataPipeUnderConstruction;
15878}();
15879/**
15880 * Determine whether a value can be used as an id.
15881 *
15882 * @param value - Input value of unknown type.
15883 *
15884 * @returns True if the value is valid id, false otherwise.
15885 */
15886
15887
15888function isId(value) {
15889 return typeof value === "string" || typeof value === "number";
15890}
15891/**
15892 * A queue.
15893 *
15894 * @typeParam T - The type of method names to be replaced by queued versions.
15895 */
15896
15897
15898var Queue = /*#__PURE__*/function () {
15899 /**
15900 * Construct a new Queue.
15901 *
15902 * @param options - Queue configuration.
15903 */
15904 function Queue(options) {
15905 _classCallCheck(this, Queue);
15906
15907 this._queue = [];
15908 this._timeout = null;
15909 this._extended = null; // options
15910
15911 this.delay = null;
15912 this.max = Infinity;
15913 this.setOptions(options);
15914 }
15915 /**
15916 * Update the configuration of the queue.
15917 *
15918 * @param options - Queue configuration.
15919 */
15920
15921
15922 _createClass(Queue, [{
15923 key: "setOptions",
15924 value: function setOptions(options) {
15925 if (options && typeof options.delay !== "undefined") {
15926 this.delay = options.delay;
15927 }
15928
15929 if (options && typeof options.max !== "undefined") {
15930 this.max = options.max;
15931 }
15932
15933 this._flushIfNeeded();
15934 }
15935 /**
15936 * Extend an object with queuing functionality.
15937 * The object will be extended with a function flush, and the methods provided in options.replace will be replaced with queued ones.
15938 *
15939 * @param object - The object to be extended.
15940 * @param options - Additional options.
15941 *
15942 * @returns The created queue.
15943 */
15944
15945 }, {
15946 key: "destroy",
15947 value:
15948 /**
15949 * Destroy the queue. The queue will first flush all queued actions, and in case it has extended an object, will restore the original object.
15950 */
15951 function destroy() {
15952 this.flush();
15953
15954 if (this._extended) {
15955 var object = this._extended.object;
15956 var methods = this._extended.methods;
15957
15958 for (var i = 0; i < methods.length; i++) {
15959 var method = methods[i];
15960
15961 if (method.original) {
15962 // @TODO: better solution?
15963 object[method.name] = method.original;
15964 } else {
15965 // @TODO: better solution?
15966 delete object[method.name];
15967 }
15968 }
15969
15970 this._extended = null;
15971 }
15972 }
15973 /**
15974 * Replace a method on an object with a queued version.
15975 *
15976 * @param object - Object having the method.
15977 * @param method - The method name.
15978 */
15979
15980 }, {
15981 key: "replace",
15982 value: function replace(object, method) {
15983 /* eslint-disable-next-line @typescript-eslint/no-this-alias -- Function this is necessary in the function bellow, so class this has to be saved into a variable here. */
15984 var me = this;
15985 var original = object[method];
15986
15987 if (!original) {
15988 throw new Error("Method " + method + " undefined");
15989 }
15990
15991 object[method] = function () {
15992 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
15993 args[_key] = arguments[_key];
15994 }
15995
15996 // add this call to the queue
15997 me.queue({
15998 args: args,
15999 fn: original,
16000 context: this
16001 });
16002 };
16003 }
16004 /**
16005 * Queue a call.
16006 *
16007 * @param entry - The function or entry to be queued.
16008 */
16009
16010 }, {
16011 key: "queue",
16012 value: function queue(entry) {
16013 if (typeof entry === "function") {
16014 this._queue.push({
16015 fn: entry
16016 });
16017 } else {
16018 this._queue.push(entry);
16019 }
16020
16021 this._flushIfNeeded();
16022 }
16023 /**
16024 * Check whether the queue needs to be flushed.
16025 */
16026
16027 }, {
16028 key: "_flushIfNeeded",
16029 value: function _flushIfNeeded() {
16030 var _this = this;
16031
16032 // flush when the maximum is exceeded.
16033 if (this._queue.length > this.max) {
16034 this.flush();
16035 } // flush after a period of inactivity when a delay is configured
16036
16037
16038 if (this._timeout != null) {
16039 clearTimeout(this._timeout);
16040 this._timeout = null;
16041 }
16042
16043 if (this.queue.length > 0 && typeof this.delay === "number") {
16044 this._timeout = setTimeout$1(function () {
16045 _this.flush();
16046 }, this.delay);
16047 }
16048 }
16049 /**
16050 * Flush all queued calls
16051 */
16052
16053 }, {
16054 key: "flush",
16055 value: function flush() {
16056 var _context5, _context6;
16057
16058 forEach$2(_context5 = splice(_context6 = this._queue).call(_context6, 0)).call(_context5, function (entry) {
16059 entry.fn.apply(entry.context || entry.fn, entry.args || []);
16060 });
16061 }
16062 }], [{
16063 key: "extend",
16064 value: function extend(object, options) {
16065 var queue = new Queue(options);
16066
16067 if (object.flush !== undefined) {
16068 throw new Error("Target object already has a property flush");
16069 }
16070
16071 object.flush = function () {
16072 queue.flush();
16073 };
16074
16075 var methods = [{
16076 name: "flush",
16077 original: undefined
16078 }];
16079
16080 if (options && options.replace) {
16081 for (var i = 0; i < options.replace.length; i++) {
16082 var name = options.replace[i];
16083 methods.push({
16084 name: name,
16085 // @TODO: better solution?
16086 original: object[name]
16087 }); // @TODO: better solution?
16088
16089 queue.replace(object, name);
16090 }
16091 }
16092
16093 queue._extended = {
16094 object: object,
16095 methods: methods
16096 };
16097 return queue;
16098 }
16099 }]);
16100
16101 return Queue;
16102}();
16103/**
16104 * [[DataSet]] code that can be reused in [[DataView]] or other similar implementations of [[DataInterface]].
16105 *
16106 * @typeParam Item - Item type that may or may not have an id.
16107 * @typeParam IdProp - Name of the property that contains the id.
16108 */
16109
16110
16111var DataSetPart = /*#__PURE__*/function () {
16112 function DataSetPart() {
16113 _classCallCheck(this, DataSetPart);
16114
16115 this._subscribers = {
16116 "*": [],
16117 add: [],
16118 remove: [],
16119 update: []
16120 };
16121 /**
16122 * @deprecated Use on instead (PS: DataView.subscribe === DataView.on).
16123 */
16124
16125 this.subscribe = DataSetPart.prototype.on;
16126 /**
16127 * @deprecated Use off instead (PS: DataView.unsubscribe === DataView.off).
16128 */
16129
16130 this.unsubscribe = DataSetPart.prototype.off;
16131 }
16132 /**
16133 * Trigger an event
16134 *
16135 * @param event - Event name.
16136 * @param payload - Event payload.
16137 * @param senderId - Id of the sender.
16138 */
16139
16140
16141 _createClass(DataSetPart, [{
16142 key: "_trigger",
16143 value: function _trigger(event, payload, senderId) {
16144 var _context7, _context8;
16145
16146 if (event === "*") {
16147 throw new Error("Cannot trigger event *");
16148 }
16149
16150 forEach$2(_context7 = concat(_context8 = []).call(_context8, _toConsumableArray(this._subscribers[event]), _toConsumableArray(this._subscribers["*"]))).call(_context7, function (subscriber) {
16151 subscriber(event, payload, senderId != null ? senderId : null);
16152 });
16153 }
16154 /**
16155 * Subscribe to an event, add an event listener.
16156 *
16157 * @remarks Non-function callbacks are ignored.
16158 *
16159 * @param event - Event name.
16160 * @param callback - Callback method.
16161 */
16162
16163 }, {
16164 key: "on",
16165 value: function on(event, callback) {
16166 if (typeof callback === "function") {
16167 this._subscribers[event].push(callback);
16168 } // @TODO: Maybe throw for invalid callbacks?
16169
16170 }
16171 /**
16172 * Unsubscribe from an event, remove an event listener.
16173 *
16174 * @remarks If the same callback was subscribed more than once **all** occurences will be removed.
16175 *
16176 * @param event - Event name.
16177 * @param callback - Callback method.
16178 */
16179
16180 }, {
16181 key: "off",
16182 value: function off(event, callback) {
16183 var _context9;
16184
16185 this._subscribers[event] = filter(_context9 = this._subscribers[event]).call(_context9, function (subscriber) {
16186 return subscriber !== callback;
16187 });
16188 }
16189 }]);
16190
16191 return DataSetPart;
16192}();
16193/**
16194 * Data stream
16195 *
16196 * @remarks
16197 * [[DataStream]] offers an always up to date stream of items from a [[DataSet]] or [[DataView]].
16198 * That means that the stream is evaluated at the time of iteration, conversion to another data type or when [[cache]] is called, not when the [[DataStream]] was created.
16199 * Multiple invocations of for example [[toItemArray]] may yield different results (if the data source like for example [[DataSet]] gets modified).
16200 *
16201 * @typeParam Item - The item type this stream is going to work with.
16202 */
16203
16204
16205var DataStream = /*#__PURE__*/function (_Symbol$iterator) {
16206 /**
16207 * Create a new data stream.
16208 *
16209 * @param pairs - The id, item pairs.
16210 */
16211 function DataStream(pairs) {
16212 _classCallCheck(this, DataStream);
16213
16214 this._pairs = pairs;
16215 }
16216 /**
16217 * Return an iterable of key, value pairs for every entry in the stream.
16218 */
16219
16220
16221 _createClass(DataStream, [{
16222 key: _Symbol$iterator,
16223 value:
16224 /*#__PURE__*/
16225 regenerator.mark(function value() {
16226 var _iterator, _step, _step$value, id, item;
16227
16228 return regenerator.wrap(function value$(_context10) {
16229 while (1) {
16230 switch (_context10.prev = _context10.next) {
16231 case 0:
16232 _iterator = _createForOfIteratorHelper$7(this._pairs);
16233 _context10.prev = 1;
16234
16235 _iterator.s();
16236
16237 case 3:
16238 if ((_step = _iterator.n()).done) {
16239 _context10.next = 9;
16240 break;
16241 }
16242
16243 _step$value = _slicedToArray(_step.value, 2), id = _step$value[0], item = _step$value[1];
16244 _context10.next = 7;
16245 return [id, item];
16246
16247 case 7:
16248 _context10.next = 3;
16249 break;
16250
16251 case 9:
16252 _context10.next = 14;
16253 break;
16254
16255 case 11:
16256 _context10.prev = 11;
16257 _context10.t0 = _context10["catch"](1);
16258
16259 _iterator.e(_context10.t0);
16260
16261 case 14:
16262 _context10.prev = 14;
16263
16264 _iterator.f();
16265
16266 return _context10.finish(14);
16267
16268 case 17:
16269 case "end":
16270 return _context10.stop();
16271 }
16272 }
16273 }, value, this, [[1, 11, 14, 17]]);
16274 })
16275 /**
16276 * Return an iterable of key, value pairs for every entry in the stream.
16277 */
16278
16279 }, {
16280 key: "entries",
16281 value:
16282 /*#__PURE__*/
16283 regenerator.mark(function entries() {
16284 var _iterator2, _step2, _step2$value, id, item;
16285
16286 return regenerator.wrap(function entries$(_context11) {
16287 while (1) {
16288 switch (_context11.prev = _context11.next) {
16289 case 0:
16290 _iterator2 = _createForOfIteratorHelper$7(this._pairs);
16291 _context11.prev = 1;
16292
16293 _iterator2.s();
16294
16295 case 3:
16296 if ((_step2 = _iterator2.n()).done) {
16297 _context11.next = 9;
16298 break;
16299 }
16300
16301 _step2$value = _slicedToArray(_step2.value, 2), id = _step2$value[0], item = _step2$value[1];
16302 _context11.next = 7;
16303 return [id, item];
16304
16305 case 7:
16306 _context11.next = 3;
16307 break;
16308
16309 case 9:
16310 _context11.next = 14;
16311 break;
16312
16313 case 11:
16314 _context11.prev = 11;
16315 _context11.t0 = _context11["catch"](1);
16316
16317 _iterator2.e(_context11.t0);
16318
16319 case 14:
16320 _context11.prev = 14;
16321
16322 _iterator2.f();
16323
16324 return _context11.finish(14);
16325
16326 case 17:
16327 case "end":
16328 return _context11.stop();
16329 }
16330 }
16331 }, entries, this, [[1, 11, 14, 17]]);
16332 })
16333 /**
16334 * Return an iterable of keys in the stream.
16335 */
16336
16337 }, {
16338 key: "keys",
16339 value:
16340 /*#__PURE__*/
16341 regenerator.mark(function keys() {
16342 var _iterator3, _step3, _step3$value, id;
16343
16344 return regenerator.wrap(function keys$(_context12) {
16345 while (1) {
16346 switch (_context12.prev = _context12.next) {
16347 case 0:
16348 _iterator3 = _createForOfIteratorHelper$7(this._pairs);
16349 _context12.prev = 1;
16350
16351 _iterator3.s();
16352
16353 case 3:
16354 if ((_step3 = _iterator3.n()).done) {
16355 _context12.next = 9;
16356 break;
16357 }
16358
16359 _step3$value = _slicedToArray(_step3.value, 1), id = _step3$value[0];
16360 _context12.next = 7;
16361 return id;
16362
16363 case 7:
16364 _context12.next = 3;
16365 break;
16366
16367 case 9:
16368 _context12.next = 14;
16369 break;
16370
16371 case 11:
16372 _context12.prev = 11;
16373 _context12.t0 = _context12["catch"](1);
16374
16375 _iterator3.e(_context12.t0);
16376
16377 case 14:
16378 _context12.prev = 14;
16379
16380 _iterator3.f();
16381
16382 return _context12.finish(14);
16383
16384 case 17:
16385 case "end":
16386 return _context12.stop();
16387 }
16388 }
16389 }, keys, this, [[1, 11, 14, 17]]);
16390 })
16391 /**
16392 * Return an iterable of values in the stream.
16393 */
16394
16395 }, {
16396 key: "values",
16397 value:
16398 /*#__PURE__*/
16399 regenerator.mark(function values() {
16400 var _iterator4, _step4, _step4$value, item;
16401
16402 return regenerator.wrap(function values$(_context13) {
16403 while (1) {
16404 switch (_context13.prev = _context13.next) {
16405 case 0:
16406 _iterator4 = _createForOfIteratorHelper$7(this._pairs);
16407 _context13.prev = 1;
16408
16409 _iterator4.s();
16410
16411 case 3:
16412 if ((_step4 = _iterator4.n()).done) {
16413 _context13.next = 9;
16414 break;
16415 }
16416
16417 _step4$value = _slicedToArray(_step4.value, 2), item = _step4$value[1];
16418 _context13.next = 7;
16419 return item;
16420
16421 case 7:
16422 _context13.next = 3;
16423 break;
16424
16425 case 9:
16426 _context13.next = 14;
16427 break;
16428
16429 case 11:
16430 _context13.prev = 11;
16431 _context13.t0 = _context13["catch"](1);
16432
16433 _iterator4.e(_context13.t0);
16434
16435 case 14:
16436 _context13.prev = 14;
16437
16438 _iterator4.f();
16439
16440 return _context13.finish(14);
16441
16442 case 17:
16443 case "end":
16444 return _context13.stop();
16445 }
16446 }
16447 }, values, this, [[1, 11, 14, 17]]);
16448 })
16449 /**
16450 * Return an array containing all the ids in this stream.
16451 *
16452 * @remarks
16453 * The array may contain duplicities.
16454 *
16455 * @returns The array with all ids from this stream.
16456 */
16457
16458 }, {
16459 key: "toIdArray",
16460 value: function toIdArray() {
16461 var _context14;
16462
16463 return map$3(_context14 = _toConsumableArray(this._pairs)).call(_context14, function (pair) {
16464 return pair[0];
16465 });
16466 }
16467 /**
16468 * Return an array containing all the items in this stream.
16469 *
16470 * @remarks
16471 * The array may contain duplicities.
16472 *
16473 * @returns The array with all items from this stream.
16474 */
16475
16476 }, {
16477 key: "toItemArray",
16478 value: function toItemArray() {
16479 var _context15;
16480
16481 return map$3(_context15 = _toConsumableArray(this._pairs)).call(_context15, function (pair) {
16482 return pair[1];
16483 });
16484 }
16485 /**
16486 * Return an array containing all the entries in this stream.
16487 *
16488 * @remarks
16489 * The array may contain duplicities.
16490 *
16491 * @returns The array with all entries from this stream.
16492 */
16493
16494 }, {
16495 key: "toEntryArray",
16496 value: function toEntryArray() {
16497 return _toConsumableArray(this._pairs);
16498 }
16499 /**
16500 * Return an object map containing all the items in this stream accessible by ids.
16501 *
16502 * @remarks
16503 * In case of duplicate ids (coerced to string so `7 == '7'`) the last encoutered appears in the returned object.
16504 *
16505 * @returns The object map of all id → item pairs from this stream.
16506 */
16507
16508 }, {
16509 key: "toObjectMap",
16510 value: function toObjectMap() {
16511 var map = create$4(null);
16512
16513 var _iterator5 = _createForOfIteratorHelper$7(this._pairs),
16514 _step5;
16515
16516 try {
16517 for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
16518 var _step5$value = _slicedToArray(_step5.value, 2),
16519 id = _step5$value[0],
16520 item = _step5$value[1];
16521
16522 map[id] = item;
16523 }
16524 } catch (err) {
16525 _iterator5.e(err);
16526 } finally {
16527 _iterator5.f();
16528 }
16529
16530 return map;
16531 }
16532 /**
16533 * Return a map containing all the items in this stream accessible by ids.
16534 *
16535 * @returns The map of all id → item pairs from this stream.
16536 */
16537
16538 }, {
16539 key: "toMap",
16540 value: function toMap() {
16541 return new map(this._pairs);
16542 }
16543 /**
16544 * Return a set containing all the (unique) ids in this stream.
16545 *
16546 * @returns The set of all ids from this stream.
16547 */
16548
16549 }, {
16550 key: "toIdSet",
16551 value: function toIdSet() {
16552 return new set(this.toIdArray());
16553 }
16554 /**
16555 * Return a set containing all the (unique) items in this stream.
16556 *
16557 * @returns The set of all items from this stream.
16558 */
16559
16560 }, {
16561 key: "toItemSet",
16562 value: function toItemSet() {
16563 return new set(this.toItemArray());
16564 }
16565 /**
16566 * Cache the items from this stream.
16567 *
16568 * @remarks
16569 * This method allows for items to be fetched immediatelly and used (possibly multiple times) later.
16570 * It can also be used to optimize performance as [[DataStream]] would otherwise reevaluate everything upon each iteration.
16571 *
16572 * ## Example
16573 * ```javascript
16574 * const ds = new DataSet([…])
16575 *
16576 * const cachedStream = ds.stream()
16577 * .filter(…)
16578 * .sort(…)
16579 * .map(…)
16580 * .cached(…) // Data are fetched, processed and cached here.
16581 *
16582 * ds.clear()
16583 * chachedStream // Still has all the items.
16584 * ```
16585 *
16586 * @returns A new [[DataStream]] with cached items (detached from the original [[DataSet]]).
16587 */
16588
16589 }, {
16590 key: "cache",
16591 value: function cache() {
16592 return new DataStream(_toConsumableArray(this._pairs));
16593 }
16594 /**
16595 * Get the distinct values of given property.
16596 *
16597 * @param callback - The function that picks and possibly converts the property.
16598 *
16599 * @typeParam T - The type of the distinct value.
16600 *
16601 * @returns A set of all distinct properties.
16602 */
16603
16604 }, {
16605 key: "distinct",
16606 value: function distinct(callback) {
16607 var set$1 = new set();
16608
16609 var _iterator6 = _createForOfIteratorHelper$7(this._pairs),
16610 _step6;
16611
16612 try {
16613 for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
16614 var _step6$value = _slicedToArray(_step6.value, 2),
16615 id = _step6$value[0],
16616 item = _step6$value[1];
16617
16618 set$1.add(callback(item, id));
16619 }
16620 } catch (err) {
16621 _iterator6.e(err);
16622 } finally {
16623 _iterator6.f();
16624 }
16625
16626 return set$1;
16627 }
16628 /**
16629 * Filter the items of the stream.
16630 *
16631 * @param callback - The function that decides whether an item will be included.
16632 *
16633 * @returns A new data stream with the filtered items.
16634 */
16635
16636 }, {
16637 key: "filter",
16638 value: function filter(callback) {
16639 var pairs = this._pairs;
16640 return new DataStream(_defineProperty({}, iterator, /*#__PURE__*/regenerator.mark(function _callee() {
16641 var _iterator7, _step7, _step7$value, id, item;
16642
16643 return regenerator.wrap(function _callee$(_context16) {
16644 while (1) {
16645 switch (_context16.prev = _context16.next) {
16646 case 0:
16647 _iterator7 = _createForOfIteratorHelper$7(pairs);
16648 _context16.prev = 1;
16649
16650 _iterator7.s();
16651
16652 case 3:
16653 if ((_step7 = _iterator7.n()).done) {
16654 _context16.next = 10;
16655 break;
16656 }
16657
16658 _step7$value = _slicedToArray(_step7.value, 2), id = _step7$value[0], item = _step7$value[1];
16659
16660 if (!callback(item, id)) {
16661 _context16.next = 8;
16662 break;
16663 }
16664
16665 _context16.next = 8;
16666 return [id, item];
16667
16668 case 8:
16669 _context16.next = 3;
16670 break;
16671
16672 case 10:
16673 _context16.next = 15;
16674 break;
16675
16676 case 12:
16677 _context16.prev = 12;
16678 _context16.t0 = _context16["catch"](1);
16679
16680 _iterator7.e(_context16.t0);
16681
16682 case 15:
16683 _context16.prev = 15;
16684
16685 _iterator7.f();
16686
16687 return _context16.finish(15);
16688
16689 case 18:
16690 case "end":
16691 return _context16.stop();
16692 }
16693 }
16694 }, _callee, null, [[1, 12, 15, 18]]);
16695 })));
16696 }
16697 /**
16698 * Execute a callback for each item of the stream.
16699 *
16700 * @param callback - The function that will be invoked for each item.
16701 */
16702
16703 }, {
16704 key: "forEach",
16705 value: function forEach(callback) {
16706 var _iterator8 = _createForOfIteratorHelper$7(this._pairs),
16707 _step8;
16708
16709 try {
16710 for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
16711 var _step8$value = _slicedToArray(_step8.value, 2),
16712 id = _step8$value[0],
16713 item = _step8$value[1];
16714
16715 callback(item, id);
16716 }
16717 } catch (err) {
16718 _iterator8.e(err);
16719 } finally {
16720 _iterator8.f();
16721 }
16722 }
16723 /**
16724 * Map the items into a different type.
16725 *
16726 * @param callback - The function that does the conversion.
16727 *
16728 * @typeParam Mapped - The type of the item after mapping.
16729 *
16730 * @returns A new data stream with the mapped items.
16731 */
16732
16733 }, {
16734 key: "map",
16735 value: function map(callback) {
16736 var pairs = this._pairs;
16737 return new DataStream(_defineProperty({}, iterator, /*#__PURE__*/regenerator.mark(function _callee2() {
16738 var _iterator9, _step9, _step9$value, id, item;
16739
16740 return regenerator.wrap(function _callee2$(_context17) {
16741 while (1) {
16742 switch (_context17.prev = _context17.next) {
16743 case 0:
16744 _iterator9 = _createForOfIteratorHelper$7(pairs);
16745 _context17.prev = 1;
16746
16747 _iterator9.s();
16748
16749 case 3:
16750 if ((_step9 = _iterator9.n()).done) {
16751 _context17.next = 9;
16752 break;
16753 }
16754
16755 _step9$value = _slicedToArray(_step9.value, 2), id = _step9$value[0], item = _step9$value[1];
16756 _context17.next = 7;
16757 return [id, callback(item, id)];
16758
16759 case 7:
16760 _context17.next = 3;
16761 break;
16762
16763 case 9:
16764 _context17.next = 14;
16765 break;
16766
16767 case 11:
16768 _context17.prev = 11;
16769 _context17.t0 = _context17["catch"](1);
16770
16771 _iterator9.e(_context17.t0);
16772
16773 case 14:
16774 _context17.prev = 14;
16775
16776 _iterator9.f();
16777
16778 return _context17.finish(14);
16779
16780 case 17:
16781 case "end":
16782 return _context17.stop();
16783 }
16784 }
16785 }, _callee2, null, [[1, 11, 14, 17]]);
16786 })));
16787 }
16788 /**
16789 * Get the item with the maximum value of given property.
16790 *
16791 * @param callback - The function that picks and possibly converts the property.
16792 *
16793 * @returns The item with the maximum if found otherwise null.
16794 */
16795
16796 }, {
16797 key: "max",
16798 value: function max(callback) {
16799 var iter = getIterator(this._pairs);
16800
16801 var curr = iter.next();
16802
16803 if (curr.done) {
16804 return null;
16805 }
16806
16807 var maxItem = curr.value[1];
16808 var maxValue = callback(curr.value[1], curr.value[0]);
16809
16810 while (!(curr = iter.next()).done) {
16811 var _curr$value = _slicedToArray(curr.value, 2),
16812 id = _curr$value[0],
16813 item = _curr$value[1];
16814
16815 var _value = callback(item, id);
16816
16817 if (_value > maxValue) {
16818 maxValue = _value;
16819 maxItem = item;
16820 }
16821 }
16822
16823 return maxItem;
16824 }
16825 /**
16826 * Get the item with the minimum value of given property.
16827 *
16828 * @param callback - The function that picks and possibly converts the property.
16829 *
16830 * @returns The item with the minimum if found otherwise null.
16831 */
16832
16833 }, {
16834 key: "min",
16835 value: function min(callback) {
16836 var iter = getIterator(this._pairs);
16837
16838 var curr = iter.next();
16839
16840 if (curr.done) {
16841 return null;
16842 }
16843
16844 var minItem = curr.value[1];
16845 var minValue = callback(curr.value[1], curr.value[0]);
16846
16847 while (!(curr = iter.next()).done) {
16848 var _curr$value2 = _slicedToArray(curr.value, 2),
16849 id = _curr$value2[0],
16850 item = _curr$value2[1];
16851
16852 var _value2 = callback(item, id);
16853
16854 if (_value2 < minValue) {
16855 minValue = _value2;
16856 minItem = item;
16857 }
16858 }
16859
16860 return minItem;
16861 }
16862 /**
16863 * Reduce the items into a single value.
16864 *
16865 * @param callback - The function that does the reduction.
16866 * @param accumulator - The initial value of the accumulator.
16867 *
16868 * @typeParam T - The type of the accumulated value.
16869 *
16870 * @returns The reduced value.
16871 */
16872
16873 }, {
16874 key: "reduce",
16875 value: function reduce(callback, accumulator) {
16876 var _iterator10 = _createForOfIteratorHelper$7(this._pairs),
16877 _step10;
16878
16879 try {
16880 for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
16881 var _step10$value = _slicedToArray(_step10.value, 2),
16882 id = _step10$value[0],
16883 item = _step10$value[1];
16884
16885 accumulator = callback(accumulator, item, id);
16886 }
16887 } catch (err) {
16888 _iterator10.e(err);
16889 } finally {
16890 _iterator10.f();
16891 }
16892
16893 return accumulator;
16894 }
16895 /**
16896 * Sort the items.
16897 *
16898 * @param callback - Item comparator.
16899 *
16900 * @returns A new stream with sorted items.
16901 */
16902
16903 }, {
16904 key: "sort",
16905 value: function sort$1(callback) {
16906 var _this2 = this;
16907
16908 return new DataStream(_defineProperty({}, iterator, function () {
16909 var _context18;
16910
16911 return getIterator(sort(_context18 = _toConsumableArray(_this2._pairs)).call(_context18, function (_ref, _ref2) {
16912 var _ref3 = _slicedToArray(_ref, 2),
16913 idA = _ref3[0],
16914 itemA = _ref3[1];
16915
16916 var _ref4 = _slicedToArray(_ref2, 2),
16917 idB = _ref4[0],
16918 itemB = _ref4[1];
16919
16920 return callback(itemA, itemB, idA, idB);
16921 }));
16922 }));
16923 }
16924 }]);
16925
16926 return DataStream;
16927}(iterator);
16928/**
16929 * Add an id to given item if it doesn't have one already.
16930 *
16931 * @remarks
16932 * The item will be modified.
16933 *
16934 * @param item - The item that will have an id after a call to this function.
16935 * @param idProp - The key of the id property.
16936 *
16937 * @typeParam Item - Item type that may or may not have an id.
16938 * @typeParam IdProp - Name of the property that contains the id.
16939 *
16940 * @returns true
16941 */
16942
16943
16944function ensureFullItem(item, idProp) {
16945 if (item[idProp] == null) {
16946 // generate an id
16947 item[idProp] = v4();
16948 }
16949
16950 return item;
16951}
16952/**
16953 * # DataSet
16954 *
16955 * Vis.js comes with a flexible DataSet, which can be used to hold and
16956 * manipulate unstructured data and listen for changes in the data. The DataSet
16957 * is key/value based. Data items can be added, updated and removed from the
16958 * DataSet, and one can subscribe to changes in the DataSet. The data in the
16959 * DataSet can be filtered and ordered. Data can be normalized when appending it
16960 * to the DataSet as well.
16961 *
16962 * ## Example
16963 *
16964 * The following example shows how to use a DataSet.
16965 *
16966 * ```javascript
16967 * // create a DataSet
16968 * var options = {};
16969 * var data = new vis.DataSet(options);
16970 *
16971 * // add items
16972 * // note that the data items can contain different properties and data formats
16973 * data.add([
16974 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
16975 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
16976 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
16977 * {id: 4, text: 'item 4'}
16978 * ]);
16979 *
16980 * // subscribe to any change in the DataSet
16981 * data.on('*', function (event, properties, senderId) {
16982 * console.log('event', event, properties);
16983 * });
16984 *
16985 * // update an existing item
16986 * data.update({id: 2, group: 1});
16987 *
16988 * // remove an item
16989 * data.remove(4);
16990 *
16991 * // get all ids
16992 * var ids = data.getIds();
16993 * console.log('ids', ids);
16994 *
16995 * // get a specific item
16996 * var item1 = data.get(1);
16997 * console.log('item1', item1);
16998 *
16999 * // retrieve a filtered subset of the data
17000 * var items = data.get({
17001 * filter: function (item) {
17002 * return item.group == 1;
17003 * }
17004 * });
17005 * console.log('filtered items', items);
17006 * ```
17007 *
17008 * @typeParam Item - Item type that may or may not have an id.
17009 * @typeParam IdProp - Name of the property that contains the id.
17010 */
17011
17012
17013var DataSet = /*#__PURE__*/function (_DataSetPart) {
17014 _inherits(DataSet, _DataSetPart);
17015
17016 var _super = _createSuper$t(DataSet);
17017
17018 /**
17019 * Construct a new DataSet.
17020 *
17021 * @param data - Initial data or options.
17022 * @param options - Options (type error if data is also options).
17023 */
17024 function DataSet(data, options) {
17025 var _this3;
17026
17027 _classCallCheck(this, DataSet);
17028
17029 _this3 = _super.call(this);
17030 _this3._queue = null; // correctly read optional arguments
17031
17032 if (data && !isArray$2(data)) {
17033 options = data;
17034 data = [];
17035 }
17036
17037 _this3._options = options || {};
17038 _this3._data = new map(); // map with data indexed by id
17039
17040 _this3.length = 0; // number of items in the DataSet
17041
17042 _this3._idProp = _this3._options.fieldId || "id"; // name of the field containing id
17043 // add initial data when provided
17044
17045 if (data && data.length) {
17046 _this3.add(data);
17047 }
17048
17049 _this3.setOptions(options);
17050
17051 return _this3;
17052 }
17053 /** @inheritDoc */
17054
17055
17056 _createClass(DataSet, [{
17057 key: "idProp",
17058 get: function get() {
17059 return this._idProp;
17060 }
17061 /**
17062 * Set new options.
17063 *
17064 * @param options - The new options.
17065 */
17066
17067 }, {
17068 key: "setOptions",
17069 value: function setOptions(options) {
17070 if (options && options.queue !== undefined) {
17071 if (options.queue === false) {
17072 // delete queue if loaded
17073 if (this._queue) {
17074 this._queue.destroy();
17075
17076 this._queue = null;
17077 }
17078 } else {
17079 // create queue and update its options
17080 if (!this._queue) {
17081 this._queue = Queue.extend(this, {
17082 replace: ["add", "update", "remove"]
17083 });
17084 }
17085
17086 if (options.queue && _typeof(options.queue) === "object") {
17087 this._queue.setOptions(options.queue);
17088 }
17089 }
17090 }
17091 }
17092 /**
17093 * Add a data item or an array with items.
17094 *
17095 * After the items are added to the DataSet, the DataSet will trigger an event `add`. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
17096 *
17097 * ## Example
17098 *
17099 * ```javascript
17100 * // create a DataSet
17101 * const data = new vis.DataSet()
17102 *
17103 * // add items
17104 * const ids = data.add([
17105 * { id: 1, text: 'item 1' },
17106 * { id: 2, text: 'item 2' },
17107 * { text: 'item without an id' }
17108 * ])
17109 *
17110 * console.log(ids) // [1, 2, '<UUIDv4>']
17111 * ```
17112 *
17113 * @param data - Items to be added (ids will be generated if missing).
17114 * @param senderId - Sender id.
17115 *
17116 * @returns addedIds - Array with the ids (generated if not present) of the added items.
17117 *
17118 * @throws When an item with the same id as any of the added items already exists.
17119 */
17120
17121 }, {
17122 key: "add",
17123 value: function add(data, senderId) {
17124 var _this4 = this;
17125
17126 var addedIds = [];
17127 var id;
17128
17129 if (isArray$2(data)) {
17130 // Array
17131 var idsToAdd = map$3(data).call(data, function (d) {
17132 return d[_this4._idProp];
17133 });
17134
17135 if (some(idsToAdd).call(idsToAdd, function (id) {
17136 return _this4._data.has(id);
17137 })) {
17138 throw new Error("A duplicate id was found in the parameter array.");
17139 }
17140
17141 for (var i = 0, len = data.length; i < len; i++) {
17142 id = this._addItem(data[i]);
17143 addedIds.push(id);
17144 }
17145 } else if (data && _typeof(data) === "object") {
17146 // Single item
17147 id = this._addItem(data);
17148 addedIds.push(id);
17149 } else {
17150 throw new Error("Unknown dataType");
17151 }
17152
17153 if (addedIds.length) {
17154 this._trigger("add", {
17155 items: addedIds
17156 }, senderId);
17157 }
17158
17159 return addedIds;
17160 }
17161 /**
17162 * Update existing items. When an item does not exist, it will be created.
17163 *
17164 * @remarks
17165 * The provided properties will be merged in the existing item. When an item does not exist, it will be created.
17166 *
17167 * After the items are updated, the DataSet will trigger an event `add` for the added items, and an event `update`. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
17168 *
17169 * ## Example
17170 *
17171 * ```javascript
17172 * // create a DataSet
17173 * const data = new vis.DataSet([
17174 * { id: 1, text: 'item 1' },
17175 * { id: 2, text: 'item 2' },
17176 * { id: 3, text: 'item 3' }
17177 * ])
17178 *
17179 * // update items
17180 * const ids = data.update([
17181 * { id: 2, text: 'item 2 (updated)' },
17182 * { id: 4, text: 'item 4 (new)' }
17183 * ])
17184 *
17185 * console.log(ids) // [2, 4]
17186 * ```
17187 *
17188 * ## Warning for TypeScript users
17189 * This method may introduce partial items into the data set. Use add or updateOnly instead for better type safety.
17190 *
17191 * @param data - Items to be updated (if the id is already present) or added (if the id is missing).
17192 * @param senderId - Sender id.
17193 *
17194 * @returns updatedIds - The ids of the added (these may be newly generated if there was no id in the item from the data) or updated items.
17195 *
17196 * @throws When the supplied data is neither an item nor an array of items.
17197 */
17198
17199 }, {
17200 key: "update",
17201 value: function update(data, senderId) {
17202 var _this5 = this;
17203
17204 var addedIds = [];
17205 var updatedIds = [];
17206 var oldData = [];
17207 var updatedData = [];
17208 var idProp = this._idProp;
17209
17210 var addOrUpdate = function addOrUpdate(item) {
17211 var origId = item[idProp];
17212
17213 if (origId != null && _this5._data.has(origId)) {
17214 var fullItem = item; // it has an id, therefore it is a fullitem
17215
17216 var oldItem = assign$2({}, _this5._data.get(origId)); // update item
17217
17218
17219 var id = _this5._updateItem(fullItem);
17220
17221 updatedIds.push(id);
17222 updatedData.push(fullItem);
17223 oldData.push(oldItem);
17224 } else {
17225 // add new item
17226 var _id = _this5._addItem(item);
17227
17228 addedIds.push(_id);
17229 }
17230 };
17231
17232 if (isArray$2(data)) {
17233 // Array
17234 for (var i = 0, len = data.length; i < len; i++) {
17235 if (data[i] && _typeof(data[i]) === "object") {
17236 addOrUpdate(data[i]);
17237 } else {
17238 console.warn("Ignoring input item, which is not an object at index " + i);
17239 }
17240 }
17241 } else if (data && _typeof(data) === "object") {
17242 // Single item
17243 addOrUpdate(data);
17244 } else {
17245 throw new Error("Unknown dataType");
17246 }
17247
17248 if (addedIds.length) {
17249 this._trigger("add", {
17250 items: addedIds
17251 }, senderId);
17252 }
17253
17254 if (updatedIds.length) {
17255 var props = {
17256 items: updatedIds,
17257 oldData: oldData,
17258 data: updatedData
17259 }; // TODO: remove deprecated property 'data' some day
17260 //Object.defineProperty(props, 'data', {
17261 // 'get': (function() {
17262 // console.warn('Property data is deprecated. Use DataSet.get(ids) to retrieve the new data, use the oldData property on this object to get the old data');
17263 // return updatedData;
17264 // }).bind(this)
17265 //});
17266
17267 this._trigger("update", props, senderId);
17268 }
17269
17270 return concat(addedIds).call(addedIds, updatedIds);
17271 }
17272 /**
17273 * Update existing items. When an item does not exist, an error will be thrown.
17274 *
17275 * @remarks
17276 * The provided properties will be deeply merged into the existing item.
17277 * When an item does not exist (id not present in the data set or absent), an error will be thrown and nothing will be changed.
17278 *
17279 * After the items are updated, the DataSet will trigger an event `update`.
17280 * When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
17281 *
17282 * ## Example
17283 *
17284 * ```javascript
17285 * // create a DataSet
17286 * const data = new vis.DataSet([
17287 * { id: 1, text: 'item 1' },
17288 * { id: 2, text: 'item 2' },
17289 * { id: 3, text: 'item 3' },
17290 * ])
17291 *
17292 * // update items
17293 * const ids = data.update([
17294 * { id: 2, text: 'item 2 (updated)' }, // works
17295 * // { id: 4, text: 'item 4 (new)' }, // would throw
17296 * // { text: 'item 4 (new)' }, // would also throw
17297 * ])
17298 *
17299 * console.log(ids) // [2]
17300 * ```
17301 *
17302 * @param data - Updates (the id and optionally other props) to the items in this data set.
17303 * @param senderId - Sender id.
17304 *
17305 * @returns updatedIds - The ids of the updated items.
17306 *
17307 * @throws When the supplied data is neither an item nor an array of items, when the ids are missing.
17308 */
17309
17310 }, {
17311 key: "updateOnly",
17312 value: function updateOnly(data, senderId) {
17313 var _context19,
17314 _this6 = this;
17315
17316 if (!isArray$2(data)) {
17317 data = [data];
17318 }
17319
17320 var updateEventData = map$3(_context19 = map$3(data).call(data, function (update) {
17321 var oldData = _this6._data.get(update[_this6._idProp]);
17322
17323 if (oldData == null) {
17324 throw new Error("Updating non-existent items is not allowed.");
17325 }
17326
17327 return {
17328 oldData: oldData,
17329 update: update
17330 };
17331 })).call(_context19, function (_ref5) {
17332 var oldData = _ref5.oldData,
17333 update = _ref5.update;
17334 var id = oldData[_this6._idProp];
17335 var updatedData = pureDeepObjectAssign(oldData, update);
17336
17337 _this6._data.set(id, updatedData);
17338
17339 return {
17340 id: id,
17341 oldData: oldData,
17342 updatedData: updatedData
17343 };
17344 });
17345
17346 if (updateEventData.length) {
17347 var props = {
17348 items: map$3(updateEventData).call(updateEventData, function (value) {
17349 return value.id;
17350 }),
17351 oldData: map$3(updateEventData).call(updateEventData, function (value) {
17352 return value.oldData;
17353 }),
17354 data: map$3(updateEventData).call(updateEventData, function (value) {
17355 return value.updatedData;
17356 })
17357 }; // TODO: remove deprecated property 'data' some day
17358 //Object.defineProperty(props, 'data', {
17359 // 'get': (function() {
17360 // console.warn('Property data is deprecated. Use DataSet.get(ids) to retrieve the new data, use the oldData property on this object to get the old data');
17361 // return updatedData;
17362 // }).bind(this)
17363 //});
17364
17365 this._trigger("update", props, senderId);
17366
17367 return props.items;
17368 } else {
17369 return [];
17370 }
17371 }
17372 /** @inheritDoc */
17373
17374 }, {
17375 key: "get",
17376 value: function get(first, second) {
17377 // @TODO: Woudn't it be better to split this into multiple methods?
17378 // parse the arguments
17379 var id = undefined;
17380 var ids = undefined;
17381 var options = undefined;
17382
17383 if (isId(first)) {
17384 // get(id [, options])
17385 id = first;
17386 options = second;
17387 } else if (isArray$2(first)) {
17388 // get(ids [, options])
17389 ids = first;
17390 options = second;
17391 } else {
17392 // get([, options])
17393 options = first;
17394 } // determine the return type
17395
17396
17397 var returnType = options && options.returnType === "Object" ? "Object" : "Array"; // @TODO: WTF is this? Or am I missing something?
17398 // var returnType
17399 // if (options && options.returnType) {
17400 // var allowedValues = ['Array', 'Object']
17401 // returnType =
17402 // allowedValues.indexOf(options.returnType) == -1
17403 // ? 'Array'
17404 // : options.returnType
17405 // } else {
17406 // returnType = 'Array'
17407 // }
17408 // build options
17409
17410 var filter$1 = options && filter(options);
17411
17412 var items = [];
17413 var item = undefined;
17414 var itemIds = undefined;
17415 var itemId = undefined; // convert items
17416
17417 if (id != null) {
17418 // return a single item
17419 item = this._data.get(id);
17420
17421 if (item && filter$1 && !filter$1(item)) {
17422 item = undefined;
17423 }
17424 } else if (ids != null) {
17425 // return a subset of items
17426 for (var i = 0, len = ids.length; i < len; i++) {
17427 item = this._data.get(ids[i]);
17428
17429 if (item != null && (!filter$1 || filter$1(item))) {
17430 items.push(item);
17431 }
17432 }
17433 } else {
17434 var _context20;
17435
17436 // return all items
17437 itemIds = _toConsumableArray(keys(_context20 = this._data).call(_context20));
17438
17439 for (var _i = 0, _len2 = itemIds.length; _i < _len2; _i++) {
17440 itemId = itemIds[_i];
17441 item = this._data.get(itemId);
17442
17443 if (item != null && (!filter$1 || filter$1(item))) {
17444 items.push(item);
17445 }
17446 }
17447 } // order the results
17448
17449
17450 if (options && options.order && id == undefined) {
17451 this._sort(items, options.order);
17452 } // filter fields of the items
17453
17454
17455 if (options && options.fields) {
17456 var fields = options.fields;
17457
17458 if (id != undefined && item != null) {
17459 item = this._filterFields(item, fields);
17460 } else {
17461 for (var _i2 = 0, _len3 = items.length; _i2 < _len3; _i2++) {
17462 items[_i2] = this._filterFields(items[_i2], fields);
17463 }
17464 }
17465 } // return the results
17466
17467
17468 if (returnType == "Object") {
17469 var result = {};
17470
17471 for (var _i3 = 0, _len4 = items.length; _i3 < _len4; _i3++) {
17472 var resultant = items[_i3]; // @TODO: Shoudn't this be this._fieldId?
17473 // result[resultant.id] = resultant
17474
17475 var _id2 = resultant[this._idProp];
17476 result[_id2] = resultant;
17477 }
17478
17479 return result;
17480 } else {
17481 if (id != null) {
17482 var _item;
17483
17484 // a single item
17485 return (_item = item) !== null && _item !== void 0 ? _item : null;
17486 } else {
17487 // just return our array
17488 return items;
17489 }
17490 }
17491 }
17492 /** @inheritDoc */
17493
17494 }, {
17495 key: "getIds",
17496 value: function getIds(options) {
17497 var data = this._data;
17498
17499 var filter$1 = options && filter(options);
17500
17501 var order = options && options.order;
17502
17503 var itemIds = _toConsumableArray(keys(data).call(data));
17504
17505 var ids = [];
17506
17507 if (filter$1) {
17508 // get filtered items
17509 if (order) {
17510 // create ordered list
17511 var items = [];
17512
17513 for (var i = 0, len = itemIds.length; i < len; i++) {
17514 var id = itemIds[i];
17515
17516 var item = this._data.get(id);
17517
17518 if (item != null && filter$1(item)) {
17519 items.push(item);
17520 }
17521 }
17522
17523 this._sort(items, order);
17524
17525 for (var _i4 = 0, _len5 = items.length; _i4 < _len5; _i4++) {
17526 ids.push(items[_i4][this._idProp]);
17527 }
17528 } else {
17529 // create unordered list
17530 for (var _i5 = 0, _len6 = itemIds.length; _i5 < _len6; _i5++) {
17531 var _id3 = itemIds[_i5];
17532
17533 var _item2 = this._data.get(_id3);
17534
17535 if (_item2 != null && filter$1(_item2)) {
17536 ids.push(_item2[this._idProp]);
17537 }
17538 }
17539 }
17540 } else {
17541 // get all items
17542 if (order) {
17543 // create an ordered list
17544 var _items = [];
17545
17546 for (var _i6 = 0, _len7 = itemIds.length; _i6 < _len7; _i6++) {
17547 var _id4 = itemIds[_i6];
17548
17549 _items.push(data.get(_id4));
17550 }
17551
17552 this._sort(_items, order);
17553
17554 for (var _i7 = 0, _len8 = _items.length; _i7 < _len8; _i7++) {
17555 ids.push(_items[_i7][this._idProp]);
17556 }
17557 } else {
17558 // create unordered list
17559 for (var _i8 = 0, _len9 = itemIds.length; _i8 < _len9; _i8++) {
17560 var _id5 = itemIds[_i8];
17561
17562 var _item3 = data.get(_id5);
17563
17564 if (_item3 != null) {
17565 ids.push(_item3[this._idProp]);
17566 }
17567 }
17568 }
17569 }
17570
17571 return ids;
17572 }
17573 /** @inheritDoc */
17574
17575 }, {
17576 key: "getDataSet",
17577 value: function getDataSet() {
17578 return this;
17579 }
17580 /** @inheritDoc */
17581
17582 }, {
17583 key: "forEach",
17584 value: function forEach(callback, options) {
17585 var filter$1 = options && filter(options);
17586
17587 var data = this._data;
17588
17589 var itemIds = _toConsumableArray(keys(data).call(data));
17590
17591 if (options && options.order) {
17592 // execute forEach on ordered list
17593 var items = this.get(options);
17594
17595 for (var i = 0, len = items.length; i < len; i++) {
17596 var item = items[i];
17597 var id = item[this._idProp];
17598 callback(item, id);
17599 }
17600 } else {
17601 // unordered
17602 for (var _i9 = 0, _len10 = itemIds.length; _i9 < _len10; _i9++) {
17603 var _id6 = itemIds[_i9];
17604
17605 var _item4 = this._data.get(_id6);
17606
17607 if (_item4 != null && (!filter$1 || filter$1(_item4))) {
17608 callback(_item4, _id6);
17609 }
17610 }
17611 }
17612 }
17613 /** @inheritDoc */
17614
17615 }, {
17616 key: "map",
17617 value: function map(callback, options) {
17618 var filter$1 = options && filter(options);
17619
17620 var mappedItems = [];
17621 var data = this._data;
17622
17623 var itemIds = _toConsumableArray(keys(data).call(data)); // convert and filter items
17624
17625
17626 for (var i = 0, len = itemIds.length; i < len; i++) {
17627 var id = itemIds[i];
17628
17629 var item = this._data.get(id);
17630
17631 if (item != null && (!filter$1 || filter$1(item))) {
17632 mappedItems.push(callback(item, id));
17633 }
17634 } // order items
17635
17636
17637 if (options && options.order) {
17638 this._sort(mappedItems, options.order);
17639 }
17640
17641 return mappedItems;
17642 }
17643 /**
17644 * Filter the fields of an item.
17645 *
17646 * @param item - The item whose fields should be filtered.
17647 * @param fields - The names of the fields that will be kept.
17648 *
17649 * @typeParam K - Field name type.
17650 *
17651 * @returns The item without any additional fields.
17652 */
17653
17654 }, {
17655 key: "_filterFields",
17656 value: function _filterFields(item, fields) {
17657 var _context21;
17658
17659 if (!item) {
17660 // item is null
17661 return item;
17662 }
17663
17664 return reduce(_context21 = isArray$2(fields) ? // Use the supplied array
17665 fields : // Use the keys of the supplied object
17666 keys$4(fields)).call(_context21, function (filteredItem, field) {
17667 filteredItem[field] = item[field];
17668 return filteredItem;
17669 }, {});
17670 }
17671 /**
17672 * Sort the provided array with items.
17673 *
17674 * @param items - Items to be sorted in place.
17675 * @param order - A field name or custom sort function.
17676 *
17677 * @typeParam T - The type of the items in the items array.
17678 */
17679
17680 }, {
17681 key: "_sort",
17682 value: function _sort(items, order) {
17683 if (typeof order === "string") {
17684 // order by provided field name
17685 var name = order; // field name
17686
17687 sort(items).call(items, function (a, b) {
17688 // @TODO: How to treat missing properties?
17689 var av = a[name];
17690 var bv = b[name];
17691 return av > bv ? 1 : av < bv ? -1 : 0;
17692 });
17693 } else if (typeof order === "function") {
17694 // order by sort function
17695 sort(items).call(items, order);
17696 } else {
17697 // TODO: extend order by an Object {field:string, direction:string}
17698 // where direction can be 'asc' or 'desc'
17699 throw new TypeError("Order must be a function or a string");
17700 }
17701 }
17702 /**
17703 * Remove an item or multiple items by “reference” (only the id is used) or by id.
17704 *
17705 * The method ignores removal of non-existing items, and returns an array containing the ids of the items which are actually removed from the DataSet.
17706 *
17707 * After the items are removed, the DataSet will trigger an event `remove` for the removed items. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
17708 *
17709 * ## Example
17710 * ```javascript
17711 * // create a DataSet
17712 * const data = new vis.DataSet([
17713 * { id: 1, text: 'item 1' },
17714 * { id: 2, text: 'item 2' },
17715 * { id: 3, text: 'item 3' }
17716 * ])
17717 *
17718 * // remove items
17719 * const ids = data.remove([2, { id: 3 }, 4])
17720 *
17721 * console.log(ids) // [2, 3]
17722 * ```
17723 *
17724 * @param id - One or more items or ids of items to be removed.
17725 * @param senderId - Sender id.
17726 *
17727 * @returns The ids of the removed items.
17728 */
17729
17730 }, {
17731 key: "remove",
17732 value: function remove(id, senderId) {
17733 var removedIds = [];
17734 var removedItems = []; // force everything to be an array for simplicity
17735
17736 var ids = isArray$2(id) ? id : [id];
17737
17738 for (var i = 0, len = ids.length; i < len; i++) {
17739 var item = this._remove(ids[i]);
17740
17741 if (item) {
17742 var itemId = item[this._idProp];
17743
17744 if (itemId != null) {
17745 removedIds.push(itemId);
17746 removedItems.push(item);
17747 }
17748 }
17749 }
17750
17751 if (removedIds.length) {
17752 this._trigger("remove", {
17753 items: removedIds,
17754 oldData: removedItems
17755 }, senderId);
17756 }
17757
17758 return removedIds;
17759 }
17760 /**
17761 * Remove an item by its id or reference.
17762 *
17763 * @param id - Id of an item or the item itself.
17764 *
17765 * @returns The removed item if removed, null otherwise.
17766 */
17767
17768 }, {
17769 key: "_remove",
17770 value: function _remove(id) {
17771 // @TODO: It origianlly returned the item although the docs say id.
17772 // The code expects the item, so probably an error in the docs.
17773 var ident; // confirm the id to use based on the args type
17774
17775 if (isId(id)) {
17776 ident = id;
17777 } else if (id && _typeof(id) === "object") {
17778 ident = id[this._idProp]; // look for the identifier field using ._idProp
17779 } // do the removing if the item is found
17780
17781
17782 if (ident != null && this._data.has(ident)) {
17783 var item = this._data.get(ident) || null;
17784
17785 this._data.delete(ident);
17786
17787 --this.length;
17788 return item;
17789 }
17790
17791 return null;
17792 }
17793 /**
17794 * Clear the entire data set.
17795 *
17796 * After the items are removed, the [[DataSet]] will trigger an event `remove` for all removed items. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
17797 *
17798 * @param senderId - Sender id.
17799 *
17800 * @returns removedIds - The ids of all removed items.
17801 */
17802
17803 }, {
17804 key: "clear",
17805 value: function clear(senderId) {
17806 var _context22;
17807
17808 var ids = _toConsumableArray(keys(_context22 = this._data).call(_context22));
17809
17810 var items = [];
17811
17812 for (var i = 0, len = ids.length; i < len; i++) {
17813 items.push(this._data.get(ids[i]));
17814 }
17815
17816 this._data.clear();
17817
17818 this.length = 0;
17819
17820 this._trigger("remove", {
17821 items: ids,
17822 oldData: items
17823 }, senderId);
17824
17825 return ids;
17826 }
17827 /**
17828 * Find the item with maximum value of a specified field.
17829 *
17830 * @param field - Name of the property that should be searched for max value.
17831 *
17832 * @returns Item containing max value, or null if no items.
17833 */
17834
17835 }, {
17836 key: "max",
17837 value: function max(field) {
17838 var _context23;
17839
17840 var max = null;
17841 var maxField = null;
17842
17843 var _iterator11 = _createForOfIteratorHelper$7(values(_context23 = this._data).call(_context23)),
17844 _step11;
17845
17846 try {
17847 for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
17848 var item = _step11.value;
17849 var itemField = item[field];
17850
17851 if (typeof itemField === "number" && (maxField == null || itemField > maxField)) {
17852 max = item;
17853 maxField = itemField;
17854 }
17855 }
17856 } catch (err) {
17857 _iterator11.e(err);
17858 } finally {
17859 _iterator11.f();
17860 }
17861
17862 return max || null;
17863 }
17864 /**
17865 * Find the item with minimum value of a specified field.
17866 *
17867 * @param field - Name of the property that should be searched for min value.
17868 *
17869 * @returns Item containing min value, or null if no items.
17870 */
17871
17872 }, {
17873 key: "min",
17874 value: function min(field) {
17875 var _context24;
17876
17877 var min = null;
17878 var minField = null;
17879
17880 var _iterator12 = _createForOfIteratorHelper$7(values(_context24 = this._data).call(_context24)),
17881 _step12;
17882
17883 try {
17884 for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
17885 var item = _step12.value;
17886 var itemField = item[field];
17887
17888 if (typeof itemField === "number" && (minField == null || itemField < minField)) {
17889 min = item;
17890 minField = itemField;
17891 }
17892 }
17893 } catch (err) {
17894 _iterator12.e(err);
17895 } finally {
17896 _iterator12.f();
17897 }
17898
17899 return min || null;
17900 }
17901 /**
17902 * Find all distinct values of a specified field
17903 *
17904 * @param prop - The property name whose distinct values should be returned.
17905 *
17906 * @returns Unordered array containing all distinct values. Items without specified property are ignored.
17907 */
17908
17909 }, {
17910 key: "distinct",
17911 value: function distinct(prop) {
17912 var data = this._data;
17913
17914 var itemIds = _toConsumableArray(keys(data).call(data));
17915
17916 var values = [];
17917 var count = 0;
17918
17919 for (var i = 0, len = itemIds.length; i < len; i++) {
17920 var id = itemIds[i];
17921 var item = data.get(id);
17922 var _value3 = item[prop];
17923 var exists = false;
17924
17925 for (var j = 0; j < count; j++) {
17926 if (values[j] == _value3) {
17927 exists = true;
17928 break;
17929 }
17930 }
17931
17932 if (!exists && _value3 !== undefined) {
17933 values[count] = _value3;
17934 count++;
17935 }
17936 }
17937
17938 return values;
17939 }
17940 /**
17941 * Add a single item. Will fail when an item with the same id already exists.
17942 *
17943 * @param item - A new item to be added.
17944 *
17945 * @returns Added item's id. An id is generated when it is not present in the item.
17946 */
17947
17948 }, {
17949 key: "_addItem",
17950 value: function _addItem(item) {
17951 var fullItem = ensureFullItem(item, this._idProp);
17952 var id = fullItem[this._idProp]; // check whether this id is already taken
17953
17954 if (this._data.has(id)) {
17955 // item already exists
17956 throw new Error("Cannot add item: item with id " + id + " already exists");
17957 }
17958
17959 this._data.set(id, fullItem);
17960
17961 ++this.length;
17962 return id;
17963 }
17964 /**
17965 * Update a single item: merge with existing item.
17966 * Will fail when the item has no id, or when there does not exist an item with the same id.
17967 *
17968 * @param update - The new item
17969 *
17970 * @returns The id of the updated item.
17971 */
17972
17973 }, {
17974 key: "_updateItem",
17975 value: function _updateItem(update) {
17976 var id = update[this._idProp];
17977
17978 if (id == null) {
17979 throw new Error("Cannot update item: item has no id (item: " + stringify$1(update) + ")");
17980 }
17981
17982 var item = this._data.get(id);
17983
17984 if (!item) {
17985 // item doesn't exist
17986 throw new Error("Cannot update item: no item with id " + id + " found");
17987 }
17988
17989 this._data.set(id, _objectSpread$4(_objectSpread$4({}, item), update));
17990
17991 return id;
17992 }
17993 /** @inheritDoc */
17994
17995 }, {
17996 key: "stream",
17997 value: function stream(ids) {
17998 if (ids) {
17999 var data = this._data;
18000 return new DataStream(_defineProperty({}, iterator, /*#__PURE__*/regenerator.mark(function _callee3() {
18001 var _iterator13, _step13, id, item;
18002
18003 return regenerator.wrap(function _callee3$(_context25) {
18004 while (1) {
18005 switch (_context25.prev = _context25.next) {
18006 case 0:
18007 _iterator13 = _createForOfIteratorHelper$7(ids);
18008 _context25.prev = 1;
18009
18010 _iterator13.s();
18011
18012 case 3:
18013 if ((_step13 = _iterator13.n()).done) {
18014 _context25.next = 11;
18015 break;
18016 }
18017
18018 id = _step13.value;
18019 item = data.get(id);
18020
18021 if (!(item != null)) {
18022 _context25.next = 9;
18023 break;
18024 }
18025
18026 _context25.next = 9;
18027 return [id, item];
18028
18029 case 9:
18030 _context25.next = 3;
18031 break;
18032
18033 case 11:
18034 _context25.next = 16;
18035 break;
18036
18037 case 13:
18038 _context25.prev = 13;
18039 _context25.t0 = _context25["catch"](1);
18040
18041 _iterator13.e(_context25.t0);
18042
18043 case 16:
18044 _context25.prev = 16;
18045
18046 _iterator13.f();
18047
18048 return _context25.finish(16);
18049
18050 case 19:
18051 case "end":
18052 return _context25.stop();
18053 }
18054 }
18055 }, _callee3, null, [[1, 13, 16, 19]]);
18056 })));
18057 } else {
18058 var _context26;
18059
18060 return new DataStream(_defineProperty({}, iterator, bind$6(_context26 = entries(this._data)).call(_context26, this._data)));
18061 }
18062 }
18063 }]);
18064
18065 return DataSet;
18066}(DataSetPart);
18067/**
18068 * DataView
18069 *
18070 * A DataView offers a filtered and/or formatted view on a DataSet. One can subscribe to changes in a DataView, and easily get filtered or formatted data without having to specify filters and field types all the time.
18071 *
18072 * ## Example
18073 * ```javascript
18074 * // create a DataSet
18075 * var data = new vis.DataSet();
18076 * data.add([
18077 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
18078 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
18079 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
18080 * {id: 4, text: 'item 4'}
18081 * ]);
18082 *
18083 * // create a DataView
18084 * // the view will only contain items having a property group with value 1,
18085 * // and will only output fields id, text, and date.
18086 * var view = new vis.DataView(data, {
18087 * filter: function (item) {
18088 * return (item.group == 1);
18089 * },
18090 * fields: ['id', 'text', 'date']
18091 * });
18092 *
18093 * // subscribe to any change in the DataView
18094 * view.on('*', function (event, properties, senderId) {
18095 * console.log('event', event, properties);
18096 * });
18097 *
18098 * // update an item in the data set
18099 * data.update({id: 2, group: 1});
18100 *
18101 * // get all ids in the view
18102 * var ids = view.getIds();
18103 * console.log('ids', ids); // will output [1, 2]
18104 *
18105 * // get all items in the view
18106 * var items = view.get();
18107 * ```
18108 *
18109 * @typeParam Item - Item type that may or may not have an id.
18110 * @typeParam IdProp - Name of the property that contains the id.
18111 */
18112
18113
18114var DataView = /*#__PURE__*/function (_DataSetPart2) {
18115 _inherits(DataView, _DataSetPart2);
18116
18117 var _super2 = _createSuper$t(DataView);
18118
18119 /**
18120 * Create a DataView.
18121 *
18122 * @param data - The instance containing data (directly or indirectly).
18123 * @param options - Options to configure this data view.
18124 */
18125 function DataView(data, options) {
18126 var _context27;
18127
18128 var _this7;
18129
18130 _classCallCheck(this, DataView);
18131
18132 _this7 = _super2.call(this);
18133 /** @inheritDoc */
18134
18135 _this7.length = 0;
18136 _this7._ids = new set(); // ids of the items currently in memory (just contains a boolean true)
18137
18138 _this7._options = options || {};
18139 _this7._listener = bind$6(_context27 = _this7._onEvent).call(_context27, _assertThisInitialized(_this7));
18140
18141 _this7.setData(data);
18142
18143 return _this7;
18144 }
18145 /** @inheritDoc */
18146
18147
18148 _createClass(DataView, [{
18149 key: "idProp",
18150 get: function get() {
18151 return this.getDataSet().idProp;
18152 } // TODO: implement a function .config() to dynamically update things like configured filter
18153 // and trigger changes accordingly
18154
18155 /**
18156 * Set a data source for the view.
18157 *
18158 * @param data - The instance containing data (directly or indirectly).
18159 *
18160 * @remarks
18161 * Note that when the data view is bound to a data set it won't be garbage
18162 * collected unless the data set is too. Use `dataView.setData(null)` or
18163 * `dataView.dispose()` to enable garbage collection before you lose the last
18164 * reference.
18165 */
18166
18167 }, {
18168 key: "setData",
18169 value: function setData(data) {
18170 if (this._data) {
18171 // unsubscribe from current dataset
18172 if (this._data.off) {
18173 this._data.off("*", this._listener);
18174 } // trigger a remove of all items in memory
18175
18176
18177 var ids = this._data.getIds({
18178 filter: filter(this._options)
18179 });
18180
18181 var items = this._data.get(ids);
18182
18183 this._ids.clear();
18184
18185 this.length = 0;
18186
18187 this._trigger("remove", {
18188 items: ids,
18189 oldData: items
18190 });
18191 }
18192
18193 if (data != null) {
18194 this._data = data; // trigger an add of all added items
18195
18196 var _ids = this._data.getIds({
18197 filter: filter(this._options)
18198 });
18199
18200 for (var i = 0, len = _ids.length; i < len; i++) {
18201 var id = _ids[i];
18202
18203 this._ids.add(id);
18204 }
18205
18206 this.length = _ids.length;
18207
18208 this._trigger("add", {
18209 items: _ids
18210 });
18211 } else {
18212 this._data = new DataSet();
18213 } // subscribe to new dataset
18214
18215
18216 if (this._data.on) {
18217 this._data.on("*", this._listener);
18218 }
18219 }
18220 /**
18221 * Refresh the DataView.
18222 * Useful when the DataView has a filter function containing a variable parameter.
18223 */
18224
18225 }, {
18226 key: "refresh",
18227 value: function refresh() {
18228 var ids = this._data.getIds({
18229 filter: filter(this._options)
18230 });
18231
18232 var oldIds = _toConsumableArray(this._ids);
18233
18234 var newIds = {};
18235 var addedIds = [];
18236 var removedIds = [];
18237 var removedItems = []; // check for additions
18238
18239 for (var i = 0, len = ids.length; i < len; i++) {
18240 var id = ids[i];
18241 newIds[id] = true;
18242
18243 if (!this._ids.has(id)) {
18244 addedIds.push(id);
18245
18246 this._ids.add(id);
18247 }
18248 } // check for removals
18249
18250
18251 for (var _i10 = 0, _len11 = oldIds.length; _i10 < _len11; _i10++) {
18252 var _id7 = oldIds[_i10];
18253
18254 var item = this._data.get(_id7);
18255
18256 if (item == null) {
18257 // @TODO: Investigate.
18258 // Doesn't happen during tests or examples.
18259 // Is it really impossible or could it eventually happen?
18260 // How to handle it if it does? The types guarantee non-nullable items.
18261 console.error("If you see this, report it please.");
18262 } else if (!newIds[_id7]) {
18263 removedIds.push(_id7);
18264 removedItems.push(item);
18265
18266 this._ids.delete(_id7);
18267 }
18268 }
18269
18270 this.length += addedIds.length - removedIds.length; // trigger events
18271
18272 if (addedIds.length) {
18273 this._trigger("add", {
18274 items: addedIds
18275 });
18276 }
18277
18278 if (removedIds.length) {
18279 this._trigger("remove", {
18280 items: removedIds,
18281 oldData: removedItems
18282 });
18283 }
18284 }
18285 /** @inheritDoc */
18286
18287 }, {
18288 key: "get",
18289 value: function get(first, second) {
18290 if (this._data == null) {
18291 return null;
18292 } // parse the arguments
18293
18294
18295 var ids = null;
18296 var options;
18297
18298 if (isId(first) || isArray$2(first)) {
18299 ids = first;
18300 options = second;
18301 } else {
18302 options = first;
18303 } // extend the options with the default options and provided options
18304
18305
18306 var viewOptions = assign$2({}, this._options, options); // create a combined filter method when needed
18307
18308
18309 var thisFilter = filter(this._options);
18310
18311 var optionsFilter = options && filter(options);
18312
18313 if (thisFilter && optionsFilter) {
18314 viewOptions.filter = function (item) {
18315 return thisFilter(item) && optionsFilter(item);
18316 };
18317 }
18318
18319 if (ids == null) {
18320 return this._data.get(viewOptions);
18321 } else {
18322 return this._data.get(ids, viewOptions);
18323 }
18324 }
18325 /** @inheritDoc */
18326
18327 }, {
18328 key: "getIds",
18329 value: function getIds(options) {
18330 if (this._data.length) {
18331 var defaultFilter = filter(this._options);
18332
18333 var optionsFilter = options != null ? filter(options) : null;
18334 var filter$1;
18335
18336 if (optionsFilter) {
18337 if (defaultFilter) {
18338 filter$1 = function filter(item) {
18339 return defaultFilter(item) && optionsFilter(item);
18340 };
18341 } else {
18342 filter$1 = optionsFilter;
18343 }
18344 } else {
18345 filter$1 = defaultFilter;
18346 }
18347
18348 return this._data.getIds({
18349 filter: filter$1,
18350 order: options && options.order
18351 });
18352 } else {
18353 return [];
18354 }
18355 }
18356 /** @inheritDoc */
18357
18358 }, {
18359 key: "forEach",
18360 value: function forEach(callback, options) {
18361 if (this._data) {
18362 var _context28;
18363
18364 var defaultFilter = filter(this._options);
18365
18366 var optionsFilter = options && filter(options);
18367
18368 var filter$1;
18369
18370 if (optionsFilter) {
18371 if (defaultFilter) {
18372 filter$1 = function filter(item) {
18373 return defaultFilter(item) && optionsFilter(item);
18374 };
18375 } else {
18376 filter$1 = optionsFilter;
18377 }
18378 } else {
18379 filter$1 = defaultFilter;
18380 }
18381
18382 forEach$2(_context28 = this._data).call(_context28, callback, {
18383 filter: filter$1,
18384 order: options && options.order
18385 });
18386 }
18387 }
18388 /** @inheritDoc */
18389
18390 }, {
18391 key: "map",
18392 value: function map(callback, options) {
18393 if (this._data) {
18394 var _context29;
18395
18396 var defaultFilter = filter(this._options);
18397
18398 var optionsFilter = options && filter(options);
18399
18400 var filter$1;
18401
18402 if (optionsFilter) {
18403 if (defaultFilter) {
18404 filter$1 = function filter(item) {
18405 return defaultFilter(item) && optionsFilter(item);
18406 };
18407 } else {
18408 filter$1 = optionsFilter;
18409 }
18410 } else {
18411 filter$1 = defaultFilter;
18412 }
18413
18414 return map$3(_context29 = this._data).call(_context29, callback, {
18415 filter: filter$1,
18416 order: options && options.order
18417 });
18418 } else {
18419 return [];
18420 }
18421 }
18422 /** @inheritDoc */
18423
18424 }, {
18425 key: "getDataSet",
18426 value: function getDataSet() {
18427 return this._data.getDataSet();
18428 }
18429 /** @inheritDoc */
18430
18431 }, {
18432 key: "stream",
18433 value: function stream(ids) {
18434 var _context30;
18435
18436 return this._data.stream(ids || _defineProperty({}, iterator, bind$6(_context30 = keys(this._ids)).call(_context30, this._ids)));
18437 }
18438 /**
18439 * Render the instance unusable prior to garbage collection.
18440 *
18441 * @remarks
18442 * The intention of this method is to help discover scenarios where the data
18443 * view is being used when the programmer thinks it has been garbage collected
18444 * already. It's stricter version of `dataView.setData(null)`.
18445 */
18446
18447 }, {
18448 key: "dispose",
18449 value: function dispose() {
18450 var _this$_data;
18451
18452 if ((_this$_data = this._data) !== null && _this$_data !== void 0 && _this$_data.off) {
18453 this._data.off("*", this._listener);
18454 }
18455
18456 var message = "This data view has already been disposed of.";
18457 var replacement = {
18458 get: function get() {
18459 throw new Error(message);
18460 },
18461 set: function set() {
18462 throw new Error(message);
18463 },
18464 configurable: false
18465 };
18466
18467 var _iterator14 = _createForOfIteratorHelper$7(ownKeys$5(DataView.prototype)),
18468 _step14;
18469
18470 try {
18471 for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
18472 var key = _step14.value;
18473
18474 defineProperty$5(this, key, replacement);
18475 }
18476 } catch (err) {
18477 _iterator14.e(err);
18478 } finally {
18479 _iterator14.f();
18480 }
18481 }
18482 /**
18483 * Event listener. Will propagate all events from the connected data set to the subscribers of the DataView, but will filter the items and only trigger when there are changes in the filtered data set.
18484 *
18485 * @param event - The name of the event.
18486 * @param params - Parameters of the event.
18487 * @param senderId - Id supplied by the sender.
18488 */
18489
18490 }, {
18491 key: "_onEvent",
18492 value: function _onEvent(event, params, senderId) {
18493 if (!params || !params.items || !this._data) {
18494 return;
18495 }
18496
18497 var ids = params.items;
18498 var addedIds = [];
18499 var updatedIds = [];
18500 var removedIds = [];
18501 var oldItems = [];
18502 var updatedItems = [];
18503 var removedItems = [];
18504
18505 switch (event) {
18506 case "add":
18507 // filter the ids of the added items
18508 for (var i = 0, len = ids.length; i < len; i++) {
18509 var id = ids[i];
18510 var item = this.get(id);
18511
18512 if (item) {
18513 this._ids.add(id);
18514
18515 addedIds.push(id);
18516 }
18517 }
18518
18519 break;
18520
18521 case "update":
18522 // determine the event from the views viewpoint: an updated
18523 // item can be added, updated, or removed from this view.
18524 for (var _i11 = 0, _len12 = ids.length; _i11 < _len12; _i11++) {
18525 var _id8 = ids[_i11];
18526
18527 var _item5 = this.get(_id8);
18528
18529 if (_item5) {
18530 if (this._ids.has(_id8)) {
18531 updatedIds.push(_id8);
18532 updatedItems.push(params.data[_i11]);
18533 oldItems.push(params.oldData[_i11]);
18534 } else {
18535 this._ids.add(_id8);
18536
18537 addedIds.push(_id8);
18538 }
18539 } else {
18540 if (this._ids.has(_id8)) {
18541 this._ids.delete(_id8);
18542
18543 removedIds.push(_id8);
18544 removedItems.push(params.oldData[_i11]);
18545 }
18546 }
18547 }
18548
18549 break;
18550
18551 case "remove":
18552 // filter the ids of the removed items
18553 for (var _i12 = 0, _len13 = ids.length; _i12 < _len13; _i12++) {
18554 var _id9 = ids[_i12];
18555
18556 if (this._ids.has(_id9)) {
18557 this._ids.delete(_id9);
18558
18559 removedIds.push(_id9);
18560 removedItems.push(params.oldData[_i12]);
18561 }
18562 }
18563
18564 break;
18565 }
18566
18567 this.length += addedIds.length - removedIds.length;
18568
18569 if (addedIds.length) {
18570 this._trigger("add", {
18571 items: addedIds
18572 }, senderId);
18573 }
18574
18575 if (updatedIds.length) {
18576 this._trigger("update", {
18577 items: updatedIds,
18578 oldData: oldItems,
18579 data: updatedItems
18580 }, senderId);
18581 }
18582
18583 if (removedIds.length) {
18584 this._trigger("remove", {
18585 items: removedIds,
18586 oldData: removedItems
18587 }, senderId);
18588 }
18589 }
18590 }]);
18591
18592 return DataView;
18593}(DataSetPart);
18594/**
18595 * Check that given value is compatible with Vis Data Set interface.
18596 *
18597 * @param idProp - The expected property to contain item id.
18598 * @param v - The value to be tested.
18599 *
18600 * @returns True if all expected values and methods match, false otherwise.
18601 */
18602
18603
18604function isDataSetLike(idProp, v) {
18605 return _typeof(v) === "object" && v !== null && idProp === v.idProp && typeof v.add === "function" && typeof v.clear === "function" && typeof v.distinct === "function" && typeof forEach$2(v) === "function" && typeof v.get === "function" && typeof v.getDataSet === "function" && typeof v.getIds === "function" && typeof v.length === "number" && typeof map$3(v) === "function" && typeof v.max === "function" && typeof v.min === "function" && typeof v.off === "function" && typeof v.on === "function" && typeof v.remove === "function" && typeof v.setOptions === "function" && typeof v.stream === "function" && typeof v.update === "function" && typeof v.updateOnly === "function";
18606}
18607/**
18608 * Check that given value is compatible with Vis Data View interface.
18609 *
18610 * @param idProp - The expected property to contain item id.
18611 * @param v - The value to be tested.
18612 *
18613 * @returns True if all expected values and methods match, false otherwise.
18614 */
18615
18616
18617function isDataViewLike(idProp, v) {
18618 return _typeof(v) === "object" && v !== null && idProp === v.idProp && typeof forEach$2(v) === "function" && typeof v.get === "function" && typeof v.getDataSet === "function" && typeof v.getIds === "function" && typeof v.length === "number" && typeof map$3(v) === "function" && typeof v.off === "function" && typeof v.on === "function" && typeof v.stream === "function" && isDataSetLike(idProp, v.getDataSet());
18619}
18620
18621var index = /*#__PURE__*/Object.freeze({
18622 __proto__: null,
18623 DELETE: DELETE,
18624 DataSet: DataSet,
18625 DataStream: DataStream,
18626 DataView: DataView,
18627 Queue: Queue,
18628 createNewDataPipeFrom: createNewDataPipeFrom,
18629 isDataSetLike: isDataSetLike,
18630 isDataViewLike: isDataViewLike
18631});
18632
18633var global$2 = global$k;
18634var toString = toString$9;
18635var trim = stringTrim.trim;
18636var whitespaces = whitespaces$4;
18637var $parseFloat = global$2.parseFloat;
18638var FORCED = 1 / $parseFloat(whitespaces + '-0') !== -Infinity; // `parseFloat` method
18639// https://tc39.es/ecma262/#sec-parsefloat-string
18640
18641var numberParseFloat = FORCED ? function parseFloat(string) {
18642 var trimmedString = trim(toString(string));
18643 var result = $parseFloat(trimmedString);
18644 return result === 0 && trimmedString.charAt(0) == '-' ? -0 : result;
18645} : $parseFloat;
18646
18647var $$4 = _export;
18648var parseFloatImplementation = numberParseFloat; // `parseFloat` method
18649// https://tc39.es/ecma262/#sec-parsefloat-string
18650
18651$$4({
18652 global: true,
18653 forced: parseFloat != parseFloatImplementation
18654}, {
18655 parseFloat: parseFloatImplementation
18656});
18657
18658var path$5 = path$x;
18659var _parseFloat$2 = path$5.parseFloat;
18660
18661var parent$7 = _parseFloat$2;
18662var _parseFloat$1 = parent$7;
18663
18664var _parseFloat = _parseFloat$1;
18665
18666var $$3 = _export;
18667var fails = fails$m;
18668var getOwnPropertyNames$3 = objectGetOwnPropertyNamesExternal.f; // eslint-disable-next-line es/no-object-getownpropertynames -- required for testing
18669
18670var FAILS_ON_PRIMITIVES = fails(function () {
18671 return !Object.getOwnPropertyNames(1);
18672}); // `Object.getOwnPropertyNames` method
18673// https://tc39.es/ecma262/#sec-object.getownpropertynames
18674
18675$$3({
18676 target: 'Object',
18677 stat: true,
18678 forced: FAILS_ON_PRIMITIVES
18679}, {
18680 getOwnPropertyNames: getOwnPropertyNames$3
18681});
18682
18683var path$4 = path$x;
18684var Object$1 = path$4.Object;
18685
18686var getOwnPropertyNames$2 = function getOwnPropertyNames(it) {
18687 return Object$1.getOwnPropertyNames(it);
18688};
18689
18690var parent$6 = getOwnPropertyNames$2;
18691var getOwnPropertyNames$1 = parent$6;
18692
18693var getOwnPropertyNames = getOwnPropertyNames$1;
18694
18695/**
18696 * Helper functions for components
18697 */
18698
18699/**
18700 * Determine values to use for (sub)options of 'chosen'.
18701 *
18702 * This option is either a boolean or an object whose values should be examined further.
18703 * The relevant structures are:
18704 *
18705 * - chosen: <boolean value>
18706 * - chosen: { subOption: <boolean or function> }
18707 *
18708 * Where subOption is 'node', 'edge' or 'label'.
18709 *
18710 * The intention of this method appears to be to set a specific priority to the options;
18711 * Since most properties are either bridged or merged into the local options objects, there
18712 * is not much point in handling them separately.
18713 * TODO: examine if 'most' in previous sentence can be replaced with 'all'. In that case, we
18714 * should be able to get rid of this method.
18715 *
18716 * @param {string} subOption option within object 'chosen' to consider; either 'node', 'edge' or 'label'
18717 * @param {object} pile array of options objects to consider
18718 *
18719 * @returns {boolean | Function} value for passed subOption of 'chosen' to use
18720 */
18721
18722function choosify(subOption, pile) {
18723 // allowed values for subOption
18724 var allowed = ["node", "edge", "label"];
18725 var value = true;
18726 var chosen = topMost(pile, "chosen");
18727
18728 if (typeof chosen === "boolean") {
18729 value = chosen;
18730 } else if (_typeof(chosen) === "object") {
18731 if (indexOf(allowed).call(allowed, subOption) === -1) {
18732 throw new Error("choosify: subOption '" + subOption + "' should be one of " + "'" + allowed.join("', '") + "'");
18733 }
18734
18735 var chosenEdge = topMost(pile, ["chosen", subOption]);
18736
18737 if (typeof chosenEdge === "boolean" || typeof chosenEdge === "function") {
18738 value = chosenEdge;
18739 }
18740 }
18741
18742 return value;
18743}
18744/**
18745 * Check if the point falls within the given rectangle.
18746 *
18747 * @param {rect} rect
18748 * @param {point} point
18749 * @param {rotationPoint} [rotationPoint] if specified, the rotation that applies to the rectangle.
18750 * @returns {boolean} true if point within rectangle, false otherwise
18751 */
18752
18753function pointInRect(rect, point, rotationPoint) {
18754 if (rect.width <= 0 || rect.height <= 0) {
18755 return false; // early out
18756 }
18757
18758 if (rotationPoint !== undefined) {
18759 // Rotate the point the same amount as the rectangle
18760 var tmp = {
18761 x: point.x - rotationPoint.x,
18762 y: point.y - rotationPoint.y
18763 };
18764
18765 if (rotationPoint.angle !== 0) {
18766 // In order to get the coordinates the same, you need to
18767 // rotate in the reverse direction
18768 var angle = -rotationPoint.angle;
18769 var tmp2 = {
18770 x: Math.cos(angle) * tmp.x - Math.sin(angle) * tmp.y,
18771 y: Math.sin(angle) * tmp.x + Math.cos(angle) * tmp.y
18772 };
18773 point = tmp2;
18774 } else {
18775 point = tmp;
18776 } // Note that if a rotation is specified, the rectangle coordinates
18777 // are **not* the full canvas coordinates. They are relative to the
18778 // rotationPoint. Hence, the point coordinates need not be translated
18779 // back in this case.
18780
18781 }
18782
18783 var right = rect.x + rect.width;
18784 var bottom = rect.y + rect.width;
18785 return rect.left < point.x && right > point.x && rect.top < point.y && bottom > point.y;
18786}
18787/**
18788 * Check if given value is acceptable as a label text.
18789 *
18790 * @param {*} text value to check; can be anything at this point
18791 * @returns {boolean} true if valid label value, false otherwise
18792 */
18793
18794function isValidLabel(text) {
18795 // Note that this is quite strict: types that *might* be converted to string are disallowed
18796 return typeof text === "string" && text !== "";
18797}
18798/**
18799 * Returns x, y of self reference circle based on provided angle
18800 *
18801 * @param {object} ctx
18802 * @param {number} angle
18803 * @param {number} radius
18804 * @param {VisNode} node
18805 *
18806 * @returns {object} x and y coordinates
18807 */
18808
18809function getSelfRefCoordinates(ctx, angle, radius, node) {
18810 var x = node.x;
18811 var y = node.y;
18812
18813 if (typeof node.distanceToBorder === "function") {
18814 //calculating opposite and adjacent
18815 //distaneToBorder becomes Hypotenuse.
18816 //Formulas sin(a) = Opposite / Hypotenuse and cos(a) = Adjacent / Hypotenuse
18817 var toBorderDist = node.distanceToBorder(ctx, angle);
18818 var yFromNodeCenter = Math.sin(angle) * toBorderDist;
18819 var xFromNodeCenter = Math.cos(angle) * toBorderDist; //xFromNodeCenter is basically x and if xFromNodeCenter equals to the distance to border then it means
18820 //that y does not need calculation because it is equal node.height / 2 or node.y
18821 //same thing with yFromNodeCenter and if yFromNodeCenter equals to the distance to border then it means
18822 //that x is equal node.width / 2 or node.x
18823
18824 if (xFromNodeCenter === toBorderDist) {
18825 x += toBorderDist;
18826 y = node.y;
18827 } else if (yFromNodeCenter === toBorderDist) {
18828 x = node.x;
18829 y -= toBorderDist;
18830 } else {
18831 x += xFromNodeCenter;
18832 y -= yFromNodeCenter;
18833 }
18834 } else if (node.shape.width > node.shape.height) {
18835 x = node.x + node.shape.width * 0.5;
18836 y = node.y - radius;
18837 } else {
18838 x = node.x + radius;
18839 y = node.y - node.shape.height * 0.5;
18840 }
18841
18842 return {
18843 x: x,
18844 y: y
18845 };
18846}
18847
18848/**
18849 * Callback to determine text dimensions, using the parent label settings.
18850 *
18851 * @callback MeasureText
18852 * @param {text} text
18853 * @param {text} mod
18854 * @returns {object} { width, values} width in pixels and font attributes
18855 */
18856
18857/**
18858 * Helper class for Label which collects results of splitting labels into lines and blocks.
18859 *
18860 * @private
18861 */
18862var LabelAccumulator = /*#__PURE__*/function () {
18863 /**
18864 * @param {MeasureText} measureText
18865 */
18866 function LabelAccumulator(measureText) {
18867 _classCallCheck(this, LabelAccumulator);
18868
18869 this.measureText = measureText;
18870 this.current = 0;
18871 this.width = 0;
18872 this.height = 0;
18873 this.lines = [];
18874 }
18875 /**
18876 * Append given text to the given line.
18877 *
18878 * @param {number} l index of line to add to
18879 * @param {string} text string to append to line
18880 * @param {'bold'|'ital'|'boldital'|'mono'|'normal'} [mod='normal']
18881 * @private
18882 */
18883
18884
18885 _createClass(LabelAccumulator, [{
18886 key: "_add",
18887 value: function _add(l, text) {
18888 var mod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "normal";
18889
18890 if (this.lines[l] === undefined) {
18891 this.lines[l] = {
18892 width: 0,
18893 height: 0,
18894 blocks: []
18895 };
18896 } // We still need to set a block for undefined and empty texts, hence return at this point
18897 // This is necessary because we don't know at this point if we're at the
18898 // start of an empty line or not.
18899 // To compensate, empty blocks are removed in `finalize()`.
18900 //
18901 // Empty strings should still have a height
18902
18903
18904 var tmpText = text;
18905 if (text === undefined || text === "") tmpText = " "; // Determine width and get the font properties
18906
18907 var result = this.measureText(tmpText, mod);
18908
18909 var block = assign$2({}, values(result));
18910
18911 block.text = text;
18912 block.width = result.width;
18913 block.mod = mod;
18914
18915 if (text === undefined || text === "") {
18916 block.width = 0;
18917 }
18918
18919 this.lines[l].blocks.push(block); // Update the line width. We need this for determining if a string goes over max width
18920
18921 this.lines[l].width += block.width;
18922 }
18923 /**
18924 * Returns the width in pixels of the current line.
18925 *
18926 * @returns {number}
18927 */
18928
18929 }, {
18930 key: "curWidth",
18931 value: function curWidth() {
18932 var line = this.lines[this.current];
18933 if (line === undefined) return 0;
18934 return line.width;
18935 }
18936 /**
18937 * Add text in block to current line
18938 *
18939 * @param {string} text
18940 * @param {'bold'|'ital'|'boldital'|'mono'|'normal'} [mod='normal']
18941 */
18942
18943 }, {
18944 key: "append",
18945 value: function append(text) {
18946 var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "normal";
18947
18948 this._add(this.current, text, mod);
18949 }
18950 /**
18951 * Add text in block to current line and start a new line
18952 *
18953 * @param {string} text
18954 * @param {'bold'|'ital'|'boldital'|'mono'|'normal'} [mod='normal']
18955 */
18956
18957 }, {
18958 key: "newLine",
18959 value: function newLine(text) {
18960 var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "normal";
18961
18962 this._add(this.current, text, mod);
18963
18964 this.current++;
18965 }
18966 /**
18967 * Determine and set the heights of all the lines currently contained in this instance
18968 *
18969 * Note that width has already been set.
18970 *
18971 * @private
18972 */
18973
18974 }, {
18975 key: "determineLineHeights",
18976 value: function determineLineHeights() {
18977 for (var k = 0; k < this.lines.length; k++) {
18978 var line = this.lines[k]; // Looking for max height of blocks in line
18979
18980 var height = 0;
18981
18982 if (line.blocks !== undefined) {
18983 // Can happen if text contains e.g. '\n '
18984 for (var l = 0; l < line.blocks.length; l++) {
18985 var block = line.blocks[l];
18986
18987 if (height < block.height) {
18988 height = block.height;
18989 }
18990 }
18991 }
18992
18993 line.height = height;
18994 }
18995 }
18996 /**
18997 * Determine the full size of the label text, as determined by current lines and blocks
18998 *
18999 * @private
19000 */
19001
19002 }, {
19003 key: "determineLabelSize",
19004 value: function determineLabelSize() {
19005 var width = 0;
19006 var height = 0;
19007
19008 for (var k = 0; k < this.lines.length; k++) {
19009 var line = this.lines[k];
19010
19011 if (line.width > width) {
19012 width = line.width;
19013 }
19014
19015 height += line.height;
19016 }
19017
19018 this.width = width;
19019 this.height = height;
19020 }
19021 /**
19022 * Remove all empty blocks and empty lines we don't need
19023 *
19024 * This must be done after the width/height determination,
19025 * so that these are set properly for processing here.
19026 *
19027 * @returns {Array<Line>} Lines with empty blocks (and some empty lines) removed
19028 * @private
19029 */
19030
19031 }, {
19032 key: "removeEmptyBlocks",
19033 value: function removeEmptyBlocks() {
19034 var tmpLines = [];
19035
19036 for (var k = 0; k < this.lines.length; k++) {
19037 var line = this.lines[k]; // Note: an empty line in between text has width zero but is still relevant to layout.
19038 // So we can't use width for testing empty line here
19039
19040 if (line.blocks.length === 0) continue; // Discard final empty line always
19041
19042 if (k === this.lines.length - 1) {
19043 if (line.width === 0) continue;
19044 }
19045
19046 var tmpLine = {};
19047
19048 assign$2(tmpLine, line);
19049
19050 tmpLine.blocks = [];
19051 var firstEmptyBlock = void 0;
19052 var tmpBlocks = [];
19053
19054 for (var l = 0; l < line.blocks.length; l++) {
19055 var block = line.blocks[l];
19056
19057 if (block.width !== 0) {
19058 tmpBlocks.push(block);
19059 } else {
19060 if (firstEmptyBlock === undefined) {
19061 firstEmptyBlock = block;
19062 }
19063 }
19064 } // Ensure that there is *some* text present
19065
19066
19067 if (tmpBlocks.length === 0 && firstEmptyBlock !== undefined) {
19068 tmpBlocks.push(firstEmptyBlock);
19069 }
19070
19071 tmpLine.blocks = tmpBlocks;
19072 tmpLines.push(tmpLine);
19073 }
19074
19075 return tmpLines;
19076 }
19077 /**
19078 * Set the sizes for all lines and the whole thing.
19079 *
19080 * @returns {{width: (number|*), height: (number|*), lines: Array}}
19081 */
19082
19083 }, {
19084 key: "finalize",
19085 value: function finalize() {
19086 //console.log(JSON.stringify(this.lines, null, 2));
19087 this.determineLineHeights();
19088 this.determineLabelSize();
19089 var tmpLines = this.removeEmptyBlocks(); // Return a simple hash object for further processing.
19090
19091 return {
19092 width: this.width,
19093 height: this.height,
19094 lines: tmpLines
19095 };
19096 }
19097 }]);
19098
19099 return LabelAccumulator;
19100}();
19101
19102var tagPattern = {
19103 // HTML
19104 "<b>": /<b>/,
19105 "<i>": /<i>/,
19106 "<code>": /<code>/,
19107 "</b>": /<\/b>/,
19108 "</i>": /<\/i>/,
19109 "</code>": /<\/code>/,
19110 // Markdown
19111 "*": /\*/,
19112 // bold
19113 _: /_/,
19114 // ital
19115 "`": /`/,
19116 // mono
19117 afterBold: /[^*]/,
19118 afterItal: /[^_]/,
19119 afterMono: /[^`]/
19120};
19121/**
19122 * Internal helper class for parsing the markup tags for HTML and Markdown.
19123 *
19124 * NOTE: Sequences of tabs and spaces are reduced to single space.
19125 * Scan usage of `this.spacing` within method
19126 */
19127
19128var MarkupAccumulator = /*#__PURE__*/function () {
19129 /**
19130 * Create an instance
19131 *
19132 * @param {string} text text to parse for markup
19133 */
19134 function MarkupAccumulator(text) {
19135 _classCallCheck(this, MarkupAccumulator);
19136
19137 this.text = text;
19138 this.bold = false;
19139 this.ital = false;
19140 this.mono = false;
19141 this.spacing = false;
19142 this.position = 0;
19143 this.buffer = "";
19144 this.modStack = [];
19145 this.blocks = [];
19146 }
19147 /**
19148 * Return the mod label currently on the top of the stack
19149 *
19150 * @returns {string} label of topmost mod
19151 * @private
19152 */
19153
19154
19155 _createClass(MarkupAccumulator, [{
19156 key: "mod",
19157 value: function mod() {
19158 return this.modStack.length === 0 ? "normal" : this.modStack[0];
19159 }
19160 /**
19161 * Return the mod label currently active
19162 *
19163 * @returns {string} label of active mod
19164 * @private
19165 */
19166
19167 }, {
19168 key: "modName",
19169 value: function modName() {
19170 if (this.modStack.length === 0) return "normal";else if (this.modStack[0] === "mono") return "mono";else {
19171 if (this.bold && this.ital) {
19172 return "boldital";
19173 } else if (this.bold) {
19174 return "bold";
19175 } else if (this.ital) {
19176 return "ital";
19177 }
19178 }
19179 }
19180 /**
19181 * @private
19182 */
19183
19184 }, {
19185 key: "emitBlock",
19186 value: function emitBlock() {
19187 if (this.spacing) {
19188 this.add(" ");
19189 this.spacing = false;
19190 }
19191
19192 if (this.buffer.length > 0) {
19193 this.blocks.push({
19194 text: this.buffer,
19195 mod: this.modName()
19196 });
19197 this.buffer = "";
19198 }
19199 }
19200 /**
19201 * Output text to buffer
19202 *
19203 * @param {string} text text to add
19204 * @private
19205 */
19206
19207 }, {
19208 key: "add",
19209 value: function add(text) {
19210 if (text === " ") {
19211 this.spacing = true;
19212 }
19213
19214 if (this.spacing) {
19215 this.buffer += " ";
19216 this.spacing = false;
19217 }
19218
19219 if (text != " ") {
19220 this.buffer += text;
19221 }
19222 }
19223 /**
19224 * Handle parsing of whitespace
19225 *
19226 * @param {string} ch the character to check
19227 * @returns {boolean} true if the character was processed as whitespace, false otherwise
19228 */
19229
19230 }, {
19231 key: "parseWS",
19232 value: function parseWS(ch) {
19233 if (/[ \t]/.test(ch)) {
19234 if (!this.mono) {
19235 this.spacing = true;
19236 } else {
19237 this.add(ch);
19238 }
19239
19240 return true;
19241 }
19242
19243 return false;
19244 }
19245 /**
19246 * @param {string} tagName label for block type to set
19247 * @private
19248 */
19249
19250 }, {
19251 key: "setTag",
19252 value: function setTag(tagName) {
19253 this.emitBlock();
19254 this[tagName] = true;
19255 this.modStack.unshift(tagName);
19256 }
19257 /**
19258 * @param {string} tagName label for block type to unset
19259 * @private
19260 */
19261
19262 }, {
19263 key: "unsetTag",
19264 value: function unsetTag(tagName) {
19265 this.emitBlock();
19266 this[tagName] = false;
19267 this.modStack.shift();
19268 }
19269 /**
19270 * @param {string} tagName label for block type we are currently processing
19271 * @param {string|RegExp} tag string to match in text
19272 * @returns {boolean} true if the tag was processed, false otherwise
19273 */
19274
19275 }, {
19276 key: "parseStartTag",
19277 value: function parseStartTag(tagName, tag) {
19278 // Note: if 'mono' passed as tagName, there is a double check here. This is OK
19279 if (!this.mono && !this[tagName] && this.match(tag)) {
19280 this.setTag(tagName);
19281 return true;
19282 }
19283
19284 return false;
19285 }
19286 /**
19287 * @param {string|RegExp} tag
19288 * @param {number} [advance=true] if set, advance current position in text
19289 * @returns {boolean} true if match at given position, false otherwise
19290 * @private
19291 */
19292
19293 }, {
19294 key: "match",
19295 value: function match(tag) {
19296 var advance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19297
19298 var _this$prepareRegExp = this.prepareRegExp(tag),
19299 _this$prepareRegExp2 = _slicedToArray(_this$prepareRegExp, 2),
19300 regExp = _this$prepareRegExp2[0],
19301 length = _this$prepareRegExp2[1];
19302
19303 var matched = regExp.test(this.text.substr(this.position, length));
19304
19305 if (matched && advance) {
19306 this.position += length - 1;
19307 }
19308
19309 return matched;
19310 }
19311 /**
19312 * @param {string} tagName label for block type we are currently processing
19313 * @param {string|RegExp} tag string to match in text
19314 * @param {RegExp} [nextTag] regular expression to match for characters *following* the current tag
19315 * @returns {boolean} true if the tag was processed, false otherwise
19316 */
19317
19318 }, {
19319 key: "parseEndTag",
19320 value: function parseEndTag(tagName, tag, nextTag) {
19321 var checkTag = this.mod() === tagName;
19322
19323 if (tagName === "mono") {
19324 // special handling for 'mono'
19325 checkTag = checkTag && this.mono;
19326 } else {
19327 checkTag = checkTag && !this.mono;
19328 }
19329
19330 if (checkTag && this.match(tag)) {
19331 if (nextTag !== undefined) {
19332 // Purpose of the following match is to prevent a direct unset/set of a given tag
19333 // E.g. '*bold **still bold*' => '*bold still bold*'
19334 if (this.position === this.text.length - 1 || this.match(nextTag, false)) {
19335 this.unsetTag(tagName);
19336 }
19337 } else {
19338 this.unsetTag(tagName);
19339 }
19340
19341 return true;
19342 }
19343
19344 return false;
19345 }
19346 /**
19347 * @param {string|RegExp} tag string to match in text
19348 * @param {value} value string to replace tag with, if found at current position
19349 * @returns {boolean} true if the tag was processed, false otherwise
19350 */
19351
19352 }, {
19353 key: "replace",
19354 value: function replace(tag, value) {
19355 if (this.match(tag)) {
19356 this.add(value);
19357 this.position += length - 1;
19358 return true;
19359 }
19360
19361 return false;
19362 }
19363 /**
19364 * Create a regular expression for the tag if it isn't already one.
19365 *
19366 * The return value is an array `[RegExp, number]`, with exactly two value, where:
19367 * - RegExp is the regular expression to use
19368 * - number is the lenth of the input string to match
19369 *
19370 * @param {string|RegExp} tag string to match in text
19371 * @returns {Array} regular expression to use and length of input string to match
19372 * @private
19373 */
19374
19375 }, {
19376 key: "prepareRegExp",
19377 value: function prepareRegExp(tag) {
19378 var length;
19379 var regExp;
19380
19381 if (tag instanceof RegExp) {
19382 regExp = tag;
19383 length = 1; // ASSUMPTION: regexp only tests one character
19384 } else {
19385 // use prepared regexp if present
19386 var prepared = tagPattern[tag];
19387
19388 if (prepared !== undefined) {
19389 regExp = prepared;
19390 } else {
19391 regExp = new RegExp(tag);
19392 }
19393
19394 length = tag.length;
19395 }
19396
19397 return [regExp, length];
19398 }
19399 }]);
19400
19401 return MarkupAccumulator;
19402}();
19403/**
19404 * Helper class for Label which explodes the label text into lines and blocks within lines
19405 *
19406 * @private
19407 */
19408
19409
19410var LabelSplitter = /*#__PURE__*/function () {
19411 /**
19412 * @param {CanvasRenderingContext2D} ctx Canvas rendering context
19413 * @param {Label} parent reference to the Label instance using current instance
19414 * @param {boolean} selected
19415 * @param {boolean} hover
19416 */
19417 function LabelSplitter(ctx, parent, selected, hover) {
19418 var _this = this;
19419
19420 _classCallCheck(this, LabelSplitter);
19421
19422 this.ctx = ctx;
19423 this.parent = parent;
19424 this.selected = selected;
19425 this.hover = hover;
19426 /**
19427 * Callback to determine text width; passed to LabelAccumulator instance
19428 *
19429 * @param {string} text string to determine width of
19430 * @param {string} mod font type to use for this text
19431 * @returns {object} { width, values} width in pixels and font attributes
19432 */
19433
19434 var textWidth = function textWidth(text, mod) {
19435 if (text === undefined) return 0; // TODO: This can be done more efficiently with caching
19436 // This will set the ctx.font correctly, depending on selected/hover and mod - so that ctx.measureText() will be accurate.
19437
19438 var values = _this.parent.getFormattingValues(ctx, selected, hover, mod);
19439
19440 var width = 0;
19441
19442 if (text !== "") {
19443 var measure = _this.ctx.measureText(text);
19444
19445 width = measure.width;
19446 }
19447
19448 return {
19449 width: width,
19450 values: values
19451 };
19452 };
19453
19454 this.lines = new LabelAccumulator(textWidth);
19455 }
19456 /**
19457 * Split passed text of a label into lines and blocks.
19458 *
19459 * # NOTE
19460 *
19461 * The handling of spacing is option dependent:
19462 *
19463 * - if `font.multi : false`, all spaces are retained
19464 * - if `font.multi : true`, every sequence of spaces is compressed to a single space
19465 *
19466 * This might not be the best way to do it, but this is as it has been working till now.
19467 * In order not to break existing functionality, for the time being this behaviour will
19468 * be retained in any code changes.
19469 *
19470 * @param {string} text text to split
19471 * @returns {Array<line>}
19472 */
19473
19474
19475 _createClass(LabelSplitter, [{
19476 key: "process",
19477 value: function process(text) {
19478 if (!isValidLabel(text)) {
19479 return this.lines.finalize();
19480 }
19481
19482 var font = this.parent.fontOptions; // Normalize the end-of-line's to a single representation - order important
19483
19484 text = text.replace(/\r\n/g, "\n"); // Dos EOL's
19485
19486 text = text.replace(/\r/g, "\n"); // Mac EOL's
19487 // Note that at this point, there can be no \r's in the text.
19488 // This is used later on splitStringIntoLines() to split multifont texts.
19489
19490 var nlLines = String(text).split("\n");
19491 var lineCount = nlLines.length;
19492
19493 if (font.multi) {
19494 // Multi-font case: styling tags active
19495 for (var i = 0; i < lineCount; i++) {
19496 var blocks = this.splitBlocks(nlLines[i], font.multi); // Post: Sequences of tabs and spaces are reduced to single space
19497
19498 if (blocks === undefined) continue;
19499
19500 if (blocks.length === 0) {
19501 this.lines.newLine("");
19502 continue;
19503 }
19504
19505 if (font.maxWdt > 0) {
19506 // widthConstraint.maximum defined
19507 //console.log('Running widthConstraint multi, max: ' + this.fontOptions.maxWdt);
19508 for (var j = 0; j < blocks.length; j++) {
19509 var mod = blocks[j].mod;
19510 var _text = blocks[j].text;
19511 this.splitStringIntoLines(_text, mod, true);
19512 }
19513 } else {
19514 // widthConstraint.maximum NOT defined
19515 for (var _j = 0; _j < blocks.length; _j++) {
19516 var _mod = blocks[_j].mod;
19517 var _text2 = blocks[_j].text;
19518 this.lines.append(_text2, _mod);
19519 }
19520 }
19521
19522 this.lines.newLine();
19523 }
19524 } else {
19525 // Single-font case
19526 if (font.maxWdt > 0) {
19527 // widthConstraint.maximum defined
19528 // console.log('Running widthConstraint normal, max: ' + this.fontOptions.maxWdt);
19529 for (var _i = 0; _i < lineCount; _i++) {
19530 this.splitStringIntoLines(nlLines[_i]);
19531 }
19532 } else {
19533 // widthConstraint.maximum NOT defined
19534 for (var _i2 = 0; _i2 < lineCount; _i2++) {
19535 this.lines.newLine(nlLines[_i2]);
19536 }
19537 }
19538 }
19539
19540 return this.lines.finalize();
19541 }
19542 /**
19543 * normalize the markup system
19544 *
19545 * @param {boolean|'md'|'markdown'|'html'} markupSystem
19546 * @returns {string}
19547 */
19548
19549 }, {
19550 key: "decodeMarkupSystem",
19551 value: function decodeMarkupSystem(markupSystem) {
19552 var system = "none";
19553
19554 if (markupSystem === "markdown" || markupSystem === "md") {
19555 system = "markdown";
19556 } else if (markupSystem === true || markupSystem === "html") {
19557 system = "html";
19558 }
19559
19560 return system;
19561 }
19562 /**
19563 *
19564 * @param {string} text
19565 * @returns {Array}
19566 */
19567
19568 }, {
19569 key: "splitHtmlBlocks",
19570 value: function splitHtmlBlocks(text) {
19571 var s = new MarkupAccumulator(text);
19572
19573 var parseEntities = function parseEntities(ch) {
19574 if (/&/.test(ch)) {
19575 var parsed = s.replace(s.text, "&lt;", "<") || s.replace(s.text, "&amp;", "&");
19576
19577 if (!parsed) {
19578 s.add("&");
19579 }
19580
19581 return true;
19582 }
19583
19584 return false;
19585 };
19586
19587 while (s.position < s.text.length) {
19588 var ch = s.text.charAt(s.position);
19589 var parsed = s.parseWS(ch) || /</.test(ch) && (s.parseStartTag("bold", "<b>") || s.parseStartTag("ital", "<i>") || s.parseStartTag("mono", "<code>") || s.parseEndTag("bold", "</b>") || s.parseEndTag("ital", "</i>") || s.parseEndTag("mono", "</code>")) || parseEntities(ch);
19590
19591 if (!parsed) {
19592 s.add(ch);
19593 }
19594
19595 s.position++;
19596 }
19597
19598 s.emitBlock();
19599 return s.blocks;
19600 }
19601 /**
19602 *
19603 * @param {string} text
19604 * @returns {Array}
19605 */
19606
19607 }, {
19608 key: "splitMarkdownBlocks",
19609 value: function splitMarkdownBlocks(text) {
19610 var _this2 = this;
19611
19612 var s = new MarkupAccumulator(text);
19613 var beginable = true;
19614
19615 var parseOverride = function parseOverride(ch) {
19616 if (/\\/.test(ch)) {
19617 if (s.position < _this2.text.length + 1) {
19618 s.position++;
19619 ch = _this2.text.charAt(s.position);
19620
19621 if (/ \t/.test(ch)) {
19622 s.spacing = true;
19623 } else {
19624 s.add(ch);
19625 beginable = false;
19626 }
19627 }
19628
19629 return true;
19630 }
19631
19632 return false;
19633 };
19634
19635 while (s.position < s.text.length) {
19636 var ch = s.text.charAt(s.position);
19637 var parsed = s.parseWS(ch) || parseOverride(ch) || (beginable || s.spacing) && (s.parseStartTag("bold", "*") || s.parseStartTag("ital", "_") || s.parseStartTag("mono", "`")) || s.parseEndTag("bold", "*", "afterBold") || s.parseEndTag("ital", "_", "afterItal") || s.parseEndTag("mono", "`", "afterMono");
19638
19639 if (!parsed) {
19640 s.add(ch);
19641 beginable = false;
19642 }
19643
19644 s.position++;
19645 }
19646
19647 s.emitBlock();
19648 return s.blocks;
19649 }
19650 /**
19651 * Explodes a piece of text into single-font blocks using a given markup
19652 *
19653 * @param {string} text
19654 * @param {boolean|'md'|'markdown'|'html'} markupSystem
19655 * @returns {Array.<{text: string, mod: string}>}
19656 * @private
19657 */
19658
19659 }, {
19660 key: "splitBlocks",
19661 value: function splitBlocks(text, markupSystem) {
19662 var system = this.decodeMarkupSystem(markupSystem);
19663
19664 if (system === "none") {
19665 return [{
19666 text: text,
19667 mod: "normal"
19668 }];
19669 } else if (system === "markdown") {
19670 return this.splitMarkdownBlocks(text);
19671 } else if (system === "html") {
19672 return this.splitHtmlBlocks(text);
19673 }
19674 }
19675 /**
19676 * @param {string} text
19677 * @returns {boolean} true if text length over the current max with
19678 * @private
19679 */
19680
19681 }, {
19682 key: "overMaxWidth",
19683 value: function overMaxWidth(text) {
19684 var width = this.ctx.measureText(text).width;
19685 return this.lines.curWidth() + width > this.parent.fontOptions.maxWdt;
19686 }
19687 /**
19688 * Determine the longest part of the sentence which still fits in the
19689 * current max width.
19690 *
19691 * @param {Array} words Array of strings signifying a text lines
19692 * @returns {number} index of first item in string making string go over max
19693 * @private
19694 */
19695
19696 }, {
19697 key: "getLongestFit",
19698 value: function getLongestFit(words) {
19699 var text = "";
19700 var w = 0;
19701
19702 while (w < words.length) {
19703 var pre = text === "" ? "" : " ";
19704 var newText = text + pre + words[w];
19705 if (this.overMaxWidth(newText)) break;
19706 text = newText;
19707 w++;
19708 }
19709
19710 return w;
19711 }
19712 /**
19713 * Determine the longest part of the string which still fits in the
19714 * current max width.
19715 *
19716 * @param {Array} words Array of strings signifying a text lines
19717 * @returns {number} index of first item in string making string go over max
19718 */
19719
19720 }, {
19721 key: "getLongestFitWord",
19722 value: function getLongestFitWord(words) {
19723 var w = 0;
19724
19725 while (w < words.length) {
19726 if (this.overMaxWidth(slice$1(words).call(words, 0, w))) break;
19727 w++;
19728 }
19729
19730 return w;
19731 }
19732 /**
19733 * Split the passed text into lines, according to width constraint (if any).
19734 *
19735 * The method assumes that the input string is a single line, i.e. without lines break.
19736 *
19737 * This method retains spaces, if still present (case `font.multi: false`).
19738 * A space which falls on an internal line break, will be replaced by a newline.
19739 * There is no special handling of tabs; these go along with the flow.
19740 *
19741 * @param {string} str
19742 * @param {string} [mod='normal']
19743 * @param {boolean} [appendLast=false]
19744 * @private
19745 */
19746
19747 }, {
19748 key: "splitStringIntoLines",
19749 value: function splitStringIntoLines(str) {
19750 var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "normal";
19751 var appendLast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
19752 // Set the canvas context font, based upon the current selected/hover state
19753 // and the provided mod, so the text measurement performed by getLongestFit
19754 // will be accurate - and not just use the font of whoever last used the canvas.
19755 this.parent.getFormattingValues(this.ctx, this.selected, this.hover, mod); // Still-present spaces are relevant, retain them
19756
19757 str = str.replace(/^( +)/g, "$1\r");
19758 str = str.replace(/([^\r][^ ]*)( +)/g, "$1\r$2\r");
19759 var words = str.split("\r");
19760
19761 while (words.length > 0) {
19762 var w = this.getLongestFit(words);
19763
19764 if (w === 0) {
19765 // Special case: the first word is already larger than the max width.
19766 var word = words[0]; // Break the word to the largest part that fits the line
19767
19768 var x = this.getLongestFitWord(word);
19769 this.lines.newLine(slice$1(word).call(word, 0, x), mod); // Adjust the word, so that the rest will be done next iteration
19770
19771 words[0] = slice$1(word).call(word, x);
19772 } else {
19773 // skip any space that is replaced by a newline
19774 var newW = w;
19775
19776 if (words[w - 1] === " ") {
19777 w--;
19778 } else if (words[newW] === " ") {
19779 newW++;
19780 }
19781
19782 var text = slice$1(words).call(words, 0, w).join("");
19783
19784 if (w == words.length && appendLast) {
19785 this.lines.append(text, mod);
19786 } else {
19787 this.lines.newLine(text, mod);
19788 } // Adjust the word, so that the rest will be done next iteration
19789
19790
19791 words = slice$1(words).call(words, newW);
19792 }
19793 }
19794 }
19795 }]);
19796
19797 return LabelSplitter;
19798}();
19799
19800/**
19801 * List of special styles for multi-fonts
19802 *
19803 * @private
19804 */
19805
19806var multiFontStyle = ["bold", "ital", "boldital", "mono"];
19807/**
19808 * A Label to be used for Nodes or Edges.
19809 */
19810
19811var Label = /*#__PURE__*/function () {
19812 /**
19813 * @param {object} body
19814 * @param {object} options
19815 * @param {boolean} [edgelabel=false]
19816 */
19817 function Label(body, options) {
19818 var edgelabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
19819
19820 _classCallCheck(this, Label);
19821
19822 this.body = body;
19823 this.pointToSelf = false;
19824 this.baseSize = undefined;
19825 this.fontOptions = {}; // instance variable containing the *instance-local* font options
19826
19827 this.setOptions(options);
19828 this.size = {
19829 top: 0,
19830 left: 0,
19831 width: 0,
19832 height: 0,
19833 yLine: 0
19834 };
19835 this.isEdgeLabel = edgelabel;
19836 }
19837 /**
19838 * @param {object} options the options of the parent Node-instance
19839 */
19840
19841
19842 _createClass(Label, [{
19843 key: "setOptions",
19844 value: function setOptions(options) {
19845 this.elementOptions = options; // Reference to the options of the parent Node-instance
19846
19847 this.initFontOptions(options.font);
19848
19849 if (isValidLabel(options.label)) {
19850 this.labelDirty = true;
19851 } else {
19852 // Bad label! Change the option value to prevent bad stuff happening
19853 options.label = undefined;
19854 }
19855
19856 if (options.font !== undefined && options.font !== null) {
19857 // font options can be deleted at various levels
19858 if (typeof options.font === "string") {
19859 this.baseSize = this.fontOptions.size;
19860 } else if (_typeof(options.font) === "object") {
19861 var size = options.font.size;
19862
19863 if (size !== undefined) {
19864 this.baseSize = size;
19865 }
19866 }
19867 }
19868 }
19869 /**
19870 * Init the font Options structure.
19871 *
19872 * Member fontOptions serves as an accumulator for the current font options.
19873 * As such, it needs to be completely separated from the node options.
19874 *
19875 * @param {object} newFontOptions the new font options to process
19876 * @private
19877 */
19878
19879 }, {
19880 key: "initFontOptions",
19881 value: function initFontOptions(newFontOptions) {
19882 var _this = this;
19883
19884 // Prepare the multi-font option objects.
19885 // These will be filled in propagateFonts(), if required
19886 forEach$1(multiFontStyle, function (style) {
19887 _this.fontOptions[style] = {};
19888 }); // Handle shorthand option, if present
19889
19890 if (Label.parseFontString(this.fontOptions, newFontOptions)) {
19891 this.fontOptions.vadjust = 0;
19892 return;
19893 } // Copy over the non-multifont options, if specified
19894
19895
19896 forEach$1(newFontOptions, function (prop, n) {
19897 if (prop !== undefined && prop !== null && _typeof(prop) !== "object") {
19898 _this.fontOptions[n] = prop;
19899 }
19900 });
19901 }
19902 /**
19903 * If in-variable is a string, parse it as a font specifier.
19904 *
19905 * Note that following is not done here and have to be done after the call:
19906 * - Not all font options are set (vadjust, mod)
19907 *
19908 * @param {object} outOptions out-parameter, object in which to store the parse results (if any)
19909 * @param {object} inOptions font options to parse
19910 * @returns {boolean} true if font parsed as string, false otherwise
19911 * @static
19912 */
19913
19914 }, {
19915 key: "constrain",
19916 value:
19917 /**
19918 * Set the width and height constraints based on 'nearest' value
19919 *
19920 * @param {Array} pile array of option objects to consider
19921 * @returns {object} the actual constraint values to use
19922 * @private
19923 */
19924 function constrain(pile) {
19925 // NOTE: constrainWidth and constrainHeight never set!
19926 // NOTE: for edge labels, only 'maxWdt' set
19927 // Node labels can set all the fields
19928 var fontOptions = {
19929 constrainWidth: false,
19930 maxWdt: -1,
19931 minWdt: -1,
19932 constrainHeight: false,
19933 minHgt: -1,
19934 valign: "middle"
19935 };
19936 var widthConstraint = topMost(pile, "widthConstraint");
19937
19938 if (typeof widthConstraint === "number") {
19939 fontOptions.maxWdt = Number(widthConstraint);
19940 fontOptions.minWdt = Number(widthConstraint);
19941 } else if (_typeof(widthConstraint) === "object") {
19942 var widthConstraintMaximum = topMost(pile, ["widthConstraint", "maximum"]);
19943
19944 if (typeof widthConstraintMaximum === "number") {
19945 fontOptions.maxWdt = Number(widthConstraintMaximum);
19946 }
19947
19948 var widthConstraintMinimum = topMost(pile, ["widthConstraint", "minimum"]);
19949
19950 if (typeof widthConstraintMinimum === "number") {
19951 fontOptions.minWdt = Number(widthConstraintMinimum);
19952 }
19953 }
19954
19955 var heightConstraint = topMost(pile, "heightConstraint");
19956
19957 if (typeof heightConstraint === "number") {
19958 fontOptions.minHgt = Number(heightConstraint);
19959 } else if (_typeof(heightConstraint) === "object") {
19960 var heightConstraintMinimum = topMost(pile, ["heightConstraint", "minimum"]);
19961
19962 if (typeof heightConstraintMinimum === "number") {
19963 fontOptions.minHgt = Number(heightConstraintMinimum);
19964 }
19965
19966 var heightConstraintValign = topMost(pile, ["heightConstraint", "valign"]);
19967
19968 if (typeof heightConstraintValign === "string") {
19969 if (heightConstraintValign === "top" || heightConstraintValign === "bottom") {
19970 fontOptions.valign = heightConstraintValign;
19971 }
19972 }
19973 }
19974
19975 return fontOptions;
19976 }
19977 /**
19978 * Set options and update internal state
19979 *
19980 * @param {object} options options to set
19981 * @param {Array} pile array of option objects to consider for option 'chosen'
19982 */
19983
19984 }, {
19985 key: "update",
19986 value: function update(options, pile) {
19987 this.setOptions(options, true);
19988 this.propagateFonts(pile);
19989 deepExtend(this.fontOptions, this.constrain(pile));
19990 this.fontOptions.chooser = choosify("label", pile);
19991 }
19992 /**
19993 * When margins are set in an element, adjust sizes is called to remove them
19994 * from the width/height constraints. This must be done prior to label sizing.
19995 *
19996 * @param {{top: number, right: number, bottom: number, left: number}} margins
19997 */
19998
19999 }, {
20000 key: "adjustSizes",
20001 value: function adjustSizes(margins) {
20002 var widthBias = margins ? margins.right + margins.left : 0;
20003
20004 if (this.fontOptions.constrainWidth) {
20005 this.fontOptions.maxWdt -= widthBias;
20006 this.fontOptions.minWdt -= widthBias;
20007 }
20008
20009 var heightBias = margins ? margins.top + margins.bottom : 0;
20010
20011 if (this.fontOptions.constrainHeight) {
20012 this.fontOptions.minHgt -= heightBias;
20013 }
20014 } /////////////////////////////////////////////////////////
20015 // Methods for handling options piles
20016 // Eventually, these will be moved to a separate class
20017 /////////////////////////////////////////////////////////
20018
20019 /**
20020 * Add the font members of the passed list of option objects to the pile.
20021 *
20022 * @param {Pile} dstPile pile of option objects add to
20023 * @param {Pile} srcPile pile of option objects to take font options from
20024 * @private
20025 */
20026
20027 }, {
20028 key: "addFontOptionsToPile",
20029 value: function addFontOptionsToPile(dstPile, srcPile) {
20030 for (var i = 0; i < srcPile.length; ++i) {
20031 this.addFontToPile(dstPile, srcPile[i]);
20032 }
20033 }
20034 /**
20035 * Add given font option object to the list of objects (the 'pile') to consider for determining
20036 * multi-font option values.
20037 *
20038 * @param {Pile} pile pile of option objects to use
20039 * @param {object} options instance to add to pile
20040 * @private
20041 */
20042
20043 }, {
20044 key: "addFontToPile",
20045 value: function addFontToPile(pile, options) {
20046 if (options === undefined) return;
20047 if (options.font === undefined || options.font === null) return;
20048 var item = options.font;
20049 pile.push(item);
20050 }
20051 /**
20052 * Collect all own-property values from the font pile that aren't multi-font option objectss.
20053 *
20054 * @param {Pile} pile pile of option objects to use
20055 * @returns {object} object with all current own basic font properties
20056 * @private
20057 */
20058
20059 }, {
20060 key: "getBasicOptions",
20061 value: function getBasicOptions(pile) {
20062 var ret = {}; // Scans the whole pile to get all options present
20063
20064 for (var n = 0; n < pile.length; ++n) {
20065 var fontOptions = pile[n]; // Convert shorthand if necessary
20066
20067 var tmpShorthand = {};
20068
20069 if (Label.parseFontString(tmpShorthand, fontOptions)) {
20070 fontOptions = tmpShorthand;
20071 }
20072
20073 forEach$1(fontOptions, function (opt, name) {
20074 if (opt === undefined) return; // multi-font option need not be present
20075
20076 if (Object.prototype.hasOwnProperty.call(ret, name)) return; // Keep first value we encounter
20077
20078 if (indexOf(multiFontStyle).call(multiFontStyle, name) !== -1) {
20079 // Skip multi-font properties but we do need the structure
20080 ret[name] = {};
20081 } else {
20082 ret[name] = opt;
20083 }
20084 });
20085 }
20086
20087 return ret;
20088 }
20089 /**
20090 * Return the value for given option for the given multi-font.
20091 *
20092 * All available option objects are trawled in the set order to construct the option values.
20093 *
20094 * ---------------------------------------------------------------------
20095 * ## Traversal of pile for multi-fonts
20096 *
20097 * The determination of multi-font option values is a special case, because any values not
20098 * present in the multi-font options should by definition be taken from the main font options,
20099 * i.e. from the current 'parent' object of the multi-font option.
20100 *
20101 * ### Search order for multi-fonts
20102 *
20103 * 'bold' used as example:
20104 *
20105 * - search in option group 'bold' in local properties
20106 * - search in main font option group in local properties
20107 *
20108 * ---------------------------------------------------------------------
20109 *
20110 * @param {Pile} pile pile of option objects to use
20111 * @param {MultiFontStyle} multiName sub path for the multi-font
20112 * @param {string} option the option to search for, for the given multi-font
20113 * @returns {string|number} the value for the given option
20114 * @private
20115 */
20116
20117 }, {
20118 key: "getFontOption",
20119 value: function getFontOption(pile, multiName, option) {
20120 var multiFont; // Search multi font in local properties
20121
20122 for (var n = 0; n < pile.length; ++n) {
20123 var fontOptions = pile[n];
20124
20125 if (Object.prototype.hasOwnProperty.call(fontOptions, multiName)) {
20126 multiFont = fontOptions[multiName];
20127 if (multiFont === undefined || multiFont === null) continue; // Convert shorthand if necessary
20128 // TODO: inefficient to do this conversion every time; find a better way.
20129
20130 var tmpShorthand = {};
20131
20132 if (Label.parseFontString(tmpShorthand, multiFont)) {
20133 multiFont = tmpShorthand;
20134 }
20135
20136 if (Object.prototype.hasOwnProperty.call(multiFont, option)) {
20137 return multiFont[option];
20138 }
20139 }
20140 } // Option is not mentioned in the multi font options; take it from the parent font options.
20141 // These have already been converted with getBasicOptions(), so use the converted values.
20142
20143
20144 if (Object.prototype.hasOwnProperty.call(this.fontOptions, option)) {
20145 return this.fontOptions[option];
20146 } // A value **must** be found; you should never get here.
20147
20148
20149 throw new Error("Did not find value for multi-font for property: '" + option + "'");
20150 }
20151 /**
20152 * Return all options values for the given multi-font.
20153 *
20154 * All available option objects are trawled in the set order to construct the option values.
20155 *
20156 * @param {Pile} pile pile of option objects to use
20157 * @param {MultiFontStyle} multiName sub path for the mod-font
20158 * @returns {MultiFontOptions}
20159 * @private
20160 */
20161
20162 }, {
20163 key: "getFontOptions",
20164 value: function getFontOptions(pile, multiName) {
20165 var result = {};
20166 var optionNames = ["color", "size", "face", "mod", "vadjust"]; // List of allowed options per multi-font
20167
20168 for (var i = 0; i < optionNames.length; ++i) {
20169 var mod = optionNames[i];
20170 result[mod] = this.getFontOption(pile, multiName, mod);
20171 }
20172
20173 return result;
20174 } /////////////////////////////////////////////////////////
20175 // End methods for handling options piles
20176 /////////////////////////////////////////////////////////
20177
20178 /**
20179 * Collapse the font options for the multi-font to single objects, from
20180 * the chain of option objects passed (the 'pile').
20181 *
20182 * @param {Pile} pile sequence of option objects to consider.
20183 * First item in list assumed to be the newly set options.
20184 */
20185
20186 }, {
20187 key: "propagateFonts",
20188 value: function propagateFonts(pile) {
20189 var _this2 = this;
20190
20191 var fontPile = []; // sequence of font objects to consider, order important
20192 // Note that this.elementOptions is not used here.
20193
20194 this.addFontOptionsToPile(fontPile, pile);
20195 this.fontOptions = this.getBasicOptions(fontPile); // We set multifont values even if multi === false, for consistency (things break otherwise)
20196
20197 var _loop = function _loop(i) {
20198 var mod = multiFontStyle[i];
20199 var modOptions = _this2.fontOptions[mod];
20200
20201 var tmpMultiFontOptions = _this2.getFontOptions(fontPile, mod); // Copy over found values
20202
20203
20204 forEach$1(tmpMultiFontOptions, function (option, n) {
20205 modOptions[n] = option;
20206 });
20207 modOptions.size = Number(modOptions.size);
20208 modOptions.vadjust = Number(modOptions.vadjust);
20209 };
20210
20211 for (var i = 0; i < multiFontStyle.length; ++i) {
20212 _loop(i);
20213 }
20214 }
20215 /**
20216 * Main function. This is called from anything that wants to draw a label.
20217 *
20218 * @param {CanvasRenderingContext2D} ctx
20219 * @param {number} x
20220 * @param {number} y
20221 * @param {boolean} selected
20222 * @param {boolean} hover
20223 * @param {string} [baseline='middle']
20224 */
20225
20226 }, {
20227 key: "draw",
20228 value: function draw(ctx, x, y, selected, hover) {
20229 var baseline = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : "middle";
20230 // if no label, return
20231 if (this.elementOptions.label === undefined) return; // check if we have to render the label
20232
20233 var viewFontSize = this.fontOptions.size * this.body.view.scale;
20234 if (this.elementOptions.label && viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1) return; // This ensures that there will not be HUGE letters on screen
20235 // by setting an upper limit on the visible text size (regardless of zoomLevel)
20236
20237 if (viewFontSize >= this.elementOptions.scaling.label.maxVisible) {
20238 viewFontSize = Number(this.elementOptions.scaling.label.maxVisible) / this.body.view.scale;
20239 } // update the size cache if required
20240
20241
20242 this.calculateLabelSize(ctx, selected, hover, x, y, baseline);
20243
20244 this._drawBackground(ctx);
20245
20246 this._drawText(ctx, x, this.size.yLine, baseline, viewFontSize);
20247 }
20248 /**
20249 * Draws the label background
20250 *
20251 * @param {CanvasRenderingContext2D} ctx
20252 * @private
20253 */
20254
20255 }, {
20256 key: "_drawBackground",
20257 value: function _drawBackground(ctx) {
20258 if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") {
20259 ctx.fillStyle = this.fontOptions.background;
20260 var size = this.getSize();
20261 ctx.fillRect(size.left, size.top, size.width, size.height);
20262 }
20263 }
20264 /**
20265 *
20266 * @param {CanvasRenderingContext2D} ctx
20267 * @param {number} x
20268 * @param {number} y
20269 * @param {string} [baseline='middle']
20270 * @param {number} viewFontSize
20271 * @private
20272 */
20273
20274 }, {
20275 key: "_drawText",
20276 value: function _drawText(ctx, x, y) {
20277 var baseline = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "middle";
20278 var viewFontSize = arguments.length > 4 ? arguments[4] : undefined;
20279
20280 var _this$_setAlignment = this._setAlignment(ctx, x, y, baseline);
20281
20282 var _this$_setAlignment2 = _slicedToArray(_this$_setAlignment, 2);
20283
20284 x = _this$_setAlignment2[0];
20285 y = _this$_setAlignment2[1];
20286 ctx.textAlign = "left";
20287 x = x - this.size.width / 2; // Shift label 1/2-distance to the left
20288
20289 if (this.fontOptions.valign && this.size.height > this.size.labelHeight) {
20290 if (this.fontOptions.valign === "top") {
20291 y -= (this.size.height - this.size.labelHeight) / 2;
20292 }
20293
20294 if (this.fontOptions.valign === "bottom") {
20295 y += (this.size.height - this.size.labelHeight) / 2;
20296 }
20297 } // draw the text
20298
20299
20300 for (var i = 0; i < this.lineCount; i++) {
20301 var line = this.lines[i];
20302
20303 if (line && line.blocks) {
20304 var width = 0;
20305
20306 if (this.isEdgeLabel || this.fontOptions.align === "center") {
20307 width += (this.size.width - line.width) / 2;
20308 } else if (this.fontOptions.align === "right") {
20309 width += this.size.width - line.width;
20310 }
20311
20312 for (var j = 0; j < line.blocks.length; j++) {
20313 var block = line.blocks[j];
20314 ctx.font = block.font;
20315
20316 var _this$_getColor = this._getColor(block.color, viewFontSize, block.strokeColor),
20317 _this$_getColor2 = _slicedToArray(_this$_getColor, 2),
20318 fontColor = _this$_getColor2[0],
20319 strokeColor = _this$_getColor2[1];
20320
20321 if (block.strokeWidth > 0) {
20322 ctx.lineWidth = block.strokeWidth;
20323 ctx.strokeStyle = strokeColor;
20324 ctx.lineJoin = "round";
20325 }
20326
20327 ctx.fillStyle = fontColor;
20328
20329 if (block.strokeWidth > 0) {
20330 ctx.strokeText(block.text, x + width, y + block.vadjust);
20331 }
20332
20333 ctx.fillText(block.text, x + width, y + block.vadjust);
20334 width += block.width;
20335 }
20336
20337 y += line.height;
20338 }
20339 }
20340 }
20341 /**
20342 *
20343 * @param {CanvasRenderingContext2D} ctx
20344 * @param {number} x
20345 * @param {number} y
20346 * @param {string} baseline
20347 * @returns {Array.<number>}
20348 * @private
20349 */
20350
20351 }, {
20352 key: "_setAlignment",
20353 value: function _setAlignment(ctx, x, y, baseline) {
20354 // check for label alignment (for edges)
20355 // TODO: make alignment for nodes
20356 if (this.isEdgeLabel && this.fontOptions.align !== "horizontal" && this.pointToSelf === false) {
20357 x = 0;
20358 y = 0;
20359 var lineMargin = 2;
20360
20361 if (this.fontOptions.align === "top") {
20362 ctx.textBaseline = "alphabetic";
20363 y -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers
20364 } else if (this.fontOptions.align === "bottom") {
20365 ctx.textBaseline = "hanging";
20366 y += 2 * lineMargin; // distance from edge, required because we use hanging. Hanging has less difference between browsers
20367 } else {
20368 ctx.textBaseline = "middle";
20369 }
20370 } else {
20371 ctx.textBaseline = baseline;
20372 }
20373
20374 return [x, y];
20375 }
20376 /**
20377 * fade in when relative scale is between threshold and threshold - 1.
20378 * If the relative scale would be smaller than threshold -1 the draw function would have returned before coming here.
20379 *
20380 * @param {string} color The font color to use
20381 * @param {number} viewFontSize
20382 * @param {string} initialStrokeColor
20383 * @returns {Array.<string>} An array containing the font color and stroke color
20384 * @private
20385 */
20386
20387 }, {
20388 key: "_getColor",
20389 value: function _getColor(color, viewFontSize, initialStrokeColor) {
20390 var fontColor = color || "#000000";
20391 var strokeColor = initialStrokeColor || "#ffffff";
20392
20393 if (viewFontSize <= this.elementOptions.scaling.label.drawThreshold) {
20394 var opacity = Math.max(0, Math.min(1, 1 - (this.elementOptions.scaling.label.drawThreshold - viewFontSize)));
20395 fontColor = overrideOpacity(fontColor, opacity);
20396 strokeColor = overrideOpacity(strokeColor, opacity);
20397 }
20398
20399 return [fontColor, strokeColor];
20400 }
20401 /**
20402 *
20403 * @param {CanvasRenderingContext2D} ctx
20404 * @param {boolean} selected
20405 * @param {boolean} hover
20406 * @returns {{width: number, height: number}}
20407 */
20408
20409 }, {
20410 key: "getTextSize",
20411 value: function getTextSize(ctx) {
20412 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
20413 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
20414
20415 this._processLabel(ctx, selected, hover);
20416
20417 return {
20418 width: this.size.width,
20419 height: this.size.height,
20420 lineCount: this.lineCount
20421 };
20422 }
20423 /**
20424 * Get the current dimensions of the label
20425 *
20426 * @returns {rect}
20427 */
20428
20429 }, {
20430 key: "getSize",
20431 value: function getSize() {
20432 var lineMargin = 2;
20433 var x = this.size.left; // default values which might be overridden below
20434
20435 var y = this.size.top - 0.5 * lineMargin; // idem
20436
20437 if (this.isEdgeLabel) {
20438 var x2 = -this.size.width * 0.5;
20439
20440 switch (this.fontOptions.align) {
20441 case "middle":
20442 x = x2;
20443 y = -this.size.height * 0.5;
20444 break;
20445
20446 case "top":
20447 x = x2;
20448 y = -(this.size.height + lineMargin);
20449 break;
20450
20451 case "bottom":
20452 x = x2;
20453 y = lineMargin;
20454 break;
20455 }
20456 }
20457
20458 var ret = {
20459 left: x,
20460 top: y,
20461 width: this.size.width,
20462 height: this.size.height
20463 };
20464 return ret;
20465 }
20466 /**
20467 *
20468 * @param {CanvasRenderingContext2D} ctx
20469 * @param {boolean} selected
20470 * @param {boolean} hover
20471 * @param {number} [x=0]
20472 * @param {number} [y=0]
20473 * @param {'middle'|'hanging'} [baseline='middle']
20474 */
20475
20476 }, {
20477 key: "calculateLabelSize",
20478 value: function calculateLabelSize(ctx, selected, hover) {
20479 var x = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
20480 var y = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
20481 var baseline = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : "middle";
20482
20483 this._processLabel(ctx, selected, hover);
20484
20485 this.size.left = x - this.size.width * 0.5;
20486 this.size.top = y - this.size.height * 0.5;
20487 this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.fontOptions.size;
20488
20489 if (baseline === "hanging") {
20490 this.size.top += 0.5 * this.fontOptions.size;
20491 this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers
20492
20493 this.size.yLine += 4; // distance from node
20494 }
20495 }
20496 /**
20497 *
20498 * @param {CanvasRenderingContext2D} ctx
20499 * @param {boolean} selected
20500 * @param {boolean} hover
20501 * @param {string} mod
20502 * @returns {{color, size, face, mod, vadjust, strokeWidth: *, strokeColor: (*|string|allOptions.edges.font.strokeColor|{string}|allOptions.nodes.font.strokeColor|Array)}}
20503 */
20504
20505 }, {
20506 key: "getFormattingValues",
20507 value: function getFormattingValues(ctx, selected, hover, mod) {
20508 var getValue = function getValue(fontOptions, mod, option) {
20509 if (mod === "normal") {
20510 if (option === "mod") return "";
20511 return fontOptions[option];
20512 }
20513
20514 if (fontOptions[mod][option] !== undefined) {
20515 // Grumbl leaving out test on undefined equals false for ""
20516 return fontOptions[mod][option];
20517 } else {
20518 // Take from parent font option
20519 return fontOptions[option];
20520 }
20521 };
20522
20523 var values = {
20524 color: getValue(this.fontOptions, mod, "color"),
20525 size: getValue(this.fontOptions, mod, "size"),
20526 face: getValue(this.fontOptions, mod, "face"),
20527 mod: getValue(this.fontOptions, mod, "mod"),
20528 vadjust: getValue(this.fontOptions, mod, "vadjust"),
20529 strokeWidth: this.fontOptions.strokeWidth,
20530 strokeColor: this.fontOptions.strokeColor
20531 };
20532
20533 if (selected || hover) {
20534 if (mod === "normal" && this.fontOptions.chooser === true && this.elementOptions.labelHighlightBold) {
20535 values.mod = "bold";
20536 } else {
20537 if (typeof this.fontOptions.chooser === "function") {
20538 this.fontOptions.chooser(values, this.elementOptions.id, selected, hover);
20539 }
20540 }
20541 }
20542
20543 var fontString = "";
20544
20545 if (values.mod !== undefined && values.mod !== "") {
20546 // safeguard for undefined - this happened
20547 fontString += values.mod + " ";
20548 }
20549
20550 fontString += values.size + "px " + values.face;
20551 ctx.font = fontString.replace(/"/g, "");
20552 values.font = ctx.font;
20553 values.height = values.size;
20554 return values;
20555 }
20556 /**
20557 *
20558 * @param {boolean} selected
20559 * @param {boolean} hover
20560 * @returns {boolean}
20561 */
20562
20563 }, {
20564 key: "differentState",
20565 value: function differentState(selected, hover) {
20566 return selected !== this.selectedState || hover !== this.hoverState;
20567 }
20568 /**
20569 * This explodes the passed text into lines and determines the width, height and number of lines.
20570 *
20571 * @param {CanvasRenderingContext2D} ctx
20572 * @param {boolean} selected
20573 * @param {boolean} hover
20574 * @param {string} inText the text to explode
20575 * @returns {{width, height, lines}|*}
20576 * @private
20577 */
20578
20579 }, {
20580 key: "_processLabelText",
20581 value: function _processLabelText(ctx, selected, hover, inText) {
20582 var splitter = new LabelSplitter(ctx, this, selected, hover);
20583 return splitter.process(inText);
20584 }
20585 /**
20586 * This explodes the label string into lines and sets the width, height and number of lines.
20587 *
20588 * @param {CanvasRenderingContext2D} ctx
20589 * @param {boolean} selected
20590 * @param {boolean} hover
20591 * @private
20592 */
20593
20594 }, {
20595 key: "_processLabel",
20596 value: function _processLabel(ctx, selected, hover) {
20597 if (this.labelDirty === false && !this.differentState(selected, hover)) return;
20598
20599 var state = this._processLabelText(ctx, selected, hover, this.elementOptions.label);
20600
20601 if (this.fontOptions.minWdt > 0 && state.width < this.fontOptions.minWdt) {
20602 state.width = this.fontOptions.minWdt;
20603 }
20604
20605 this.size.labelHeight = state.height;
20606
20607 if (this.fontOptions.minHgt > 0 && state.height < this.fontOptions.minHgt) {
20608 state.height = this.fontOptions.minHgt;
20609 }
20610
20611 this.lines = state.lines;
20612 this.lineCount = state.lines.length;
20613 this.size.width = state.width;
20614 this.size.height = state.height;
20615 this.selectedState = selected;
20616 this.hoverState = hover;
20617 this.labelDirty = false;
20618 }
20619 /**
20620 * Check if this label is visible
20621 *
20622 * @returns {boolean} true if this label will be show, false otherwise
20623 */
20624
20625 }, {
20626 key: "visible",
20627 value: function visible() {
20628 if (this.size.width === 0 || this.size.height === 0 || this.elementOptions.label === undefined) {
20629 return false; // nothing to display
20630 }
20631
20632 var viewFontSize = this.fontOptions.size * this.body.view.scale;
20633
20634 if (viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1) {
20635 return false; // Too small or too far away to show
20636 }
20637
20638 return true;
20639 }
20640 }], [{
20641 key: "parseFontString",
20642 value: function parseFontString(outOptions, inOptions) {
20643 if (!inOptions || typeof inOptions !== "string") return false;
20644 var newOptionsArray = inOptions.split(" ");
20645 outOptions.size = +newOptionsArray[0].replace("px", "");
20646 outOptions.face = newOptionsArray[1];
20647 outOptions.color = newOptionsArray[2];
20648 return true;
20649 }
20650 }]);
20651
20652 return Label;
20653}();
20654
20655/**
20656 * The Base class for all Nodes.
20657 */
20658var NodeBase = /*#__PURE__*/function () {
20659 /**
20660 * @param {object} options
20661 * @param {object} body
20662 * @param {Label} labelModule
20663 */
20664 function NodeBase(options, body, labelModule) {
20665 _classCallCheck(this, NodeBase);
20666
20667 this.body = body;
20668 this.labelModule = labelModule;
20669 this.setOptions(options);
20670 this.top = undefined;
20671 this.left = undefined;
20672 this.height = undefined;
20673 this.width = undefined;
20674 this.radius = undefined;
20675 this.margin = undefined;
20676 this.refreshNeeded = true;
20677 this.boundingBox = {
20678 top: 0,
20679 left: 0,
20680 right: 0,
20681 bottom: 0
20682 };
20683 }
20684 /**
20685 *
20686 * @param {object} options
20687 */
20688
20689
20690 _createClass(NodeBase, [{
20691 key: "setOptions",
20692 value: function setOptions(options) {
20693 this.options = options;
20694 }
20695 /**
20696 *
20697 * @param {Label} labelModule
20698 * @private
20699 */
20700
20701 }, {
20702 key: "_setMargins",
20703 value: function _setMargins(labelModule) {
20704 this.margin = {};
20705
20706 if (this.options.margin) {
20707 if (_typeof(this.options.margin) == "object") {
20708 this.margin.top = this.options.margin.top;
20709 this.margin.right = this.options.margin.right;
20710 this.margin.bottom = this.options.margin.bottom;
20711 this.margin.left = this.options.margin.left;
20712 } else {
20713 this.margin.top = this.options.margin;
20714 this.margin.right = this.options.margin;
20715 this.margin.bottom = this.options.margin;
20716 this.margin.left = this.options.margin;
20717 }
20718 }
20719
20720 labelModule.adjustSizes(this.margin);
20721 }
20722 /**
20723 *
20724 * @param {CanvasRenderingContext2D} ctx
20725 * @param {number} angle
20726 * @returns {number}
20727 * @private
20728 */
20729
20730 }, {
20731 key: "_distanceToBorder",
20732 value: function _distanceToBorder(ctx, angle) {
20733 var borderWidth = this.options.borderWidth;
20734
20735 if (ctx) {
20736 this.resize(ctx);
20737 }
20738
20739 return Math.min(Math.abs(this.width / 2 / Math.cos(angle)), Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
20740 }
20741 /**
20742 *
20743 * @param {CanvasRenderingContext2D} ctx
20744 * @param {ArrowOptions} values
20745 */
20746
20747 }, {
20748 key: "enableShadow",
20749 value: function enableShadow(ctx, values) {
20750 if (values.shadow) {
20751 ctx.shadowColor = values.shadowColor;
20752 ctx.shadowBlur = values.shadowSize;
20753 ctx.shadowOffsetX = values.shadowX;
20754 ctx.shadowOffsetY = values.shadowY;
20755 }
20756 }
20757 /**
20758 *
20759 * @param {CanvasRenderingContext2D} ctx
20760 * @param {ArrowOptions} values
20761 */
20762
20763 }, {
20764 key: "disableShadow",
20765 value: function disableShadow(ctx, values) {
20766 if (values.shadow) {
20767 ctx.shadowColor = "rgba(0,0,0,0)";
20768 ctx.shadowBlur = 0;
20769 ctx.shadowOffsetX = 0;
20770 ctx.shadowOffsetY = 0;
20771 }
20772 }
20773 /**
20774 *
20775 * @param {CanvasRenderingContext2D} ctx
20776 * @param {ArrowOptions} values
20777 */
20778
20779 }, {
20780 key: "enableBorderDashes",
20781 value: function enableBorderDashes(ctx, values) {
20782 if (values.borderDashes !== false) {
20783 if (ctx.setLineDash !== undefined) {
20784 var dashes = values.borderDashes;
20785
20786 if (dashes === true) {
20787 dashes = [5, 15];
20788 }
20789
20790 ctx.setLineDash(dashes);
20791 } else {
20792 console.warn("setLineDash is not supported in this browser. The dashed borders cannot be used.");
20793 this.options.shapeProperties.borderDashes = false;
20794 values.borderDashes = false;
20795 }
20796 }
20797 }
20798 /**
20799 *
20800 * @param {CanvasRenderingContext2D} ctx
20801 * @param {ArrowOptions} values
20802 */
20803
20804 }, {
20805 key: "disableBorderDashes",
20806 value: function disableBorderDashes(ctx, values) {
20807 if (values.borderDashes !== false) {
20808 if (ctx.setLineDash !== undefined) {
20809 ctx.setLineDash([0]);
20810 } else {
20811 console.warn("setLineDash is not supported in this browser. The dashed borders cannot be used.");
20812 this.options.shapeProperties.borderDashes = false;
20813 values.borderDashes = false;
20814 }
20815 }
20816 }
20817 /**
20818 * Determine if the shape of a node needs to be recalculated.
20819 *
20820 * @param {boolean} selected
20821 * @param {boolean} hover
20822 * @returns {boolean}
20823 * @protected
20824 */
20825
20826 }, {
20827 key: "needsRefresh",
20828 value: function needsRefresh(selected, hover) {
20829 if (this.refreshNeeded === true) {
20830 // This is probably not the best location to reset this member.
20831 // However, in the current logic, it is the most convenient one.
20832 this.refreshNeeded = false;
20833 return true;
20834 }
20835
20836 return this.width === undefined || this.labelModule.differentState(selected, hover);
20837 }
20838 /**
20839 *
20840 * @param {CanvasRenderingContext2D} ctx
20841 * @param {ArrowOptions} values
20842 */
20843
20844 }, {
20845 key: "initContextForDraw",
20846 value: function initContextForDraw(ctx, values) {
20847 var borderWidth = values.borderWidth / this.body.view.scale;
20848 ctx.lineWidth = Math.min(this.width, borderWidth);
20849 ctx.strokeStyle = values.borderColor;
20850 ctx.fillStyle = values.color;
20851 }
20852 /**
20853 *
20854 * @param {CanvasRenderingContext2D} ctx
20855 * @param {ArrowOptions} values
20856 */
20857
20858 }, {
20859 key: "performStroke",
20860 value: function performStroke(ctx, values) {
20861 var borderWidth = values.borderWidth / this.body.view.scale; //draw dashed border if enabled, save and restore is required for firefox not to crash on unix.
20862
20863 ctx.save(); // if borders are zero width, they will be drawn with width 1 by default. This prevents that
20864
20865 if (borderWidth > 0) {
20866 this.enableBorderDashes(ctx, values); //draw the border
20867
20868 ctx.stroke(); //disable dashed border for other elements
20869
20870 this.disableBorderDashes(ctx, values);
20871 }
20872
20873 ctx.restore();
20874 }
20875 /**
20876 *
20877 * @param {CanvasRenderingContext2D} ctx
20878 * @param {ArrowOptions} values
20879 */
20880
20881 }, {
20882 key: "performFill",
20883 value: function performFill(ctx, values) {
20884 ctx.save();
20885 ctx.fillStyle = values.color; // draw shadow if enabled
20886
20887 this.enableShadow(ctx, values); // draw the background
20888
20889 fill(ctx).call(ctx); // disable shadows for other elements.
20890
20891
20892 this.disableShadow(ctx, values);
20893 ctx.restore();
20894 this.performStroke(ctx, values);
20895 }
20896 /**
20897 *
20898 * @param {number} margin
20899 * @private
20900 */
20901
20902 }, {
20903 key: "_addBoundingBoxMargin",
20904 value: function _addBoundingBoxMargin(margin) {
20905 this.boundingBox.left -= margin;
20906 this.boundingBox.top -= margin;
20907 this.boundingBox.bottom += margin;
20908 this.boundingBox.right += margin;
20909 }
20910 /**
20911 * Actual implementation of this method call.
20912 *
20913 * Doing it like this makes it easier to override
20914 * in the child classes.
20915 *
20916 * @param {number} x width
20917 * @param {number} y height
20918 * @param {CanvasRenderingContext2D} ctx
20919 * @param {boolean} selected
20920 * @param {boolean} hover
20921 * @private
20922 */
20923
20924 }, {
20925 key: "_updateBoundingBox",
20926 value: function _updateBoundingBox(x, y, ctx, selected, hover) {
20927 if (ctx !== undefined) {
20928 this.resize(ctx, selected, hover);
20929 }
20930
20931 this.left = x - this.width / 2;
20932 this.top = y - this.height / 2;
20933 this.boundingBox.left = this.left;
20934 this.boundingBox.top = this.top;
20935 this.boundingBox.bottom = this.top + this.height;
20936 this.boundingBox.right = this.left + this.width;
20937 }
20938 /**
20939 * Default implementation of this method call.
20940 * This acts as a stub which can be overridden.
20941 *
20942 * @param {number} x width
20943 * @param {number} y height
20944 * @param {CanvasRenderingContext2D} ctx
20945 * @param {boolean} selected
20946 * @param {boolean} hover
20947 */
20948
20949 }, {
20950 key: "updateBoundingBox",
20951 value: function updateBoundingBox(x, y, ctx, selected, hover) {
20952 this._updateBoundingBox(x, y, ctx, selected, hover);
20953 }
20954 /**
20955 * Determine the dimensions to use for nodes with an internal label
20956 *
20957 * Currently, these are: Circle, Ellipse, Database, Box
20958 * The other nodes have external labels, and will not call this method
20959 *
20960 * If there is no label, decent default values are supplied.
20961 *
20962 * @param {CanvasRenderingContext2D} ctx
20963 * @param {boolean} [selected]
20964 * @param {boolean} [hover]
20965 * @returns {{width:number, height:number}}
20966 */
20967
20968 }, {
20969 key: "getDimensionsFromLabel",
20970 value: function getDimensionsFromLabel(ctx, selected, hover) {
20971 // NOTE: previously 'textSize' was not put in 'this' for Ellipse
20972 // TODO: examine the consequences.
20973 this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
20974 var width = this.textSize.width;
20975 var height = this.textSize.height;
20976 var DEFAULT_SIZE = 14;
20977
20978 if (width === 0) {
20979 // This happens when there is no label text set
20980 width = DEFAULT_SIZE; // use a decent default
20981
20982 height = DEFAULT_SIZE; // if width zero, then height also always zero
20983 }
20984
20985 return {
20986 width: width,
20987 height: height
20988 };
20989 }
20990 }]);
20991
20992 return NodeBase;
20993}();
20994
20995function _createSuper$s(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$s(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
20996
20997function _isNativeReflectConstruct$s() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
20998/**
20999 * A Box Node/Cluster shape.
21000 *
21001 * @augments NodeBase
21002 */
21003
21004var Box$1 = /*#__PURE__*/function (_NodeBase) {
21005 _inherits(Box, _NodeBase);
21006
21007 var _super = _createSuper$s(Box);
21008
21009 /**
21010 * @param {object} options
21011 * @param {object} body
21012 * @param {Label} labelModule
21013 */
21014 function Box(options, body, labelModule) {
21015 var _this;
21016
21017 _classCallCheck(this, Box);
21018
21019 _this = _super.call(this, options, body, labelModule);
21020
21021 _this._setMargins(labelModule);
21022
21023 return _this;
21024 }
21025 /**
21026 *
21027 * @param {CanvasRenderingContext2D} ctx
21028 * @param {boolean} [selected]
21029 * @param {boolean} [hover]
21030 */
21031
21032
21033 _createClass(Box, [{
21034 key: "resize",
21035 value: function resize(ctx) {
21036 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
21037 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
21038
21039 if (this.needsRefresh(selected, hover)) {
21040 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
21041 this.width = dimensions.width + this.margin.right + this.margin.left;
21042 this.height = dimensions.height + this.margin.top + this.margin.bottom;
21043 this.radius = this.width / 2;
21044 }
21045 }
21046 /**
21047 *
21048 * @param {CanvasRenderingContext2D} ctx
21049 * @param {number} x width
21050 * @param {number} y height
21051 * @param {boolean} selected
21052 * @param {boolean} hover
21053 * @param {ArrowOptions} values
21054 */
21055
21056 }, {
21057 key: "draw",
21058 value: function draw(ctx, x, y, selected, hover, values) {
21059 this.resize(ctx, selected, hover);
21060 this.left = x - this.width / 2;
21061 this.top = y - this.height / 2;
21062 this.initContextForDraw(ctx, values);
21063 drawRoundRect(ctx, this.left, this.top, this.width, this.height, values.borderRadius);
21064 this.performFill(ctx, values);
21065 this.updateBoundingBox(x, y, ctx, selected, hover);
21066 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, this.top + this.textSize.height / 2 + this.margin.top, selected, hover);
21067 }
21068 /**
21069 *
21070 * @param {number} x width
21071 * @param {number} y height
21072 * @param {CanvasRenderingContext2D} ctx
21073 * @param {boolean} selected
21074 * @param {boolean} hover
21075 */
21076
21077 }, {
21078 key: "updateBoundingBox",
21079 value: function updateBoundingBox(x, y, ctx, selected, hover) {
21080 this._updateBoundingBox(x, y, ctx, selected, hover);
21081
21082 var borderRadius = this.options.shapeProperties.borderRadius; // only effective for box
21083
21084 this._addBoundingBoxMargin(borderRadius);
21085 }
21086 /**
21087 *
21088 * @param {CanvasRenderingContext2D} ctx
21089 * @param {number} angle
21090 * @returns {number}
21091 */
21092
21093 }, {
21094 key: "distanceToBorder",
21095 value: function distanceToBorder(ctx, angle) {
21096 if (ctx) {
21097 this.resize(ctx);
21098 }
21099
21100 var borderWidth = this.options.borderWidth;
21101 return Math.min(Math.abs(this.width / 2 / Math.cos(angle)), Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
21102 }
21103 }]);
21104
21105 return Box;
21106}(NodeBase);
21107
21108function _createSuper$r(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$r(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21109
21110function _isNativeReflectConstruct$r() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21111/**
21112 * NOTE: This is a bad base class
21113 *
21114 * Child classes are:
21115 *
21116 * Image - uses *only* image methods
21117 * Circle - uses *only* _drawRawCircle
21118 * CircleImage - uses all
21119 *
21120 * TODO: Refactor, move _drawRawCircle to different module, derive Circle from NodeBase
21121 * Rename this to ImageBase
21122 * Consolidate common code in Image and CircleImage to base class
21123 *
21124 * @augments NodeBase
21125 */
21126
21127var CircleImageBase = /*#__PURE__*/function (_NodeBase) {
21128 _inherits(CircleImageBase, _NodeBase);
21129
21130 var _super = _createSuper$r(CircleImageBase);
21131
21132 /**
21133 * @param {object} options
21134 * @param {object} body
21135 * @param {Label} labelModule
21136 */
21137 function CircleImageBase(options, body, labelModule) {
21138 var _this;
21139
21140 _classCallCheck(this, CircleImageBase);
21141
21142 _this = _super.call(this, options, body, labelModule);
21143 _this.labelOffset = 0;
21144 _this.selected = false;
21145 return _this;
21146 }
21147 /**
21148 *
21149 * @param {object} options
21150 * @param {object} [imageObj]
21151 * @param {object} [imageObjAlt]
21152 */
21153
21154
21155 _createClass(CircleImageBase, [{
21156 key: "setOptions",
21157 value: function setOptions(options, imageObj, imageObjAlt) {
21158 this.options = options;
21159
21160 if (!(imageObj === undefined && imageObjAlt === undefined)) {
21161 this.setImages(imageObj, imageObjAlt);
21162 }
21163 }
21164 /**
21165 * Set the images for this node.
21166 *
21167 * The images can be updated after the initial setting of options;
21168 * therefore, this method needs to be reentrant.
21169 *
21170 * For correct working in error cases, it is necessary to properly set
21171 * field 'nodes.brokenImage' in the options.
21172 *
21173 * @param {Image} imageObj required; main image to show for this node
21174 * @param {Image|undefined} imageObjAlt optional; image to show when node is selected
21175 */
21176
21177 }, {
21178 key: "setImages",
21179 value: function setImages(imageObj, imageObjAlt) {
21180 if (imageObjAlt && this.selected) {
21181 this.imageObj = imageObjAlt;
21182 this.imageObjAlt = imageObj;
21183 } else {
21184 this.imageObj = imageObj;
21185 this.imageObjAlt = imageObjAlt;
21186 }
21187 }
21188 /**
21189 * Set selection and switch between the base and the selected image.
21190 *
21191 * Do the switch only if imageObjAlt exists.
21192 *
21193 * @param {boolean} selected value of new selected state for current node
21194 */
21195
21196 }, {
21197 key: "switchImages",
21198 value: function switchImages(selected) {
21199 var selection_changed = selected && !this.selected || !selected && this.selected;
21200 this.selected = selected; // Remember new selection
21201
21202 if (this.imageObjAlt !== undefined && selection_changed) {
21203 var imageTmp = this.imageObj;
21204 this.imageObj = this.imageObjAlt;
21205 this.imageObjAlt = imageTmp;
21206 }
21207 }
21208 /**
21209 * Returns Image Padding from node options
21210 *
21211 * @returns {{top: number,left: number,bottom: number,right: number}} image padding inside this shape
21212 * @private
21213 */
21214
21215 }, {
21216 key: "_getImagePadding",
21217 value: function _getImagePadding() {
21218 var imgPadding = {
21219 top: 0,
21220 right: 0,
21221 bottom: 0,
21222 left: 0
21223 };
21224
21225 if (this.options.imagePadding) {
21226 var optImgPadding = this.options.imagePadding;
21227
21228 if (_typeof(optImgPadding) == "object") {
21229 imgPadding.top = optImgPadding.top;
21230 imgPadding.right = optImgPadding.right;
21231 imgPadding.bottom = optImgPadding.bottom;
21232 imgPadding.left = optImgPadding.left;
21233 } else {
21234 imgPadding.top = optImgPadding;
21235 imgPadding.right = optImgPadding;
21236 imgPadding.bottom = optImgPadding;
21237 imgPadding.left = optImgPadding;
21238 }
21239 }
21240
21241 return imgPadding;
21242 }
21243 /**
21244 * Adjust the node dimensions for a loaded image.
21245 *
21246 * Pre: this.imageObj is valid
21247 */
21248
21249 }, {
21250 key: "_resizeImage",
21251 value: function _resizeImage() {
21252 var width, height;
21253
21254 if (this.options.shapeProperties.useImageSize === false) {
21255 // Use the size property
21256 var ratio_width = 1;
21257 var ratio_height = 1; // Only calculate the proper ratio if both width and height not zero
21258
21259 if (this.imageObj.width && this.imageObj.height) {
21260 if (this.imageObj.width > this.imageObj.height) {
21261 ratio_width = this.imageObj.width / this.imageObj.height;
21262 } else {
21263 ratio_height = this.imageObj.height / this.imageObj.width;
21264 }
21265 }
21266
21267 width = this.options.size * 2 * ratio_width;
21268 height = this.options.size * 2 * ratio_height;
21269 } else {
21270 // Use the image size with image padding
21271 var imgPadding = this._getImagePadding();
21272
21273 width = this.imageObj.width + imgPadding.left + imgPadding.right;
21274 height = this.imageObj.height + imgPadding.top + imgPadding.bottom;
21275 }
21276
21277 this.width = width;
21278 this.height = height;
21279 this.radius = 0.5 * this.width;
21280 }
21281 /**
21282 *
21283 * @param {CanvasRenderingContext2D} ctx
21284 * @param {number} x width
21285 * @param {number} y height
21286 * @param {ArrowOptions} values
21287 * @private
21288 */
21289
21290 }, {
21291 key: "_drawRawCircle",
21292 value: function _drawRawCircle(ctx, x, y, values) {
21293 this.initContextForDraw(ctx, values);
21294 drawCircle(ctx, x, y, values.size);
21295 this.performFill(ctx, values);
21296 }
21297 /**
21298 *
21299 * @param {CanvasRenderingContext2D} ctx
21300 * @param {ArrowOptions} values
21301 * @private
21302 */
21303
21304 }, {
21305 key: "_drawImageAtPosition",
21306 value: function _drawImageAtPosition(ctx, values) {
21307 if (this.imageObj.width != 0) {
21308 // draw the image
21309 ctx.globalAlpha = values.opacity !== undefined ? values.opacity : 1; // draw shadow if enabled
21310
21311 this.enableShadow(ctx, values);
21312 var factor = 1;
21313
21314 if (this.options.shapeProperties.interpolation === true) {
21315 factor = this.imageObj.width / this.width / this.body.view.scale;
21316 }
21317
21318 var imgPadding = this._getImagePadding();
21319
21320 var imgPosLeft = this.left + imgPadding.left;
21321 var imgPosTop = this.top + imgPadding.top;
21322 var imgWidth = this.width - imgPadding.left - imgPadding.right;
21323 var imgHeight = this.height - imgPadding.top - imgPadding.bottom;
21324 this.imageObj.drawImageAtPosition(ctx, factor, imgPosLeft, imgPosTop, imgWidth, imgHeight); // disable shadows for other elements.
21325
21326 this.disableShadow(ctx, values);
21327 }
21328 }
21329 /**
21330 *
21331 * @param {CanvasRenderingContext2D} ctx
21332 * @param {number} x width
21333 * @param {number} y height
21334 * @param {boolean} selected
21335 * @param {boolean} hover
21336 * @private
21337 */
21338
21339 }, {
21340 key: "_drawImageLabel",
21341 value: function _drawImageLabel(ctx, x, y, selected, hover) {
21342 var offset = 0;
21343
21344 if (this.height !== undefined) {
21345 offset = this.height * 0.5;
21346 var labelDimensions = this.labelModule.getTextSize(ctx, selected, hover);
21347
21348 if (labelDimensions.lineCount >= 1) {
21349 offset += labelDimensions.height / 2;
21350 }
21351 }
21352
21353 var yLabel = y + offset;
21354
21355 if (this.options.label) {
21356 this.labelOffset = offset;
21357 }
21358
21359 this.labelModule.draw(ctx, x, yLabel, selected, hover, "hanging");
21360 }
21361 }]);
21362
21363 return CircleImageBase;
21364}(NodeBase);
21365
21366function _createSuper$q(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$q(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21367
21368function _isNativeReflectConstruct$q() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21369/**
21370 * A Circle Node/Cluster shape.
21371 *
21372 * @augments CircleImageBase
21373 */
21374
21375var Circle$1 = /*#__PURE__*/function (_CircleImageBase) {
21376 _inherits(Circle, _CircleImageBase);
21377
21378 var _super = _createSuper$q(Circle);
21379
21380 /**
21381 * @param {object} options
21382 * @param {object} body
21383 * @param {Label} labelModule
21384 */
21385 function Circle(options, body, labelModule) {
21386 var _this;
21387
21388 _classCallCheck(this, Circle);
21389
21390 _this = _super.call(this, options, body, labelModule);
21391
21392 _this._setMargins(labelModule);
21393
21394 return _this;
21395 }
21396 /**
21397 *
21398 * @param {CanvasRenderingContext2D} ctx
21399 * @param {boolean} [selected]
21400 * @param {boolean} [hover]
21401 */
21402
21403
21404 _createClass(Circle, [{
21405 key: "resize",
21406 value: function resize(ctx) {
21407 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
21408 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
21409
21410 if (this.needsRefresh(selected, hover)) {
21411 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
21412 var diameter = Math.max(dimensions.width + this.margin.right + this.margin.left, dimensions.height + this.margin.top + this.margin.bottom);
21413 this.options.size = diameter / 2; // NOTE: this size field only set here, not in Ellipse, Database, Box
21414
21415 this.width = diameter;
21416 this.height = diameter;
21417 this.radius = this.width / 2;
21418 }
21419 }
21420 /**
21421 *
21422 * @param {CanvasRenderingContext2D} ctx
21423 * @param {number} x width
21424 * @param {number} y height
21425 * @param {boolean} selected
21426 * @param {boolean} hover
21427 * @param {ArrowOptions} values
21428 */
21429
21430 }, {
21431 key: "draw",
21432 value: function draw(ctx, x, y, selected, hover, values) {
21433 this.resize(ctx, selected, hover);
21434 this.left = x - this.width / 2;
21435 this.top = y - this.height / 2;
21436
21437 this._drawRawCircle(ctx, x, y, values);
21438
21439 this.updateBoundingBox(x, y);
21440 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, y, selected, hover);
21441 }
21442 /**
21443 *
21444 * @param {number} x width
21445 * @param {number} y height
21446 */
21447
21448 }, {
21449 key: "updateBoundingBox",
21450 value: function updateBoundingBox(x, y) {
21451 this.boundingBox.top = y - this.options.size;
21452 this.boundingBox.left = x - this.options.size;
21453 this.boundingBox.right = x + this.options.size;
21454 this.boundingBox.bottom = y + this.options.size;
21455 }
21456 /**
21457 *
21458 * @param {CanvasRenderingContext2D} ctx
21459 * @returns {number}
21460 */
21461
21462 }, {
21463 key: "distanceToBorder",
21464 value: function distanceToBorder(ctx) {
21465 if (ctx) {
21466 this.resize(ctx);
21467 }
21468
21469 return this.width * 0.5;
21470 }
21471 }]);
21472
21473 return Circle;
21474}(CircleImageBase);
21475
21476function _createSuper$p(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$p(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21477
21478function _isNativeReflectConstruct$p() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21479/**
21480 * A CircularImage Node/Cluster shape.
21481 *
21482 * @augments CircleImageBase
21483 */
21484
21485var CircularImage = /*#__PURE__*/function (_CircleImageBase) {
21486 _inherits(CircularImage, _CircleImageBase);
21487
21488 var _super = _createSuper$p(CircularImage);
21489
21490 /**
21491 * @param {object} options
21492 * @param {object} body
21493 * @param {Label} labelModule
21494 * @param {Image} imageObj
21495 * @param {Image} imageObjAlt
21496 */
21497 function CircularImage(options, body, labelModule, imageObj, imageObjAlt) {
21498 var _this;
21499
21500 _classCallCheck(this, CircularImage);
21501
21502 _this = _super.call(this, options, body, labelModule);
21503
21504 _this.setImages(imageObj, imageObjAlt);
21505
21506 return _this;
21507 }
21508 /**
21509 *
21510 * @param {CanvasRenderingContext2D} ctx
21511 * @param {boolean} [selected]
21512 * @param {boolean} [hover]
21513 */
21514
21515
21516 _createClass(CircularImage, [{
21517 key: "resize",
21518 value: function resize(ctx) {
21519 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
21520 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
21521 var imageAbsent = this.imageObj.src === undefined || this.imageObj.width === undefined || this.imageObj.height === undefined;
21522
21523 if (imageAbsent) {
21524 var diameter = this.options.size * 2;
21525 this.width = diameter;
21526 this.height = diameter;
21527 this.radius = 0.5 * this.width;
21528 return;
21529 } // At this point, an image is present, i.e. this.imageObj is valid.
21530
21531
21532 if (this.needsRefresh(selected, hover)) {
21533 this._resizeImage();
21534 }
21535 }
21536 /**
21537 *
21538 * @param {CanvasRenderingContext2D} ctx
21539 * @param {number} x width
21540 * @param {number} y height
21541 * @param {boolean} selected
21542 * @param {boolean} hover
21543 * @param {ArrowOptions} values
21544 */
21545
21546 }, {
21547 key: "draw",
21548 value: function draw(ctx, x, y, selected, hover, values) {
21549 this.switchImages(selected);
21550 this.resize();
21551 var labelX = x,
21552 labelY = y;
21553
21554 if (this.options.shapeProperties.coordinateOrigin === "top-left") {
21555 this.left = x;
21556 this.top = y;
21557 labelX += this.width / 2;
21558 labelY += this.height / 2;
21559 } else {
21560 this.left = x - this.width / 2;
21561 this.top = y - this.height / 2;
21562 } // draw the background circle. IMPORTANT: the stroke in this method is used by the clip method below.
21563
21564
21565 this._drawRawCircle(ctx, labelX, labelY, values); // now we draw in the circle, we save so we can revert the clip operation after drawing.
21566
21567
21568 ctx.save(); // clip is used to use the stroke in drawRawCircle as an area that we can draw in.
21569
21570 ctx.clip(); // draw the image
21571
21572 this._drawImageAtPosition(ctx, values); // restore so we can again draw on the full canvas
21573
21574
21575 ctx.restore();
21576
21577 this._drawImageLabel(ctx, labelX, labelY, selected, hover);
21578
21579 this.updateBoundingBox(x, y);
21580 } // TODO: compare with Circle.updateBoundingBox(), consolidate? More stuff is happening here
21581
21582 /**
21583 *
21584 * @param {number} x width
21585 * @param {number} y height
21586 */
21587
21588 }, {
21589 key: "updateBoundingBox",
21590 value: function updateBoundingBox(x, y) {
21591 if (this.options.shapeProperties.coordinateOrigin === "top-left") {
21592 this.boundingBox.top = y;
21593 this.boundingBox.left = x;
21594 this.boundingBox.right = x + this.options.size * 2;
21595 this.boundingBox.bottom = y + this.options.size * 2;
21596 } else {
21597 this.boundingBox.top = y - this.options.size;
21598 this.boundingBox.left = x - this.options.size;
21599 this.boundingBox.right = x + this.options.size;
21600 this.boundingBox.bottom = y + this.options.size;
21601 } // TODO: compare with Image.updateBoundingBox(), consolidate?
21602
21603
21604 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
21605 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
21606 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelOffset);
21607 }
21608 /**
21609 *
21610 * @param {CanvasRenderingContext2D} ctx
21611 * @returns {number}
21612 */
21613
21614 }, {
21615 key: "distanceToBorder",
21616 value: function distanceToBorder(ctx) {
21617 if (ctx) {
21618 this.resize(ctx);
21619 }
21620
21621 return this.width * 0.5;
21622 }
21623 }]);
21624
21625 return CircularImage;
21626}(CircleImageBase);
21627
21628function _createSuper$o(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$o(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21629
21630function _isNativeReflectConstruct$o() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21631/**
21632 * Base class for constructing Node/Cluster Shapes.
21633 *
21634 * @augments NodeBase
21635 */
21636
21637var ShapeBase = /*#__PURE__*/function (_NodeBase) {
21638 _inherits(ShapeBase, _NodeBase);
21639
21640 var _super = _createSuper$o(ShapeBase);
21641
21642 /**
21643 * @param {object} options
21644 * @param {object} body
21645 * @param {Label} labelModule
21646 */
21647 function ShapeBase(options, body, labelModule) {
21648 _classCallCheck(this, ShapeBase);
21649
21650 return _super.call(this, options, body, labelModule);
21651 }
21652 /**
21653 *
21654 * @param {CanvasRenderingContext2D} ctx
21655 * @param {boolean} [selected]
21656 * @param {boolean} [hover]
21657 * @param {object} [values={size: this.options.size}]
21658 */
21659
21660
21661 _createClass(ShapeBase, [{
21662 key: "resize",
21663 value: function resize(ctx) {
21664 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
21665 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
21666 var values = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
21667 size: this.options.size
21668 };
21669
21670 if (this.needsRefresh(selected, hover)) {
21671 var _this$customSizeWidth, _this$customSizeHeigh;
21672
21673 this.labelModule.getTextSize(ctx, selected, hover);
21674 var size = 2 * values.size;
21675 this.width = (_this$customSizeWidth = this.customSizeWidth) !== null && _this$customSizeWidth !== void 0 ? _this$customSizeWidth : size;
21676 this.height = (_this$customSizeHeigh = this.customSizeHeight) !== null && _this$customSizeHeigh !== void 0 ? _this$customSizeHeigh : size;
21677 this.radius = 0.5 * this.width;
21678 }
21679 }
21680 /**
21681 *
21682 * @param {CanvasRenderingContext2D} ctx
21683 * @param {string} shape
21684 * @param {number} sizeMultiplier - Unused! TODO: Remove next major release
21685 * @param {number} x
21686 * @param {number} y
21687 * @param {boolean} selected
21688 * @param {boolean} hover
21689 * @param {ArrowOptions} values
21690 * @private
21691 *
21692 * @returns {object} Callbacks to draw later on higher layers.
21693 */
21694
21695 }, {
21696 key: "_drawShape",
21697 value: function _drawShape(ctx, shape, sizeMultiplier, x, y, selected, hover, values) {
21698 var _this = this;
21699
21700 this.resize(ctx, selected, hover, values);
21701 this.left = x - this.width / 2;
21702 this.top = y - this.height / 2;
21703 this.initContextForDraw(ctx, values);
21704 getShape(shape)(ctx, x, y, values.size);
21705 this.performFill(ctx, values);
21706
21707 if (this.options.icon !== undefined) {
21708 if (this.options.icon.code !== undefined) {
21709 ctx.font = (selected ? "bold " : "") + this.height / 2 + "px " + (this.options.icon.face || "FontAwesome");
21710 ctx.fillStyle = this.options.icon.color || "black";
21711 ctx.textAlign = "center";
21712 ctx.textBaseline = "middle";
21713 ctx.fillText(this.options.icon.code, x, y);
21714 }
21715 }
21716
21717 return {
21718 drawExternalLabel: function drawExternalLabel() {
21719 if (_this.options.label !== undefined) {
21720 // Need to call following here in order to ensure value for
21721 // `this.labelModule.size.height`.
21722 _this.labelModule.calculateLabelSize(ctx, selected, hover, x, y, "hanging");
21723
21724 var yLabel = y + 0.5 * _this.height + 0.5 * _this.labelModule.size.height;
21725
21726 _this.labelModule.draw(ctx, x, yLabel, selected, hover, "hanging");
21727 }
21728
21729 _this.updateBoundingBox(x, y);
21730 }
21731 };
21732 }
21733 /**
21734 *
21735 * @param {number} x
21736 * @param {number} y
21737 */
21738
21739 }, {
21740 key: "updateBoundingBox",
21741 value: function updateBoundingBox(x, y) {
21742 this.boundingBox.top = y - this.options.size;
21743 this.boundingBox.left = x - this.options.size;
21744 this.boundingBox.right = x + this.options.size;
21745 this.boundingBox.bottom = y + this.options.size;
21746
21747 if (this.options.label !== undefined && this.labelModule.size.width > 0) {
21748 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
21749 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
21750 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelModule.size.height);
21751 }
21752 }
21753 }]);
21754
21755 return ShapeBase;
21756}(NodeBase);
21757
21758function ownKeys$3(object, enumerableOnly) { var keys = keys$4(object); if (getOwnPropertySymbols) { var symbols = getOwnPropertySymbols(object); if (enumerableOnly) { symbols = filter(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$2(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
21759
21760function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { var _context; forEach$2(_context = ownKeys$3(Object(source), true)).call(_context, function (key) { _defineProperty(target, key, source[key]); }); } else if (getOwnPropertyDescriptors) { defineProperties(target, getOwnPropertyDescriptors(source)); } else { var _context2; forEach$2(_context2 = ownKeys$3(Object(source))).call(_context2, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$2(source, key)); }); } } return target; }
21761
21762function _createSuper$n(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$n(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21763
21764function _isNativeReflectConstruct$n() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21765/**
21766 * A CustomShape Node/Cluster shape.
21767 *
21768 * @augments ShapeBase
21769 */
21770
21771var CustomShape = /*#__PURE__*/function (_ShapeBase) {
21772 _inherits(CustomShape, _ShapeBase);
21773
21774 var _super = _createSuper$n(CustomShape);
21775
21776 /**
21777 * @param {object} options
21778 * @param {object} body
21779 * @param {Label} labelModule
21780 * @param {Function} ctxRenderer
21781
21782 */
21783 function CustomShape(options, body, labelModule, ctxRenderer) {
21784 var _this;
21785
21786 _classCallCheck(this, CustomShape);
21787
21788 _this = _super.call(this, options, body, labelModule, ctxRenderer);
21789 _this.ctxRenderer = ctxRenderer;
21790 return _this;
21791 }
21792 /**
21793 *
21794 * @param {CanvasRenderingContext2D} ctx
21795 * @param {number} x width
21796 * @param {number} y height
21797 * @param {boolean} selected
21798 * @param {boolean} hover
21799 * @param {ArrowOptions} values
21800 *
21801 * @returns {object} Callbacks to draw later on different layers.
21802 */
21803
21804
21805 _createClass(CustomShape, [{
21806 key: "draw",
21807 value: function draw(ctx, x, y, selected, hover, values) {
21808 this.resize(ctx, selected, hover, values);
21809 this.left = x - this.width / 2;
21810 this.top = y - this.height / 2; // Guard right away because someone may just draw in the function itself.
21811
21812 ctx.save();
21813 var drawLater = this.ctxRenderer({
21814 ctx: ctx,
21815 id: this.options.id,
21816 x: x,
21817 y: y,
21818 state: {
21819 selected: selected,
21820 hover: hover
21821 },
21822 style: _objectSpread$3({}, values),
21823 label: this.options.label
21824 }); // Render the node shape bellow arrows.
21825
21826 if (drawLater.drawNode != null) {
21827 drawLater.drawNode();
21828 }
21829
21830 ctx.restore();
21831
21832 if (drawLater.drawExternalLabel) {
21833 // Guard the external label (above arrows) drawing function.
21834 var drawExternalLabel = drawLater.drawExternalLabel;
21835
21836 drawLater.drawExternalLabel = function () {
21837 ctx.save();
21838 drawExternalLabel();
21839 ctx.restore();
21840 };
21841 }
21842
21843 if (drawLater.nodeDimensions) {
21844 this.customSizeWidth = drawLater.nodeDimensions.width;
21845 this.customSizeHeight = drawLater.nodeDimensions.height;
21846 }
21847
21848 return drawLater;
21849 }
21850 /**
21851 *
21852 * @param {CanvasRenderingContext2D} ctx
21853 * @param {number} angle
21854 * @returns {number}
21855 */
21856
21857 }, {
21858 key: "distanceToBorder",
21859 value: function distanceToBorder(ctx, angle) {
21860 return this._distanceToBorder(ctx, angle);
21861 }
21862 }]);
21863
21864 return CustomShape;
21865}(ShapeBase);
21866
21867function _createSuper$m(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$m(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21868
21869function _isNativeReflectConstruct$m() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21870/**
21871 * A Database Node/Cluster shape.
21872 *
21873 * @augments NodeBase
21874 */
21875
21876var Database = /*#__PURE__*/function (_NodeBase) {
21877 _inherits(Database, _NodeBase);
21878
21879 var _super = _createSuper$m(Database);
21880
21881 /**
21882 * @param {object} options
21883 * @param {object} body
21884 * @param {Label} labelModule
21885 */
21886 function Database(options, body, labelModule) {
21887 var _this;
21888
21889 _classCallCheck(this, Database);
21890
21891 _this = _super.call(this, options, body, labelModule);
21892
21893 _this._setMargins(labelModule);
21894
21895 return _this;
21896 }
21897 /**
21898 *
21899 * @param {CanvasRenderingContext2D} ctx
21900 * @param {boolean} selected
21901 * @param {boolean} hover
21902 */
21903
21904
21905 _createClass(Database, [{
21906 key: "resize",
21907 value: function resize(ctx, selected, hover) {
21908 if (this.needsRefresh(selected, hover)) {
21909 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
21910 var size = dimensions.width + this.margin.right + this.margin.left;
21911 this.width = size;
21912 this.height = size;
21913 this.radius = this.width / 2;
21914 }
21915 }
21916 /**
21917 *
21918 * @param {CanvasRenderingContext2D} ctx
21919 * @param {number} x width
21920 * @param {number} y height
21921 * @param {boolean} selected
21922 * @param {boolean} hover
21923 * @param {ArrowOptions} values
21924 */
21925
21926 }, {
21927 key: "draw",
21928 value: function draw(ctx, x, y, selected, hover, values) {
21929 this.resize(ctx, selected, hover);
21930 this.left = x - this.width / 2;
21931 this.top = y - this.height / 2;
21932 this.initContextForDraw(ctx, values);
21933 drawDatabase(ctx, x - this.width / 2, y - this.height / 2, this.width, this.height);
21934 this.performFill(ctx, values);
21935 this.updateBoundingBox(x, y, ctx, selected, hover);
21936 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, this.top + this.textSize.height / 2 + this.margin.top, selected, hover);
21937 }
21938 /**
21939 *
21940 * @param {CanvasRenderingContext2D} ctx
21941 * @param {number} angle
21942 * @returns {number}
21943 */
21944
21945 }, {
21946 key: "distanceToBorder",
21947 value: function distanceToBorder(ctx, angle) {
21948 return this._distanceToBorder(ctx, angle);
21949 }
21950 }]);
21951
21952 return Database;
21953}(NodeBase);
21954
21955function _createSuper$l(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$l(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
21956
21957function _isNativeReflectConstruct$l() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21958/**
21959 * A Diamond Node/Cluster shape.
21960 *
21961 * @augments ShapeBase
21962 */
21963
21964var Diamond$1 = /*#__PURE__*/function (_ShapeBase) {
21965 _inherits(Diamond, _ShapeBase);
21966
21967 var _super = _createSuper$l(Diamond);
21968
21969 /**
21970 * @param {object} options
21971 * @param {object} body
21972 * @param {Label} labelModule
21973 */
21974 function Diamond(options, body, labelModule) {
21975 _classCallCheck(this, Diamond);
21976
21977 return _super.call(this, options, body, labelModule);
21978 }
21979 /**
21980 *
21981 * @param {CanvasRenderingContext2D} ctx
21982 * @param {number} x width
21983 * @param {number} y height
21984 * @param {boolean} selected
21985 * @param {boolean} hover
21986 * @param {ArrowOptions} values
21987 *
21988 * @returns {object} Callbacks to draw later on higher layers.
21989 */
21990
21991
21992 _createClass(Diamond, [{
21993 key: "draw",
21994 value: function draw(ctx, x, y, selected, hover, values) {
21995 return this._drawShape(ctx, "diamond", 4, x, y, selected, hover, values);
21996 }
21997 /**
21998 *
21999 * @param {CanvasRenderingContext2D} ctx
22000 * @param {number} angle
22001 * @returns {number}
22002 */
22003
22004 }, {
22005 key: "distanceToBorder",
22006 value: function distanceToBorder(ctx, angle) {
22007 return this._distanceToBorder(ctx, angle);
22008 }
22009 }]);
22010
22011 return Diamond;
22012}(ShapeBase);
22013
22014function _createSuper$k(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$k(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22015
22016function _isNativeReflectConstruct$k() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22017/**
22018 * A Dot Node/Cluster shape.
22019 *
22020 * @augments ShapeBase
22021 */
22022
22023var Dot = /*#__PURE__*/function (_ShapeBase) {
22024 _inherits(Dot, _ShapeBase);
22025
22026 var _super = _createSuper$k(Dot);
22027
22028 /**
22029 * @param {object} options
22030 * @param {object} body
22031 * @param {Label} labelModule
22032 */
22033 function Dot(options, body, labelModule) {
22034 _classCallCheck(this, Dot);
22035
22036 return _super.call(this, options, body, labelModule);
22037 }
22038 /**
22039 *
22040 * @param {CanvasRenderingContext2D} ctx
22041 * @param {number} x width
22042 * @param {number} y height
22043 * @param {boolean} selected
22044 * @param {boolean} hover
22045 * @param {ArrowOptions} values
22046 *
22047 * @returns {object} Callbacks to draw later on higher layers.
22048 */
22049
22050
22051 _createClass(Dot, [{
22052 key: "draw",
22053 value: function draw(ctx, x, y, selected, hover, values) {
22054 return this._drawShape(ctx, "circle", 2, x, y, selected, hover, values);
22055 }
22056 /**
22057 *
22058 * @param {CanvasRenderingContext2D} ctx
22059 * @returns {number}
22060 */
22061
22062 }, {
22063 key: "distanceToBorder",
22064 value: function distanceToBorder(ctx) {
22065 if (ctx) {
22066 this.resize(ctx);
22067 }
22068
22069 return this.options.size;
22070 }
22071 }]);
22072
22073 return Dot;
22074}(ShapeBase);
22075
22076function _createSuper$j(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$j(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22077
22078function _isNativeReflectConstruct$j() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22079/**
22080 * Am Ellipse Node/Cluster shape.
22081 *
22082 * @augments NodeBase
22083 */
22084
22085var Ellipse = /*#__PURE__*/function (_NodeBase) {
22086 _inherits(Ellipse, _NodeBase);
22087
22088 var _super = _createSuper$j(Ellipse);
22089
22090 /**
22091 * @param {object} options
22092 * @param {object} body
22093 * @param {Label} labelModule
22094 */
22095 function Ellipse(options, body, labelModule) {
22096 _classCallCheck(this, Ellipse);
22097
22098 return _super.call(this, options, body, labelModule);
22099 }
22100 /**
22101 *
22102 * @param {CanvasRenderingContext2D} ctx
22103 * @param {boolean} [selected]
22104 * @param {boolean} [hover]
22105 */
22106
22107
22108 _createClass(Ellipse, [{
22109 key: "resize",
22110 value: function resize(ctx) {
22111 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
22112 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
22113
22114 if (this.needsRefresh(selected, hover)) {
22115 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
22116 this.height = dimensions.height * 2;
22117 this.width = dimensions.width + dimensions.height;
22118 this.radius = 0.5 * this.width;
22119 }
22120 }
22121 /**
22122 *
22123 * @param {CanvasRenderingContext2D} ctx
22124 * @param {number} x width
22125 * @param {number} y height
22126 * @param {boolean} selected
22127 * @param {boolean} hover
22128 * @param {ArrowOptions} values
22129 */
22130
22131 }, {
22132 key: "draw",
22133 value: function draw(ctx, x, y, selected, hover, values) {
22134 this.resize(ctx, selected, hover);
22135 this.left = x - this.width * 0.5;
22136 this.top = y - this.height * 0.5;
22137 this.initContextForDraw(ctx, values);
22138 drawEllipse(ctx, this.left, this.top, this.width, this.height);
22139 this.performFill(ctx, values);
22140 this.updateBoundingBox(x, y, ctx, selected, hover);
22141 this.labelModule.draw(ctx, x, y, selected, hover);
22142 }
22143 /**
22144 *
22145 * @param {CanvasRenderingContext2D} ctx
22146 * @param {number} angle
22147 * @returns {number}
22148 */
22149
22150 }, {
22151 key: "distanceToBorder",
22152 value: function distanceToBorder(ctx, angle) {
22153 if (ctx) {
22154 this.resize(ctx);
22155 }
22156
22157 var a = this.width * 0.5;
22158 var b = this.height * 0.5;
22159 var w = Math.sin(angle) * a;
22160 var h = Math.cos(angle) * b;
22161 return a * b / Math.sqrt(w * w + h * h);
22162 }
22163 }]);
22164
22165 return Ellipse;
22166}(NodeBase);
22167
22168function _createSuper$i(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$i(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22169
22170function _isNativeReflectConstruct$i() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22171/**
22172 * An icon replacement for the default Node shape.
22173 *
22174 * @augments NodeBase
22175 */
22176
22177var Icon = /*#__PURE__*/function (_NodeBase) {
22178 _inherits(Icon, _NodeBase);
22179
22180 var _super = _createSuper$i(Icon);
22181
22182 /**
22183 * @param {object} options
22184 * @param {object} body
22185 * @param {Label} labelModule
22186 */
22187 function Icon(options, body, labelModule) {
22188 var _this;
22189
22190 _classCallCheck(this, Icon);
22191
22192 _this = _super.call(this, options, body, labelModule);
22193
22194 _this._setMargins(labelModule);
22195
22196 return _this;
22197 }
22198 /**
22199 *
22200 * @param {CanvasRenderingContext2D} ctx - Unused.
22201 * @param {boolean} [selected]
22202 * @param {boolean} [hover]
22203 */
22204
22205
22206 _createClass(Icon, [{
22207 key: "resize",
22208 value: function resize(ctx, selected, hover) {
22209 if (this.needsRefresh(selected, hover)) {
22210 this.iconSize = {
22211 width: Number(this.options.icon.size),
22212 height: Number(this.options.icon.size)
22213 };
22214 this.width = this.iconSize.width + this.margin.right + this.margin.left;
22215 this.height = this.iconSize.height + this.margin.top + this.margin.bottom;
22216 this.radius = 0.5 * this.width;
22217 }
22218 }
22219 /**
22220 *
22221 * @param {CanvasRenderingContext2D} ctx
22222 * @param {number} x width
22223 * @param {number} y height
22224 * @param {boolean} selected
22225 * @param {boolean} hover
22226 * @param {ArrowOptions} values
22227 *
22228 * @returns {object} Callbacks to draw later on higher layers.
22229 */
22230
22231 }, {
22232 key: "draw",
22233 value: function draw(ctx, x, y, selected, hover, values) {
22234 var _this2 = this;
22235
22236 this.resize(ctx, selected, hover);
22237 this.options.icon.size = this.options.icon.size || 50;
22238 this.left = x - this.width / 2;
22239 this.top = y - this.height / 2;
22240
22241 this._icon(ctx, x, y, selected, hover, values);
22242
22243 return {
22244 drawExternalLabel: function drawExternalLabel() {
22245 if (_this2.options.label !== undefined) {
22246 var iconTextSpacing = 5;
22247
22248 _this2.labelModule.draw(ctx, _this2.left + _this2.iconSize.width / 2 + _this2.margin.left, y + _this2.height / 2 + iconTextSpacing, selected);
22249 }
22250
22251 _this2.updateBoundingBox(x, y);
22252 }
22253 };
22254 }
22255 /**
22256 *
22257 * @param {number} x
22258 * @param {number} y
22259 */
22260
22261 }, {
22262 key: "updateBoundingBox",
22263 value: function updateBoundingBox(x, y) {
22264 this.boundingBox.top = y - this.options.icon.size * 0.5;
22265 this.boundingBox.left = x - this.options.icon.size * 0.5;
22266 this.boundingBox.right = x + this.options.icon.size * 0.5;
22267 this.boundingBox.bottom = y + this.options.icon.size * 0.5;
22268
22269 if (this.options.label !== undefined && this.labelModule.size.width > 0) {
22270 var iconTextSpacing = 5;
22271 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
22272 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
22273 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelModule.size.height + iconTextSpacing);
22274 }
22275 }
22276 /**
22277 *
22278 * @param {CanvasRenderingContext2D} ctx
22279 * @param {number} x width
22280 * @param {number} y height
22281 * @param {boolean} selected
22282 * @param {boolean} hover - Unused
22283 * @param {ArrowOptions} values
22284 */
22285
22286 }, {
22287 key: "_icon",
22288 value: function _icon(ctx, x, y, selected, hover, values) {
22289 var iconSize = Number(this.options.icon.size);
22290
22291 if (this.options.icon.code !== undefined) {
22292 ctx.font = [this.options.icon.weight != null ? this.options.icon.weight : selected ? "bold" : "", // If the weight is forced (for example to make Font Awesome 5 work
22293 // properly) substitute slightly bigger size for bold font face.
22294 (this.options.icon.weight != null && selected ? 5 : 0) + iconSize + "px", this.options.icon.face].join(" "); // draw icon
22295
22296 ctx.fillStyle = this.options.icon.color || "black";
22297 ctx.textAlign = "center";
22298 ctx.textBaseline = "middle"; // draw shadow if enabled
22299
22300 this.enableShadow(ctx, values);
22301 ctx.fillText(this.options.icon.code, x, y); // disable shadows for other elements.
22302
22303 this.disableShadow(ctx, values);
22304 } else {
22305 console.error("When using the icon shape, you need to define the code in the icon options object. This can be done per node or globally.");
22306 }
22307 }
22308 /**
22309 *
22310 * @param {CanvasRenderingContext2D} ctx
22311 * @param {number} angle
22312 * @returns {number}
22313 */
22314
22315 }, {
22316 key: "distanceToBorder",
22317 value: function distanceToBorder(ctx, angle) {
22318 return this._distanceToBorder(ctx, angle);
22319 }
22320 }]);
22321
22322 return Icon;
22323}(NodeBase);
22324
22325function _createSuper$h(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$h(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22326
22327function _isNativeReflectConstruct$h() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22328/**
22329 * An image-based replacement for the default Node shape.
22330 *
22331 * @augments CircleImageBase
22332 */
22333
22334var Image$2 = /*#__PURE__*/function (_CircleImageBase) {
22335 _inherits(Image, _CircleImageBase);
22336
22337 var _super = _createSuper$h(Image);
22338
22339 /**
22340 * @param {object} options
22341 * @param {object} body
22342 * @param {Label} labelModule
22343 * @param {Image} imageObj
22344 * @param {Image} imageObjAlt
22345 */
22346 function Image(options, body, labelModule, imageObj, imageObjAlt) {
22347 var _this;
22348
22349 _classCallCheck(this, Image);
22350
22351 _this = _super.call(this, options, body, labelModule);
22352
22353 _this.setImages(imageObj, imageObjAlt);
22354
22355 return _this;
22356 }
22357 /**
22358 *
22359 * @param {CanvasRenderingContext2D} ctx - Unused.
22360 * @param {boolean} [selected]
22361 * @param {boolean} [hover]
22362 */
22363
22364
22365 _createClass(Image, [{
22366 key: "resize",
22367 value: function resize(ctx) {
22368 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
22369 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
22370 var imageAbsent = this.imageObj.src === undefined || this.imageObj.width === undefined || this.imageObj.height === undefined;
22371
22372 if (imageAbsent) {
22373 var side = this.options.size * 2;
22374 this.width = side;
22375 this.height = side;
22376 return;
22377 }
22378
22379 if (this.needsRefresh(selected, hover)) {
22380 this._resizeImage();
22381 }
22382 }
22383 /**
22384 *
22385 * @param {CanvasRenderingContext2D} ctx
22386 * @param {number} x width
22387 * @param {number} y height
22388 * @param {boolean} selected
22389 * @param {boolean} hover
22390 * @param {ArrowOptions} values
22391 */
22392
22393 }, {
22394 key: "draw",
22395 value: function draw(ctx, x, y, selected, hover, values) {
22396 ctx.save();
22397 this.switchImages(selected);
22398 this.resize();
22399 var labelX = x,
22400 labelY = y;
22401
22402 if (this.options.shapeProperties.coordinateOrigin === "top-left") {
22403 this.left = x;
22404 this.top = y;
22405 labelX += this.width / 2;
22406 labelY += this.height / 2;
22407 } else {
22408 this.left = x - this.width / 2;
22409 this.top = y - this.height / 2;
22410 }
22411
22412 if (this.options.shapeProperties.useBorderWithImage === true) {
22413 var neutralborderWidth = this.options.borderWidth;
22414 var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth;
22415 var borderWidth = (selected ? selectionLineWidth : neutralborderWidth) / this.body.view.scale;
22416 ctx.lineWidth = Math.min(this.width, borderWidth);
22417 ctx.beginPath();
22418 var strokeStyle = selected ? this.options.color.highlight.border : hover ? this.options.color.hover.border : this.options.color.border;
22419 var fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background;
22420
22421 if (values.opacity !== undefined) {
22422 strokeStyle = overrideOpacity(strokeStyle, values.opacity);
22423 fillStyle = overrideOpacity(fillStyle, values.opacity);
22424 } // setup the line properties.
22425
22426
22427 ctx.strokeStyle = strokeStyle; // set a fillstyle
22428
22429 ctx.fillStyle = fillStyle; // draw a rectangle to form the border around. This rectangle is filled so the opacity of a picture (in future vis releases?) can be used to tint the image
22430
22431 ctx.rect(this.left - 0.5 * ctx.lineWidth, this.top - 0.5 * ctx.lineWidth, this.width + ctx.lineWidth, this.height + ctx.lineWidth);
22432
22433 fill(ctx).call(ctx);
22434
22435 this.performStroke(ctx, values);
22436 ctx.closePath();
22437 }
22438
22439 this._drawImageAtPosition(ctx, values);
22440
22441 this._drawImageLabel(ctx, labelX, labelY, selected, hover);
22442
22443 this.updateBoundingBox(x, y);
22444 ctx.restore();
22445 }
22446 /**
22447 *
22448 * @param {number} x
22449 * @param {number} y
22450 */
22451
22452 }, {
22453 key: "updateBoundingBox",
22454 value: function updateBoundingBox(x, y) {
22455 this.resize();
22456
22457 if (this.options.shapeProperties.coordinateOrigin === "top-left") {
22458 this.left = x;
22459 this.top = y;
22460 } else {
22461 this.left = x - this.width / 2;
22462 this.top = y - this.height / 2;
22463 }
22464
22465 this.boundingBox.left = this.left;
22466 this.boundingBox.top = this.top;
22467 this.boundingBox.bottom = this.top + this.height;
22468 this.boundingBox.right = this.left + this.width;
22469
22470 if (this.options.label !== undefined && this.labelModule.size.width > 0) {
22471 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
22472 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
22473 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelOffset);
22474 }
22475 }
22476 /**
22477 *
22478 * @param {CanvasRenderingContext2D} ctx
22479 * @param {number} angle
22480 * @returns {number}
22481 */
22482
22483 }, {
22484 key: "distanceToBorder",
22485 value: function distanceToBorder(ctx, angle) {
22486 return this._distanceToBorder(ctx, angle);
22487 }
22488 }]);
22489
22490 return Image;
22491}(CircleImageBase);
22492
22493function _createSuper$g(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$g(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22494
22495function _isNativeReflectConstruct$g() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22496/**
22497 * A Square Node/Cluster shape.
22498 *
22499 * @augments ShapeBase
22500 */
22501
22502var Square = /*#__PURE__*/function (_ShapeBase) {
22503 _inherits(Square, _ShapeBase);
22504
22505 var _super = _createSuper$g(Square);
22506
22507 /**
22508 * @param {object} options
22509 * @param {object} body
22510 * @param {Label} labelModule
22511 */
22512 function Square(options, body, labelModule) {
22513 _classCallCheck(this, Square);
22514
22515 return _super.call(this, options, body, labelModule);
22516 }
22517 /**
22518 *
22519 * @param {CanvasRenderingContext2D} ctx
22520 * @param {number} x width
22521 * @param {number} y height
22522 * @param {boolean} selected
22523 * @param {boolean} hover
22524 * @param {ArrowOptions} values
22525 *
22526 * @returns {object} Callbacks to draw later on higher layers.
22527 */
22528
22529
22530 _createClass(Square, [{
22531 key: "draw",
22532 value: function draw(ctx, x, y, selected, hover, values) {
22533 return this._drawShape(ctx, "square", 2, x, y, selected, hover, values);
22534 }
22535 /**
22536 *
22537 * @param {CanvasRenderingContext2D} ctx
22538 * @param {number} angle
22539 * @returns {number}
22540 */
22541
22542 }, {
22543 key: "distanceToBorder",
22544 value: function distanceToBorder(ctx, angle) {
22545 return this._distanceToBorder(ctx, angle);
22546 }
22547 }]);
22548
22549 return Square;
22550}(ShapeBase);
22551
22552function _createSuper$f(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$f(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22553
22554function _isNativeReflectConstruct$f() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22555/**
22556 * A Hexagon Node/Cluster shape.
22557 *
22558 * @augments ShapeBase
22559 */
22560
22561var Hexagon = /*#__PURE__*/function (_ShapeBase) {
22562 _inherits(Hexagon, _ShapeBase);
22563
22564 var _super = _createSuper$f(Hexagon);
22565
22566 /**
22567 * @param {object} options
22568 * @param {object} body
22569 * @param {Label} labelModule
22570 */
22571 function Hexagon(options, body, labelModule) {
22572 _classCallCheck(this, Hexagon);
22573
22574 return _super.call(this, options, body, labelModule);
22575 }
22576 /**
22577 *
22578 * @param {CanvasRenderingContext2D} ctx
22579 * @param {number} x width
22580 * @param {number} y height
22581 * @param {boolean} selected
22582 * @param {boolean} hover
22583 * @param {ArrowOptions} values
22584 *
22585 * @returns {object} Callbacks to draw later on higher layers.
22586 */
22587
22588
22589 _createClass(Hexagon, [{
22590 key: "draw",
22591 value: function draw(ctx, x, y, selected, hover, values) {
22592 return this._drawShape(ctx, "hexagon", 4, x, y, selected, hover, values);
22593 }
22594 /**
22595 *
22596 * @param {CanvasRenderingContext2D} ctx
22597 * @param {number} angle
22598 * @returns {number}
22599 */
22600
22601 }, {
22602 key: "distanceToBorder",
22603 value: function distanceToBorder(ctx, angle) {
22604 return this._distanceToBorder(ctx, angle);
22605 }
22606 }]);
22607
22608 return Hexagon;
22609}(ShapeBase);
22610
22611function _createSuper$e(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$e(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22612
22613function _isNativeReflectConstruct$e() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22614/**
22615 * A Star Node/Cluster shape.
22616 *
22617 * @augments ShapeBase
22618 */
22619
22620var Star = /*#__PURE__*/function (_ShapeBase) {
22621 _inherits(Star, _ShapeBase);
22622
22623 var _super = _createSuper$e(Star);
22624
22625 /**
22626 * @param {object} options
22627 * @param {object} body
22628 * @param {Label} labelModule
22629 */
22630 function Star(options, body, labelModule) {
22631 _classCallCheck(this, Star);
22632
22633 return _super.call(this, options, body, labelModule);
22634 }
22635 /**
22636 *
22637 * @param {CanvasRenderingContext2D} ctx
22638 * @param {number} x width
22639 * @param {number} y height
22640 * @param {boolean} selected
22641 * @param {boolean} hover
22642 * @param {ArrowOptions} values
22643 *
22644 * @returns {object} Callbacks to draw later on higher layers.
22645 */
22646
22647
22648 _createClass(Star, [{
22649 key: "draw",
22650 value: function draw(ctx, x, y, selected, hover, values) {
22651 return this._drawShape(ctx, "star", 4, x, y, selected, hover, values);
22652 }
22653 /**
22654 *
22655 * @param {CanvasRenderingContext2D} ctx
22656 * @param {number} angle
22657 * @returns {number}
22658 */
22659
22660 }, {
22661 key: "distanceToBorder",
22662 value: function distanceToBorder(ctx, angle) {
22663 return this._distanceToBorder(ctx, angle);
22664 }
22665 }]);
22666
22667 return Star;
22668}(ShapeBase);
22669
22670function _createSuper$d(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$d(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22671
22672function _isNativeReflectConstruct$d() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22673/**
22674 * A text-based replacement for the default Node shape.
22675 *
22676 * @augments NodeBase
22677 */
22678
22679var Text = /*#__PURE__*/function (_NodeBase) {
22680 _inherits(Text, _NodeBase);
22681
22682 var _super = _createSuper$d(Text);
22683
22684 /**
22685 * @param {object} options
22686 * @param {object} body
22687 * @param {Label} labelModule
22688 */
22689 function Text(options, body, labelModule) {
22690 var _this;
22691
22692 _classCallCheck(this, Text);
22693
22694 _this = _super.call(this, options, body, labelModule);
22695
22696 _this._setMargins(labelModule);
22697
22698 return _this;
22699 }
22700 /**
22701 *
22702 * @param {CanvasRenderingContext2D} ctx
22703 * @param {boolean} selected
22704 * @param {boolean} hover
22705 */
22706
22707
22708 _createClass(Text, [{
22709 key: "resize",
22710 value: function resize(ctx, selected, hover) {
22711 if (this.needsRefresh(selected, hover)) {
22712 this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
22713 this.width = this.textSize.width + this.margin.right + this.margin.left;
22714 this.height = this.textSize.height + this.margin.top + this.margin.bottom;
22715 this.radius = 0.5 * this.width;
22716 }
22717 }
22718 /**
22719 *
22720 * @param {CanvasRenderingContext2D} ctx
22721 * @param {number} x width
22722 * @param {number} y height
22723 * @param {boolean} selected
22724 * @param {boolean} hover
22725 * @param {ArrowOptions} values
22726 */
22727
22728 }, {
22729 key: "draw",
22730 value: function draw(ctx, x, y, selected, hover, values) {
22731 this.resize(ctx, selected, hover);
22732 this.left = x - this.width / 2;
22733 this.top = y - this.height / 2; // draw shadow if enabled
22734
22735 this.enableShadow(ctx, values);
22736 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, this.top + this.textSize.height / 2 + this.margin.top, selected, hover); // disable shadows for other elements.
22737
22738 this.disableShadow(ctx, values);
22739 this.updateBoundingBox(x, y, ctx, selected, hover);
22740 }
22741 /**
22742 *
22743 * @param {CanvasRenderingContext2D} ctx
22744 * @param {number} angle
22745 * @returns {number}
22746 */
22747
22748 }, {
22749 key: "distanceToBorder",
22750 value: function distanceToBorder(ctx, angle) {
22751 return this._distanceToBorder(ctx, angle);
22752 }
22753 }]);
22754
22755 return Text;
22756}(NodeBase);
22757
22758function _createSuper$c(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$c(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22759
22760function _isNativeReflectConstruct$c() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22761/**
22762 * A Triangle Node/Cluster shape.
22763 *
22764 * @augments ShapeBase
22765 */
22766
22767var Triangle$1 = /*#__PURE__*/function (_ShapeBase) {
22768 _inherits(Triangle, _ShapeBase);
22769
22770 var _super = _createSuper$c(Triangle);
22771
22772 /**
22773 * @param {object} options
22774 * @param {object} body
22775 * @param {Label} labelModule
22776 */
22777 function Triangle(options, body, labelModule) {
22778 _classCallCheck(this, Triangle);
22779
22780 return _super.call(this, options, body, labelModule);
22781 }
22782 /**
22783 *
22784 * @param {CanvasRenderingContext2D} ctx
22785 * @param {number} x
22786 * @param {number} y
22787 * @param {boolean} selected
22788 * @param {boolean} hover
22789 * @param {ArrowOptions} values
22790 *
22791 * @returns {object} Callbacks to draw later on higher layers.
22792 */
22793
22794
22795 _createClass(Triangle, [{
22796 key: "draw",
22797 value: function draw(ctx, x, y, selected, hover, values) {
22798 return this._drawShape(ctx, "triangle", 3, x, y, selected, hover, values);
22799 }
22800 /**
22801 *
22802 * @param {CanvasRenderingContext2D} ctx
22803 * @param {number} angle
22804 * @returns {number}
22805 */
22806
22807 }, {
22808 key: "distanceToBorder",
22809 value: function distanceToBorder(ctx, angle) {
22810 return this._distanceToBorder(ctx, angle);
22811 }
22812 }]);
22813
22814 return Triangle;
22815}(ShapeBase);
22816
22817function _createSuper$b(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$b(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
22818
22819function _isNativeReflectConstruct$b() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
22820/**
22821 * A downward facing Triangle Node/Cluster shape.
22822 *
22823 * @augments ShapeBase
22824 */
22825
22826var TriangleDown = /*#__PURE__*/function (_ShapeBase) {
22827 _inherits(TriangleDown, _ShapeBase);
22828
22829 var _super = _createSuper$b(TriangleDown);
22830
22831 /**
22832 * @param {object} options
22833 * @param {object} body
22834 * @param {Label} labelModule
22835 */
22836 function TriangleDown(options, body, labelModule) {
22837 _classCallCheck(this, TriangleDown);
22838
22839 return _super.call(this, options, body, labelModule);
22840 }
22841 /**
22842 *
22843 * @param {CanvasRenderingContext2D} ctx
22844 * @param {number} x
22845 * @param {number} y
22846 * @param {boolean} selected
22847 * @param {boolean} hover
22848 * @param {ArrowOptions} values
22849 *
22850 * @returns {object} Callbacks to draw later on higher layers.
22851 */
22852
22853
22854 _createClass(TriangleDown, [{
22855 key: "draw",
22856 value: function draw(ctx, x, y, selected, hover, values) {
22857 return this._drawShape(ctx, "triangleDown", 3, x, y, selected, hover, values);
22858 }
22859 /**
22860 *
22861 * @param {CanvasRenderingContext2D} ctx
22862 * @param {number} angle
22863 * @returns {number}
22864 */
22865
22866 }, {
22867 key: "distanceToBorder",
22868 value: function distanceToBorder(ctx, angle) {
22869 return this._distanceToBorder(ctx, angle);
22870 }
22871 }]);
22872
22873 return TriangleDown;
22874}(ShapeBase);
22875
22876function ownKeys$2(object, enumerableOnly) { var keys = keys$4(object); if (getOwnPropertySymbols) { var symbols = getOwnPropertySymbols(object); if (enumerableOnly) { symbols = filter(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$2(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
22877
22878function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { var _context5; forEach$2(_context5 = ownKeys$2(Object(source), true)).call(_context5, function (key) { _defineProperty(target, key, source[key]); }); } else if (getOwnPropertyDescriptors) { defineProperties(target, getOwnPropertyDescriptors(source)); } else { var _context6; forEach$2(_context6 = ownKeys$2(Object(source))).call(_context6, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$2(source, key)); }); } } return target; }
22879/**
22880 * A node. A node can be connected to other nodes via one or multiple edges.
22881 */
22882
22883var Node = /*#__PURE__*/function () {
22884 /**
22885 *
22886 * @param {object} options An object containing options for the node. All
22887 * options are optional, except for the id.
22888 * {number} id Id of the node. Required
22889 * {string} label Text label for the node
22890 * {number} x Horizontal position of the node
22891 * {number} y Vertical position of the node
22892 * {string} shape Node shape
22893 * {string} image An image url
22894 * {string} title A title text, can be HTML
22895 * {anytype} group A group name or number
22896 *
22897 * @param {object} body Shared state of current network instance
22898 * @param {Network.Images} imagelist A list with images. Only needed when the node has an image
22899 * @param {Groups} grouplist A list with groups. Needed for retrieving group options
22900 * @param {object} globalOptions Current global node options; these serve as defaults for the node instance
22901 * @param {object} defaultOptions Global default options for nodes; note that this is also the prototype
22902 * for parameter `globalOptions`.
22903 */
22904 function Node(options, body, imagelist, grouplist, globalOptions, defaultOptions) {
22905 _classCallCheck(this, Node);
22906
22907 this.options = bridgeObject(globalOptions);
22908 this.globalOptions = globalOptions;
22909 this.defaultOptions = defaultOptions;
22910 this.body = body;
22911 this.edges = []; // all edges connected to this node
22912 // set defaults for the options
22913
22914 this.id = undefined;
22915 this.imagelist = imagelist;
22916 this.grouplist = grouplist; // state options
22917
22918 this.x = undefined;
22919 this.y = undefined;
22920 this.baseSize = this.options.size;
22921 this.baseFontSize = this.options.font.size;
22922 this.predefinedPosition = false; // used to check if initial fit should just take the range or approximate
22923
22924 this.selected = false;
22925 this.hover = false;
22926 this.labelModule = new Label(this.body, this.options, false
22927 /* Not edge label */
22928 );
22929 this.setOptions(options);
22930 }
22931 /**
22932 * Attach a edge to the node
22933 *
22934 * @param {Edge} edge
22935 */
22936
22937
22938 _createClass(Node, [{
22939 key: "attachEdge",
22940 value: function attachEdge(edge) {
22941 var _context;
22942
22943 if (indexOf(_context = this.edges).call(_context, edge) === -1) {
22944 this.edges.push(edge);
22945 }
22946 }
22947 /**
22948 * Detach a edge from the node
22949 *
22950 * @param {Edge} edge
22951 */
22952
22953 }, {
22954 key: "detachEdge",
22955 value: function detachEdge(edge) {
22956 var _context2;
22957
22958 var index = indexOf(_context2 = this.edges).call(_context2, edge);
22959
22960 if (index != -1) {
22961 var _context3;
22962
22963 splice(_context3 = this.edges).call(_context3, index, 1);
22964 }
22965 }
22966 /**
22967 * Set or overwrite options for the node
22968 *
22969 * @param {object} options an object with options
22970 * @returns {null|boolean}
22971 */
22972
22973 }, {
22974 key: "setOptions",
22975 value: function setOptions(options) {
22976 var currentShape = this.options.shape;
22977
22978 if (!options) {
22979 return; // Note that the return value will be 'undefined'! This is OK.
22980 } // Save the color for later.
22981 // This is necessary in order to prevent local color from being overwritten by group color.
22982 // TODO: To prevent such workarounds the way options are handled should be rewritten from scratch.
22983 // This is not the only problem with current options handling.
22984
22985
22986 if (typeof options.color !== "undefined") {
22987 this._localColor = options.color;
22988 } // basic options
22989
22990
22991 if (options.id !== undefined) {
22992 this.id = options.id;
22993 }
22994
22995 if (this.id === undefined) {
22996 throw new Error("Node must have an id");
22997 }
22998
22999 Node.checkMass(options, this.id); // set these options locally
23000 // clear x and y positions
23001
23002 if (options.x !== undefined) {
23003 if (options.x === null) {
23004 this.x = undefined;
23005 this.predefinedPosition = false;
23006 } else {
23007 this.x = _parseInt(options.x);
23008 this.predefinedPosition = true;
23009 }
23010 }
23011
23012 if (options.y !== undefined) {
23013 if (options.y === null) {
23014 this.y = undefined;
23015 this.predefinedPosition = false;
23016 } else {
23017 this.y = _parseInt(options.y);
23018 this.predefinedPosition = true;
23019 }
23020 }
23021
23022 if (options.size !== undefined) {
23023 this.baseSize = options.size;
23024 }
23025
23026 if (options.value !== undefined) {
23027 options.value = _parseFloat(options.value);
23028 } // this transforms all shorthands into fully defined options
23029
23030
23031 Node.parseOptions(this.options, options, true, this.globalOptions, this.grouplist);
23032 var pile = [options, this.options, this.defaultOptions];
23033 this.chooser = choosify("node", pile);
23034
23035 this._load_images();
23036
23037 this.updateLabelModule(options); // Need to set local opacity after `this.updateLabelModule(options);` because `this.updateLabelModule(options);` overrites local opacity with group opacity
23038
23039 if (options.opacity !== undefined && Node.checkOpacity(options.opacity)) {
23040 this.options.opacity = options.opacity;
23041 }
23042
23043 this.updateShape(currentShape);
23044 return options.hidden !== undefined || options.physics !== undefined;
23045 }
23046 /**
23047 * Load the images from the options, for the nodes that need them.
23048 *
23049 * Images are always loaded, even if they are not used in the current shape.
23050 * The user may switch to an image shape later on.
23051 *
23052 * @private
23053 */
23054
23055 }, {
23056 key: "_load_images",
23057 value: function _load_images() {
23058 if (this.options.shape === "circularImage" || this.options.shape === "image") {
23059 if (this.options.image === undefined) {
23060 throw new Error("Option image must be defined for node type '" + this.options.shape + "'");
23061 }
23062 }
23063
23064 if (this.options.image === undefined) {
23065 return;
23066 }
23067
23068 if (this.imagelist === undefined) {
23069 throw new Error("Internal Error: No images provided");
23070 }
23071
23072 if (typeof this.options.image === "string") {
23073 this.imageObj = this.imagelist.load(this.options.image, this.options.brokenImage, this.id);
23074 } else {
23075 if (this.options.image.unselected === undefined) {
23076 throw new Error("No unselected image provided");
23077 }
23078
23079 this.imageObj = this.imagelist.load(this.options.image.unselected, this.options.brokenImage, this.id);
23080
23081 if (this.options.image.selected !== undefined) {
23082 this.imageObjAlt = this.imagelist.load(this.options.image.selected, this.options.brokenImage, this.id);
23083 } else {
23084 this.imageObjAlt = undefined;
23085 }
23086 }
23087 }
23088 /**
23089 * Check that opacity is only between 0 and 1
23090 *
23091 * @param {number} opacity
23092 * @returns {boolean}
23093 */
23094
23095 }, {
23096 key: "getFormattingValues",
23097 value:
23098 /**
23099 *
23100 * @returns {{color: *, borderWidth: *, borderColor: *, size: *, borderDashes: (boolean|Array|allOptions.nodes.shapeProperties.borderDashes|{boolean, array}), borderRadius: (number|allOptions.nodes.shapeProperties.borderRadius|{number}|Array), shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *}}
23101 */
23102 function getFormattingValues() {
23103 var values = {
23104 color: this.options.color.background,
23105 opacity: this.options.opacity,
23106 borderWidth: this.options.borderWidth,
23107 borderColor: this.options.color.border,
23108 size: this.options.size,
23109 borderDashes: this.options.shapeProperties.borderDashes,
23110 borderRadius: this.options.shapeProperties.borderRadius,
23111 shadow: this.options.shadow.enabled,
23112 shadowColor: this.options.shadow.color,
23113 shadowSize: this.options.shadow.size,
23114 shadowX: this.options.shadow.x,
23115 shadowY: this.options.shadow.y
23116 };
23117
23118 if (this.selected || this.hover) {
23119 if (this.chooser === true) {
23120 if (this.selected) {
23121 if (this.options.borderWidthSelected != null) {
23122 values.borderWidth = this.options.borderWidthSelected;
23123 } else {
23124 values.borderWidth *= 2;
23125 }
23126
23127 values.color = this.options.color.highlight.background;
23128 values.borderColor = this.options.color.highlight.border;
23129 values.shadow = this.options.shadow.enabled;
23130 } else if (this.hover) {
23131 values.color = this.options.color.hover.background;
23132 values.borderColor = this.options.color.hover.border;
23133 values.shadow = this.options.shadow.enabled;
23134 }
23135 } else if (typeof this.chooser === "function") {
23136 this.chooser(values, this.options.id, this.selected, this.hover);
23137
23138 if (values.shadow === false) {
23139 if (values.shadowColor !== this.options.shadow.color || values.shadowSize !== this.options.shadow.size || values.shadowX !== this.options.shadow.x || values.shadowY !== this.options.shadow.y) {
23140 values.shadow = true;
23141 }
23142 }
23143 }
23144 } else {
23145 values.shadow = this.options.shadow.enabled;
23146 }
23147
23148 if (this.options.opacity !== undefined) {
23149 var opacity = this.options.opacity;
23150 values.borderColor = overrideOpacity(values.borderColor, opacity);
23151 values.color = overrideOpacity(values.color, opacity);
23152 values.shadowColor = overrideOpacity(values.shadowColor, opacity);
23153 }
23154
23155 return values;
23156 }
23157 /**
23158 *
23159 * @param {object} options
23160 */
23161
23162 }, {
23163 key: "updateLabelModule",
23164 value: function updateLabelModule(options) {
23165 if (this.options.label === undefined || this.options.label === null) {
23166 this.options.label = "";
23167 }
23168
23169 Node.updateGroupOptions(this.options, _objectSpread$2(_objectSpread$2({}, options), {}, {
23170 color: options && options.color || this._localColor || undefined
23171 }), this.grouplist); //
23172 // Note:The prototype chain for this.options is:
23173 //
23174 // this.options -> NodesHandler.options -> NodesHandler.defaultOptions
23175 // (also: this.globalOptions)
23176 //
23177 // Note that the prototypes are mentioned explicitly in the pile list below;
23178 // WE DON'T WANT THE ORDER OF THE PROTOTYPES!!!! At least, not for font handling of labels.
23179 // This is a good indication that the prototype usage of options is deficient.
23180 //
23181
23182 var currentGroup = this.grouplist.get(this.options.group, false);
23183 var pile = [options, // new options
23184 this.options, // current node options, see comment above for prototype
23185 currentGroup, // group options, if any
23186 this.globalOptions, // Currently set global node options
23187 this.defaultOptions // Default global node options
23188 ];
23189 this.labelModule.update(this.options, pile);
23190
23191 if (this.labelModule.baseSize !== undefined) {
23192 this.baseFontSize = this.labelModule.baseSize;
23193 }
23194 }
23195 /**
23196 *
23197 * @param {string} currentShape
23198 */
23199
23200 }, {
23201 key: "updateShape",
23202 value: function updateShape(currentShape) {
23203 if (currentShape === this.options.shape && this.shape) {
23204 this.shape.setOptions(this.options, this.imageObj, this.imageObjAlt);
23205 } else {
23206 // choose draw method depending on the shape
23207 switch (this.options.shape) {
23208 case "box":
23209 this.shape = new Box$1(this.options, this.body, this.labelModule);
23210 break;
23211
23212 case "circle":
23213 this.shape = new Circle$1(this.options, this.body, this.labelModule);
23214 break;
23215
23216 case "circularImage":
23217 this.shape = new CircularImage(this.options, this.body, this.labelModule, this.imageObj, this.imageObjAlt);
23218 break;
23219
23220 case "custom":
23221 this.shape = new CustomShape(this.options, this.body, this.labelModule, this.options.ctxRenderer);
23222 break;
23223
23224 case "database":
23225 this.shape = new Database(this.options, this.body, this.labelModule);
23226 break;
23227
23228 case "diamond":
23229 this.shape = new Diamond$1(this.options, this.body, this.labelModule);
23230 break;
23231
23232 case "dot":
23233 this.shape = new Dot(this.options, this.body, this.labelModule);
23234 break;
23235
23236 case "ellipse":
23237 this.shape = new Ellipse(this.options, this.body, this.labelModule);
23238 break;
23239
23240 case "icon":
23241 this.shape = new Icon(this.options, this.body, this.labelModule);
23242 break;
23243
23244 case "image":
23245 this.shape = new Image$2(this.options, this.body, this.labelModule, this.imageObj, this.imageObjAlt);
23246 break;
23247
23248 case "square":
23249 this.shape = new Square(this.options, this.body, this.labelModule);
23250 break;
23251
23252 case "hexagon":
23253 this.shape = new Hexagon(this.options, this.body, this.labelModule);
23254 break;
23255
23256 case "star":
23257 this.shape = new Star(this.options, this.body, this.labelModule);
23258 break;
23259
23260 case "text":
23261 this.shape = new Text(this.options, this.body, this.labelModule);
23262 break;
23263
23264 case "triangle":
23265 this.shape = new Triangle$1(this.options, this.body, this.labelModule);
23266 break;
23267
23268 case "triangleDown":
23269 this.shape = new TriangleDown(this.options, this.body, this.labelModule);
23270 break;
23271
23272 default:
23273 this.shape = new Ellipse(this.options, this.body, this.labelModule);
23274 break;
23275 }
23276 }
23277
23278 this.needsRefresh();
23279 }
23280 /**
23281 * select this node
23282 */
23283
23284 }, {
23285 key: "select",
23286 value: function select() {
23287 this.selected = true;
23288 this.needsRefresh();
23289 }
23290 /**
23291 * unselect this node
23292 */
23293
23294 }, {
23295 key: "unselect",
23296 value: function unselect() {
23297 this.selected = false;
23298 this.needsRefresh();
23299 }
23300 /**
23301 * Reset the calculated size of the node, forces it to recalculate its size
23302 */
23303
23304 }, {
23305 key: "needsRefresh",
23306 value: function needsRefresh() {
23307 this.shape.refreshNeeded = true;
23308 }
23309 /**
23310 * get the title of this node.
23311 *
23312 * @returns {string} title The title of the node, or undefined when no title
23313 * has been set.
23314 */
23315
23316 }, {
23317 key: "getTitle",
23318 value: function getTitle() {
23319 return this.options.title;
23320 }
23321 /**
23322 * Calculate the distance to the border of the Node
23323 *
23324 * @param {CanvasRenderingContext2D} ctx
23325 * @param {number} angle Angle in radians
23326 * @returns {number} distance Distance to the border in pixels
23327 */
23328
23329 }, {
23330 key: "distanceToBorder",
23331 value: function distanceToBorder(ctx, angle) {
23332 return this.shape.distanceToBorder(ctx, angle);
23333 }
23334 /**
23335 * Check if this node has a fixed x and y position
23336 *
23337 * @returns {boolean} true if fixed, false if not
23338 */
23339
23340 }, {
23341 key: "isFixed",
23342 value: function isFixed() {
23343 return this.options.fixed.x && this.options.fixed.y;
23344 }
23345 /**
23346 * check if this node is selecte
23347 *
23348 * @returns {boolean} selected True if node is selected, else false
23349 */
23350
23351 }, {
23352 key: "isSelected",
23353 value: function isSelected() {
23354 return this.selected;
23355 }
23356 /**
23357 * Retrieve the value of the node. Can be undefined
23358 *
23359 * @returns {number} value
23360 */
23361
23362 }, {
23363 key: "getValue",
23364 value: function getValue() {
23365 return this.options.value;
23366 }
23367 /**
23368 * Get the current dimensions of the label
23369 *
23370 * @returns {rect}
23371 */
23372
23373 }, {
23374 key: "getLabelSize",
23375 value: function getLabelSize() {
23376 return this.labelModule.size();
23377 }
23378 /**
23379 * Adjust the value range of the node. The node will adjust it's size
23380 * based on its value.
23381 *
23382 * @param {number} min
23383 * @param {number} max
23384 * @param {number} total
23385 */
23386
23387 }, {
23388 key: "setValueRange",
23389 value: function setValueRange(min, max, total) {
23390 if (this.options.value !== undefined) {
23391 var scale = this.options.scaling.customScalingFunction(min, max, total, this.options.value);
23392 var sizeDiff = this.options.scaling.max - this.options.scaling.min;
23393
23394 if (this.options.scaling.label.enabled === true) {
23395 var fontDiff = this.options.scaling.label.max - this.options.scaling.label.min;
23396 this.options.font.size = this.options.scaling.label.min + scale * fontDiff;
23397 }
23398
23399 this.options.size = this.options.scaling.min + scale * sizeDiff;
23400 } else {
23401 this.options.size = this.baseSize;
23402 this.options.font.size = this.baseFontSize;
23403 }
23404
23405 this.updateLabelModule();
23406 }
23407 /**
23408 * Draw this node in the given canvas
23409 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
23410 *
23411 * @param {CanvasRenderingContext2D} ctx
23412 *
23413 * @returns {object} Callbacks to draw later on higher layers.
23414 */
23415
23416 }, {
23417 key: "draw",
23418 value: function draw(ctx) {
23419 var values = this.getFormattingValues();
23420 return this.shape.draw(ctx, this.x, this.y, this.selected, this.hover, values) || {};
23421 }
23422 /**
23423 * Update the bounding box of the shape
23424 *
23425 * @param {CanvasRenderingContext2D} ctx
23426 */
23427
23428 }, {
23429 key: "updateBoundingBox",
23430 value: function updateBoundingBox(ctx) {
23431 this.shape.updateBoundingBox(this.x, this.y, ctx);
23432 }
23433 /**
23434 * Recalculate the size of this node in the given canvas
23435 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
23436 *
23437 * @param {CanvasRenderingContext2D} ctx
23438 */
23439
23440 }, {
23441 key: "resize",
23442 value: function resize(ctx) {
23443 var values = this.getFormattingValues();
23444 this.shape.resize(ctx, this.selected, this.hover, values);
23445 }
23446 /**
23447 * Determine all visual elements of this node instance, in which the given
23448 * point falls within the bounding shape.
23449 *
23450 * @param {point} point
23451 * @returns {Array.<nodeClickItem|nodeLabelClickItem>} list with the items which are on the point
23452 */
23453
23454 }, {
23455 key: "getItemsOnPoint",
23456 value: function getItemsOnPoint(point) {
23457 var ret = [];
23458
23459 if (this.labelModule.visible()) {
23460 if (pointInRect(this.labelModule.getSize(), point)) {
23461 ret.push({
23462 nodeId: this.id,
23463 labelId: 0
23464 });
23465 }
23466 }
23467
23468 if (pointInRect(this.shape.boundingBox, point)) {
23469 ret.push({
23470 nodeId: this.id
23471 });
23472 }
23473
23474 return ret;
23475 }
23476 /**
23477 * Check if this object is overlapping with the provided object
23478 *
23479 * @param {object} obj an object with parameters left, top, right, bottom
23480 * @returns {boolean} True if location is located on node
23481 */
23482
23483 }, {
23484 key: "isOverlappingWith",
23485 value: function isOverlappingWith(obj) {
23486 return this.shape.left < obj.right && this.shape.left + this.shape.width > obj.left && this.shape.top < obj.bottom && this.shape.top + this.shape.height > obj.top;
23487 }
23488 /**
23489 * Check if this object is overlapping with the provided object
23490 *
23491 * @param {object} obj an object with parameters left, top, right, bottom
23492 * @returns {boolean} True if location is located on node
23493 */
23494
23495 }, {
23496 key: "isBoundingBoxOverlappingWith",
23497 value: function isBoundingBoxOverlappingWith(obj) {
23498 return this.shape.boundingBox.left < obj.right && this.shape.boundingBox.right > obj.left && this.shape.boundingBox.top < obj.bottom && this.shape.boundingBox.bottom > obj.top;
23499 }
23500 /**
23501 * Check valid values for mass
23502 *
23503 * The mass may not be negative or zero. If it is, reset to 1
23504 *
23505 * @param {object} options
23506 * @param {Node.id} id
23507 * @static
23508 */
23509
23510 }], [{
23511 key: "checkOpacity",
23512 value: function checkOpacity(opacity) {
23513 return 0 <= opacity && opacity <= 1;
23514 }
23515 /**
23516 * Check that origin is 'center' or 'top-left'
23517 *
23518 * @param {string} origin
23519 * @returns {boolean}
23520 */
23521
23522 }, {
23523 key: "checkCoordinateOrigin",
23524 value: function checkCoordinateOrigin(origin) {
23525 return origin === undefined || origin === "center" || origin === "top-left";
23526 }
23527 /**
23528 * Copy group option values into the node options.
23529 *
23530 * The group options override the global node options, so the copy of group options
23531 * must happen *after* the global node options have been set.
23532 *
23533 * This method must also be called also if the global node options have changed and the group options did not.
23534 *
23535 * @param {object} parentOptions
23536 * @param {object} newOptions new values for the options, currently only passed in for check
23537 * @param {object} groupList
23538 */
23539
23540 }, {
23541 key: "updateGroupOptions",
23542 value: function updateGroupOptions(parentOptions, newOptions, groupList) {
23543 var _context4;
23544
23545 if (groupList === undefined) return; // No groups, nothing to do
23546
23547 var group = parentOptions.group; // paranoia: the selected group is already merged into node options, check.
23548
23549 if (newOptions !== undefined && newOptions.group !== undefined && group !== newOptions.group) {
23550 throw new Error("updateGroupOptions: group values in options don't match.");
23551 }
23552
23553 var hasGroup = typeof group === "number" || typeof group === "string" && group != "";
23554 if (!hasGroup) return; // current node has no group, no need to merge
23555
23556 var groupObj = groupList.get(group);
23557
23558 if (groupObj.opacity !== undefined && newOptions.opacity === undefined) {
23559 if (!Node.checkOpacity(groupObj.opacity)) {
23560 console.error("Invalid option for node opacity. Value must be between 0 and 1, found: " + groupObj.opacity);
23561 groupObj.opacity = undefined;
23562 }
23563 } // Skip any new option to avoid them being overridden by the group options.
23564
23565
23566 var skipProperties = filter(_context4 = getOwnPropertyNames(newOptions)).call(_context4, function (p) {
23567 return newOptions[p] != null;
23568 }); // Always skip merging group font options into parent; these are required to be distinct for labels
23569
23570
23571 skipProperties.push("font");
23572 selectiveNotDeepExtend(skipProperties, parentOptions, groupObj); // the color object needs to be completely defined.
23573 // Since groups can partially overwrite the colors, we parse it again, just in case.
23574
23575 parentOptions.color = parseColor(parentOptions.color);
23576 }
23577 /**
23578 * This process all possible shorthands in the new options and makes sure that the parentOptions are fully defined.
23579 * Static so it can also be used by the handler.
23580 *
23581 * @param {object} parentOptions
23582 * @param {object} newOptions
23583 * @param {boolean} [allowDeletion=false]
23584 * @param {object} [globalOptions={}]
23585 * @param {object} [groupList]
23586 * @static
23587 */
23588
23589 }, {
23590 key: "parseOptions",
23591 value: function parseOptions(parentOptions, newOptions) {
23592 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
23593 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
23594 var groupList = arguments.length > 4 ? arguments[4] : undefined;
23595 var fields = ["color", "fixed", "shadow"];
23596 selectiveNotDeepExtend(fields, parentOptions, newOptions, allowDeletion);
23597 Node.checkMass(newOptions);
23598
23599 if (parentOptions.opacity !== undefined) {
23600 if (!Node.checkOpacity(parentOptions.opacity)) {
23601 console.error("Invalid option for node opacity. Value must be between 0 and 1, found: " + parentOptions.opacity);
23602 parentOptions.opacity = undefined;
23603 }
23604 }
23605
23606 if (newOptions.opacity !== undefined) {
23607 if (!Node.checkOpacity(newOptions.opacity)) {
23608 console.error("Invalid option for node opacity. Value must be between 0 and 1, found: " + newOptions.opacity);
23609 newOptions.opacity = undefined;
23610 }
23611 }
23612
23613 if (newOptions.shapeProperties && !Node.checkCoordinateOrigin(newOptions.shapeProperties.coordinateOrigin)) {
23614 console.error("Invalid option for node coordinateOrigin, found: " + newOptions.shapeProperties.coordinateOrigin);
23615 } // merge the shadow options into the parent.
23616
23617
23618 mergeOptions(parentOptions, newOptions, "shadow", globalOptions); // individual shape newOptions
23619
23620 if (newOptions.color !== undefined && newOptions.color !== null) {
23621 var parsedColor = parseColor(newOptions.color);
23622 fillIfDefined(parentOptions.color, parsedColor);
23623 } else if (allowDeletion === true && newOptions.color === null) {
23624 parentOptions.color = bridgeObject(globalOptions.color); // set the object back to the global options
23625 } // handle the fixed options
23626
23627
23628 if (newOptions.fixed !== undefined && newOptions.fixed !== null) {
23629 if (typeof newOptions.fixed === "boolean") {
23630 parentOptions.fixed.x = newOptions.fixed;
23631 parentOptions.fixed.y = newOptions.fixed;
23632 } else {
23633 if (newOptions.fixed.x !== undefined && typeof newOptions.fixed.x === "boolean") {
23634 parentOptions.fixed.x = newOptions.fixed.x;
23635 }
23636
23637 if (newOptions.fixed.y !== undefined && typeof newOptions.fixed.y === "boolean") {
23638 parentOptions.fixed.y = newOptions.fixed.y;
23639 }
23640 }
23641 }
23642
23643 if (allowDeletion === true && newOptions.font === null) {
23644 parentOptions.font = bridgeObject(globalOptions.font); // set the object back to the global options
23645 }
23646
23647 Node.updateGroupOptions(parentOptions, newOptions, groupList); // handle the scaling options, specifically the label part
23648
23649 if (newOptions.scaling !== undefined) {
23650 mergeOptions(parentOptions.scaling, newOptions.scaling, "label", globalOptions.scaling);
23651 }
23652 }
23653 }, {
23654 key: "checkMass",
23655 value: function checkMass(options, id) {
23656 if (options.mass !== undefined && options.mass <= 0) {
23657 var strId = "";
23658
23659 if (id !== undefined) {
23660 strId = " in node id: " + id;
23661 }
23662
23663 console.error("%cNegative or zero mass disallowed" + strId + ", setting mass to 1.", VALIDATOR_PRINT_STYLE$1);
23664 options.mass = 1;
23665 }
23666 }
23667 }]);
23668
23669 return Node;
23670}();
23671
23672function _createForOfIteratorHelper$6(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$6(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
23673
23674function _unsupportedIterableToArray$6(o, minLen) { var _context4; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$6(o, minLen); var n = slice$1(_context4 = Object.prototype.toString.call(o)).call(_context4, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$6(o, minLen); }
23675
23676function _arrayLikeToArray$6(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
23677/**
23678 * Handler for Nodes
23679 */
23680
23681var NodesHandler = /*#__PURE__*/function () {
23682 /**
23683 * @param {object} body
23684 * @param {Images} images
23685 * @param {Array.<Group>} groups
23686 * @param {LayoutEngine} layoutEngine
23687 */
23688 function NodesHandler(body, images, groups, layoutEngine) {
23689 var _context,
23690 _this = this;
23691
23692 _classCallCheck(this, NodesHandler);
23693
23694 this.body = body;
23695 this.images = images;
23696 this.groups = groups;
23697 this.layoutEngine = layoutEngine; // create the node API in the body container
23698
23699 this.body.functions.createNode = bind$6(_context = this.create).call(_context, this);
23700 this.nodesListeners = {
23701 add: function add(event, params) {
23702 _this.add(params.items);
23703 },
23704 update: function update(event, params) {
23705 _this.update(params.items, params.data, params.oldData);
23706 },
23707 remove: function remove(event, params) {
23708 _this.remove(params.items);
23709 }
23710 };
23711 this.defaultOptions = {
23712 borderWidth: 1,
23713 borderWidthSelected: undefined,
23714 brokenImage: undefined,
23715 color: {
23716 border: "#2B7CE9",
23717 background: "#97C2FC",
23718 highlight: {
23719 border: "#2B7CE9",
23720 background: "#D2E5FF"
23721 },
23722 hover: {
23723 border: "#2B7CE9",
23724 background: "#D2E5FF"
23725 }
23726 },
23727 opacity: undefined,
23728 // number between 0 and 1
23729 fixed: {
23730 x: false,
23731 y: false
23732 },
23733 font: {
23734 color: "#343434",
23735 size: 14,
23736 // px
23737 face: "arial",
23738 background: "none",
23739 strokeWidth: 0,
23740 // px
23741 strokeColor: "#ffffff",
23742 align: "center",
23743 vadjust: 0,
23744 multi: false,
23745 bold: {
23746 mod: "bold"
23747 },
23748 boldital: {
23749 mod: "bold italic"
23750 },
23751 ital: {
23752 mod: "italic"
23753 },
23754 mono: {
23755 mod: "",
23756 size: 15,
23757 // px
23758 face: "monospace",
23759 vadjust: 2
23760 }
23761 },
23762 group: undefined,
23763 hidden: false,
23764 icon: {
23765 face: "FontAwesome",
23766 //'FontAwesome',
23767 code: undefined,
23768 //'\uf007',
23769 size: 50,
23770 //50,
23771 color: "#2B7CE9" //'#aa00ff'
23772
23773 },
23774 image: undefined,
23775 // --> URL
23776 imagePadding: {
23777 // only for image shape
23778 top: 0,
23779 right: 0,
23780 bottom: 0,
23781 left: 0
23782 },
23783 label: undefined,
23784 labelHighlightBold: true,
23785 level: undefined,
23786 margin: {
23787 top: 5,
23788 right: 5,
23789 bottom: 5,
23790 left: 5
23791 },
23792 mass: 1,
23793 physics: true,
23794 scaling: {
23795 min: 10,
23796 max: 30,
23797 label: {
23798 enabled: false,
23799 min: 14,
23800 max: 30,
23801 maxVisible: 30,
23802 drawThreshold: 5
23803 },
23804 customScalingFunction: function customScalingFunction(min, max, total, value) {
23805 if (max === min) {
23806 return 0.5;
23807 } else {
23808 var scale = 1 / (max - min);
23809 return Math.max(0, (value - min) * scale);
23810 }
23811 }
23812 },
23813 shadow: {
23814 enabled: false,
23815 color: "rgba(0,0,0,0.5)",
23816 size: 10,
23817 x: 5,
23818 y: 5
23819 },
23820 shape: "ellipse",
23821 shapeProperties: {
23822 borderDashes: false,
23823 // only for borders
23824 borderRadius: 6,
23825 // only for box shape
23826 interpolation: true,
23827 // only for image and circularImage shapes
23828 useImageSize: false,
23829 // only for image and circularImage shapes
23830 useBorderWithImage: false,
23831 // only for image shape
23832 coordinateOrigin: "center" // only for image and circularImage shapes
23833
23834 },
23835 size: 25,
23836 title: undefined,
23837 value: undefined,
23838 x: undefined,
23839 y: undefined
23840 }; // Protect from idiocy
23841
23842 if (this.defaultOptions.mass <= 0) {
23843 throw "Internal error: mass in defaultOptions of NodesHandler may not be zero or negative";
23844 }
23845
23846 this.options = bridgeObject(this.defaultOptions);
23847 this.bindEventListeners();
23848 }
23849 /**
23850 * Binds event listeners
23851 */
23852
23853
23854 _createClass(NodesHandler, [{
23855 key: "bindEventListeners",
23856 value: function bindEventListeners() {
23857 var _context2,
23858 _context3,
23859 _this2 = this;
23860
23861 // refresh the nodes. Used when reverting from hierarchical layout
23862 this.body.emitter.on("refreshNodes", bind$6(_context2 = this.refresh).call(_context2, this));
23863 this.body.emitter.on("refresh", bind$6(_context3 = this.refresh).call(_context3, this));
23864 this.body.emitter.on("destroy", function () {
23865 forEach$1(_this2.nodesListeners, function (callback, event) {
23866 if (_this2.body.data.nodes) _this2.body.data.nodes.off(event, callback);
23867 });
23868 delete _this2.body.functions.createNode;
23869 delete _this2.nodesListeners.add;
23870 delete _this2.nodesListeners.update;
23871 delete _this2.nodesListeners.remove;
23872 delete _this2.nodesListeners;
23873 });
23874 }
23875 /**
23876 *
23877 * @param {object} options
23878 */
23879
23880 }, {
23881 key: "setOptions",
23882 value: function setOptions(options) {
23883 if (options !== undefined) {
23884 Node.parseOptions(this.options, options); // Need to set opacity here because Node.parseOptions is also used for groups,
23885 // if you set opacity in Node.parseOptions it overwrites group opacity.
23886
23887 if (options.opacity !== undefined) {
23888 if (isNan(options.opacity) || !_isFinite(options.opacity) || options.opacity < 0 || options.opacity > 1) {
23889 console.error("Invalid option for node opacity. Value must be between 0 and 1, found: " + options.opacity);
23890 } else {
23891 this.options.opacity = options.opacity;
23892 }
23893 } // update the shape in all nodes
23894
23895
23896 if (options.shape !== undefined) {
23897 for (var nodeId in this.body.nodes) {
23898 if (Object.prototype.hasOwnProperty.call(this.body.nodes, nodeId)) {
23899 this.body.nodes[nodeId].updateShape();
23900 }
23901 }
23902 } // Update the labels of nodes if any relevant options changed.
23903
23904
23905 if (typeof options.font !== "undefined" || typeof options.widthConstraint !== "undefined" || typeof options.heightConstraint !== "undefined") {
23906 for (var _i = 0, _Object$keys = keys$4(this.body.nodes); _i < _Object$keys.length; _i++) {
23907 var _nodeId = _Object$keys[_i];
23908
23909 this.body.nodes[_nodeId].updateLabelModule();
23910
23911 this.body.nodes[_nodeId].needsRefresh();
23912 }
23913 } // update the shape size in all nodes
23914
23915
23916 if (options.size !== undefined) {
23917 for (var _nodeId2 in this.body.nodes) {
23918 if (Object.prototype.hasOwnProperty.call(this.body.nodes, _nodeId2)) {
23919 this.body.nodes[_nodeId2].needsRefresh();
23920 }
23921 }
23922 } // update the state of the variables if needed
23923
23924
23925 if (options.hidden !== undefined || options.physics !== undefined) {
23926 this.body.emitter.emit("_dataChanged");
23927 }
23928 }
23929 }
23930 /**
23931 * Set a data set with nodes for the network
23932 *
23933 * @param {Array | DataSet | DataView} nodes The data containing the nodes.
23934 * @param {boolean} [doNotEmit=false] - Suppress data changed event.
23935 * @private
23936 */
23937
23938 }, {
23939 key: "setData",
23940 value: function setData(nodes) {
23941 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
23942 var oldNodesData = this.body.data.nodes;
23943
23944 if (isDataViewLike("id", nodes)) {
23945 this.body.data.nodes = nodes;
23946 } else if (isArray$2(nodes)) {
23947 this.body.data.nodes = new DataSet();
23948 this.body.data.nodes.add(nodes);
23949 } else if (!nodes) {
23950 this.body.data.nodes = new DataSet();
23951 } else {
23952 throw new TypeError("Array or DataSet expected");
23953 }
23954
23955 if (oldNodesData) {
23956 // unsubscribe from old dataset
23957 forEach$1(this.nodesListeners, function (callback, event) {
23958 oldNodesData.off(event, callback);
23959 });
23960 } // remove drawn nodes
23961
23962
23963 this.body.nodes = {};
23964
23965 if (this.body.data.nodes) {
23966 // subscribe to new dataset
23967 var me = this;
23968 forEach$1(this.nodesListeners, function (callback, event) {
23969 me.body.data.nodes.on(event, callback);
23970 }); // draw all new nodes
23971
23972 var ids = this.body.data.nodes.getIds();
23973 this.add(ids, true);
23974 }
23975
23976 if (doNotEmit === false) {
23977 this.body.emitter.emit("_dataChanged");
23978 }
23979 }
23980 /**
23981 * Add nodes
23982 *
23983 * @param {number[] | string[]} ids
23984 * @param {boolean} [doNotEmit=false]
23985 * @private
23986 */
23987
23988 }, {
23989 key: "add",
23990 value: function add(ids) {
23991 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
23992 var id;
23993 var newNodes = [];
23994
23995 for (var i = 0; i < ids.length; i++) {
23996 id = ids[i];
23997 var properties = this.body.data.nodes.get(id);
23998 var node = this.create(properties);
23999 newNodes.push(node);
24000 this.body.nodes[id] = node; // note: this may replace an existing node
24001 }
24002
24003 this.layoutEngine.positionInitially(newNodes);
24004
24005 if (doNotEmit === false) {
24006 this.body.emitter.emit("_dataChanged");
24007 }
24008 }
24009 /**
24010 * Update existing nodes, or create them when not yet existing
24011 *
24012 * @param {number[] | string[]} ids id's of changed nodes
24013 * @param {Array} changedData array with changed data
24014 * @param {Array|undefined} oldData optional; array with previous data
24015 * @private
24016 */
24017
24018 }, {
24019 key: "update",
24020 value: function update(ids, changedData, oldData) {
24021 var nodes = this.body.nodes;
24022 var dataChanged = false;
24023
24024 for (var i = 0; i < ids.length; i++) {
24025 var id = ids[i];
24026 var node = nodes[id];
24027 var data = changedData[i];
24028
24029 if (node !== undefined) {
24030 // update node
24031 if (node.setOptions(data)) {
24032 dataChanged = true;
24033 }
24034 } else {
24035 dataChanged = true; // create node
24036
24037 node = this.create(data);
24038 nodes[id] = node;
24039 }
24040 }
24041
24042 if (!dataChanged && oldData !== undefined) {
24043 // Check for any changes which should trigger a layout recalculation
24044 // For now, this is just 'level' for hierarchical layout
24045 // Assumption: old and new data arranged in same order; at time of writing, this holds.
24046 dataChanged = some(changedData).call(changedData, function (newValue, index) {
24047 var oldValue = oldData[index];
24048 return oldValue && oldValue.level !== newValue.level;
24049 });
24050 }
24051
24052 if (dataChanged === true) {
24053 this.body.emitter.emit("_dataChanged");
24054 } else {
24055 this.body.emitter.emit("_dataUpdated");
24056 }
24057 }
24058 /**
24059 * Remove existing nodes. If nodes do not exist, the method will just ignore it.
24060 *
24061 * @param {number[] | string[]} ids
24062 * @private
24063 */
24064
24065 }, {
24066 key: "remove",
24067 value: function remove(ids) {
24068 var nodes = this.body.nodes;
24069
24070 for (var i = 0; i < ids.length; i++) {
24071 var id = ids[i];
24072 delete nodes[id];
24073 }
24074
24075 this.body.emitter.emit("_dataChanged");
24076 }
24077 /**
24078 * create a node
24079 *
24080 * @param {object} properties
24081 * @param {class} [constructorClass=Node.default]
24082 * @returns {*}
24083 */
24084
24085 }, {
24086 key: "create",
24087 value: function create(properties) {
24088 var constructorClass = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Node;
24089 return new constructorClass(properties, this.body, this.images, this.groups, this.options, this.defaultOptions);
24090 }
24091 /**
24092 *
24093 * @param {boolean} [clearPositions=false]
24094 */
24095
24096 }, {
24097 key: "refresh",
24098 value: function refresh() {
24099 var _this3 = this;
24100
24101 var clearPositions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
24102 forEach$1(this.body.nodes, function (node, nodeId) {
24103 var data = _this3.body.data.nodes.get(nodeId);
24104
24105 if (data !== undefined) {
24106 if (clearPositions === true) {
24107 node.setOptions({
24108 x: null,
24109 y: null
24110 });
24111 }
24112
24113 node.setOptions({
24114 fixed: false
24115 });
24116 node.setOptions(data);
24117 }
24118 });
24119 }
24120 /**
24121 * Returns the positions of the nodes.
24122 *
24123 * @param {Array.<Node.id> | string} [ids] --> optional, can be array of nodeIds, can be string
24124 * @returns {{}}
24125 */
24126
24127 }, {
24128 key: "getPositions",
24129 value: function getPositions(ids) {
24130 var dataArray = {};
24131
24132 if (ids !== undefined) {
24133 if (isArray$2(ids) === true) {
24134 for (var i = 0; i < ids.length; i++) {
24135 if (this.body.nodes[ids[i]] !== undefined) {
24136 var node = this.body.nodes[ids[i]];
24137 dataArray[ids[i]] = {
24138 x: Math.round(node.x),
24139 y: Math.round(node.y)
24140 };
24141 }
24142 }
24143 } else {
24144 if (this.body.nodes[ids] !== undefined) {
24145 var _node = this.body.nodes[ids];
24146 dataArray[ids] = {
24147 x: Math.round(_node.x),
24148 y: Math.round(_node.y)
24149 };
24150 }
24151 }
24152 } else {
24153 for (var _i2 = 0; _i2 < this.body.nodeIndices.length; _i2++) {
24154 var _node2 = this.body.nodes[this.body.nodeIndices[_i2]];
24155 dataArray[this.body.nodeIndices[_i2]] = {
24156 x: Math.round(_node2.x),
24157 y: Math.round(_node2.y)
24158 };
24159 }
24160 }
24161
24162 return dataArray;
24163 }
24164 /**
24165 * Retrieves the x y position of a specific id.
24166 *
24167 * @param {string} id The id to retrieve.
24168 *
24169 * @throws {TypeError} If no id is included.
24170 * @throws {ReferenceError} If an invalid id is provided.
24171 *
24172 * @returns {{ x: number, y: number }} Returns X, Y canvas position of the node with given id.
24173 */
24174
24175 }, {
24176 key: "getPosition",
24177 value: function getPosition(id) {
24178 if (id == undefined) {
24179 throw new TypeError("No id was specified for getPosition method.");
24180 } else if (this.body.nodes[id] == undefined) {
24181 throw new ReferenceError("NodeId provided for getPosition does not exist. Provided: ".concat(id));
24182 } else {
24183 return {
24184 x: Math.round(this.body.nodes[id].x),
24185 y: Math.round(this.body.nodes[id].y)
24186 };
24187 }
24188 }
24189 /**
24190 * Load the XY positions of the nodes into the dataset.
24191 */
24192
24193 }, {
24194 key: "storePositions",
24195 value: function storePositions() {
24196 // todo: add support for clusters and hierarchical.
24197 var dataArray = [];
24198 var dataset = this.body.data.nodes.getDataSet();
24199
24200 var _iterator = _createForOfIteratorHelper$6(dataset.get()),
24201 _step;
24202
24203 try {
24204 for (_iterator.s(); !(_step = _iterator.n()).done;) {
24205 var dsNode = _step.value;
24206 var id = dsNode.id;
24207 var bodyNode = this.body.nodes[id];
24208 var x = Math.round(bodyNode.x);
24209 var y = Math.round(bodyNode.y);
24210
24211 if (dsNode.x !== x || dsNode.y !== y) {
24212 dataArray.push({
24213 id: id,
24214 x: x,
24215 y: y
24216 });
24217 }
24218 }
24219 } catch (err) {
24220 _iterator.e(err);
24221 } finally {
24222 _iterator.f();
24223 }
24224
24225 dataset.update(dataArray);
24226 }
24227 /**
24228 * get the bounding box of a node.
24229 *
24230 * @param {Node.id} nodeId
24231 * @returns {j|*}
24232 */
24233
24234 }, {
24235 key: "getBoundingBox",
24236 value: function getBoundingBox(nodeId) {
24237 if (this.body.nodes[nodeId] !== undefined) {
24238 return this.body.nodes[nodeId].shape.boundingBox;
24239 }
24240 }
24241 /**
24242 * Get the Ids of nodes connected to this node.
24243 *
24244 * @param {Node.id} nodeId
24245 * @param {'to'|'from'|undefined} direction values 'from' and 'to' select respectively parent and child nodes only.
24246 * Any other value returns both parent and child nodes.
24247 * @returns {Array}
24248 */
24249
24250 }, {
24251 key: "getConnectedNodes",
24252 value: function getConnectedNodes(nodeId, direction) {
24253 var nodeList = [];
24254
24255 if (this.body.nodes[nodeId] !== undefined) {
24256 var node = this.body.nodes[nodeId];
24257 var nodeObj = {}; // used to quickly check if node already exists
24258
24259 for (var i = 0; i < node.edges.length; i++) {
24260 var edge = node.edges[i];
24261
24262 if (direction !== "to" && edge.toId == node.id) {
24263 // these are double equals since ids can be numeric or string
24264 if (nodeObj[edge.fromId] === undefined) {
24265 nodeList.push(edge.fromId);
24266 nodeObj[edge.fromId] = true;
24267 }
24268 } else if (direction !== "from" && edge.fromId == node.id) {
24269 // these are double equals since ids can be numeric or string
24270 if (nodeObj[edge.toId] === undefined) {
24271 nodeList.push(edge.toId);
24272 nodeObj[edge.toId] = true;
24273 }
24274 }
24275 }
24276 }
24277
24278 return nodeList;
24279 }
24280 /**
24281 * Get the ids of the edges connected to this node.
24282 *
24283 * @param {Node.id} nodeId
24284 * @returns {*}
24285 */
24286
24287 }, {
24288 key: "getConnectedEdges",
24289 value: function getConnectedEdges(nodeId) {
24290 var edgeList = [];
24291
24292 if (this.body.nodes[nodeId] !== undefined) {
24293 var node = this.body.nodes[nodeId];
24294
24295 for (var i = 0; i < node.edges.length; i++) {
24296 edgeList.push(node.edges[i].id);
24297 }
24298 } else {
24299 console.error("NodeId provided for getConnectedEdges does not exist. Provided: ", nodeId);
24300 }
24301
24302 return edgeList;
24303 }
24304 /**
24305 * Move a node.
24306 *
24307 * @param {Node.id} nodeId
24308 * @param {number} x
24309 * @param {number} y
24310 */
24311
24312 }, {
24313 key: "moveNode",
24314 value: function moveNode(nodeId, x, y) {
24315 var _this4 = this;
24316
24317 if (this.body.nodes[nodeId] !== undefined) {
24318 this.body.nodes[nodeId].x = Number(x);
24319 this.body.nodes[nodeId].y = Number(y);
24320
24321 setTimeout$1(function () {
24322 _this4.body.emitter.emit("startSimulation");
24323 }, 0);
24324 } else {
24325 console.error("Node id supplied to moveNode does not exist. Provided: ", nodeId);
24326 }
24327 }
24328 }]);
24329
24330 return NodesHandler;
24331}();
24332
24333var $$2 = _export;
24334var isObject$2 = isObject$j;
24335var anObject$1 = anObject$d;
24336var has = has$c;
24337var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor;
24338var getPrototypeOf = objectGetPrototypeOf; // `Reflect.get` method
24339// https://tc39.es/ecma262/#sec-reflect.get
24340
24341function get$4(target, propertyKey
24342/* , receiver */
24343) {
24344 var receiver = arguments.length < 3 ? target : arguments[2];
24345 var descriptor, prototype;
24346 if (anObject$1(target) === receiver) return target[propertyKey];
24347 if (descriptor = getOwnPropertyDescriptorModule.f(target, propertyKey)) return has(descriptor, 'value') ? descriptor.value : descriptor.get === undefined ? undefined : descriptor.get.call(receiver);
24348 if (isObject$2(prototype = getPrototypeOf(target))) return get$4(prototype, propertyKey, receiver);
24349}
24350
24351$$2({
24352 target: 'Reflect',
24353 stat: true
24354}, {
24355 get: get$4
24356});
24357
24358var path$3 = path$x;
24359var get$3 = path$3.Reflect.get;
24360
24361var parent$5 = get$3;
24362var get$2 = parent$5;
24363
24364var parent$4 = get$2;
24365var get$1 = parent$4;
24366
24367var get = get$1;
24368
24369var parent$3 = getOwnPropertyDescriptor$3;
24370var getOwnPropertyDescriptor$1 = parent$3;
24371
24372var getOwnPropertyDescriptor = getOwnPropertyDescriptor$1;
24373
24374function _superPropBase(object, property) {
24375 while (!Object.prototype.hasOwnProperty.call(object, property)) {
24376 object = _getPrototypeOf(object);
24377 if (object === null) break;
24378 }
24379
24380 return object;
24381}
24382
24383function _get(target, property, receiver) {
24384 if (typeof Reflect !== "undefined" && get) {
24385 _get = get;
24386 } else {
24387 _get = function _get(target, property, receiver) {
24388 var base = _superPropBase(target, property);
24389 if (!base) return;
24390
24391 var desc = getOwnPropertyDescriptor(base, property);
24392
24393 if (desc.get) {
24394 return desc.get.call(receiver);
24395 }
24396
24397 return desc.value;
24398 };
24399 }
24400
24401 return _get(target, property, receiver || target);
24402}
24403
24404var $$1 = _export; // eslint-disable-next-line es/no-math-hypot -- required for testing
24405
24406var $hypot = Math.hypot;
24407var abs = Math.abs;
24408var sqrt = Math.sqrt; // Chrome 77 bug
24409// https://bugs.chromium.org/p/v8/issues/detail?id=9546
24410
24411var BUGGY = !!$hypot && $hypot(Infinity, NaN) !== Infinity; // `Math.hypot` method
24412// https://tc39.es/ecma262/#sec-math.hypot
24413
24414$$1({
24415 target: 'Math',
24416 stat: true,
24417 forced: BUGGY
24418}, {
24419 // eslint-disable-next-line no-unused-vars -- required for `.length`
24420 hypot: function hypot(value1, value2) {
24421 var sum = 0;
24422 var i = 0;
24423 var aLen = arguments.length;
24424 var larg = 0;
24425 var arg, div;
24426
24427 while (i < aLen) {
24428 arg = abs(arguments[i++]);
24429
24430 if (larg < arg) {
24431 div = larg / arg;
24432 sum = sum * div * div + 1;
24433 larg = arg;
24434 } else if (arg > 0) {
24435 div = arg / larg;
24436 sum += div * div;
24437 } else sum += arg;
24438 }
24439
24440 return larg === Infinity ? Infinity : larg * sqrt(sum);
24441 }
24442});
24443
24444var path$2 = path$x;
24445var hypot$2 = path$2.Math.hypot;
24446
24447var parent$2 = hypot$2;
24448var hypot$1 = parent$2;
24449
24450var hypot = hypot$1;
24451
24452function _createSuper$a(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$a(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
24453
24454function _isNativeReflectConstruct$a() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
24455/**
24456 * Common methods for endpoints
24457 *
24458 * @class
24459 */
24460
24461var EndPoint = /*#__PURE__*/function () {
24462 function EndPoint() {
24463 _classCallCheck(this, EndPoint);
24464 }
24465
24466 _createClass(EndPoint, null, [{
24467 key: "transform",
24468 value:
24469 /**
24470 * Apply transformation on points for display.
24471 *
24472 * The following is done:
24473 * - rotate by the specified angle
24474 * - multiply the (normalized) coordinates by the passed length
24475 * - offset by the target coordinates
24476 *
24477 * @param points - The point(s) to be transformed.
24478 * @param arrowData - The data determining the result of the transformation.
24479 */
24480 function transform(points, arrowData) {
24481 if (!isArray$2(points)) {
24482 points = [points];
24483 }
24484
24485 var x = arrowData.point.x;
24486 var y = arrowData.point.y;
24487 var angle = arrowData.angle;
24488 var length = arrowData.length;
24489
24490 for (var i = 0; i < points.length; ++i) {
24491 var p = points[i];
24492 var xt = p.x * Math.cos(angle) - p.y * Math.sin(angle);
24493 var yt = p.x * Math.sin(angle) + p.y * Math.cos(angle);
24494 p.x = x + length * xt;
24495 p.y = y + length * yt;
24496 }
24497 }
24498 /**
24499 * Draw a closed path using the given real coordinates.
24500 *
24501 * @param ctx - The path will be rendered into this context.
24502 * @param points - The points of the path.
24503 */
24504
24505 }, {
24506 key: "drawPath",
24507 value: function drawPath(ctx, points) {
24508 ctx.beginPath();
24509 ctx.moveTo(points[0].x, points[0].y);
24510
24511 for (var i = 1; i < points.length; ++i) {
24512 ctx.lineTo(points[i].x, points[i].y);
24513 }
24514
24515 ctx.closePath();
24516 }
24517 }]);
24518
24519 return EndPoint;
24520}();
24521/**
24522 * Drawing methods for the arrow endpoint.
24523 */
24524
24525
24526var Image$1 = /*#__PURE__*/function (_EndPoint) {
24527 _inherits(Image, _EndPoint);
24528
24529 var _super = _createSuper$a(Image);
24530
24531 function Image() {
24532 _classCallCheck(this, Image);
24533
24534 return _super.apply(this, arguments);
24535 }
24536
24537 _createClass(Image, null, [{
24538 key: "draw",
24539 value:
24540 /**
24541 * Draw this shape at the end of a line.
24542 *
24543 * @param ctx - The shape will be rendered into this context.
24544 * @param arrowData - The data determining the shape.
24545 *
24546 * @returns False as there is no way to fill an image.
24547 */
24548 function draw(ctx, arrowData) {
24549 if (arrowData.image) {
24550 ctx.save();
24551 ctx.translate(arrowData.point.x, arrowData.point.y);
24552 ctx.rotate(Math.PI / 2 + arrowData.angle);
24553 var width = arrowData.imageWidth != null ? arrowData.imageWidth : arrowData.image.width;
24554 var height = arrowData.imageHeight != null ? arrowData.imageHeight : arrowData.image.height;
24555 arrowData.image.drawImageAtPosition(ctx, 1, // scale
24556 -width / 2, // x
24557 0, // y
24558 width, height);
24559 ctx.restore();
24560 }
24561
24562 return false;
24563 }
24564 }]);
24565
24566 return Image;
24567}(EndPoint);
24568/**
24569 * Drawing methods for the arrow endpoint.
24570 */
24571
24572
24573var Arrow = /*#__PURE__*/function (_EndPoint2) {
24574 _inherits(Arrow, _EndPoint2);
24575
24576 var _super2 = _createSuper$a(Arrow);
24577
24578 function Arrow() {
24579 _classCallCheck(this, Arrow);
24580
24581 return _super2.apply(this, arguments);
24582 }
24583
24584 _createClass(Arrow, null, [{
24585 key: "draw",
24586 value:
24587 /**
24588 * Draw this shape at the end of a line.
24589 *
24590 * @param ctx - The shape will be rendered into this context.
24591 * @param arrowData - The data determining the shape.
24592 *
24593 * @returns True because ctx.fill() can be used to fill the arrow.
24594 */
24595 function draw(ctx, arrowData) {
24596 // Normalized points of closed path, in the order that they should be drawn.
24597 // (0, 0) is the attachment point, and the point around which should be rotated
24598 var points = [{
24599 x: 0,
24600 y: 0
24601 }, {
24602 x: -1,
24603 y: 0.3
24604 }, {
24605 x: -0.9,
24606 y: 0
24607 }, {
24608 x: -1,
24609 y: -0.3
24610 }];
24611 EndPoint.transform(points, arrowData);
24612 EndPoint.drawPath(ctx, points);
24613 return true;
24614 }
24615 }]);
24616
24617 return Arrow;
24618}(EndPoint);
24619/**
24620 * Drawing methods for the crow endpoint.
24621 */
24622
24623
24624var Crow = /*#__PURE__*/function () {
24625 function Crow() {
24626 _classCallCheck(this, Crow);
24627 }
24628
24629 _createClass(Crow, null, [{
24630 key: "draw",
24631 value:
24632 /**
24633 * Draw this shape at the end of a line.
24634 *
24635 * @param ctx - The shape will be rendered into this context.
24636 * @param arrowData - The data determining the shape.
24637 *
24638 * @returns True because ctx.fill() can be used to fill the arrow.
24639 */
24640 function draw(ctx, arrowData) {
24641 // Normalized points of closed path, in the order that they should be drawn.
24642 // (0, 0) is the attachment point, and the point around which should be rotated
24643 var points = [{
24644 x: -1,
24645 y: 0
24646 }, {
24647 x: 0,
24648 y: 0.3
24649 }, {
24650 x: -0.4,
24651 y: 0
24652 }, {
24653 x: 0,
24654 y: -0.3
24655 }];
24656 EndPoint.transform(points, arrowData);
24657 EndPoint.drawPath(ctx, points);
24658 return true;
24659 }
24660 }]);
24661
24662 return Crow;
24663}();
24664/**
24665 * Drawing methods for the curve endpoint.
24666 */
24667
24668
24669var Curve = /*#__PURE__*/function () {
24670 function Curve() {
24671 _classCallCheck(this, Curve);
24672 }
24673
24674 _createClass(Curve, null, [{
24675 key: "draw",
24676 value:
24677 /**
24678 * Draw this shape at the end of a line.
24679 *
24680 * @param ctx - The shape will be rendered into this context.
24681 * @param arrowData - The data determining the shape.
24682 *
24683 * @returns True because ctx.fill() can be used to fill the arrow.
24684 */
24685 function draw(ctx, arrowData) {
24686 // Normalized points of closed path, in the order that they should be drawn.
24687 // (0, 0) is the attachment point, and the point around which should be rotated
24688 var point = {
24689 x: -0.4,
24690 y: 0
24691 };
24692 EndPoint.transform(point, arrowData); // Update endpoint style for drawing transparent arc.
24693
24694 ctx.strokeStyle = ctx.fillStyle;
24695 ctx.fillStyle = "rgba(0, 0, 0, 0)"; // Define curve endpoint as semicircle.
24696
24697 var pi = Math.PI;
24698 var startAngle = arrowData.angle - pi / 2;
24699 var endAngle = arrowData.angle + pi / 2;
24700 ctx.beginPath();
24701 ctx.arc(point.x, point.y, arrowData.length * 0.4, startAngle, endAngle, false);
24702 ctx.stroke();
24703 return true;
24704 }
24705 }]);
24706
24707 return Curve;
24708}();
24709/**
24710 * Drawing methods for the inverted curve endpoint.
24711 */
24712
24713
24714var InvertedCurve = /*#__PURE__*/function () {
24715 function InvertedCurve() {
24716 _classCallCheck(this, InvertedCurve);
24717 }
24718
24719 _createClass(InvertedCurve, null, [{
24720 key: "draw",
24721 value:
24722 /**
24723 * Draw this shape at the end of a line.
24724 *
24725 * @param ctx - The shape will be rendered into this context.
24726 * @param arrowData - The data determining the shape.
24727 *
24728 * @returns True because ctx.fill() can be used to fill the arrow.
24729 */
24730 function draw(ctx, arrowData) {
24731 // Normalized points of closed path, in the order that they should be drawn.
24732 // (0, 0) is the attachment point, and the point around which should be rotated
24733 var point = {
24734 x: -0.3,
24735 y: 0
24736 };
24737 EndPoint.transform(point, arrowData); // Update endpoint style for drawing transparent arc.
24738
24739 ctx.strokeStyle = ctx.fillStyle;
24740 ctx.fillStyle = "rgba(0, 0, 0, 0)"; // Define inverted curve endpoint as semicircle.
24741
24742 var pi = Math.PI;
24743 var startAngle = arrowData.angle + pi / 2;
24744 var endAngle = arrowData.angle + 3 * pi / 2;
24745 ctx.beginPath();
24746 ctx.arc(point.x, point.y, arrowData.length * 0.4, startAngle, endAngle, false);
24747 ctx.stroke();
24748 return true;
24749 }
24750 }]);
24751
24752 return InvertedCurve;
24753}();
24754/**
24755 * Drawing methods for the trinagle endpoint.
24756 */
24757
24758
24759var Triangle = /*#__PURE__*/function () {
24760 function Triangle() {
24761 _classCallCheck(this, Triangle);
24762 }
24763
24764 _createClass(Triangle, null, [{
24765 key: "draw",
24766 value:
24767 /**
24768 * Draw this shape at the end of a line.
24769 *
24770 * @param ctx - The shape will be rendered into this context.
24771 * @param arrowData - The data determining the shape.
24772 *
24773 * @returns True because ctx.fill() can be used to fill the arrow.
24774 */
24775 function draw(ctx, arrowData) {
24776 // Normalized points of closed path, in the order that they should be drawn.
24777 // (0, 0) is the attachment point, and the point around which should be rotated
24778 var points = [{
24779 x: 0.02,
24780 y: 0
24781 }, {
24782 x: -1,
24783 y: 0.3
24784 }, {
24785 x: -1,
24786 y: -0.3
24787 }];
24788 EndPoint.transform(points, arrowData);
24789 EndPoint.drawPath(ctx, points);
24790 return true;
24791 }
24792 }]);
24793
24794 return Triangle;
24795}();
24796/**
24797 * Drawing methods for the inverted trinagle endpoint.
24798 */
24799
24800
24801var InvertedTriangle = /*#__PURE__*/function () {
24802 function InvertedTriangle() {
24803 _classCallCheck(this, InvertedTriangle);
24804 }
24805
24806 _createClass(InvertedTriangle, null, [{
24807 key: "draw",
24808 value:
24809 /**
24810 * Draw this shape at the end of a line.
24811 *
24812 * @param ctx - The shape will be rendered into this context.
24813 * @param arrowData - The data determining the shape.
24814 *
24815 * @returns True because ctx.fill() can be used to fill the arrow.
24816 */
24817 function draw(ctx, arrowData) {
24818 // Normalized points of closed path, in the order that they should be drawn.
24819 // (0, 0) is the attachment point, and the point around which should be rotated
24820 var points = [{
24821 x: 0,
24822 y: 0.3
24823 }, {
24824 x: 0,
24825 y: -0.3
24826 }, {
24827 x: -1,
24828 y: 0
24829 }];
24830 EndPoint.transform(points, arrowData);
24831 EndPoint.drawPath(ctx, points);
24832 return true;
24833 }
24834 }]);
24835
24836 return InvertedTriangle;
24837}();
24838/**
24839 * Drawing methods for the circle endpoint.
24840 */
24841
24842
24843var Circle = /*#__PURE__*/function () {
24844 function Circle() {
24845 _classCallCheck(this, Circle);
24846 }
24847
24848 _createClass(Circle, null, [{
24849 key: "draw",
24850 value:
24851 /**
24852 * Draw this shape at the end of a line.
24853 *
24854 * @param ctx - The shape will be rendered into this context.
24855 * @param arrowData - The data determining the shape.
24856 *
24857 * @returns True because ctx.fill() can be used to fill the arrow.
24858 */
24859 function draw(ctx, arrowData) {
24860 var point = {
24861 x: -0.4,
24862 y: 0
24863 };
24864 EndPoint.transform(point, arrowData);
24865 drawCircle(ctx, point.x, point.y, arrowData.length * 0.4);
24866 return true;
24867 }
24868 }]);
24869
24870 return Circle;
24871}();
24872/**
24873 * Drawing methods for the bar endpoint.
24874 */
24875
24876
24877var Bar = /*#__PURE__*/function () {
24878 function Bar() {
24879 _classCallCheck(this, Bar);
24880 }
24881
24882 _createClass(Bar, null, [{
24883 key: "draw",
24884 value:
24885 /**
24886 * Draw this shape at the end of a line.
24887 *
24888 * @param ctx - The shape will be rendered into this context.
24889 * @param arrowData - The data determining the shape.
24890 *
24891 * @returns True because ctx.fill() can be used to fill the arrow.
24892 */
24893 function draw(ctx, arrowData) {
24894 /*
24895 var points = [
24896 {x:0, y:0.5},
24897 {x:0, y:-0.5}
24898 ];
24899 EndPoint.transform(points, arrowData);
24900 ctx.beginPath();
24901 ctx.moveTo(points[0].x, points[0].y);
24902 ctx.lineTo(points[1].x, points[1].y);
24903 ctx.stroke();
24904 */
24905 var points = [{
24906 x: 0,
24907 y: 0.5
24908 }, {
24909 x: 0,
24910 y: -0.5
24911 }, {
24912 x: -0.15,
24913 y: -0.5
24914 }, {
24915 x: -0.15,
24916 y: 0.5
24917 }];
24918 EndPoint.transform(points, arrowData);
24919 EndPoint.drawPath(ctx, points);
24920 return true;
24921 }
24922 }]);
24923
24924 return Bar;
24925}();
24926/**
24927 * Drawing methods for the box endpoint.
24928 */
24929
24930
24931var Box = /*#__PURE__*/function () {
24932 function Box() {
24933 _classCallCheck(this, Box);
24934 }
24935
24936 _createClass(Box, null, [{
24937 key: "draw",
24938 value:
24939 /**
24940 * Draw this shape at the end of a line.
24941 *
24942 * @param ctx - The shape will be rendered into this context.
24943 * @param arrowData - The data determining the shape.
24944 *
24945 * @returns True because ctx.fill() can be used to fill the arrow.
24946 */
24947 function draw(ctx, arrowData) {
24948 var points = [{
24949 x: 0,
24950 y: 0.3
24951 }, {
24952 x: 0,
24953 y: -0.3
24954 }, {
24955 x: -0.6,
24956 y: -0.3
24957 }, {
24958 x: -0.6,
24959 y: 0.3
24960 }];
24961 EndPoint.transform(points, arrowData);
24962 EndPoint.drawPath(ctx, points);
24963 return true;
24964 }
24965 }]);
24966
24967 return Box;
24968}();
24969/**
24970 * Drawing methods for the diamond endpoint.
24971 */
24972
24973
24974var Diamond = /*#__PURE__*/function () {
24975 function Diamond() {
24976 _classCallCheck(this, Diamond);
24977 }
24978
24979 _createClass(Diamond, null, [{
24980 key: "draw",
24981 value:
24982 /**
24983 * Draw this shape at the end of a line.
24984 *
24985 * @param ctx - The shape will be rendered into this context.
24986 * @param arrowData - The data determining the shape.
24987 *
24988 * @returns True because ctx.fill() can be used to fill the arrow.
24989 */
24990 function draw(ctx, arrowData) {
24991 var points = [{
24992 x: 0,
24993 y: 0
24994 }, {
24995 x: -0.5,
24996 y: -0.3
24997 }, {
24998 x: -1,
24999 y: 0
25000 }, {
25001 x: -0.5,
25002 y: 0.3
25003 }];
25004 EndPoint.transform(points, arrowData);
25005 EndPoint.drawPath(ctx, points);
25006 return true;
25007 }
25008 }]);
25009
25010 return Diamond;
25011}();
25012/**
25013 * Drawing methods for the vee endpoint.
25014 */
25015
25016
25017var Vee = /*#__PURE__*/function () {
25018 function Vee() {
25019 _classCallCheck(this, Vee);
25020 }
25021
25022 _createClass(Vee, null, [{
25023 key: "draw",
25024 value:
25025 /**
25026 * Draw this shape at the end of a line.
25027 *
25028 * @param ctx - The shape will be rendered into this context.
25029 * @param arrowData - The data determining the shape.
25030 *
25031 * @returns True because ctx.fill() can be used to fill the arrow.
25032 */
25033 function draw(ctx, arrowData) {
25034 // Normalized points of closed path, in the order that they should be drawn.
25035 // (0, 0) is the attachment point, and the point around which should be rotated
25036 var points = [{
25037 x: -1,
25038 y: 0.3
25039 }, {
25040 x: -0.5,
25041 y: 0
25042 }, {
25043 x: -1,
25044 y: -0.3
25045 }, {
25046 x: 0,
25047 y: 0
25048 }];
25049 EndPoint.transform(points, arrowData);
25050 EndPoint.drawPath(ctx, points);
25051 return true;
25052 }
25053 }]);
25054
25055 return Vee;
25056}();
25057/**
25058 * Drawing methods for the endpoints.
25059 */
25060
25061
25062var EndPoints = /*#__PURE__*/function () {
25063 function EndPoints() {
25064 _classCallCheck(this, EndPoints);
25065 }
25066
25067 _createClass(EndPoints, null, [{
25068 key: "draw",
25069 value:
25070 /**
25071 * Draw an endpoint.
25072 *
25073 * @param ctx - The shape will be rendered into this context.
25074 * @param arrowData - The data determining the shape.
25075 *
25076 * @returns True if ctx.fill() can be used to fill the arrow, false otherwise.
25077 */
25078 function draw(ctx, arrowData) {
25079 var type;
25080
25081 if (arrowData.type) {
25082 type = arrowData.type.toLowerCase();
25083 }
25084
25085 switch (type) {
25086 case "image":
25087 return Image$1.draw(ctx, arrowData);
25088
25089 case "circle":
25090 return Circle.draw(ctx, arrowData);
25091
25092 case "box":
25093 return Box.draw(ctx, arrowData);
25094
25095 case "crow":
25096 return Crow.draw(ctx, arrowData);
25097
25098 case "curve":
25099 return Curve.draw(ctx, arrowData);
25100
25101 case "diamond":
25102 return Diamond.draw(ctx, arrowData);
25103
25104 case "inv_curve":
25105 return InvertedCurve.draw(ctx, arrowData);
25106
25107 case "triangle":
25108 return Triangle.draw(ctx, arrowData);
25109
25110 case "inv_triangle":
25111 return InvertedTriangle.draw(ctx, arrowData);
25112
25113 case "bar":
25114 return Bar.draw(ctx, arrowData);
25115
25116 case "vee":
25117 return Vee.draw(ctx, arrowData);
25118
25119 case "arrow": // fall-through
25120
25121 default:
25122 return Arrow.draw(ctx, arrowData);
25123 }
25124 }
25125 }]);
25126
25127 return EndPoints;
25128}();
25129
25130function ownKeys$1(object, enumerableOnly) { var keys = keys$4(object); if (getOwnPropertySymbols) { var symbols = getOwnPropertySymbols(object); if (enumerableOnly) { symbols = filter(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$2(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
25131
25132function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { var _context2; forEach$2(_context2 = ownKeys$1(Object(source), true)).call(_context2, function (key) { _defineProperty(target, key, source[key]); }); } else if (getOwnPropertyDescriptors) { defineProperties(target, getOwnPropertyDescriptors(source)); } else { var _context3; forEach$2(_context3 = ownKeys$1(Object(source))).call(_context3, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$2(source, key)); }); } } return target; }
25133/**
25134 * The Base Class for all edges.
25135 */
25136
25137var EdgeBase = /*#__PURE__*/function () {
25138 /**
25139 * Create a new instance.
25140 *
25141 * @param options - The options object of given edge.
25142 * @param _body - The body of the network.
25143 * @param _labelModule - Label module.
25144 */
25145 function EdgeBase(options, _body, _labelModule) {
25146 _classCallCheck(this, EdgeBase);
25147
25148 this._body = _body;
25149 this._labelModule = _labelModule;
25150 this.color = {};
25151 this.colorDirty = true;
25152 this.hoverWidth = 1.5;
25153 this.selectionWidth = 2;
25154 this.setOptions(options);
25155 this.fromPoint = this.from;
25156 this.toPoint = this.to;
25157 }
25158 /** @inheritDoc */
25159
25160
25161 _createClass(EdgeBase, [{
25162 key: "connect",
25163 value: function connect() {
25164 this.from = this._body.nodes[this.options.from];
25165 this.to = this._body.nodes[this.options.to];
25166 }
25167 /** @inheritDoc */
25168
25169 }, {
25170 key: "cleanup",
25171 value: function cleanup() {
25172 return false;
25173 }
25174 /**
25175 * Set new edge options.
25176 *
25177 * @param options - The new edge options object.
25178 */
25179
25180 }, {
25181 key: "setOptions",
25182 value: function setOptions(options) {
25183 this.options = options;
25184 this.from = this._body.nodes[this.options.from];
25185 this.to = this._body.nodes[this.options.to];
25186 this.id = this.options.id;
25187 }
25188 /** @inheritDoc */
25189
25190 }, {
25191 key: "drawLine",
25192 value: function drawLine(ctx, values, _selected, _hover) {
25193 var viaNode = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.getViaNode();
25194 // set style
25195 ctx.strokeStyle = this.getColor(ctx, values);
25196 ctx.lineWidth = values.width;
25197
25198 if (values.dashes !== false) {
25199 this._drawDashedLine(ctx, values, viaNode);
25200 } else {
25201 this._drawLine(ctx, values, viaNode);
25202 }
25203 }
25204 /**
25205 * Draw a line with given style between two nodes through supplied node(s).
25206 *
25207 * @param ctx - The context that will be used for rendering.
25208 * @param values - Formatting values like color, opacity or shadow.
25209 * @param viaNode - Additional control point(s) for the edge.
25210 * @param fromPoint - TODO: Seems ignored, remove?
25211 * @param toPoint - TODO: Seems ignored, remove?
25212 */
25213
25214 }, {
25215 key: "_drawLine",
25216 value: function _drawLine(ctx, values, viaNode, fromPoint, toPoint) {
25217 if (this.from != this.to) {
25218 // draw line
25219 this._line(ctx, values, viaNode, fromPoint, toPoint);
25220 } else {
25221 var _this$_getCircleData = this._getCircleData(ctx),
25222 _this$_getCircleData2 = _slicedToArray(_this$_getCircleData, 3),
25223 x = _this$_getCircleData2[0],
25224 y = _this$_getCircleData2[1],
25225 radius = _this$_getCircleData2[2];
25226
25227 this._circle(ctx, values, x, y, radius);
25228 }
25229 }
25230 /**
25231 * Draw a dashed line with given style between two nodes through supplied node(s).
25232 *
25233 * @param ctx - The context that will be used for rendering.
25234 * @param values - Formatting values like color, opacity or shadow.
25235 * @param viaNode - Additional control point(s) for the edge.
25236 * @param _fromPoint - Ignored (TODO: remove in the future).
25237 * @param _toPoint - Ignored (TODO: remove in the future).
25238 */
25239
25240 }, {
25241 key: "_drawDashedLine",
25242 value: function _drawDashedLine(ctx, values, viaNode, _fromPoint, _toPoint) {
25243 ctx.lineCap = "round";
25244 var pattern = isArray$2(values.dashes) ? values.dashes : [5, 5]; // only firefox and chrome support this method, else we use the legacy one.
25245
25246 if (ctx.setLineDash !== undefined) {
25247 ctx.save(); // set dash settings for chrome or firefox
25248
25249 ctx.setLineDash(pattern);
25250 ctx.lineDashOffset = 0; // draw the line
25251
25252 if (this.from != this.to) {
25253 // draw line
25254 this._line(ctx, values, viaNode);
25255 } else {
25256 var _this$_getCircleData3 = this._getCircleData(ctx),
25257 _this$_getCircleData4 = _slicedToArray(_this$_getCircleData3, 3),
25258 x = _this$_getCircleData4[0],
25259 y = _this$_getCircleData4[1],
25260 radius = _this$_getCircleData4[2];
25261
25262 this._circle(ctx, values, x, y, radius);
25263 } // restore the dash settings.
25264
25265
25266 ctx.setLineDash([0]);
25267 ctx.lineDashOffset = 0;
25268 ctx.restore();
25269 } else {
25270 // unsupporting smooth lines
25271 if (this.from != this.to) {
25272 // draw line
25273 drawDashedLine(ctx, this.from.x, this.from.y, this.to.x, this.to.y, pattern);
25274 } else {
25275 var _this$_getCircleData5 = this._getCircleData(ctx),
25276 _this$_getCircleData6 = _slicedToArray(_this$_getCircleData5, 3),
25277 _x = _this$_getCircleData6[0],
25278 _y = _this$_getCircleData6[1],
25279 _radius = _this$_getCircleData6[2];
25280
25281 this._circle(ctx, values, _x, _y, _radius);
25282 } // draw shadow if enabled
25283
25284
25285 this.enableShadow(ctx, values);
25286 ctx.stroke(); // disable shadows for other elements.
25287
25288 this.disableShadow(ctx, values);
25289 }
25290 }
25291 /**
25292 * Find the intersection between the border of the node and the edge.
25293 *
25294 * @param node - The node (either from or to node of the edge).
25295 * @param ctx - The context that will be used for rendering.
25296 * @param options - Additional options.
25297 *
25298 * @returns Cartesian coordinates of the intersection between the border of the node and the edge.
25299 */
25300
25301 }, {
25302 key: "findBorderPosition",
25303 value: function findBorderPosition(node, ctx, options) {
25304 if (this.from != this.to) {
25305 return this._findBorderPosition(node, ctx, options);
25306 } else {
25307 return this._findBorderPositionCircle(node, ctx, options);
25308 }
25309 }
25310 /** @inheritDoc */
25311
25312 }, {
25313 key: "findBorderPositions",
25314 value: function findBorderPositions(ctx) {
25315 if (this.from != this.to) {
25316 return {
25317 from: this._findBorderPosition(this.from, ctx),
25318 to: this._findBorderPosition(this.to, ctx)
25319 };
25320 } else {
25321 var _context;
25322
25323 var _this$_getCircleData$ = slice$1(_context = this._getCircleData(ctx)).call(_context, 0, 2),
25324 _this$_getCircleData$2 = _slicedToArray(_this$_getCircleData$, 2),
25325 x = _this$_getCircleData$2[0],
25326 y = _this$_getCircleData$2[1];
25327
25328 return {
25329 from: this._findBorderPositionCircle(this.from, ctx, {
25330 x: x,
25331 y: y,
25332 low: 0.25,
25333 high: 0.6,
25334 direction: -1
25335 }),
25336 to: this._findBorderPositionCircle(this.from, ctx, {
25337 x: x,
25338 y: y,
25339 low: 0.6,
25340 high: 0.8,
25341 direction: 1
25342 })
25343 };
25344 }
25345 }
25346 /**
25347 * Compute the center point and radius of an edge connected to the same node at both ends.
25348 *
25349 * @param ctx - The context that will be used for rendering.
25350 *
25351 * @returns `[x, y, radius]`
25352 */
25353
25354 }, {
25355 key: "_getCircleData",
25356 value: function _getCircleData(ctx) {
25357 var radius = this.options.selfReference.size;
25358
25359 if (ctx !== undefined) {
25360 if (this.from.shape.width === undefined) {
25361 this.from.shape.resize(ctx);
25362 }
25363 } // get circle coordinates
25364
25365
25366 var coordinates = getSelfRefCoordinates(ctx, this.options.selfReference.angle, radius, this.from);
25367 return [coordinates.x, coordinates.y, radius];
25368 }
25369 /**
25370 * Get a point on a circle.
25371 *
25372 * @param x - Center of the circle on the x axis.
25373 * @param y - Center of the circle on the y axis.
25374 * @param radius - Radius of the circle.
25375 * @param position - Value between 0 (line start) and 1 (line end).
25376 *
25377 * @returns Cartesian coordinates of requested point on the circle.
25378 */
25379
25380 }, {
25381 key: "_pointOnCircle",
25382 value: function _pointOnCircle(x, y, radius, position) {
25383 var angle = position * 2 * Math.PI;
25384 return {
25385 x: x + radius * Math.cos(angle),
25386 y: y - radius * Math.sin(angle)
25387 };
25388 }
25389 /**
25390 * Find the intersection between the border of the node and the edge.
25391 *
25392 * @remarks
25393 * This function uses binary search to look for the point where the circle crosses the border of the node.
25394 *
25395 * @param nearNode - The node (either from or to node of the edge).
25396 * @param ctx - The context that will be used for rendering.
25397 * @param options - Additional options.
25398 *
25399 * @returns Cartesian coordinates of the intersection between the border of the node and the edge.
25400 */
25401
25402 }, {
25403 key: "_findBorderPositionCircle",
25404 value: function _findBorderPositionCircle(nearNode, ctx, options) {
25405 var x = options.x;
25406 var y = options.y;
25407 var low = options.low;
25408 var high = options.high;
25409 var direction = options.direction;
25410 var maxIterations = 10;
25411 var radius = this.options.selfReference.size;
25412 var threshold = 0.05;
25413 var pos;
25414 var middle = (low + high) * 0.5;
25415 var endPointOffset = 0;
25416
25417 if (this.options.arrowStrikethrough === true) {
25418 if (direction === -1) {
25419 endPointOffset = this.options.endPointOffset.from;
25420 } else if (direction === 1) {
25421 endPointOffset = this.options.endPointOffset.to;
25422 }
25423 }
25424
25425 var iteration = 0;
25426
25427 do {
25428 middle = (low + high) * 0.5;
25429 pos = this._pointOnCircle(x, y, radius, middle);
25430 var angle = Math.atan2(nearNode.y - pos.y, nearNode.x - pos.x);
25431 var distanceToBorder = nearNode.distanceToBorder(ctx, angle) + endPointOffset;
25432 var distanceToPoint = Math.sqrt(Math.pow(pos.x - nearNode.x, 2) + Math.pow(pos.y - nearNode.y, 2));
25433 var difference = distanceToBorder - distanceToPoint;
25434
25435 if (Math.abs(difference) < threshold) {
25436 break; // found
25437 } else if (difference > 0) {
25438 // distance to nodes is larger than distance to border --> t needs to be bigger if we're looking at the to node.
25439 if (direction > 0) {
25440 low = middle;
25441 } else {
25442 high = middle;
25443 }
25444 } else {
25445 if (direction > 0) {
25446 high = middle;
25447 } else {
25448 low = middle;
25449 }
25450 }
25451
25452 ++iteration;
25453 } while (low <= high && iteration < maxIterations);
25454
25455 return _objectSpread$1(_objectSpread$1({}, pos), {}, {
25456 t: middle
25457 });
25458 }
25459 /**
25460 * Get the line width of the edge. Depends on width and whether one of the connected nodes is selected.
25461 *
25462 * @param selected - Determines wheter the line is selected.
25463 * @param hover - Determines wheter the line is being hovered, only applies if selected is false.
25464 *
25465 * @returns The width of the line.
25466 */
25467
25468 }, {
25469 key: "getLineWidth",
25470 value: function getLineWidth(selected, hover) {
25471 if (selected === true) {
25472 return Math.max(this.selectionWidth, 0.3 / this._body.view.scale);
25473 } else if (hover === true) {
25474 return Math.max(this.hoverWidth, 0.3 / this._body.view.scale);
25475 } else {
25476 return Math.max(this.options.width, 0.3 / this._body.view.scale);
25477 }
25478 }
25479 /**
25480 * Compute the color or gradient for given edge.
25481 *
25482 * @param ctx - The context that will be used for rendering.
25483 * @param values - Formatting values like color, opacity or shadow.
25484 * @param _selected - Ignored (TODO: remove in the future).
25485 * @param _hover - Ignored (TODO: remove in the future).
25486 *
25487 * @returns Color string if single color is inherited or gradient if two.
25488 */
25489
25490 }, {
25491 key: "getColor",
25492 value: function getColor(ctx, values) {
25493 if (values.inheritsColor !== false) {
25494 // when this is a loop edge, just use the 'from' method
25495 if (values.inheritsColor === "both" && this.from.id !== this.to.id) {
25496 var grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y);
25497 var fromColor = this.from.options.color.highlight.border;
25498 var toColor = this.to.options.color.highlight.border;
25499
25500 if (this.from.selected === false && this.to.selected === false) {
25501 fromColor = overrideOpacity(this.from.options.color.border, values.opacity);
25502 toColor = overrideOpacity(this.to.options.color.border, values.opacity);
25503 } else if (this.from.selected === true && this.to.selected === false) {
25504 toColor = this.to.options.color.border;
25505 } else if (this.from.selected === false && this.to.selected === true) {
25506 fromColor = this.from.options.color.border;
25507 }
25508
25509 grd.addColorStop(0, fromColor);
25510 grd.addColorStop(1, toColor); // -------------------- this returns -------------------- //
25511
25512 return grd;
25513 }
25514
25515 if (values.inheritsColor === "to") {
25516 return overrideOpacity(this.to.options.color.border, values.opacity);
25517 } else {
25518 // "from"
25519 return overrideOpacity(this.from.options.color.border, values.opacity);
25520 }
25521 } else {
25522 return overrideOpacity(values.color, values.opacity);
25523 }
25524 }
25525 /**
25526 * Draw a line from a node to itself, a circle.
25527 *
25528 * @param ctx - The context that will be used for rendering.
25529 * @param values - Formatting values like color, opacity or shadow.
25530 * @param x - Center of the circle on the x axis.
25531 * @param y - Center of the circle on the y axis.
25532 * @param radius - Radius of the circle.
25533 */
25534
25535 }, {
25536 key: "_circle",
25537 value: function _circle(ctx, values, x, y, radius) {
25538 // draw shadow if enabled
25539 this.enableShadow(ctx, values); //full circle
25540
25541 var angleFrom = 0;
25542 var angleTo = Math.PI * 2;
25543
25544 if (!this.options.selfReference.renderBehindTheNode) {
25545 //render only parts which are not overlaping with parent node
25546 //need to find x,y of from point and x,y to point
25547 //calculating radians
25548 var low = this.options.selfReference.angle;
25549 var high = this.options.selfReference.angle + Math.PI;
25550
25551 var pointTFrom = this._findBorderPositionCircle(this.from, ctx, {
25552 x: x,
25553 y: y,
25554 low: low,
25555 high: high,
25556 direction: -1
25557 });
25558
25559 var pointTTo = this._findBorderPositionCircle(this.from, ctx, {
25560 x: x,
25561 y: y,
25562 low: low,
25563 high: high,
25564 direction: 1
25565 });
25566
25567 angleFrom = Math.atan2(pointTFrom.y - y, pointTFrom.x - x);
25568 angleTo = Math.atan2(pointTTo.y - y, pointTTo.x - x);
25569 } // draw a circle
25570
25571
25572 ctx.beginPath();
25573 ctx.arc(x, y, radius, angleFrom, angleTo, false);
25574 ctx.stroke(); // disable shadows for other elements.
25575
25576 this.disableShadow(ctx, values);
25577 }
25578 /**
25579 * @inheritDoc
25580 *
25581 * @remarks
25582 * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
25583 */
25584
25585 }, {
25586 key: "getDistanceToEdge",
25587 value: function getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
25588 if (this.from != this.to) {
25589 return this._getDistanceToEdge(x1, y1, x2, y2, x3, y3);
25590 } else {
25591 var _this$_getCircleData7 = this._getCircleData(undefined),
25592 _this$_getCircleData8 = _slicedToArray(_this$_getCircleData7, 3),
25593 x = _this$_getCircleData8[0],
25594 y = _this$_getCircleData8[1],
25595 radius = _this$_getCircleData8[2];
25596
25597 var dx = x - x3;
25598 var dy = y - y3;
25599 return Math.abs(Math.sqrt(dx * dx + dy * dy) - radius);
25600 }
25601 }
25602 /**
25603 * Calculate the distance between a point (x3, y3) and a line segment from (x1, y1) to (x2, y2).
25604 *
25605 * @param x1 - First end of the line segment on the x axis.
25606 * @param y1 - First end of the line segment on the y axis.
25607 * @param x2 - Second end of the line segment on the x axis.
25608 * @param y2 - Second end of the line segment on the y axis.
25609 * @param x3 - Position of the point on the x axis.
25610 * @param y3 - Position of the point on the y axis.
25611 *
25612 * @returns The distance between the line segment and the point.
25613 */
25614
25615 }, {
25616 key: "_getDistanceToLine",
25617 value: function _getDistanceToLine(x1, y1, x2, y2, x3, y3) {
25618 var px = x2 - x1;
25619 var py = y2 - y1;
25620 var something = px * px + py * py;
25621 var u = ((x3 - x1) * px + (y3 - y1) * py) / something;
25622
25623 if (u > 1) {
25624 u = 1;
25625 } else if (u < 0) {
25626 u = 0;
25627 }
25628
25629 var x = x1 + u * px;
25630 var y = y1 + u * py;
25631 var dx = x - x3;
25632 var dy = y - y3; //# Note: If the actual distance does not matter,
25633 //# if you only want to compare what this function
25634 //# returns to other results of this function, you
25635 //# can just return the squared distance instead
25636 //# (i.e. remove the sqrt) to gain a little performance
25637
25638 return Math.sqrt(dx * dx + dy * dy);
25639 }
25640 /** @inheritDoc */
25641
25642 }, {
25643 key: "getArrowData",
25644 value: function getArrowData(ctx, position, viaNode, _selected, _hover, values) {
25645 // set lets
25646 var angle;
25647 var arrowPoint;
25648 var node1;
25649 var node2;
25650 var reversed;
25651 var scaleFactor;
25652 var type;
25653 var lineWidth = values.width;
25654
25655 if (position === "from") {
25656 node1 = this.from;
25657 node2 = this.to;
25658 reversed = values.fromArrowScale < 0;
25659 scaleFactor = Math.abs(values.fromArrowScale);
25660 type = values.fromArrowType;
25661 } else if (position === "to") {
25662 node1 = this.to;
25663 node2 = this.from;
25664 reversed = values.toArrowScale < 0;
25665 scaleFactor = Math.abs(values.toArrowScale);
25666 type = values.toArrowType;
25667 } else {
25668 node1 = this.to;
25669 node2 = this.from;
25670 reversed = values.middleArrowScale < 0;
25671 scaleFactor = Math.abs(values.middleArrowScale);
25672 type = values.middleArrowType;
25673 }
25674
25675 var length = 15 * scaleFactor + 3 * lineWidth; // 3* lineWidth is the width of the edge.
25676 // if not connected to itself
25677
25678 if (node1 != node2) {
25679 var approximateEdgeLength = hypot(node1.x - node2.x, node1.y - node2.y);
25680
25681 var relativeLength = length / approximateEdgeLength;
25682
25683 if (position !== "middle") {
25684 // draw arrow head
25685 if (this.options.smooth.enabled === true) {
25686 var pointT = this._findBorderPosition(node1, ctx, {
25687 via: viaNode
25688 });
25689
25690 var guidePos = this.getPoint(pointT.t + relativeLength * (position === "from" ? 1 : -1), viaNode);
25691 angle = Math.atan2(pointT.y - guidePos.y, pointT.x - guidePos.x);
25692 arrowPoint = pointT;
25693 } else {
25694 angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
25695 arrowPoint = this._findBorderPosition(node1, ctx);
25696 }
25697 } else {
25698 // Negative half length reverses arrow direction.
25699 var halfLength = (reversed ? -relativeLength : relativeLength) / 2;
25700 var guidePos1 = this.getPoint(0.5 + halfLength, viaNode);
25701 var guidePos2 = this.getPoint(0.5 - halfLength, viaNode);
25702 angle = Math.atan2(guidePos1.y - guidePos2.y, guidePos1.x - guidePos2.x);
25703 arrowPoint = this.getPoint(0.5, viaNode);
25704 }
25705 } else {
25706 // draw circle
25707 var _this$_getCircleData9 = this._getCircleData(ctx),
25708 _this$_getCircleData10 = _slicedToArray(_this$_getCircleData9, 3),
25709 x = _this$_getCircleData10[0],
25710 y = _this$_getCircleData10[1],
25711 radius = _this$_getCircleData10[2];
25712
25713 if (position === "from") {
25714 var low = this.options.selfReference.angle;
25715 var high = this.options.selfReference.angle + Math.PI;
25716
25717 var _pointT = this._findBorderPositionCircle(this.from, ctx, {
25718 x: x,
25719 y: y,
25720 low: low,
25721 high: high,
25722 direction: -1
25723 });
25724
25725 angle = _pointT.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
25726 arrowPoint = _pointT;
25727 } else if (position === "to") {
25728 var _low = this.options.selfReference.angle;
25729
25730 var _high = this.options.selfReference.angle + Math.PI;
25731
25732 var _pointT2 = this._findBorderPositionCircle(this.from, ctx, {
25733 x: x,
25734 y: y,
25735 low: _low,
25736 high: _high,
25737 direction: 1
25738 });
25739
25740 angle = _pointT2.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
25741 arrowPoint = _pointT2;
25742 } else {
25743 var pos = this.options.selfReference.angle / (2 * Math.PI);
25744 arrowPoint = this._pointOnCircle(x, y, radius, pos);
25745 angle = pos * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
25746 }
25747 }
25748
25749 var xi = arrowPoint.x - length * 0.9 * Math.cos(angle);
25750 var yi = arrowPoint.y - length * 0.9 * Math.sin(angle);
25751 var arrowCore = {
25752 x: xi,
25753 y: yi
25754 };
25755 return {
25756 point: arrowPoint,
25757 core: arrowCore,
25758 angle: angle,
25759 length: length,
25760 type: type
25761 };
25762 }
25763 /** @inheritDoc */
25764
25765 }, {
25766 key: "drawArrowHead",
25767 value: function drawArrowHead(ctx, values, _selected, _hover, arrowData) {
25768 // set style
25769 ctx.strokeStyle = this.getColor(ctx, values);
25770 ctx.fillStyle = ctx.strokeStyle;
25771 ctx.lineWidth = values.width;
25772 var canFill = EndPoints.draw(ctx, arrowData);
25773
25774 if (canFill) {
25775 // draw shadow if enabled
25776 this.enableShadow(ctx, values);
25777
25778 fill(ctx).call(ctx); // disable shadows for other elements.
25779
25780
25781 this.disableShadow(ctx, values);
25782 }
25783 }
25784 /**
25785 * Set the shadow formatting values in the context if enabled, do nothing otherwise.
25786 *
25787 * @param ctx - The context that will be used for rendering.
25788 * @param values - Formatting values for the shadow.
25789 */
25790
25791 }, {
25792 key: "enableShadow",
25793 value: function enableShadow(ctx, values) {
25794 if (values.shadow === true) {
25795 ctx.shadowColor = values.shadowColor;
25796 ctx.shadowBlur = values.shadowSize;
25797 ctx.shadowOffsetX = values.shadowX;
25798 ctx.shadowOffsetY = values.shadowY;
25799 }
25800 }
25801 /**
25802 * Reset the shadow formatting values in the context if enabled, do nothing otherwise.
25803 *
25804 * @param ctx - The context that will be used for rendering.
25805 * @param values - Formatting values for the shadow.
25806 */
25807
25808 }, {
25809 key: "disableShadow",
25810 value: function disableShadow(ctx, values) {
25811 if (values.shadow === true) {
25812 ctx.shadowColor = "rgba(0,0,0,0)";
25813 ctx.shadowBlur = 0;
25814 ctx.shadowOffsetX = 0;
25815 ctx.shadowOffsetY = 0;
25816 }
25817 }
25818 /**
25819 * Render the background according to the formatting values.
25820 *
25821 * @param ctx - The context that will be used for rendering.
25822 * @param values - Formatting values for the background.
25823 */
25824
25825 }, {
25826 key: "drawBackground",
25827 value: function drawBackground(ctx, values) {
25828 if (values.background !== false) {
25829 // save original line attrs
25830 var origCtxAttr = {
25831 strokeStyle: ctx.strokeStyle,
25832 lineWidth: ctx.lineWidth,
25833 dashes: ctx.dashes
25834 };
25835 ctx.strokeStyle = values.backgroundColor;
25836 ctx.lineWidth = values.backgroundSize;
25837 this.setStrokeDashed(ctx, values.backgroundDashes);
25838 ctx.stroke(); // restore original line attrs
25839
25840 ctx.strokeStyle = origCtxAttr.strokeStyle;
25841 ctx.lineWidth = origCtxAttr.lineWidth;
25842 ctx.dashes = origCtxAttr.dashes;
25843 this.setStrokeDashed(ctx, values.dashes);
25844 }
25845 }
25846 /**
25847 * Set the line dash pattern if supported. Logs a warning to the console if it isn't supported.
25848 *
25849 * @param ctx - The context that will be used for rendering.
25850 * @param dashes - The pattern [line, space, line…], true for default dashed line or false for normal line.
25851 */
25852
25853 }, {
25854 key: "setStrokeDashed",
25855 value: function setStrokeDashed(ctx, dashes) {
25856 if (dashes !== false) {
25857 if (ctx.setLineDash !== undefined) {
25858 var pattern = isArray$2(dashes) ? dashes : [5, 5];
25859 ctx.setLineDash(pattern);
25860 } else {
25861 console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");
25862 }
25863 } else {
25864 if (ctx.setLineDash !== undefined) {
25865 ctx.setLineDash([]);
25866 } else {
25867 console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");
25868 }
25869 }
25870 }
25871 }]);
25872
25873 return EdgeBase;
25874}();
25875
25876function ownKeys(object, enumerableOnly) { var keys = keys$4(object); if (getOwnPropertySymbols) { var symbols = getOwnPropertySymbols(object); if (enumerableOnly) { symbols = filter(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$2(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
25877
25878function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { var _context; forEach$2(_context = ownKeys(Object(source), true)).call(_context, function (key) { _defineProperty(target, key, source[key]); }); } else if (getOwnPropertyDescriptors) { defineProperties(target, getOwnPropertyDescriptors(source)); } else { var _context2; forEach$2(_context2 = ownKeys(Object(source))).call(_context2, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$2(source, key)); }); } } return target; }
25879
25880function _createSuper$9(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$9(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
25881
25882function _isNativeReflectConstruct$9() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
25883/**
25884 * The Base Class for all Bezier edges.
25885 * Bezier curves are used to model smooth gradual curves in paths between nodes.
25886 */
25887
25888var BezierEdgeBase = /*#__PURE__*/function (_EdgeBase) {
25889 _inherits(BezierEdgeBase, _EdgeBase);
25890
25891 var _super = _createSuper$9(BezierEdgeBase);
25892
25893 /**
25894 * Create a new instance.
25895 *
25896 * @param options - The options object of given edge.
25897 * @param body - The body of the network.
25898 * @param labelModule - Label module.
25899 */
25900 function BezierEdgeBase(options, body, labelModule) {
25901 _classCallCheck(this, BezierEdgeBase);
25902
25903 return _super.call(this, options, body, labelModule);
25904 }
25905 /**
25906 * Find the intersection between the border of the node and the edge.
25907 *
25908 * @remarks
25909 * This function uses binary search to look for the point where the bezier curve crosses the border of the node.
25910 *
25911 * @param nearNode - The node (either from or to node of the edge).
25912 * @param ctx - The context that will be used for rendering.
25913 * @param viaNode - Additional node(s) the edge passes through.
25914 *
25915 * @returns Cartesian coordinates of the intersection between the border of the node and the edge.
25916 */
25917
25918
25919 _createClass(BezierEdgeBase, [{
25920 key: "_findBorderPositionBezier",
25921 value: function _findBorderPositionBezier(nearNode, ctx) {
25922 var viaNode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._getViaCoordinates();
25923 var maxIterations = 10;
25924 var threshold = 0.2;
25925 var from = false;
25926 var high = 1;
25927 var low = 0;
25928 var node = this.to;
25929 var pos;
25930 var middle;
25931 var endPointOffset = this.options.endPointOffset ? this.options.endPointOffset.to : 0;
25932
25933 if (nearNode.id === this.from.id) {
25934 node = this.from;
25935 from = true;
25936 endPointOffset = this.options.endPointOffset ? this.options.endPointOffset.from : 0;
25937 }
25938
25939 if (this.options.arrowStrikethrough === false) {
25940 endPointOffset = 0;
25941 }
25942
25943 var iteration = 0;
25944
25945 do {
25946 middle = (low + high) * 0.5;
25947 pos = this.getPoint(middle, viaNode);
25948 var angle = Math.atan2(node.y - pos.y, node.x - pos.x);
25949 var distanceToBorder = node.distanceToBorder(ctx, angle) + endPointOffset;
25950 var distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2));
25951 var difference = distanceToBorder - distanceToPoint;
25952
25953 if (Math.abs(difference) < threshold) {
25954 break; // found
25955 } else if (difference < 0) {
25956 // distance to nodes is larger than distance to border --> t needs to be bigger if we're looking at the to node.
25957 if (from === false) {
25958 low = middle;
25959 } else {
25960 high = middle;
25961 }
25962 } else {
25963 if (from === false) {
25964 high = middle;
25965 } else {
25966 low = middle;
25967 }
25968 }
25969
25970 ++iteration;
25971 } while (low <= high && iteration < maxIterations);
25972
25973 return _objectSpread(_objectSpread({}, pos), {}, {
25974 t: middle
25975 });
25976 }
25977 /**
25978 * Calculate the distance between a point (x3,y3) and a line segment from (x1,y1) to (x2,y2).
25979 *
25980 * @remarks
25981 * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
25982 *
25983 * @param x1 - First end of the line segment on the x axis.
25984 * @param y1 - First end of the line segment on the y axis.
25985 * @param x2 - Second end of the line segment on the x axis.
25986 * @param y2 - Second end of the line segment on the y axis.
25987 * @param x3 - Position of the point on the x axis.
25988 * @param y3 - Position of the point on the y axis.
25989 * @param via - The control point for the edge.
25990 *
25991 * @returns The distance between the line segment and the point.
25992 */
25993
25994 }, {
25995 key: "_getDistanceToBezierEdge",
25996 value: function _getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via) {
25997 // x3,y3 is the point
25998 var minDistance = 1e9;
25999 var distance;
26000 var i, t, x, y;
26001 var lastX = x1;
26002 var lastY = y1;
26003
26004 for (i = 1; i < 10; i++) {
26005 t = 0.1 * i;
26006 x = Math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * via.x + Math.pow(t, 2) * x2;
26007 y = Math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * via.y + Math.pow(t, 2) * y2;
26008
26009 if (i > 0) {
26010 distance = this._getDistanceToLine(lastX, lastY, x, y, x3, y3);
26011 minDistance = distance < minDistance ? distance : minDistance;
26012 }
26013
26014 lastX = x;
26015 lastY = y;
26016 }
26017
26018 return minDistance;
26019 }
26020 /**
26021 * Render a bezier curve between two nodes.
26022 *
26023 * @remarks
26024 * The method accepts zero, one or two control points.
26025 * Passing zero control points just draws a straight line.
26026 *
26027 * @param ctx - The context that will be used for rendering.
26028 * @param values - Style options for edge drawing.
26029 * @param viaNode1 - First control point for curve drawing.
26030 * @param viaNode2 - Second control point for curve drawing.
26031 */
26032
26033 }, {
26034 key: "_bezierCurve",
26035 value: function _bezierCurve(ctx, values, viaNode1, viaNode2) {
26036 ctx.beginPath();
26037 ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
26038
26039 if (viaNode1 != null && viaNode1.x != null) {
26040 if (viaNode2 != null && viaNode2.x != null) {
26041 ctx.bezierCurveTo(viaNode1.x, viaNode1.y, viaNode2.x, viaNode2.y, this.toPoint.x, this.toPoint.y);
26042 } else {
26043 ctx.quadraticCurveTo(viaNode1.x, viaNode1.y, this.toPoint.x, this.toPoint.y);
26044 }
26045 } else {
26046 // fallback to normal straight edge
26047 ctx.lineTo(this.toPoint.x, this.toPoint.y);
26048 } // draw a background
26049
26050
26051 this.drawBackground(ctx, values); // draw shadow if enabled
26052
26053 this.enableShadow(ctx, values);
26054 ctx.stroke();
26055 this.disableShadow(ctx, values);
26056 }
26057 /** @inheritDoc */
26058
26059 }, {
26060 key: "getViaNode",
26061 value: function getViaNode() {
26062 return this._getViaCoordinates();
26063 }
26064 }]);
26065
26066 return BezierEdgeBase;
26067}(EdgeBase);
26068
26069function _createSuper$8(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$8(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
26070
26071function _isNativeReflectConstruct$8() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
26072/**
26073 * A Dynamic Bezier Edge. Bezier curves are used to model smooth gradual
26074 * curves in paths between nodes. The Dynamic piece refers to how the curve
26075 * reacts to physics changes.
26076 *
26077 * @augments BezierEdgeBase
26078 */
26079
26080var BezierEdgeDynamic = /*#__PURE__*/function (_BezierEdgeBase) {
26081 _inherits(BezierEdgeDynamic, _BezierEdgeBase);
26082
26083 var _super = _createSuper$8(BezierEdgeDynamic);
26084
26085 /**
26086 * Create a new instance.
26087 *
26088 * @param options - The options object of given edge.
26089 * @param body - The body of the network.
26090 * @param labelModule - Label module.
26091 */
26092 function BezierEdgeDynamic(options, body, labelModule) {
26093 var _this;
26094
26095 _classCallCheck(this, BezierEdgeDynamic);
26096
26097 //this.via = undefined; // Here for completeness but not allowed to defined before super() is invoked.
26098 _this = _super.call(this, options, body, labelModule); // --> this calls the setOptions below
26099
26100 _this.via = _this.via; // constructor → super → super → setOptions → setupSupportNode
26101
26102 _this._boundFunction = function () {
26103 _this.positionBezierNode();
26104 };
26105
26106 _this._body.emitter.on("_repositionBezierNodes", _this._boundFunction);
26107
26108 return _this;
26109 }
26110 /** @inheritDoc */
26111
26112
26113 _createClass(BezierEdgeDynamic, [{
26114 key: "setOptions",
26115 value: function setOptions(options) {
26116 _get(_getPrototypeOf(BezierEdgeDynamic.prototype), "setOptions", this).call(this, options); // check if the physics has changed.
26117
26118
26119 var physicsChange = false;
26120
26121 if (this.options.physics !== options.physics) {
26122 physicsChange = true;
26123 } // set the options and the to and from nodes
26124
26125
26126 this.options = options;
26127 this.id = this.options.id;
26128 this.from = this._body.nodes[this.options.from];
26129 this.to = this._body.nodes[this.options.to]; // setup the support node and connect
26130
26131 this.setupSupportNode();
26132 this.connect(); // when we change the physics state of the edge, we reposition the support node.
26133
26134 if (physicsChange === true) {
26135 this.via.setOptions({
26136 physics: this.options.physics
26137 });
26138 this.positionBezierNode();
26139 }
26140 }
26141 /** @inheritDoc */
26142
26143 }, {
26144 key: "connect",
26145 value: function connect() {
26146 this.from = this._body.nodes[this.options.from];
26147 this.to = this._body.nodes[this.options.to];
26148
26149 if (this.from === undefined || this.to === undefined || this.options.physics === false) {
26150 this.via.setOptions({
26151 physics: false
26152 });
26153 } else {
26154 // fix weird behaviour where a self referencing node has physics enabled
26155 if (this.from.id === this.to.id) {
26156 this.via.setOptions({
26157 physics: false
26158 });
26159 } else {
26160 this.via.setOptions({
26161 physics: true
26162 });
26163 }
26164 }
26165 }
26166 /** @inheritDoc */
26167
26168 }, {
26169 key: "cleanup",
26170 value: function cleanup() {
26171 this._body.emitter.off("_repositionBezierNodes", this._boundFunction);
26172
26173 if (this.via !== undefined) {
26174 delete this._body.nodes[this.via.id];
26175 this.via = undefined;
26176 return true;
26177 }
26178
26179 return false;
26180 }
26181 /**
26182 * Create and add a support node if not already present.
26183 *
26184 * @remarks
26185 * Bezier curves require an anchor point to calculate the smooth flow.
26186 * These points are nodes.
26187 * These nodes are invisible but are used for the force calculation.
26188 *
26189 * The changed data is not called, if needed, it is returned by the main edge constructor.
26190 */
26191
26192 }, {
26193 key: "setupSupportNode",
26194 value: function setupSupportNode() {
26195 if (this.via === undefined) {
26196 var nodeId = "edgeId:" + this.id;
26197
26198 var node = this._body.functions.createNode({
26199 id: nodeId,
26200 shape: "circle",
26201 physics: true,
26202 hidden: true
26203 });
26204
26205 this._body.nodes[nodeId] = node;
26206 this.via = node;
26207 this.via.parentEdgeId = this.id;
26208 this.positionBezierNode();
26209 }
26210 }
26211 /**
26212 * Position bezier node.
26213 */
26214
26215 }, {
26216 key: "positionBezierNode",
26217 value: function positionBezierNode() {
26218 if (this.via !== undefined && this.from !== undefined && this.to !== undefined) {
26219 this.via.x = 0.5 * (this.from.x + this.to.x);
26220 this.via.y = 0.5 * (this.from.y + this.to.y);
26221 } else if (this.via !== undefined) {
26222 this.via.x = 0;
26223 this.via.y = 0;
26224 }
26225 }
26226 /** @inheritDoc */
26227
26228 }, {
26229 key: "_line",
26230 value: function _line(ctx, values, viaNode) {
26231 this._bezierCurve(ctx, values, viaNode);
26232 }
26233 /** @inheritDoc */
26234
26235 }, {
26236 key: "_getViaCoordinates",
26237 value: function _getViaCoordinates() {
26238 return this.via;
26239 }
26240 /** @inheritDoc */
26241
26242 }, {
26243 key: "getViaNode",
26244 value: function getViaNode() {
26245 return this.via;
26246 }
26247 /** @inheritDoc */
26248
26249 }, {
26250 key: "getPoint",
26251 value: function getPoint(position) {
26252 var viaNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.via;
26253
26254 if (this.from === this.to) {
26255 var _this$_getCircleData = this._getCircleData(),
26256 _this$_getCircleData2 = _slicedToArray(_this$_getCircleData, 3),
26257 cx = _this$_getCircleData2[0],
26258 cy = _this$_getCircleData2[1],
26259 cr = _this$_getCircleData2[2];
26260
26261 var a = 2 * Math.PI * (1 - position);
26262 return {
26263 x: cx + cr * Math.sin(a),
26264 y: cy + cr - cr * (1 - Math.cos(a))
26265 };
26266 } else {
26267 return {
26268 x: Math.pow(1 - position, 2) * this.fromPoint.x + 2 * position * (1 - position) * viaNode.x + Math.pow(position, 2) * this.toPoint.x,
26269 y: Math.pow(1 - position, 2) * this.fromPoint.y + 2 * position * (1 - position) * viaNode.y + Math.pow(position, 2) * this.toPoint.y
26270 };
26271 }
26272 }
26273 /** @inheritDoc */
26274
26275 }, {
26276 key: "_findBorderPosition",
26277 value: function _findBorderPosition(nearNode, ctx) {
26278 return this._findBorderPositionBezier(nearNode, ctx, this.via);
26279 }
26280 /** @inheritDoc */
26281
26282 }, {
26283 key: "_getDistanceToEdge",
26284 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
26285 // x3,y3 is the point
26286 return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, this.via);
26287 }
26288 }]);
26289
26290 return BezierEdgeDynamic;
26291}(BezierEdgeBase);
26292
26293function _createSuper$7(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$7(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
26294
26295function _isNativeReflectConstruct$7() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
26296/**
26297 * A Static Bezier Edge. Bezier curves are used to model smooth gradual curves in paths between nodes.
26298 */
26299
26300var BezierEdgeStatic = /*#__PURE__*/function (_BezierEdgeBase) {
26301 _inherits(BezierEdgeStatic, _BezierEdgeBase);
26302
26303 var _super = _createSuper$7(BezierEdgeStatic);
26304
26305 /**
26306 * Create a new instance.
26307 *
26308 * @param options - The options object of given edge.
26309 * @param body - The body of the network.
26310 * @param labelModule - Label module.
26311 */
26312 function BezierEdgeStatic(options, body, labelModule) {
26313 _classCallCheck(this, BezierEdgeStatic);
26314
26315 return _super.call(this, options, body, labelModule);
26316 }
26317 /** @inheritDoc */
26318
26319
26320 _createClass(BezierEdgeStatic, [{
26321 key: "_line",
26322 value: function _line(ctx, values, viaNode) {
26323 this._bezierCurve(ctx, values, viaNode);
26324 }
26325 /** @inheritDoc */
26326
26327 }, {
26328 key: "getViaNode",
26329 value: function getViaNode() {
26330 return this._getViaCoordinates();
26331 }
26332 /**
26333 * Compute the coordinates of the via node.
26334 *
26335 * @remarks
26336 * We do not use the to and fromPoints here to make the via nodes the same as edges without arrows.
26337 *
26338 * @returns Cartesian coordinates of the via node.
26339 */
26340
26341 }, {
26342 key: "_getViaCoordinates",
26343 value: function _getViaCoordinates() {
26344 // Assumption: x/y coordinates in from/to always defined
26345 var factor = this.options.smooth.roundness;
26346 var type = this.options.smooth.type;
26347 var dx = Math.abs(this.from.x - this.to.x);
26348 var dy = Math.abs(this.from.y - this.to.y);
26349
26350 if (type === "discrete" || type === "diagonalCross") {
26351 var stepX;
26352 var stepY;
26353
26354 if (dx <= dy) {
26355 stepX = stepY = factor * dy;
26356 } else {
26357 stepX = stepY = factor * dx;
26358 }
26359
26360 if (this.from.x > this.to.x) {
26361 stepX = -stepX;
26362 }
26363
26364 if (this.from.y >= this.to.y) {
26365 stepY = -stepY;
26366 }
26367
26368 var xVia = this.from.x + stepX;
26369 var yVia = this.from.y + stepY;
26370
26371 if (type === "discrete") {
26372 if (dx <= dy) {
26373 xVia = dx < factor * dy ? this.from.x : xVia;
26374 } else {
26375 yVia = dy < factor * dx ? this.from.y : yVia;
26376 }
26377 }
26378
26379 return {
26380 x: xVia,
26381 y: yVia
26382 };
26383 } else if (type === "straightCross") {
26384 var _stepX = (1 - factor) * dx;
26385
26386 var _stepY = (1 - factor) * dy;
26387
26388 if (dx <= dy) {
26389 // up - down
26390 _stepX = 0;
26391
26392 if (this.from.y < this.to.y) {
26393 _stepY = -_stepY;
26394 }
26395 } else {
26396 // left - right
26397 if (this.from.x < this.to.x) {
26398 _stepX = -_stepX;
26399 }
26400
26401 _stepY = 0;
26402 }
26403
26404 return {
26405 x: this.to.x + _stepX,
26406 y: this.to.y + _stepY
26407 };
26408 } else if (type === "horizontal") {
26409 var _stepX2 = (1 - factor) * dx;
26410
26411 if (this.from.x < this.to.x) {
26412 _stepX2 = -_stepX2;
26413 }
26414
26415 return {
26416 x: this.to.x + _stepX2,
26417 y: this.from.y
26418 };
26419 } else if (type === "vertical") {
26420 var _stepY2 = (1 - factor) * dy;
26421
26422 if (this.from.y < this.to.y) {
26423 _stepY2 = -_stepY2;
26424 }
26425
26426 return {
26427 x: this.from.x,
26428 y: this.to.y + _stepY2
26429 };
26430 } else if (type === "curvedCW") {
26431 dx = this.to.x - this.from.x;
26432 dy = this.from.y - this.to.y;
26433 var radius = Math.sqrt(dx * dx + dy * dy);
26434 var pi = Math.PI;
26435 var originalAngle = Math.atan2(dy, dx);
26436 var myAngle = (originalAngle + (factor * 0.5 + 0.5) * pi) % (2 * pi);
26437 return {
26438 x: this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle),
26439 y: this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle)
26440 };
26441 } else if (type === "curvedCCW") {
26442 dx = this.to.x - this.from.x;
26443 dy = this.from.y - this.to.y;
26444
26445 var _radius = Math.sqrt(dx * dx + dy * dy);
26446
26447 var _pi = Math.PI;
26448
26449 var _originalAngle = Math.atan2(dy, dx);
26450
26451 var _myAngle = (_originalAngle + (-factor * 0.5 + 0.5) * _pi) % (2 * _pi);
26452
26453 return {
26454 x: this.from.x + (factor * 0.5 + 0.5) * _radius * Math.sin(_myAngle),
26455 y: this.from.y + (factor * 0.5 + 0.5) * _radius * Math.cos(_myAngle)
26456 };
26457 } else {
26458 // continuous
26459 var _stepX3;
26460
26461 var _stepY3;
26462
26463 if (dx <= dy) {
26464 _stepX3 = _stepY3 = factor * dy;
26465 } else {
26466 _stepX3 = _stepY3 = factor * dx;
26467 }
26468
26469 if (this.from.x > this.to.x) {
26470 _stepX3 = -_stepX3;
26471 }
26472
26473 if (this.from.y >= this.to.y) {
26474 _stepY3 = -_stepY3;
26475 }
26476
26477 var _xVia = this.from.x + _stepX3;
26478
26479 var _yVia = this.from.y + _stepY3;
26480
26481 if (dx <= dy) {
26482 if (this.from.x <= this.to.x) {
26483 _xVia = this.to.x < _xVia ? this.to.x : _xVia;
26484 } else {
26485 _xVia = this.to.x > _xVia ? this.to.x : _xVia;
26486 }
26487 } else {
26488 if (this.from.y >= this.to.y) {
26489 _yVia = this.to.y > _yVia ? this.to.y : _yVia;
26490 } else {
26491 _yVia = this.to.y < _yVia ? this.to.y : _yVia;
26492 }
26493 }
26494
26495 return {
26496 x: _xVia,
26497 y: _yVia
26498 };
26499 }
26500 }
26501 /** @inheritDoc */
26502
26503 }, {
26504 key: "_findBorderPosition",
26505 value: function _findBorderPosition(nearNode, ctx) {
26506 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
26507 return this._findBorderPositionBezier(nearNode, ctx, options.via);
26508 }
26509 /** @inheritDoc */
26510
26511 }, {
26512 key: "_getDistanceToEdge",
26513 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
26514 var viaNode = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : this._getViaCoordinates();
26515 // x3,y3 is the point
26516 return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, viaNode);
26517 }
26518 /** @inheritDoc */
26519
26520 }, {
26521 key: "getPoint",
26522 value: function getPoint(position) {
26523 var viaNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._getViaCoordinates();
26524 var t = position;
26525 var x = Math.pow(1 - t, 2) * this.fromPoint.x + 2 * t * (1 - t) * viaNode.x + Math.pow(t, 2) * this.toPoint.x;
26526 var y = Math.pow(1 - t, 2) * this.fromPoint.y + 2 * t * (1 - t) * viaNode.y + Math.pow(t, 2) * this.toPoint.y;
26527 return {
26528 x: x,
26529 y: y
26530 };
26531 }
26532 }]);
26533
26534 return BezierEdgeStatic;
26535}(BezierEdgeBase);
26536
26537function _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$6(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
26538
26539function _isNativeReflectConstruct$6() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
26540/**
26541 * A Base Class for all Cubic Bezier Edges. Bezier curves are used to model
26542 * smooth gradual curves in paths between nodes.
26543 *
26544 * @augments BezierEdgeBase
26545 */
26546
26547var CubicBezierEdgeBase = /*#__PURE__*/function (_BezierEdgeBase) {
26548 _inherits(CubicBezierEdgeBase, _BezierEdgeBase);
26549
26550 var _super = _createSuper$6(CubicBezierEdgeBase);
26551
26552 /**
26553 * Create a new instance.
26554 *
26555 * @param options - The options object of given edge.
26556 * @param body - The body of the network.
26557 * @param labelModule - Label module.
26558 */
26559 function CubicBezierEdgeBase(options, body, labelModule) {
26560 _classCallCheck(this, CubicBezierEdgeBase);
26561
26562 return _super.call(this, options, body, labelModule);
26563 }
26564 /**
26565 * Calculate the distance between a point (x3,y3) and a line segment from (x1,y1) to (x2,y2).
26566 *
26567 * @remarks
26568 * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
26569 * https://en.wikipedia.org/wiki/B%C3%A9zier_curve
26570 *
26571 * @param x1 - First end of the line segment on the x axis.
26572 * @param y1 - First end of the line segment on the y axis.
26573 * @param x2 - Second end of the line segment on the x axis.
26574 * @param y2 - Second end of the line segment on the y axis.
26575 * @param x3 - Position of the point on the x axis.
26576 * @param y3 - Position of the point on the y axis.
26577 * @param via1 - The first point this edge passes through.
26578 * @param via2 - The second point this edge passes through.
26579 *
26580 * @returns The distance between the line segment and the point.
26581 */
26582
26583
26584 _createClass(CubicBezierEdgeBase, [{
26585 key: "_getDistanceToBezierEdge2",
26586 value: function _getDistanceToBezierEdge2(x1, y1, x2, y2, x3, y3, via1, via2) {
26587 // x3,y3 is the point
26588 var minDistance = 1e9;
26589 var lastX = x1;
26590 var lastY = y1;
26591 var vec = [0, 0, 0, 0];
26592
26593 for (var i = 1; i < 10; i++) {
26594 var t = 0.1 * i;
26595 vec[0] = Math.pow(1 - t, 3);
26596 vec[1] = 3 * t * Math.pow(1 - t, 2);
26597 vec[2] = 3 * Math.pow(t, 2) * (1 - t);
26598 vec[3] = Math.pow(t, 3);
26599 var x = vec[0] * x1 + vec[1] * via1.x + vec[2] * via2.x + vec[3] * x2;
26600 var y = vec[0] * y1 + vec[1] * via1.y + vec[2] * via2.y + vec[3] * y2;
26601
26602 if (i > 0) {
26603 var distance = this._getDistanceToLine(lastX, lastY, x, y, x3, y3);
26604
26605 minDistance = distance < minDistance ? distance : minDistance;
26606 }
26607
26608 lastX = x;
26609 lastY = y;
26610 }
26611
26612 return minDistance;
26613 }
26614 }]);
26615
26616 return CubicBezierEdgeBase;
26617}(BezierEdgeBase);
26618
26619function _createSuper$5(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$5(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
26620
26621function _isNativeReflectConstruct$5() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
26622/**
26623 * A Cubic Bezier Edge. Bezier curves are used to model smooth gradual curves in paths between nodes.
26624 */
26625
26626var CubicBezierEdge = /*#__PURE__*/function (_CubicBezierEdgeBase) {
26627 _inherits(CubicBezierEdge, _CubicBezierEdgeBase);
26628
26629 var _super = _createSuper$5(CubicBezierEdge);
26630
26631 /**
26632 * Create a new instance.
26633 *
26634 * @param options - The options object of given edge.
26635 * @param body - The body of the network.
26636 * @param labelModule - Label module.
26637 */
26638 function CubicBezierEdge(options, body, labelModule) {
26639 _classCallCheck(this, CubicBezierEdge);
26640
26641 return _super.call(this, options, body, labelModule);
26642 }
26643 /** @inheritDoc */
26644
26645
26646 _createClass(CubicBezierEdge, [{
26647 key: "_line",
26648 value: function _line(ctx, values, viaNodes) {
26649 // get the coordinates of the support points.
26650 var via1 = viaNodes[0];
26651 var via2 = viaNodes[1];
26652
26653 this._bezierCurve(ctx, values, via1, via2);
26654 }
26655 /**
26656 * Compute the additional points the edge passes through.
26657 *
26658 * @returns Cartesian coordinates of the points the edge passes through.
26659 */
26660
26661 }, {
26662 key: "_getViaCoordinates",
26663 value: function _getViaCoordinates() {
26664 var dx = this.from.x - this.to.x;
26665 var dy = this.from.y - this.to.y;
26666 var x1;
26667 var y1;
26668 var x2;
26669 var y2;
26670 var roundness = this.options.smooth.roundness; // horizontal if x > y or if direction is forced or if direction is horizontal
26671
26672 if ((Math.abs(dx) > Math.abs(dy) || this.options.smooth.forceDirection === true || this.options.smooth.forceDirection === "horizontal") && this.options.smooth.forceDirection !== "vertical") {
26673 y1 = this.from.y;
26674 y2 = this.to.y;
26675 x1 = this.from.x - roundness * dx;
26676 x2 = this.to.x + roundness * dx;
26677 } else {
26678 y1 = this.from.y - roundness * dy;
26679 y2 = this.to.y + roundness * dy;
26680 x1 = this.from.x;
26681 x2 = this.to.x;
26682 }
26683
26684 return [{
26685 x: x1,
26686 y: y1
26687 }, {
26688 x: x2,
26689 y: y2
26690 }];
26691 }
26692 /** @inheritDoc */
26693
26694 }, {
26695 key: "getViaNode",
26696 value: function getViaNode() {
26697 return this._getViaCoordinates();
26698 }
26699 /** @inheritDoc */
26700
26701 }, {
26702 key: "_findBorderPosition",
26703 value: function _findBorderPosition(nearNode, ctx) {
26704 return this._findBorderPositionBezier(nearNode, ctx);
26705 }
26706 /** @inheritDoc */
26707
26708 }, {
26709 key: "_getDistanceToEdge",
26710 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
26711 var _ref = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : this._getViaCoordinates(),
26712 _ref2 = _slicedToArray(_ref, 2),
26713 via1 = _ref2[0],
26714 via2 = _ref2[1];
26715
26716 // x3,y3 is the point
26717 return this._getDistanceToBezierEdge2(x1, y1, x2, y2, x3, y3, via1, via2);
26718 }
26719 /** @inheritDoc */
26720
26721 }, {
26722 key: "getPoint",
26723 value: function getPoint(position) {
26724 var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._getViaCoordinates(),
26725 _ref4 = _slicedToArray(_ref3, 2),
26726 via1 = _ref4[0],
26727 via2 = _ref4[1];
26728
26729 var t = position;
26730 var vec = [Math.pow(1 - t, 3), 3 * t * Math.pow(1 - t, 2), 3 * Math.pow(t, 2) * (1 - t), Math.pow(t, 3)];
26731 var x = vec[0] * this.fromPoint.x + vec[1] * via1.x + vec[2] * via2.x + vec[3] * this.toPoint.x;
26732 var y = vec[0] * this.fromPoint.y + vec[1] * via1.y + vec[2] * via2.y + vec[3] * this.toPoint.y;
26733 return {
26734 x: x,
26735 y: y
26736 };
26737 }
26738 }]);
26739
26740 return CubicBezierEdge;
26741}(CubicBezierEdgeBase);
26742
26743function _createSuper$4(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$4(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
26744
26745function _isNativeReflectConstruct$4() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
26746/**
26747 * A Straight Edge.
26748 */
26749
26750var StraightEdge = /*#__PURE__*/function (_EdgeBase) {
26751 _inherits(StraightEdge, _EdgeBase);
26752
26753 var _super = _createSuper$4(StraightEdge);
26754
26755 /**
26756 * Create a new instance.
26757 *
26758 * @param options - The options object of given edge.
26759 * @param body - The body of the network.
26760 * @param labelModule - Label module.
26761 */
26762 function StraightEdge(options, body, labelModule) {
26763 _classCallCheck(this, StraightEdge);
26764
26765 return _super.call(this, options, body, labelModule);
26766 }
26767 /** @inheritDoc */
26768
26769
26770 _createClass(StraightEdge, [{
26771 key: "_line",
26772 value: function _line(ctx, values) {
26773 // draw a straight line
26774 ctx.beginPath();
26775 ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
26776 ctx.lineTo(this.toPoint.x, this.toPoint.y); // draw shadow if enabled
26777
26778 this.enableShadow(ctx, values);
26779 ctx.stroke();
26780 this.disableShadow(ctx, values);
26781 }
26782 /** @inheritDoc */
26783
26784 }, {
26785 key: "getViaNode",
26786 value: function getViaNode() {
26787 return undefined;
26788 }
26789 /** @inheritDoc */
26790
26791 }, {
26792 key: "getPoint",
26793 value: function getPoint(position) {
26794 return {
26795 x: (1 - position) * this.fromPoint.x + position * this.toPoint.x,
26796 y: (1 - position) * this.fromPoint.y + position * this.toPoint.y
26797 };
26798 }
26799 /** @inheritDoc */
26800
26801 }, {
26802 key: "_findBorderPosition",
26803 value: function _findBorderPosition(nearNode, ctx) {
26804 var node1 = this.to;
26805 var node2 = this.from;
26806
26807 if (nearNode.id === this.from.id) {
26808 node1 = this.from;
26809 node2 = this.to;
26810 }
26811
26812 var angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
26813 var dx = node1.x - node2.x;
26814 var dy = node1.y - node2.y;
26815 var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
26816 var toBorderDist = nearNode.distanceToBorder(ctx, angle);
26817 var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
26818 return {
26819 x: (1 - toBorderPoint) * node2.x + toBorderPoint * node1.x,
26820 y: (1 - toBorderPoint) * node2.y + toBorderPoint * node1.y,
26821 t: 0
26822 };
26823 }
26824 /** @inheritDoc */
26825
26826 }, {
26827 key: "_getDistanceToEdge",
26828 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
26829 // x3,y3 is the point
26830 return this._getDistanceToLine(x1, y1, x2, y2, x3, y3);
26831 }
26832 }]);
26833
26834 return StraightEdge;
26835}(EdgeBase);
26836
26837/**
26838 * An edge connects two nodes and has a specific direction.
26839 */
26840
26841var Edge = /*#__PURE__*/function () {
26842 /**
26843 * @param {object} options values specific to this edge, must contain at least 'from' and 'to'
26844 * @param {object} body shared state from Network instance
26845 * @param {Network.Images} imagelist A list with images. Only needed when the edge has image arrows.
26846 * @param {object} globalOptions options from the EdgesHandler instance
26847 * @param {object} defaultOptions default options from the EdgeHandler instance. Value and reference are constant
26848 */
26849 function Edge(options, body, imagelist, globalOptions, defaultOptions) {
26850 _classCallCheck(this, Edge);
26851
26852 if (body === undefined) {
26853 throw new Error("No body provided");
26854 } // Since globalOptions is constant in values as well as reference,
26855 // Following needs to be done only once.
26856
26857
26858 this.options = bridgeObject(globalOptions);
26859 this.globalOptions = globalOptions;
26860 this.defaultOptions = defaultOptions;
26861 this.body = body;
26862 this.imagelist = imagelist; // initialize variables
26863
26864 this.id = undefined;
26865 this.fromId = undefined;
26866 this.toId = undefined;
26867 this.selected = false;
26868 this.hover = false;
26869 this.labelDirty = true;
26870 this.baseWidth = this.options.width;
26871 this.baseFontSize = this.options.font.size;
26872 this.from = undefined; // a node
26873
26874 this.to = undefined; // a node
26875
26876 this.edgeType = undefined;
26877 this.connected = false;
26878 this.labelModule = new Label(this.body, this.options, true
26879 /* It's an edge label */
26880 );
26881 this.setOptions(options);
26882 }
26883 /**
26884 * Set or overwrite options for the edge
26885 *
26886 * @param {object} options an object with options
26887 * @returns {undefined|boolean} undefined if no options, true if layout affecting data changed, false otherwise.
26888 */
26889
26890
26891 _createClass(Edge, [{
26892 key: "setOptions",
26893 value: function setOptions(options) {
26894 if (!options) {
26895 return;
26896 } // Following options if changed affect the layout.
26897
26898
26899 var affectsLayout = typeof options.physics !== "undefined" && this.options.physics !== options.physics || typeof options.hidden !== "undefined" && (this.options.hidden || false) !== (options.hidden || false) || typeof options.from !== "undefined" && this.options.from !== options.from || typeof options.to !== "undefined" && this.options.to !== options.to;
26900 Edge.parseOptions(this.options, options, true, this.globalOptions);
26901
26902 if (options.id !== undefined) {
26903 this.id = options.id;
26904 }
26905
26906 if (options.from !== undefined) {
26907 this.fromId = options.from;
26908 }
26909
26910 if (options.to !== undefined) {
26911 this.toId = options.to;
26912 }
26913
26914 if (options.title !== undefined) {
26915 this.title = options.title;
26916 }
26917
26918 if (options.value !== undefined) {
26919 options.value = _parseFloat(options.value);
26920 }
26921
26922 var pile = [options, this.options, this.defaultOptions];
26923 this.chooser = choosify("edge", pile); // update label Module
26924
26925 this.updateLabelModule(options); // Update edge type, this if changed affects the layout.
26926
26927 affectsLayout = this.updateEdgeType() || affectsLayout; // if anything has been updates, reset the selection width and the hover width
26928
26929 this._setInteractionWidths(); // A node is connected when it has a from and to node that both exist in the network.body.nodes.
26930
26931
26932 this.connect();
26933 return affectsLayout;
26934 }
26935 /**
26936 *
26937 * @param {object} parentOptions
26938 * @param {object} newOptions
26939 * @param {boolean} [allowDeletion=false]
26940 * @param {object} [globalOptions={}]
26941 * @param {boolean} [copyFromGlobals=false]
26942 */
26943
26944 }, {
26945 key: "getFormattingValues",
26946 value:
26947 /**
26948 *
26949 * @returns {ArrowOptions}
26950 */
26951 function getFormattingValues() {
26952 var toArrow = this.options.arrows.to === true || this.options.arrows.to.enabled === true;
26953 var fromArrow = this.options.arrows.from === true || this.options.arrows.from.enabled === true;
26954 var middleArrow = this.options.arrows.middle === true || this.options.arrows.middle.enabled === true;
26955 var inheritsColor = this.options.color.inherit;
26956 var values = {
26957 toArrow: toArrow,
26958 toArrowScale: this.options.arrows.to.scaleFactor,
26959 toArrowType: this.options.arrows.to.type,
26960 toArrowSrc: this.options.arrows.to.src,
26961 toArrowImageWidth: this.options.arrows.to.imageWidth,
26962 toArrowImageHeight: this.options.arrows.to.imageHeight,
26963 middleArrow: middleArrow,
26964 middleArrowScale: this.options.arrows.middle.scaleFactor,
26965 middleArrowType: this.options.arrows.middle.type,
26966 middleArrowSrc: this.options.arrows.middle.src,
26967 middleArrowImageWidth: this.options.arrows.middle.imageWidth,
26968 middleArrowImageHeight: this.options.arrows.middle.imageHeight,
26969 fromArrow: fromArrow,
26970 fromArrowScale: this.options.arrows.from.scaleFactor,
26971 fromArrowType: this.options.arrows.from.type,
26972 fromArrowSrc: this.options.arrows.from.src,
26973 fromArrowImageWidth: this.options.arrows.from.imageWidth,
26974 fromArrowImageHeight: this.options.arrows.from.imageHeight,
26975 arrowStrikethrough: this.options.arrowStrikethrough,
26976 color: inheritsColor ? undefined : this.options.color.color,
26977 inheritsColor: inheritsColor,
26978 opacity: this.options.color.opacity,
26979 hidden: this.options.hidden,
26980 length: this.options.length,
26981 shadow: this.options.shadow.enabled,
26982 shadowColor: this.options.shadow.color,
26983 shadowSize: this.options.shadow.size,
26984 shadowX: this.options.shadow.x,
26985 shadowY: this.options.shadow.y,
26986 dashes: this.options.dashes,
26987 width: this.options.width,
26988 background: this.options.background.enabled,
26989 backgroundColor: this.options.background.color,
26990 backgroundSize: this.options.background.size,
26991 backgroundDashes: this.options.background.dashes
26992 };
26993
26994 if (this.selected || this.hover) {
26995 if (this.chooser === true) {
26996 if (this.selected) {
26997 var selectedWidth = this.options.selectionWidth;
26998
26999 if (typeof selectedWidth === "function") {
27000 values.width = selectedWidth(values.width);
27001 } else if (typeof selectedWidth === "number") {
27002 values.width += selectedWidth;
27003 }
27004
27005 values.width = Math.max(values.width, 0.3 / this.body.view.scale);
27006 values.color = this.options.color.highlight;
27007 values.shadow = this.options.shadow.enabled;
27008 } else if (this.hover) {
27009 var hoverWidth = this.options.hoverWidth;
27010
27011 if (typeof hoverWidth === "function") {
27012 values.width = hoverWidth(values.width);
27013 } else if (typeof hoverWidth === "number") {
27014 values.width += hoverWidth;
27015 }
27016
27017 values.width = Math.max(values.width, 0.3 / this.body.view.scale);
27018 values.color = this.options.color.hover;
27019 values.shadow = this.options.shadow.enabled;
27020 }
27021 } else if (typeof this.chooser === "function") {
27022 this.chooser(values, this.options.id, this.selected, this.hover);
27023
27024 if (values.color !== undefined) {
27025 values.inheritsColor = false;
27026 }
27027
27028 if (values.shadow === false) {
27029 if (values.shadowColor !== this.options.shadow.color || values.shadowSize !== this.options.shadow.size || values.shadowX !== this.options.shadow.x || values.shadowY !== this.options.shadow.y) {
27030 values.shadow = true;
27031 }
27032 }
27033 }
27034 } else {
27035 values.shadow = this.options.shadow.enabled;
27036 values.width = Math.max(values.width, 0.3 / this.body.view.scale);
27037 }
27038
27039 return values;
27040 }
27041 /**
27042 * update the options in the label module
27043 *
27044 * @param {object} options
27045 */
27046
27047 }, {
27048 key: "updateLabelModule",
27049 value: function updateLabelModule(options) {
27050 var pile = [options, this.options, this.globalOptions, // Currently set global edge options
27051 this.defaultOptions];
27052 this.labelModule.update(this.options, pile);
27053
27054 if (this.labelModule.baseSize !== undefined) {
27055 this.baseFontSize = this.labelModule.baseSize;
27056 }
27057 }
27058 /**
27059 * update the edge type, set the options
27060 *
27061 * @returns {boolean}
27062 */
27063
27064 }, {
27065 key: "updateEdgeType",
27066 value: function updateEdgeType() {
27067 var smooth = this.options.smooth;
27068 var dataChanged = false;
27069 var changeInType = true;
27070
27071 if (this.edgeType !== undefined) {
27072 if (this.edgeType instanceof BezierEdgeDynamic && smooth.enabled === true && smooth.type === "dynamic" || this.edgeType instanceof CubicBezierEdge && smooth.enabled === true && smooth.type === "cubicBezier" || this.edgeType instanceof BezierEdgeStatic && smooth.enabled === true && smooth.type !== "dynamic" && smooth.type !== "cubicBezier" || this.edgeType instanceof StraightEdge && smooth.type.enabled === false) {
27073 changeInType = false;
27074 }
27075
27076 if (changeInType === true) {
27077 dataChanged = this.cleanup();
27078 }
27079 }
27080
27081 if (changeInType === true) {
27082 if (smooth.enabled === true) {
27083 if (smooth.type === "dynamic") {
27084 dataChanged = true;
27085 this.edgeType = new BezierEdgeDynamic(this.options, this.body, this.labelModule);
27086 } else if (smooth.type === "cubicBezier") {
27087 this.edgeType = new CubicBezierEdge(this.options, this.body, this.labelModule);
27088 } else {
27089 this.edgeType = new BezierEdgeStatic(this.options, this.body, this.labelModule);
27090 }
27091 } else {
27092 this.edgeType = new StraightEdge(this.options, this.body, this.labelModule);
27093 }
27094 } else {
27095 // if nothing changes, we just set the options.
27096 this.edgeType.setOptions(this.options);
27097 }
27098
27099 return dataChanged;
27100 }
27101 /**
27102 * Connect an edge to its nodes
27103 */
27104
27105 }, {
27106 key: "connect",
27107 value: function connect() {
27108 this.disconnect();
27109 this.from = this.body.nodes[this.fromId] || undefined;
27110 this.to = this.body.nodes[this.toId] || undefined;
27111 this.connected = this.from !== undefined && this.to !== undefined;
27112
27113 if (this.connected === true) {
27114 this.from.attachEdge(this);
27115 this.to.attachEdge(this);
27116 } else {
27117 if (this.from) {
27118 this.from.detachEdge(this);
27119 }
27120
27121 if (this.to) {
27122 this.to.detachEdge(this);
27123 }
27124 }
27125
27126 this.edgeType.connect();
27127 }
27128 /**
27129 * Disconnect an edge from its nodes
27130 */
27131
27132 }, {
27133 key: "disconnect",
27134 value: function disconnect() {
27135 if (this.from) {
27136 this.from.detachEdge(this);
27137 this.from = undefined;
27138 }
27139
27140 if (this.to) {
27141 this.to.detachEdge(this);
27142 this.to = undefined;
27143 }
27144
27145 this.connected = false;
27146 }
27147 /**
27148 * get the title of this edge.
27149 *
27150 * @returns {string} title The title of the edge, or undefined when no title
27151 * has been set.
27152 */
27153
27154 }, {
27155 key: "getTitle",
27156 value: function getTitle() {
27157 return this.title;
27158 }
27159 /**
27160 * check if this node is selecte
27161 *
27162 * @returns {boolean} selected True if node is selected, else false
27163 */
27164
27165 }, {
27166 key: "isSelected",
27167 value: function isSelected() {
27168 return this.selected;
27169 }
27170 /**
27171 * Retrieve the value of the edge. Can be undefined
27172 *
27173 * @returns {number} value
27174 */
27175
27176 }, {
27177 key: "getValue",
27178 value: function getValue() {
27179 return this.options.value;
27180 }
27181 /**
27182 * Adjust the value range of the edge. The edge will adjust it's width
27183 * based on its value.
27184 *
27185 * @param {number} min
27186 * @param {number} max
27187 * @param {number} total
27188 */
27189
27190 }, {
27191 key: "setValueRange",
27192 value: function setValueRange(min, max, total) {
27193 if (this.options.value !== undefined) {
27194 var scale = this.options.scaling.customScalingFunction(min, max, total, this.options.value);
27195 var widthDiff = this.options.scaling.max - this.options.scaling.min;
27196
27197 if (this.options.scaling.label.enabled === true) {
27198 var fontDiff = this.options.scaling.label.max - this.options.scaling.label.min;
27199 this.options.font.size = this.options.scaling.label.min + scale * fontDiff;
27200 }
27201
27202 this.options.width = this.options.scaling.min + scale * widthDiff;
27203 } else {
27204 this.options.width = this.baseWidth;
27205 this.options.font.size = this.baseFontSize;
27206 }
27207
27208 this._setInteractionWidths();
27209
27210 this.updateLabelModule();
27211 }
27212 /**
27213 *
27214 * @private
27215 */
27216
27217 }, {
27218 key: "_setInteractionWidths",
27219 value: function _setInteractionWidths() {
27220 if (typeof this.options.hoverWidth === "function") {
27221 this.edgeType.hoverWidth = this.options.hoverWidth(this.options.width);
27222 } else {
27223 this.edgeType.hoverWidth = this.options.hoverWidth + this.options.width;
27224 }
27225
27226 if (typeof this.options.selectionWidth === "function") {
27227 this.edgeType.selectionWidth = this.options.selectionWidth(this.options.width);
27228 } else {
27229 this.edgeType.selectionWidth = this.options.selectionWidth + this.options.width;
27230 }
27231 }
27232 /**
27233 * Redraw a edge
27234 * Draw this edge in the given canvas
27235 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
27236 *
27237 * @param {CanvasRenderingContext2D} ctx
27238 */
27239
27240 }, {
27241 key: "draw",
27242 value: function draw(ctx) {
27243 var values = this.getFormattingValues();
27244
27245 if (values.hidden) {
27246 return;
27247 } // get the via node from the edge type
27248
27249
27250 var viaNode = this.edgeType.getViaNode(); // draw line and label
27251
27252 this.edgeType.drawLine(ctx, values, this.selected, this.hover, viaNode);
27253 this.drawLabel(ctx, viaNode);
27254 }
27255 /**
27256 * Redraw arrows
27257 * Draw this arrows in the given canvas
27258 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
27259 *
27260 * @param {CanvasRenderingContext2D} ctx
27261 */
27262
27263 }, {
27264 key: "drawArrows",
27265 value: function drawArrows(ctx) {
27266 var values = this.getFormattingValues();
27267
27268 if (values.hidden) {
27269 return;
27270 } // get the via node from the edge type
27271
27272
27273 var viaNode = this.edgeType.getViaNode();
27274 var arrowData = {}; // restore edge targets to defaults
27275
27276 this.edgeType.fromPoint = this.edgeType.from;
27277 this.edgeType.toPoint = this.edgeType.to; // from and to arrows give a different end point for edges. we set them here
27278
27279 if (values.fromArrow) {
27280 arrowData.from = this.edgeType.getArrowData(ctx, "from", viaNode, this.selected, this.hover, values);
27281 if (values.arrowStrikethrough === false) this.edgeType.fromPoint = arrowData.from.core;
27282
27283 if (values.fromArrowSrc) {
27284 arrowData.from.image = this.imagelist.load(values.fromArrowSrc);
27285 }
27286
27287 if (values.fromArrowImageWidth) {
27288 arrowData.from.imageWidth = values.fromArrowImageWidth;
27289 }
27290
27291 if (values.fromArrowImageHeight) {
27292 arrowData.from.imageHeight = values.fromArrowImageHeight;
27293 }
27294 }
27295
27296 if (values.toArrow) {
27297 arrowData.to = this.edgeType.getArrowData(ctx, "to", viaNode, this.selected, this.hover, values);
27298 if (values.arrowStrikethrough === false) this.edgeType.toPoint = arrowData.to.core;
27299
27300 if (values.toArrowSrc) {
27301 arrowData.to.image = this.imagelist.load(values.toArrowSrc);
27302 }
27303
27304 if (values.toArrowImageWidth) {
27305 arrowData.to.imageWidth = values.toArrowImageWidth;
27306 }
27307
27308 if (values.toArrowImageHeight) {
27309 arrowData.to.imageHeight = values.toArrowImageHeight;
27310 }
27311 } // the middle arrow depends on the line, which can depend on the to and from arrows so we do this one lastly.
27312
27313
27314 if (values.middleArrow) {
27315 arrowData.middle = this.edgeType.getArrowData(ctx, "middle", viaNode, this.selected, this.hover, values);
27316
27317 if (values.middleArrowSrc) {
27318 arrowData.middle.image = this.imagelist.load(values.middleArrowSrc);
27319 }
27320
27321 if (values.middleArrowImageWidth) {
27322 arrowData.middle.imageWidth = values.middleArrowImageWidth;
27323 }
27324
27325 if (values.middleArrowImageHeight) {
27326 arrowData.middle.imageHeight = values.middleArrowImageHeight;
27327 }
27328 }
27329
27330 if (values.fromArrow) {
27331 this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.from);
27332 }
27333
27334 if (values.middleArrow) {
27335 this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.middle);
27336 }
27337
27338 if (values.toArrow) {
27339 this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.to);
27340 }
27341 }
27342 /**
27343 *
27344 * @param {CanvasRenderingContext2D} ctx
27345 * @param {Node} viaNode
27346 */
27347
27348 }, {
27349 key: "drawLabel",
27350 value: function drawLabel(ctx, viaNode) {
27351 if (this.options.label !== undefined) {
27352 // set style
27353 var node1 = this.from;
27354 var node2 = this.to;
27355
27356 if (this.labelModule.differentState(this.selected, this.hover)) {
27357 this.labelModule.getTextSize(ctx, this.selected, this.hover);
27358 }
27359
27360 var point;
27361
27362 if (node1.id != node2.id) {
27363 this.labelModule.pointToSelf = false;
27364 point = this.edgeType.getPoint(0.5, viaNode);
27365 ctx.save();
27366
27367 var rotationPoint = this._getRotation(ctx);
27368
27369 if (rotationPoint.angle != 0) {
27370 ctx.translate(rotationPoint.x, rotationPoint.y);
27371 ctx.rotate(rotationPoint.angle);
27372 } // draw the label
27373
27374
27375 this.labelModule.draw(ctx, point.x, point.y, this.selected, this.hover);
27376 /*
27377 // Useful debug code: draw a border around the label
27378 // This should **not** be enabled in production!
27379 var size = this.labelModule.getSize();; // ;; intentional so lint catches it
27380 ctx.strokeStyle = "#ff0000";
27381 ctx.strokeRect(size.left, size.top, size.width, size.height);
27382 // End debug code
27383 */
27384
27385 ctx.restore();
27386 } else {
27387 // Ignore the orientations.
27388 this.labelModule.pointToSelf = true; // get circle coordinates
27389
27390 var coordinates = getSelfRefCoordinates(ctx, this.options.selfReference.angle, this.options.selfReference.size, node1);
27391 point = this._pointOnCircle(coordinates.x, coordinates.y, this.options.selfReference.size, this.options.selfReference.angle);
27392 this.labelModule.draw(ctx, point.x, point.y, this.selected, this.hover);
27393 }
27394 }
27395 }
27396 /**
27397 * Determine all visual elements of this edge instance, in which the given
27398 * point falls within the bounding shape.
27399 *
27400 * @param {point} point
27401 * @returns {Array.<edgeClickItem|edgeLabelClickItem>} list with the items which are on the point
27402 */
27403
27404 }, {
27405 key: "getItemsOnPoint",
27406 value: function getItemsOnPoint(point) {
27407 var ret = [];
27408
27409 if (this.labelModule.visible()) {
27410 var rotationPoint = this._getRotation();
27411
27412 if (pointInRect(this.labelModule.getSize(), point, rotationPoint)) {
27413 ret.push({
27414 edgeId: this.id,
27415 labelId: 0
27416 });
27417 }
27418 }
27419
27420 var obj = {
27421 left: point.x,
27422 top: point.y
27423 };
27424
27425 if (this.isOverlappingWith(obj)) {
27426 ret.push({
27427 edgeId: this.id
27428 });
27429 }
27430
27431 return ret;
27432 }
27433 /**
27434 * Check if this object is overlapping with the provided object
27435 *
27436 * @param {object} obj an object with parameters left, top
27437 * @returns {boolean} True if location is located on the edge
27438 */
27439
27440 }, {
27441 key: "isOverlappingWith",
27442 value: function isOverlappingWith(obj) {
27443 if (this.connected) {
27444 var distMax = 10;
27445 var xFrom = this.from.x;
27446 var yFrom = this.from.y;
27447 var xTo = this.to.x;
27448 var yTo = this.to.y;
27449 var xObj = obj.left;
27450 var yObj = obj.top;
27451 var dist = this.edgeType.getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
27452 return dist < distMax;
27453 } else {
27454 return false;
27455 }
27456 }
27457 /**
27458 * Determine the rotation point, if any.
27459 *
27460 * @param {CanvasRenderingContext2D} [ctx] if passed, do a recalculation of the label size
27461 * @returns {rotationPoint} the point to rotate around and the angle in radians to rotate
27462 * @private
27463 */
27464
27465 }, {
27466 key: "_getRotation",
27467 value: function _getRotation(ctx) {
27468 var viaNode = this.edgeType.getViaNode();
27469 var point = this.edgeType.getPoint(0.5, viaNode);
27470
27471 if (ctx !== undefined) {
27472 this.labelModule.calculateLabelSize(ctx, this.selected, this.hover, point.x, point.y);
27473 }
27474
27475 var ret = {
27476 x: point.x,
27477 y: this.labelModule.size.yLine,
27478 angle: 0
27479 };
27480
27481 if (!this.labelModule.visible()) {
27482 return ret; // Don't even bother doing the atan2, there's nothing to draw
27483 }
27484
27485 if (this.options.font.align === "horizontal") {
27486 return ret; // No need to calculate angle
27487 }
27488
27489 var dy = this.from.y - this.to.y;
27490 var dx = this.from.x - this.to.x;
27491 var angle = Math.atan2(dy, dx); // radians
27492 // rotate so that label is readable
27493
27494 if (angle < -1 && dx < 0 || angle > 0 && dx < 0) {
27495 angle += Math.PI;
27496 }
27497
27498 ret.angle = angle;
27499 return ret;
27500 }
27501 /**
27502 * Get a point on a circle
27503 *
27504 * @param {number} x
27505 * @param {number} y
27506 * @param {number} radius
27507 * @param {number} angle
27508 * @returns {object} point
27509 * @private
27510 */
27511
27512 }, {
27513 key: "_pointOnCircle",
27514 value: function _pointOnCircle(x, y, radius, angle) {
27515 return {
27516 x: x + radius * Math.cos(angle),
27517 y: y - radius * Math.sin(angle)
27518 };
27519 }
27520 /**
27521 * Sets selected state to true
27522 */
27523
27524 }, {
27525 key: "select",
27526 value: function select() {
27527 this.selected = true;
27528 }
27529 /**
27530 * Sets selected state to false
27531 */
27532
27533 }, {
27534 key: "unselect",
27535 value: function unselect() {
27536 this.selected = false;
27537 }
27538 /**
27539 * cleans all required things on delete
27540 *
27541 * @returns {*}
27542 */
27543
27544 }, {
27545 key: "cleanup",
27546 value: function cleanup() {
27547 return this.edgeType.cleanup();
27548 }
27549 /**
27550 * Remove edge from the list and perform necessary cleanup.
27551 */
27552
27553 }, {
27554 key: "remove",
27555 value: function remove() {
27556 this.cleanup();
27557 this.disconnect();
27558 delete this.body.edges[this.id];
27559 }
27560 /**
27561 * Check if both connecting nodes exist
27562 *
27563 * @returns {boolean}
27564 */
27565
27566 }, {
27567 key: "endPointsValid",
27568 value: function endPointsValid() {
27569 return this.body.nodes[this.fromId] !== undefined && this.body.nodes[this.toId] !== undefined;
27570 }
27571 }], [{
27572 key: "parseOptions",
27573 value: function parseOptions(parentOptions, newOptions) {
27574 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
27575 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
27576 var copyFromGlobals = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
27577 var fields = ["endPointOffset", "arrowStrikethrough", "id", "from", "hidden", "hoverWidth", "labelHighlightBold", "length", "line", "opacity", "physics", "scaling", "selectionWidth", "selfReferenceSize", "selfReference", "to", "title", "value", "width", "font", "chosen", "widthConstraint"]; // only deep extend the items in the field array. These do not have shorthand.
27578
27579 selectiveDeepExtend(fields, parentOptions, newOptions, allowDeletion); // Only use endPointOffset values (from and to) if it's valid values
27580
27581 if (newOptions.endPointOffset !== undefined && newOptions.endPointOffset.from !== undefined) {
27582 if (_isFinite(newOptions.endPointOffset.from)) {
27583 parentOptions.endPointOffset.from = newOptions.endPointOffset.from;
27584 } else {
27585 parentOptions.endPointOffset.from = globalOptions.endPointOffset.from !== undefined ? globalOptions.endPointOffset.from : 0;
27586 console.error("endPointOffset.from is not a valid number");
27587 }
27588 }
27589
27590 if (newOptions.endPointOffset !== undefined && newOptions.endPointOffset.to !== undefined) {
27591 if (_isFinite(newOptions.endPointOffset.to)) {
27592 parentOptions.endPointOffset.to = newOptions.endPointOffset.to;
27593 } else {
27594 parentOptions.endPointOffset.to = globalOptions.endPointOffset.to !== undefined ? globalOptions.endPointOffset.to : 0;
27595 console.error("endPointOffset.to is not a valid number");
27596 }
27597 } // Only copy label if it's a legal value.
27598
27599
27600 if (isValidLabel(newOptions.label)) {
27601 parentOptions.label = newOptions.label;
27602 } else if (!isValidLabel(parentOptions.label)) {
27603 parentOptions.label = undefined;
27604 }
27605
27606 mergeOptions(parentOptions, newOptions, "smooth", globalOptions);
27607 mergeOptions(parentOptions, newOptions, "shadow", globalOptions);
27608 mergeOptions(parentOptions, newOptions, "background", globalOptions);
27609
27610 if (newOptions.dashes !== undefined && newOptions.dashes !== null) {
27611 parentOptions.dashes = newOptions.dashes;
27612 } else if (allowDeletion === true && newOptions.dashes === null) {
27613 parentOptions.dashes = create$4(globalOptions.dashes); // this sets the pointer of the option back to the global option.
27614 } // set the scaling newOptions
27615
27616
27617 if (newOptions.scaling !== undefined && newOptions.scaling !== null) {
27618 if (newOptions.scaling.min !== undefined) {
27619 parentOptions.scaling.min = newOptions.scaling.min;
27620 }
27621
27622 if (newOptions.scaling.max !== undefined) {
27623 parentOptions.scaling.max = newOptions.scaling.max;
27624 }
27625
27626 mergeOptions(parentOptions.scaling, newOptions.scaling, "label", globalOptions.scaling);
27627 } else if (allowDeletion === true && newOptions.scaling === null) {
27628 parentOptions.scaling = create$4(globalOptions.scaling); // this sets the pointer of the option back to the global option.
27629 } // handle multiple input cases for arrows
27630
27631
27632 if (newOptions.arrows !== undefined && newOptions.arrows !== null) {
27633 if (typeof newOptions.arrows === "string") {
27634 var arrows = newOptions.arrows.toLowerCase();
27635 parentOptions.arrows.to.enabled = indexOf(arrows).call(arrows, "to") != -1;
27636 parentOptions.arrows.middle.enabled = indexOf(arrows).call(arrows, "middle") != -1;
27637 parentOptions.arrows.from.enabled = indexOf(arrows).call(arrows, "from") != -1;
27638 } else if (_typeof(newOptions.arrows) === "object") {
27639 mergeOptions(parentOptions.arrows, newOptions.arrows, "to", globalOptions.arrows);
27640 mergeOptions(parentOptions.arrows, newOptions.arrows, "middle", globalOptions.arrows);
27641 mergeOptions(parentOptions.arrows, newOptions.arrows, "from", globalOptions.arrows);
27642 } else {
27643 throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:" + stringify$1(newOptions.arrows));
27644 }
27645 } else if (allowDeletion === true && newOptions.arrows === null) {
27646 parentOptions.arrows = create$4(globalOptions.arrows); // this sets the pointer of the option back to the global option.
27647 } // handle multiple input cases for color
27648
27649
27650 if (newOptions.color !== undefined && newOptions.color !== null) {
27651 var fromColor = isString(newOptions.color) ? {
27652 color: newOptions.color,
27653 highlight: newOptions.color,
27654 hover: newOptions.color,
27655 inherit: false,
27656 opacity: 1
27657 } : newOptions.color;
27658 var toColor = parentOptions.color; // If passed, fill in values from default options - required in the case of no prototype bridging
27659
27660 if (copyFromGlobals) {
27661 deepExtend(toColor, globalOptions.color, false, allowDeletion);
27662 } else {
27663 // Clear local properties - need to do it like this in order to retain prototype bridges
27664 for (var i in toColor) {
27665 if (Object.prototype.hasOwnProperty.call(toColor, i)) {
27666 delete toColor[i];
27667 }
27668 }
27669 }
27670
27671 if (isString(toColor)) {
27672 toColor.color = toColor;
27673 toColor.highlight = toColor;
27674 toColor.hover = toColor;
27675 toColor.inherit = false;
27676
27677 if (fromColor.opacity === undefined) {
27678 toColor.opacity = 1.0; // set default
27679 }
27680 } else {
27681 var colorsDefined = false;
27682
27683 if (fromColor.color !== undefined) {
27684 toColor.color = fromColor.color;
27685 colorsDefined = true;
27686 }
27687
27688 if (fromColor.highlight !== undefined) {
27689 toColor.highlight = fromColor.highlight;
27690 colorsDefined = true;
27691 }
27692
27693 if (fromColor.hover !== undefined) {
27694 toColor.hover = fromColor.hover;
27695 colorsDefined = true;
27696 }
27697
27698 if (fromColor.inherit !== undefined) {
27699 toColor.inherit = fromColor.inherit;
27700 }
27701
27702 if (fromColor.opacity !== undefined) {
27703 toColor.opacity = Math.min(1, Math.max(0, fromColor.opacity));
27704 }
27705
27706 if (colorsDefined === true) {
27707 toColor.inherit = false;
27708 } else {
27709 if (toColor.inherit === undefined) {
27710 toColor.inherit = "from"; // Set default
27711 }
27712 }
27713 }
27714 } else if (allowDeletion === true && newOptions.color === null) {
27715 parentOptions.color = bridgeObject(globalOptions.color); // set the object back to the global options
27716 }
27717
27718 if (allowDeletion === true && newOptions.font === null) {
27719 parentOptions.font = bridgeObject(globalOptions.font); // set the object back to the global options
27720 }
27721
27722 if (Object.prototype.hasOwnProperty.call(newOptions, "selfReferenceSize")) {
27723 console.warn("The selfReferenceSize property has been deprecated. Please use selfReference property instead. The selfReference can be set like thise selfReference:{size:30, angle:Math.PI / 4}");
27724 parentOptions.selfReference.size = newOptions.selfReferenceSize;
27725 }
27726 }
27727 }]);
27728
27729 return Edge;
27730}();
27731
27732/**
27733 * Handler for Edges
27734 */
27735
27736var EdgesHandler = /*#__PURE__*/function () {
27737 /**
27738 * @param {object} body
27739 * @param {Array.<Image>} images
27740 * @param {Array.<Group>} groups
27741 */
27742 function EdgesHandler(body, images, groups) {
27743 var _context,
27744 _this = this;
27745
27746 _classCallCheck(this, EdgesHandler);
27747
27748 this.body = body;
27749 this.images = images;
27750 this.groups = groups; // create the edge API in the body container
27751
27752 this.body.functions.createEdge = bind$6(_context = this.create).call(_context, this);
27753 this.edgesListeners = {
27754 add: function add(event, params) {
27755 _this.add(params.items);
27756 },
27757 update: function update(event, params) {
27758 _this.update(params.items);
27759 },
27760 remove: function remove(event, params) {
27761 _this.remove(params.items);
27762 }
27763 };
27764 this.options = {};
27765 this.defaultOptions = {
27766 arrows: {
27767 to: {
27768 enabled: false,
27769 scaleFactor: 1,
27770 type: "arrow"
27771 },
27772 // boolean / {arrowScaleFactor:1} / {enabled: false, arrowScaleFactor:1}
27773 middle: {
27774 enabled: false,
27775 scaleFactor: 1,
27776 type: "arrow"
27777 },
27778 from: {
27779 enabled: false,
27780 scaleFactor: 1,
27781 type: "arrow"
27782 }
27783 },
27784 endPointOffset: {
27785 from: 0,
27786 to: 0
27787 },
27788 arrowStrikethrough: true,
27789 color: {
27790 color: "#848484",
27791 highlight: "#848484",
27792 hover: "#848484",
27793 inherit: "from",
27794 opacity: 1.0
27795 },
27796 dashes: false,
27797 font: {
27798 color: "#343434",
27799 size: 14,
27800 // px
27801 face: "arial",
27802 background: "none",
27803 strokeWidth: 2,
27804 // px
27805 strokeColor: "#ffffff",
27806 align: "horizontal",
27807 multi: false,
27808 vadjust: 0,
27809 bold: {
27810 mod: "bold"
27811 },
27812 boldital: {
27813 mod: "bold italic"
27814 },
27815 ital: {
27816 mod: "italic"
27817 },
27818 mono: {
27819 mod: "",
27820 size: 15,
27821 // px
27822 face: "courier new",
27823 vadjust: 2
27824 }
27825 },
27826 hidden: false,
27827 hoverWidth: 1.5,
27828 label: undefined,
27829 labelHighlightBold: true,
27830 length: undefined,
27831 physics: true,
27832 scaling: {
27833 min: 1,
27834 max: 15,
27835 label: {
27836 enabled: true,
27837 min: 14,
27838 max: 30,
27839 maxVisible: 30,
27840 drawThreshold: 5
27841 },
27842 customScalingFunction: function customScalingFunction(min, max, total, value) {
27843 if (max === min) {
27844 return 0.5;
27845 } else {
27846 var scale = 1 / (max - min);
27847 return Math.max(0, (value - min) * scale);
27848 }
27849 }
27850 },
27851 selectionWidth: 1.5,
27852 selfReference: {
27853 size: 20,
27854 angle: Math.PI / 4,
27855 renderBehindTheNode: true
27856 },
27857 shadow: {
27858 enabled: false,
27859 color: "rgba(0,0,0,0.5)",
27860 size: 10,
27861 x: 5,
27862 y: 5
27863 },
27864 background: {
27865 enabled: false,
27866 color: "rgba(111,111,111,1)",
27867 size: 10,
27868 dashes: false
27869 },
27870 smooth: {
27871 enabled: true,
27872 type: "dynamic",
27873 forceDirection: "none",
27874 roundness: 0.5
27875 },
27876 title: undefined,
27877 width: 1,
27878 value: undefined
27879 };
27880 deepExtend(this.options, this.defaultOptions);
27881 this.bindEventListeners();
27882 }
27883 /**
27884 * Binds event listeners
27885 */
27886
27887
27888 _createClass(EdgesHandler, [{
27889 key: "bindEventListeners",
27890 value: function bindEventListeners() {
27891 var _this2 = this,
27892 _context2,
27893 _context3;
27894
27895 // this allows external modules to force all dynamic curves to turn static.
27896 this.body.emitter.on("_forceDisableDynamicCurves", function (type) {
27897 var emit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
27898
27899 if (type === "dynamic") {
27900 type = "continuous";
27901 }
27902
27903 var dataChanged = false;
27904
27905 for (var edgeId in _this2.body.edges) {
27906 if (Object.prototype.hasOwnProperty.call(_this2.body.edges, edgeId)) {
27907 var edge = _this2.body.edges[edgeId];
27908
27909 var edgeData = _this2.body.data.edges.get(edgeId); // only forcibly remove the smooth curve if the data has been set of the edge has the smooth curves defined.
27910 // this is because a change in the global would not affect these curves.
27911
27912
27913 if (edgeData != null) {
27914 var smoothOptions = edgeData.smooth;
27915
27916 if (smoothOptions !== undefined) {
27917 if (smoothOptions.enabled === true && smoothOptions.type === "dynamic") {
27918 if (type === undefined) {
27919 edge.setOptions({
27920 smooth: false
27921 });
27922 } else {
27923 edge.setOptions({
27924 smooth: {
27925 type: type
27926 }
27927 });
27928 }
27929
27930 dataChanged = true;
27931 }
27932 }
27933 }
27934 }
27935 }
27936
27937 if (emit === true && dataChanged === true) {
27938 _this2.body.emitter.emit("_dataChanged");
27939 }
27940 }); // this is called when options of EXISTING nodes or edges have changed.
27941 //
27942 // NOTE: Not true, called when options have NOT changed, for both existing as well as new nodes.
27943 // See update() for logic.
27944 // TODO: Verify and examine the consequences of this. It might still trigger when
27945 // non-option fields have changed, but then reconnecting edges is still useless.
27946 // Alternatively, it might also be called when edges are removed.
27947 //
27948
27949 this.body.emitter.on("_dataUpdated", function () {
27950 _this2.reconnectEdges();
27951 }); // refresh the edges. Used when reverting from hierarchical layout
27952
27953 this.body.emitter.on("refreshEdges", bind$6(_context2 = this.refresh).call(_context2, this));
27954 this.body.emitter.on("refresh", bind$6(_context3 = this.refresh).call(_context3, this));
27955 this.body.emitter.on("destroy", function () {
27956 forEach$1(_this2.edgesListeners, function (callback, event) {
27957 if (_this2.body.data.edges) _this2.body.data.edges.off(event, callback);
27958 });
27959 delete _this2.body.functions.createEdge;
27960 delete _this2.edgesListeners.add;
27961 delete _this2.edgesListeners.update;
27962 delete _this2.edgesListeners.remove;
27963 delete _this2.edgesListeners;
27964 });
27965 }
27966 /**
27967 *
27968 * @param {object} options
27969 */
27970
27971 }, {
27972 key: "setOptions",
27973 value: function setOptions(options) {
27974 if (options !== undefined) {
27975 // use the parser from the Edge class to fill in all shorthand notations
27976 Edge.parseOptions(this.options, options, true, this.defaultOptions, true); // update smooth settings in all edges
27977
27978 var dataChanged = false;
27979
27980 if (options.smooth !== undefined) {
27981 for (var edgeId in this.body.edges) {
27982 if (Object.prototype.hasOwnProperty.call(this.body.edges, edgeId)) {
27983 dataChanged = this.body.edges[edgeId].updateEdgeType() || dataChanged;
27984 }
27985 }
27986 } // update fonts in all edges
27987
27988
27989 if (options.font !== undefined) {
27990 for (var _edgeId in this.body.edges) {
27991 if (Object.prototype.hasOwnProperty.call(this.body.edges, _edgeId)) {
27992 this.body.edges[_edgeId].updateLabelModule();
27993 }
27994 }
27995 } // update the state of the variables if needed
27996
27997
27998 if (options.hidden !== undefined || options.physics !== undefined || dataChanged === true) {
27999 this.body.emitter.emit("_dataChanged");
28000 }
28001 }
28002 }
28003 /**
28004 * Load edges by reading the data table
28005 *
28006 * @param {Array | DataSet | DataView} edges The data containing the edges.
28007 * @param {boolean} [doNotEmit=false] - Suppress data changed event.
28008 * @private
28009 */
28010
28011 }, {
28012 key: "setData",
28013 value: function setData(edges) {
28014 var _this3 = this;
28015
28016 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
28017 var oldEdgesData = this.body.data.edges;
28018
28019 if (isDataViewLike("id", edges)) {
28020 this.body.data.edges = edges;
28021 } else if (isArray$2(edges)) {
28022 this.body.data.edges = new DataSet();
28023 this.body.data.edges.add(edges);
28024 } else if (!edges) {
28025 this.body.data.edges = new DataSet();
28026 } else {
28027 throw new TypeError("Array or DataSet expected");
28028 } // TODO: is this null or undefined or false?
28029
28030
28031 if (oldEdgesData) {
28032 // unsubscribe from old dataset
28033 forEach$1(this.edgesListeners, function (callback, event) {
28034 oldEdgesData.off(event, callback);
28035 });
28036 } // remove drawn edges
28037
28038
28039 this.body.edges = {}; // TODO: is this null or undefined or false?
28040
28041 if (this.body.data.edges) {
28042 // subscribe to new dataset
28043 forEach$1(this.edgesListeners, function (callback, event) {
28044 _this3.body.data.edges.on(event, callback);
28045 }); // draw all new nodes
28046
28047 var ids = this.body.data.edges.getIds();
28048 this.add(ids, true);
28049 }
28050
28051 this.body.emitter.emit("_adjustEdgesForHierarchicalLayout");
28052
28053 if (doNotEmit === false) {
28054 this.body.emitter.emit("_dataChanged");
28055 }
28056 }
28057 /**
28058 * Add edges
28059 *
28060 * @param {number[] | string[]} ids
28061 * @param {boolean} [doNotEmit=false]
28062 * @private
28063 */
28064
28065 }, {
28066 key: "add",
28067 value: function add(ids) {
28068 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
28069 var edges = this.body.edges;
28070 var edgesData = this.body.data.edges;
28071
28072 for (var i = 0; i < ids.length; i++) {
28073 var id = ids[i];
28074 var oldEdge = edges[id];
28075
28076 if (oldEdge) {
28077 oldEdge.disconnect();
28078 }
28079
28080 var data = edgesData.get(id, {
28081 showInternalIds: true
28082 });
28083 edges[id] = this.create(data);
28084 }
28085
28086 this.body.emitter.emit("_adjustEdgesForHierarchicalLayout");
28087
28088 if (doNotEmit === false) {
28089 this.body.emitter.emit("_dataChanged");
28090 }
28091 }
28092 /**
28093 * Update existing edges, or create them when not yet existing
28094 *
28095 * @param {number[] | string[]} ids
28096 * @private
28097 */
28098
28099 }, {
28100 key: "update",
28101 value: function update(ids) {
28102 var edges = this.body.edges;
28103 var edgesData = this.body.data.edges;
28104 var dataChanged = false;
28105
28106 for (var i = 0; i < ids.length; i++) {
28107 var id = ids[i];
28108 var data = edgesData.get(id);
28109 var edge = edges[id];
28110
28111 if (edge !== undefined) {
28112 // update edge
28113 edge.disconnect();
28114 dataChanged = edge.setOptions(data) || dataChanged; // if a support node is added, data can be changed.
28115
28116 edge.connect();
28117 } else {
28118 // create edge
28119 this.body.edges[id] = this.create(data);
28120 dataChanged = true;
28121 }
28122 }
28123
28124 if (dataChanged === true) {
28125 this.body.emitter.emit("_adjustEdgesForHierarchicalLayout");
28126 this.body.emitter.emit("_dataChanged");
28127 } else {
28128 this.body.emitter.emit("_dataUpdated");
28129 }
28130 }
28131 /**
28132 * Remove existing edges. Non existing ids will be ignored
28133 *
28134 * @param {number[] | string[]} ids
28135 * @param {boolean} [emit=true]
28136 * @private
28137 */
28138
28139 }, {
28140 key: "remove",
28141 value: function remove(ids) {
28142 var emit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
28143 if (ids.length === 0) return; // early out
28144
28145 var edges = this.body.edges;
28146 forEach$1(ids, function (id) {
28147 var edge = edges[id];
28148
28149 if (edge !== undefined) {
28150 edge.remove();
28151 }
28152 });
28153
28154 if (emit) {
28155 this.body.emitter.emit("_dataChanged");
28156 }
28157 }
28158 /**
28159 * Refreshes Edge Handler
28160 */
28161
28162 }, {
28163 key: "refresh",
28164 value: function refresh() {
28165 var _this4 = this;
28166
28167 forEach$1(this.body.edges, function (edge, edgeId) {
28168 var data = _this4.body.data.edges.get(edgeId);
28169
28170 if (data !== undefined) {
28171 edge.setOptions(data);
28172 }
28173 });
28174 }
28175 /**
28176 *
28177 * @param {object} properties
28178 * @returns {Edge}
28179 */
28180
28181 }, {
28182 key: "create",
28183 value: function create(properties) {
28184 return new Edge(properties, this.body, this.images, this.options, this.defaultOptions);
28185 }
28186 /**
28187 * Reconnect all edges
28188 *
28189 * @private
28190 */
28191
28192 }, {
28193 key: "reconnectEdges",
28194 value: function reconnectEdges() {
28195 var id;
28196 var nodes = this.body.nodes;
28197 var edges = this.body.edges;
28198
28199 for (id in nodes) {
28200 if (Object.prototype.hasOwnProperty.call(nodes, id)) {
28201 nodes[id].edges = [];
28202 }
28203 }
28204
28205 for (id in edges) {
28206 if (Object.prototype.hasOwnProperty.call(edges, id)) {
28207 var edge = edges[id];
28208 edge.from = null;
28209 edge.to = null;
28210 edge.connect();
28211 }
28212 }
28213 }
28214 /**
28215 *
28216 * @param {Edge.id} edgeId
28217 * @returns {Array}
28218 */
28219
28220 }, {
28221 key: "getConnectedNodes",
28222 value: function getConnectedNodes(edgeId) {
28223 var nodeList = [];
28224
28225 if (this.body.edges[edgeId] !== undefined) {
28226 var edge = this.body.edges[edgeId];
28227
28228 if (edge.fromId !== undefined) {
28229 nodeList.push(edge.fromId);
28230 }
28231
28232 if (edge.toId !== undefined) {
28233 nodeList.push(edge.toId);
28234 }
28235 }
28236
28237 return nodeList;
28238 }
28239 /**
28240 * There is no direct relation between the nodes and the edges DataSet,
28241 * so the right place to do call this is in the handler for event `_dataUpdated`.
28242 */
28243
28244 }, {
28245 key: "_updateState",
28246 value: function _updateState() {
28247 this._addMissingEdges();
28248
28249 this._removeInvalidEdges();
28250 }
28251 /**
28252 * Scan for missing nodes and remove corresponding edges, if any.
28253 *
28254 * @private
28255 */
28256
28257 }, {
28258 key: "_removeInvalidEdges",
28259 value: function _removeInvalidEdges() {
28260 var _this5 = this;
28261
28262 var edgesToDelete = [];
28263 forEach$1(this.body.edges, function (edge, id) {
28264 var toNode = _this5.body.nodes[edge.toId];
28265 var fromNode = _this5.body.nodes[edge.fromId]; // Skip clustering edges here, let the Clustering module handle those
28266
28267 if (toNode !== undefined && toNode.isCluster === true || fromNode !== undefined && fromNode.isCluster === true) {
28268 return;
28269 }
28270
28271 if (toNode === undefined || fromNode === undefined) {
28272 edgesToDelete.push(id);
28273 }
28274 });
28275 this.remove(edgesToDelete, false);
28276 }
28277 /**
28278 * add all edges from dataset that are not in the cached state
28279 *
28280 * @private
28281 */
28282
28283 }, {
28284 key: "_addMissingEdges",
28285 value: function _addMissingEdges() {
28286 var edgesData = this.body.data.edges;
28287
28288 if (edgesData === undefined || edgesData === null) {
28289 return; // No edges DataSet yet; can happen on startup
28290 }
28291
28292 var edges = this.body.edges;
28293 var addIds = [];
28294
28295 forEach$2(edgesData).call(edgesData, function (edgeData, edgeId) {
28296 var edge = edges[edgeId];
28297
28298 if (edge === undefined) {
28299 addIds.push(edgeId);
28300 }
28301 });
28302
28303 this.add(addIds, true);
28304 }
28305 }]);
28306
28307 return EdgesHandler;
28308}();
28309
28310/**
28311 * Barnes Hut Solver
28312 */
28313
28314var BarnesHutSolver = /*#__PURE__*/function () {
28315 /**
28316 * @param {object} body
28317 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
28318 * @param {object} options
28319 */
28320 function BarnesHutSolver(body, physicsBody, options) {
28321 _classCallCheck(this, BarnesHutSolver);
28322
28323 this.body = body;
28324 this.physicsBody = physicsBody;
28325 this.barnesHutTree;
28326 this.setOptions(options);
28327 this._rng = Alea("BARNES HUT SOLVER"); // debug: show grid
28328 // this.body.emitter.on("afterDrawing", (ctx) => {this._debug(ctx,'#ff0000')})
28329 }
28330 /**
28331 *
28332 * @param {object} options
28333 */
28334
28335
28336 _createClass(BarnesHutSolver, [{
28337 key: "setOptions",
28338 value: function setOptions(options) {
28339 this.options = options;
28340 this.thetaInversed = 1 / this.options.theta; // if 1 then min distance = 0.5, if 0.5 then min distance = 0.5 + 0.5*node.shape.radius
28341
28342 this.overlapAvoidanceFactor = 1 - Math.max(0, Math.min(1, this.options.avoidOverlap));
28343 }
28344 /**
28345 * This function calculates the forces the nodes apply on each other based on a gravitational model.
28346 * The Barnes Hut method is used to speed up this N-body simulation.
28347 *
28348 * @private
28349 */
28350
28351 }, {
28352 key: "solve",
28353 value: function solve() {
28354 if (this.options.gravitationalConstant !== 0 && this.physicsBody.physicsNodeIndices.length > 0) {
28355 var node;
28356 var nodes = this.body.nodes;
28357 var nodeIndices = this.physicsBody.physicsNodeIndices;
28358 var nodeCount = nodeIndices.length; // create the tree
28359
28360 var barnesHutTree = this._formBarnesHutTree(nodes, nodeIndices); // for debugging
28361
28362
28363 this.barnesHutTree = barnesHutTree; // place the nodes one by one recursively
28364
28365 for (var i = 0; i < nodeCount; i++) {
28366 node = nodes[nodeIndices[i]];
28367
28368 if (node.options.mass > 0) {
28369 // starting with root is irrelevant, it never passes the BarnesHutSolver condition
28370 this._getForceContributions(barnesHutTree.root, node);
28371 }
28372 }
28373 }
28374 }
28375 /**
28376 * @param {object} parentBranch
28377 * @param {Node} node
28378 * @private
28379 */
28380
28381 }, {
28382 key: "_getForceContributions",
28383 value: function _getForceContributions(parentBranch, node) {
28384 this._getForceContribution(parentBranch.children.NW, node);
28385
28386 this._getForceContribution(parentBranch.children.NE, node);
28387
28388 this._getForceContribution(parentBranch.children.SW, node);
28389
28390 this._getForceContribution(parentBranch.children.SE, node);
28391 }
28392 /**
28393 * This function traverses the barnesHutTree. It checks when it can approximate distant nodes with their center of mass.
28394 * If a region contains a single node, we check if it is not itself, then we apply the force.
28395 *
28396 * @param {object} parentBranch
28397 * @param {Node} node
28398 * @private
28399 */
28400
28401 }, {
28402 key: "_getForceContribution",
28403 value: function _getForceContribution(parentBranch, node) {
28404 // we get no force contribution from an empty region
28405 if (parentBranch.childrenCount > 0) {
28406 // get the distance from the center of mass to the node.
28407 var dx = parentBranch.centerOfMass.x - node.x;
28408 var dy = parentBranch.centerOfMass.y - node.y;
28409 var distance = Math.sqrt(dx * dx + dy * dy); // BarnesHutSolver condition
28410 // original condition : s/d < theta = passed === d/s > 1/theta = passed
28411 // calcSize = 1/s --> d * 1/s > 1/theta = passed
28412
28413 if (distance * parentBranch.calcSize > this.thetaInversed) {
28414 this._calculateForces(distance, dx, dy, node, parentBranch);
28415 } else {
28416 // Did not pass the condition, go into children if available
28417 if (parentBranch.childrenCount === 4) {
28418 this._getForceContributions(parentBranch, node);
28419 } else {
28420 // parentBranch must have only one node, if it was empty we wouldnt be here
28421 if (parentBranch.children.data.id != node.id) {
28422 // if it is not self
28423 this._calculateForces(distance, dx, dy, node, parentBranch);
28424 }
28425 }
28426 }
28427 }
28428 }
28429 /**
28430 * Calculate the forces based on the distance.
28431 *
28432 * @param {number} distance
28433 * @param {number} dx
28434 * @param {number} dy
28435 * @param {Node} node
28436 * @param {object} parentBranch
28437 * @private
28438 */
28439
28440 }, {
28441 key: "_calculateForces",
28442 value: function _calculateForces(distance, dx, dy, node, parentBranch) {
28443 if (distance === 0) {
28444 distance = 0.1;
28445 dx = distance;
28446 }
28447
28448 if (this.overlapAvoidanceFactor < 1 && node.shape.radius) {
28449 distance = Math.max(0.1 + this.overlapAvoidanceFactor * node.shape.radius, distance - node.shape.radius);
28450 } // the dividing by the distance cubed instead of squared allows us to get the fx and fy components without sines and cosines
28451 // it is shorthand for gravityforce with distance squared and fx = dx/distance * gravityForce
28452
28453
28454 var gravityForce = this.options.gravitationalConstant * parentBranch.mass * node.options.mass / Math.pow(distance, 3);
28455 var fx = dx * gravityForce;
28456 var fy = dy * gravityForce;
28457 this.physicsBody.forces[node.id].x += fx;
28458 this.physicsBody.forces[node.id].y += fy;
28459 }
28460 /**
28461 * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes.
28462 *
28463 * @param {Array.<Node>} nodes
28464 * @param {Array.<number>} nodeIndices
28465 * @returns {{root: {centerOfMass: {x: number, y: number}, mass: number, range: {minX: number, maxX: number, minY: number, maxY: number}, size: number, calcSize: number, children: {data: null}, maxWidth: number, level: number, childrenCount: number}}} BarnesHutTree
28466 * @private
28467 */
28468
28469 }, {
28470 key: "_formBarnesHutTree",
28471 value: function _formBarnesHutTree(nodes, nodeIndices) {
28472 var node;
28473 var nodeCount = nodeIndices.length;
28474 var minX = nodes[nodeIndices[0]].x;
28475 var minY = nodes[nodeIndices[0]].y;
28476 var maxX = nodes[nodeIndices[0]].x;
28477 var maxY = nodes[nodeIndices[0]].y; // get the range of the nodes
28478
28479 for (var i = 1; i < nodeCount; i++) {
28480 var _node = nodes[nodeIndices[i]];
28481 var x = _node.x;
28482 var y = _node.y;
28483
28484 if (_node.options.mass > 0) {
28485 if (x < minX) {
28486 minX = x;
28487 }
28488
28489 if (x > maxX) {
28490 maxX = x;
28491 }
28492
28493 if (y < minY) {
28494 minY = y;
28495 }
28496
28497 if (y > maxY) {
28498 maxY = y;
28499 }
28500 }
28501 } // make the range a square
28502
28503
28504 var sizeDiff = Math.abs(maxX - minX) - Math.abs(maxY - minY); // difference between X and Y
28505
28506 if (sizeDiff > 0) {
28507 minY -= 0.5 * sizeDiff;
28508 maxY += 0.5 * sizeDiff;
28509 } // xSize > ySize
28510 else {
28511 minX += 0.5 * sizeDiff;
28512 maxX -= 0.5 * sizeDiff;
28513 } // xSize < ySize
28514
28515
28516 var minimumTreeSize = 1e-5;
28517 var rootSize = Math.max(minimumTreeSize, Math.abs(maxX - minX));
28518 var halfRootSize = 0.5 * rootSize;
28519 var centerX = 0.5 * (minX + maxX),
28520 centerY = 0.5 * (minY + maxY); // construct the barnesHutTree
28521
28522 var barnesHutTree = {
28523 root: {
28524 centerOfMass: {
28525 x: 0,
28526 y: 0
28527 },
28528 mass: 0,
28529 range: {
28530 minX: centerX - halfRootSize,
28531 maxX: centerX + halfRootSize,
28532 minY: centerY - halfRootSize,
28533 maxY: centerY + halfRootSize
28534 },
28535 size: rootSize,
28536 calcSize: 1 / rootSize,
28537 children: {
28538 data: null
28539 },
28540 maxWidth: 0,
28541 level: 0,
28542 childrenCount: 4
28543 }
28544 };
28545
28546 this._splitBranch(barnesHutTree.root); // place the nodes one by one recursively
28547
28548
28549 for (var _i = 0; _i < nodeCount; _i++) {
28550 node = nodes[nodeIndices[_i]];
28551
28552 if (node.options.mass > 0) {
28553 this._placeInTree(barnesHutTree.root, node);
28554 }
28555 } // make global
28556
28557
28558 return barnesHutTree;
28559 }
28560 /**
28561 * this updates the mass of a branch. this is increased by adding a node.
28562 *
28563 * @param {object} parentBranch
28564 * @param {Node} node
28565 * @private
28566 */
28567
28568 }, {
28569 key: "_updateBranchMass",
28570 value: function _updateBranchMass(parentBranch, node) {
28571 var centerOfMass = parentBranch.centerOfMass;
28572 var totalMass = parentBranch.mass + node.options.mass;
28573 var totalMassInv = 1 / totalMass;
28574 centerOfMass.x = centerOfMass.x * parentBranch.mass + node.x * node.options.mass;
28575 centerOfMass.x *= totalMassInv;
28576 centerOfMass.y = centerOfMass.y * parentBranch.mass + node.y * node.options.mass;
28577 centerOfMass.y *= totalMassInv;
28578 parentBranch.mass = totalMass;
28579 var biggestSize = Math.max(Math.max(node.height, node.radius), node.width);
28580 parentBranch.maxWidth = parentBranch.maxWidth < biggestSize ? biggestSize : parentBranch.maxWidth;
28581 }
28582 /**
28583 * determine in which branch the node will be placed.
28584 *
28585 * @param {object} parentBranch
28586 * @param {Node} node
28587 * @param {boolean} skipMassUpdate
28588 * @private
28589 */
28590
28591 }, {
28592 key: "_placeInTree",
28593 value: function _placeInTree(parentBranch, node, skipMassUpdate) {
28594 if (skipMassUpdate != true || skipMassUpdate === undefined) {
28595 // update the mass of the branch.
28596 this._updateBranchMass(parentBranch, node);
28597 }
28598
28599 var range = parentBranch.children.NW.range;
28600 var region;
28601
28602 if (range.maxX > node.x) {
28603 // in NW or SW
28604 if (range.maxY > node.y) {
28605 region = "NW";
28606 } else {
28607 region = "SW";
28608 }
28609 } else {
28610 // in NE or SE
28611 if (range.maxY > node.y) {
28612 region = "NE";
28613 } else {
28614 region = "SE";
28615 }
28616 }
28617
28618 this._placeInRegion(parentBranch, node, region);
28619 }
28620 /**
28621 * actually place the node in a region (or branch)
28622 *
28623 * @param {object} parentBranch
28624 * @param {Node} node
28625 * @param {'NW'| 'NE' | 'SW' | 'SE'} region
28626 * @private
28627 */
28628
28629 }, {
28630 key: "_placeInRegion",
28631 value: function _placeInRegion(parentBranch, node, region) {
28632 var children = parentBranch.children[region];
28633
28634 switch (children.childrenCount) {
28635 case 0:
28636 // place node here
28637 children.children.data = node;
28638 children.childrenCount = 1;
28639
28640 this._updateBranchMass(children, node);
28641
28642 break;
28643
28644 case 1:
28645 // convert into children
28646 // if there are two nodes exactly overlapping (on init, on opening of cluster etc.)
28647 // we move one node a little bit and we do not put it in the tree.
28648 if (children.children.data.x === node.x && children.children.data.y === node.y) {
28649 node.x += this._rng();
28650 node.y += this._rng();
28651 } else {
28652 this._splitBranch(children);
28653
28654 this._placeInTree(children, node);
28655 }
28656
28657 break;
28658
28659 case 4:
28660 // place in branch
28661 this._placeInTree(children, node);
28662
28663 break;
28664 }
28665 }
28666 /**
28667 * this function splits a branch into 4 sub branches. If the branch contained a node, we place it in the subbranch
28668 * after the split is complete.
28669 *
28670 * @param {object} parentBranch
28671 * @private
28672 */
28673
28674 }, {
28675 key: "_splitBranch",
28676 value: function _splitBranch(parentBranch) {
28677 // if the branch is shaded with a node, replace the node in the new subset.
28678 var containedNode = null;
28679
28680 if (parentBranch.childrenCount === 1) {
28681 containedNode = parentBranch.children.data;
28682 parentBranch.mass = 0;
28683 parentBranch.centerOfMass.x = 0;
28684 parentBranch.centerOfMass.y = 0;
28685 }
28686
28687 parentBranch.childrenCount = 4;
28688 parentBranch.children.data = null;
28689
28690 this._insertRegion(parentBranch, "NW");
28691
28692 this._insertRegion(parentBranch, "NE");
28693
28694 this._insertRegion(parentBranch, "SW");
28695
28696 this._insertRegion(parentBranch, "SE");
28697
28698 if (containedNode != null) {
28699 this._placeInTree(parentBranch, containedNode);
28700 }
28701 }
28702 /**
28703 * This function subdivides the region into four new segments.
28704 * Specifically, this inserts a single new segment.
28705 * It fills the children section of the parentBranch
28706 *
28707 * @param {object} parentBranch
28708 * @param {'NW'| 'NE' | 'SW' | 'SE'} region
28709 * @private
28710 */
28711
28712 }, {
28713 key: "_insertRegion",
28714 value: function _insertRegion(parentBranch, region) {
28715 var minX, maxX, minY, maxY;
28716 var childSize = 0.5 * parentBranch.size;
28717
28718 switch (region) {
28719 case "NW":
28720 minX = parentBranch.range.minX;
28721 maxX = parentBranch.range.minX + childSize;
28722 minY = parentBranch.range.minY;
28723 maxY = parentBranch.range.minY + childSize;
28724 break;
28725
28726 case "NE":
28727 minX = parentBranch.range.minX + childSize;
28728 maxX = parentBranch.range.maxX;
28729 minY = parentBranch.range.minY;
28730 maxY = parentBranch.range.minY + childSize;
28731 break;
28732
28733 case "SW":
28734 minX = parentBranch.range.minX;
28735 maxX = parentBranch.range.minX + childSize;
28736 minY = parentBranch.range.minY + childSize;
28737 maxY = parentBranch.range.maxY;
28738 break;
28739
28740 case "SE":
28741 minX = parentBranch.range.minX + childSize;
28742 maxX = parentBranch.range.maxX;
28743 minY = parentBranch.range.minY + childSize;
28744 maxY = parentBranch.range.maxY;
28745 break;
28746 }
28747
28748 parentBranch.children[region] = {
28749 centerOfMass: {
28750 x: 0,
28751 y: 0
28752 },
28753 mass: 0,
28754 range: {
28755 minX: minX,
28756 maxX: maxX,
28757 minY: minY,
28758 maxY: maxY
28759 },
28760 size: 0.5 * parentBranch.size,
28761 calcSize: 2 * parentBranch.calcSize,
28762 children: {
28763 data: null
28764 },
28765 maxWidth: 0,
28766 level: parentBranch.level + 1,
28767 childrenCount: 0
28768 };
28769 } //--------------------------- DEBUGGING BELOW ---------------------------//
28770
28771 /**
28772 * This function is for debugging purposed, it draws the tree.
28773 *
28774 * @param {CanvasRenderingContext2D} ctx
28775 * @param {string} color
28776 * @private
28777 */
28778
28779 }, {
28780 key: "_debug",
28781 value: function _debug(ctx, color) {
28782 if (this.barnesHutTree !== undefined) {
28783 ctx.lineWidth = 1;
28784
28785 this._drawBranch(this.barnesHutTree.root, ctx, color);
28786 }
28787 }
28788 /**
28789 * This function is for debugging purposes. It draws the branches recursively.
28790 *
28791 * @param {object} branch
28792 * @param {CanvasRenderingContext2D} ctx
28793 * @param {string} color
28794 * @private
28795 */
28796
28797 }, {
28798 key: "_drawBranch",
28799 value: function _drawBranch(branch, ctx, color) {
28800 if (color === undefined) {
28801 color = "#FF0000";
28802 }
28803
28804 if (branch.childrenCount === 4) {
28805 this._drawBranch(branch.children.NW, ctx);
28806
28807 this._drawBranch(branch.children.NE, ctx);
28808
28809 this._drawBranch(branch.children.SE, ctx);
28810
28811 this._drawBranch(branch.children.SW, ctx);
28812 }
28813
28814 ctx.strokeStyle = color;
28815 ctx.beginPath();
28816 ctx.moveTo(branch.range.minX, branch.range.minY);
28817 ctx.lineTo(branch.range.maxX, branch.range.minY);
28818 ctx.stroke();
28819 ctx.beginPath();
28820 ctx.moveTo(branch.range.maxX, branch.range.minY);
28821 ctx.lineTo(branch.range.maxX, branch.range.maxY);
28822 ctx.stroke();
28823 ctx.beginPath();
28824 ctx.moveTo(branch.range.maxX, branch.range.maxY);
28825 ctx.lineTo(branch.range.minX, branch.range.maxY);
28826 ctx.stroke();
28827 ctx.beginPath();
28828 ctx.moveTo(branch.range.minX, branch.range.maxY);
28829 ctx.lineTo(branch.range.minX, branch.range.minY);
28830 ctx.stroke();
28831 /*
28832 if (branch.mass > 0) {
28833 ctx.circle(branch.centerOfMass.x, branch.centerOfMass.y, 3*branch.mass);
28834 ctx.stroke();
28835 }
28836 */
28837 }
28838 }]);
28839
28840 return BarnesHutSolver;
28841}();
28842
28843/**
28844 * Repulsion Solver
28845 */
28846
28847var RepulsionSolver = /*#__PURE__*/function () {
28848 /**
28849 * @param {object} body
28850 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
28851 * @param {object} options
28852 */
28853 function RepulsionSolver(body, physicsBody, options) {
28854 _classCallCheck(this, RepulsionSolver);
28855
28856 this._rng = Alea("REPULSION SOLVER");
28857 this.body = body;
28858 this.physicsBody = physicsBody;
28859 this.setOptions(options);
28860 }
28861 /**
28862 *
28863 * @param {object} options
28864 */
28865
28866
28867 _createClass(RepulsionSolver, [{
28868 key: "setOptions",
28869 value: function setOptions(options) {
28870 this.options = options;
28871 }
28872 /**
28873 * Calculate the forces the nodes apply on each other based on a repulsion field.
28874 * This field is linearly approximated.
28875 *
28876 * @private
28877 */
28878
28879 }, {
28880 key: "solve",
28881 value: function solve() {
28882 var dx, dy, distance, fx, fy, repulsingForce, node1, node2;
28883 var nodes = this.body.nodes;
28884 var nodeIndices = this.physicsBody.physicsNodeIndices;
28885 var forces = this.physicsBody.forces; // repulsing forces between nodes
28886
28887 var nodeDistance = this.options.nodeDistance; // approximation constants
28888
28889 var a = -2 / 3 / nodeDistance;
28890 var b = 4 / 3; // we loop from i over all but the last entree in the array
28891 // j loops from i+1 to the last. This way we do not double count any of the indices, nor i === j
28892
28893 for (var i = 0; i < nodeIndices.length - 1; i++) {
28894 node1 = nodes[nodeIndices[i]];
28895
28896 for (var j = i + 1; j < nodeIndices.length; j++) {
28897 node2 = nodes[nodeIndices[j]];
28898 dx = node2.x - node1.x;
28899 dy = node2.y - node1.y;
28900 distance = Math.sqrt(dx * dx + dy * dy); // same condition as BarnesHutSolver, making sure nodes are never 100% overlapping.
28901
28902 if (distance === 0) {
28903 distance = 0.1 * this._rng();
28904 dx = distance;
28905 }
28906
28907 if (distance < 2 * nodeDistance) {
28908 if (distance < 0.5 * nodeDistance) {
28909 repulsingForce = 1.0;
28910 } else {
28911 repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / nodeDistance - 1) * steepness))
28912 }
28913
28914 repulsingForce = repulsingForce / distance;
28915 fx = dx * repulsingForce;
28916 fy = dy * repulsingForce;
28917 forces[node1.id].x -= fx;
28918 forces[node1.id].y -= fy;
28919 forces[node2.id].x += fx;
28920 forces[node2.id].y += fy;
28921 }
28922 }
28923 }
28924 }
28925 }]);
28926
28927 return RepulsionSolver;
28928}();
28929
28930/**
28931 * Hierarchical Repulsion Solver
28932 */
28933var HierarchicalRepulsionSolver = /*#__PURE__*/function () {
28934 /**
28935 * @param {object} body
28936 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
28937 * @param {object} options
28938 */
28939 function HierarchicalRepulsionSolver(body, physicsBody, options) {
28940 _classCallCheck(this, HierarchicalRepulsionSolver);
28941
28942 this.body = body;
28943 this.physicsBody = physicsBody;
28944 this.setOptions(options);
28945 }
28946 /**
28947 *
28948 * @param {object} options
28949 */
28950
28951
28952 _createClass(HierarchicalRepulsionSolver, [{
28953 key: "setOptions",
28954 value: function setOptions(options) {
28955 this.options = options;
28956 this.overlapAvoidanceFactor = Math.max(0, Math.min(1, this.options.avoidOverlap || 0));
28957 }
28958 /**
28959 * Calculate the forces the nodes apply on each other based on a repulsion field.
28960 * This field is linearly approximated.
28961 *
28962 * @private
28963 */
28964
28965 }, {
28966 key: "solve",
28967 value: function solve() {
28968 var nodes = this.body.nodes;
28969 var nodeIndices = this.physicsBody.physicsNodeIndices;
28970 var forces = this.physicsBody.forces; // repulsing forces between nodes
28971
28972 var nodeDistance = this.options.nodeDistance; // we loop from i over all but the last entree in the array
28973 // j loops from i+1 to the last. This way we do not double count any of the indices, nor i === j
28974
28975 for (var i = 0; i < nodeIndices.length - 1; i++) {
28976 var node1 = nodes[nodeIndices[i]];
28977
28978 for (var j = i + 1; j < nodeIndices.length; j++) {
28979 var node2 = nodes[nodeIndices[j]]; // nodes only affect nodes on their level
28980
28981 if (node1.level === node2.level) {
28982 var theseNodesDistance = nodeDistance + this.overlapAvoidanceFactor * ((node1.shape.radius || 0) / 2 + (node2.shape.radius || 0) / 2);
28983 var dx = node2.x - node1.x;
28984 var dy = node2.y - node1.y;
28985 var distance = Math.sqrt(dx * dx + dy * dy);
28986 var steepness = 0.05;
28987 var repulsingForce = void 0;
28988
28989 if (distance < theseNodesDistance) {
28990 repulsingForce = -Math.pow(steepness * distance, 2) + Math.pow(steepness * theseNodesDistance, 2);
28991 } else {
28992 repulsingForce = 0;
28993 } // normalize force with
28994
28995
28996 if (distance !== 0) {
28997 repulsingForce = repulsingForce / distance;
28998 }
28999
29000 var fx = dx * repulsingForce;
29001 var fy = dy * repulsingForce;
29002 forces[node1.id].x -= fx;
29003 forces[node1.id].y -= fy;
29004 forces[node2.id].x += fx;
29005 forces[node2.id].y += fy;
29006 }
29007 }
29008 }
29009 }
29010 }]);
29011
29012 return HierarchicalRepulsionSolver;
29013}();
29014
29015/**
29016 * Spring Solver
29017 */
29018var SpringSolver = /*#__PURE__*/function () {
29019 /**
29020 * @param {object} body
29021 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
29022 * @param {object} options
29023 */
29024 function SpringSolver(body, physicsBody, options) {
29025 _classCallCheck(this, SpringSolver);
29026
29027 this.body = body;
29028 this.physicsBody = physicsBody;
29029 this.setOptions(options);
29030 }
29031 /**
29032 *
29033 * @param {object} options
29034 */
29035
29036
29037 _createClass(SpringSolver, [{
29038 key: "setOptions",
29039 value: function setOptions(options) {
29040 this.options = options;
29041 }
29042 /**
29043 * This function calculates the springforces on the nodes, accounting for the support nodes.
29044 *
29045 * @private
29046 */
29047
29048 }, {
29049 key: "solve",
29050 value: function solve() {
29051 var edgeLength, edge;
29052 var edgeIndices = this.physicsBody.physicsEdgeIndices;
29053 var edges = this.body.edges;
29054 var node1, node2, node3; // forces caused by the edges, modelled as springs
29055
29056 for (var i = 0; i < edgeIndices.length; i++) {
29057 edge = edges[edgeIndices[i]];
29058
29059 if (edge.connected === true && edge.toId !== edge.fromId) {
29060 // only calculate forces if nodes are in the same sector
29061 if (this.body.nodes[edge.toId] !== undefined && this.body.nodes[edge.fromId] !== undefined) {
29062 if (edge.edgeType.via !== undefined) {
29063 edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
29064 node1 = edge.to;
29065 node2 = edge.edgeType.via;
29066 node3 = edge.from;
29067
29068 this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
29069
29070 this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
29071 } else {
29072 // the * 1.5 is here so the edge looks as large as a smooth edge. It does not initially because the smooth edges use
29073 // the support nodes which exert a repulsive force on the to and from nodes, making the edge appear larger.
29074 edgeLength = edge.options.length === undefined ? this.options.springLength * 1.5 : edge.options.length;
29075
29076 this._calculateSpringForce(edge.from, edge.to, edgeLength);
29077 }
29078 }
29079 }
29080 }
29081 }
29082 /**
29083 * This is the code actually performing the calculation for the function above.
29084 *
29085 * @param {Node} node1
29086 * @param {Node} node2
29087 * @param {number} edgeLength
29088 * @private
29089 */
29090
29091 }, {
29092 key: "_calculateSpringForce",
29093 value: function _calculateSpringForce(node1, node2, edgeLength) {
29094 var dx = node1.x - node2.x;
29095 var dy = node1.y - node2.y;
29096 var distance = Math.max(Math.sqrt(dx * dx + dy * dy), 0.01); // the 1/distance is so the fx and fy can be calculated without sine or cosine.
29097
29098 var springForce = this.options.springConstant * (edgeLength - distance) / distance;
29099 var fx = dx * springForce;
29100 var fy = dy * springForce; // handle the case where one node is not part of the physcis
29101
29102 if (this.physicsBody.forces[node1.id] !== undefined) {
29103 this.physicsBody.forces[node1.id].x += fx;
29104 this.physicsBody.forces[node1.id].y += fy;
29105 }
29106
29107 if (this.physicsBody.forces[node2.id] !== undefined) {
29108 this.physicsBody.forces[node2.id].x -= fx;
29109 this.physicsBody.forces[node2.id].y -= fy;
29110 }
29111 }
29112 }]);
29113
29114 return SpringSolver;
29115}();
29116
29117/**
29118 * Hierarchical Spring Solver
29119 */
29120var HierarchicalSpringSolver = /*#__PURE__*/function () {
29121 /**
29122 * @param {object} body
29123 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
29124 * @param {object} options
29125 */
29126 function HierarchicalSpringSolver(body, physicsBody, options) {
29127 _classCallCheck(this, HierarchicalSpringSolver);
29128
29129 this.body = body;
29130 this.physicsBody = physicsBody;
29131 this.setOptions(options);
29132 }
29133 /**
29134 *
29135 * @param {object} options
29136 */
29137
29138
29139 _createClass(HierarchicalSpringSolver, [{
29140 key: "setOptions",
29141 value: function setOptions(options) {
29142 this.options = options;
29143 }
29144 /**
29145 * This function calculates the springforces on the nodes, accounting for the support nodes.
29146 *
29147 * @private
29148 */
29149
29150 }, {
29151 key: "solve",
29152 value: function solve() {
29153 var edgeLength, edge;
29154 var dx, dy, fx, fy, springForce, distance;
29155 var edges = this.body.edges;
29156 var factor = 0.5;
29157 var edgeIndices = this.physicsBody.physicsEdgeIndices;
29158 var nodeIndices = this.physicsBody.physicsNodeIndices;
29159 var forces = this.physicsBody.forces; // initialize the spring force counters
29160
29161 for (var i = 0; i < nodeIndices.length; i++) {
29162 var nodeId = nodeIndices[i];
29163 forces[nodeId].springFx = 0;
29164 forces[nodeId].springFy = 0;
29165 } // forces caused by the edges, modelled as springs
29166
29167
29168 for (var _i = 0; _i < edgeIndices.length; _i++) {
29169 edge = edges[edgeIndices[_i]];
29170
29171 if (edge.connected === true) {
29172 edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
29173 dx = edge.from.x - edge.to.x;
29174 dy = edge.from.y - edge.to.y;
29175 distance = Math.sqrt(dx * dx + dy * dy);
29176 distance = distance === 0 ? 0.01 : distance; // the 1/distance is so the fx and fy can be calculated without sine or cosine.
29177
29178 springForce = this.options.springConstant * (edgeLength - distance) / distance;
29179 fx = dx * springForce;
29180 fy = dy * springForce;
29181
29182 if (edge.to.level != edge.from.level) {
29183 if (forces[edge.toId] !== undefined) {
29184 forces[edge.toId].springFx -= fx;
29185 forces[edge.toId].springFy -= fy;
29186 }
29187
29188 if (forces[edge.fromId] !== undefined) {
29189 forces[edge.fromId].springFx += fx;
29190 forces[edge.fromId].springFy += fy;
29191 }
29192 } else {
29193 if (forces[edge.toId] !== undefined) {
29194 forces[edge.toId].x -= factor * fx;
29195 forces[edge.toId].y -= factor * fy;
29196 }
29197
29198 if (forces[edge.fromId] !== undefined) {
29199 forces[edge.fromId].x += factor * fx;
29200 forces[edge.fromId].y += factor * fy;
29201 }
29202 }
29203 }
29204 } // normalize spring forces
29205
29206
29207 springForce = 1;
29208 var springFx, springFy;
29209
29210 for (var _i2 = 0; _i2 < nodeIndices.length; _i2++) {
29211 var _nodeId = nodeIndices[_i2];
29212 springFx = Math.min(springForce, Math.max(-springForce, forces[_nodeId].springFx));
29213 springFy = Math.min(springForce, Math.max(-springForce, forces[_nodeId].springFy));
29214 forces[_nodeId].x += springFx;
29215 forces[_nodeId].y += springFy;
29216 } // retain energy balance
29217
29218
29219 var totalFx = 0;
29220 var totalFy = 0;
29221
29222 for (var _i3 = 0; _i3 < nodeIndices.length; _i3++) {
29223 var _nodeId2 = nodeIndices[_i3];
29224 totalFx += forces[_nodeId2].x;
29225 totalFy += forces[_nodeId2].y;
29226 }
29227
29228 var correctionFx = totalFx / nodeIndices.length;
29229 var correctionFy = totalFy / nodeIndices.length;
29230
29231 for (var _i4 = 0; _i4 < nodeIndices.length; _i4++) {
29232 var _nodeId3 = nodeIndices[_i4];
29233 forces[_nodeId3].x -= correctionFx;
29234 forces[_nodeId3].y -= correctionFy;
29235 }
29236 }
29237 }]);
29238
29239 return HierarchicalSpringSolver;
29240}();
29241
29242/**
29243 * Central Gravity Solver
29244 */
29245var CentralGravitySolver = /*#__PURE__*/function () {
29246 /**
29247 * @param {object} body
29248 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
29249 * @param {object} options
29250 */
29251 function CentralGravitySolver(body, physicsBody, options) {
29252 _classCallCheck(this, CentralGravitySolver);
29253
29254 this.body = body;
29255 this.physicsBody = physicsBody;
29256 this.setOptions(options);
29257 }
29258 /**
29259 *
29260 * @param {object} options
29261 */
29262
29263
29264 _createClass(CentralGravitySolver, [{
29265 key: "setOptions",
29266 value: function setOptions(options) {
29267 this.options = options;
29268 }
29269 /**
29270 * Calculates forces for each node
29271 */
29272
29273 }, {
29274 key: "solve",
29275 value: function solve() {
29276 var dx, dy, distance, node;
29277 var nodes = this.body.nodes;
29278 var nodeIndices = this.physicsBody.physicsNodeIndices;
29279 var forces = this.physicsBody.forces;
29280
29281 for (var i = 0; i < nodeIndices.length; i++) {
29282 var nodeId = nodeIndices[i];
29283 node = nodes[nodeId];
29284 dx = -node.x;
29285 dy = -node.y;
29286 distance = Math.sqrt(dx * dx + dy * dy);
29287
29288 this._calculateForces(distance, dx, dy, forces, node);
29289 }
29290 }
29291 /**
29292 * Calculate the forces based on the distance.
29293 *
29294 * @param {number} distance
29295 * @param {number} dx
29296 * @param {number} dy
29297 * @param {object<Node.id, vis.Node>} forces
29298 * @param {Node} node
29299 * @private
29300 */
29301
29302 }, {
29303 key: "_calculateForces",
29304 value: function _calculateForces(distance, dx, dy, forces, node) {
29305 var gravityForce = distance === 0 ? 0 : this.options.centralGravity / distance;
29306 forces[node.id].x = dx * gravityForce;
29307 forces[node.id].y = dy * gravityForce;
29308 }
29309 }]);
29310
29311 return CentralGravitySolver;
29312}();
29313
29314function _createSuper$3(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$3(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
29315
29316function _isNativeReflectConstruct$3() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
29317/**
29318 * @augments BarnesHutSolver
29319 */
29320
29321var ForceAtlas2BasedRepulsionSolver = /*#__PURE__*/function (_BarnesHutSolver) {
29322 _inherits(ForceAtlas2BasedRepulsionSolver, _BarnesHutSolver);
29323
29324 var _super = _createSuper$3(ForceAtlas2BasedRepulsionSolver);
29325
29326 /**
29327 * @param {object} body
29328 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
29329 * @param {object} options
29330 */
29331 function ForceAtlas2BasedRepulsionSolver(body, physicsBody, options) {
29332 var _this;
29333
29334 _classCallCheck(this, ForceAtlas2BasedRepulsionSolver);
29335
29336 _this = _super.call(this, body, physicsBody, options);
29337 _this._rng = Alea("FORCE ATLAS 2 BASED REPULSION SOLVER");
29338 return _this;
29339 }
29340 /**
29341 * Calculate the forces based on the distance.
29342 *
29343 * @param {number} distance
29344 * @param {number} dx
29345 * @param {number} dy
29346 * @param {Node} node
29347 * @param {object} parentBranch
29348 * @private
29349 */
29350
29351
29352 _createClass(ForceAtlas2BasedRepulsionSolver, [{
29353 key: "_calculateForces",
29354 value: function _calculateForces(distance, dx, dy, node, parentBranch) {
29355 if (distance === 0) {
29356 distance = 0.1 * this._rng();
29357 dx = distance;
29358 }
29359
29360 if (this.overlapAvoidanceFactor < 1 && node.shape.radius) {
29361 distance = Math.max(0.1 + this.overlapAvoidanceFactor * node.shape.radius, distance - node.shape.radius);
29362 }
29363
29364 var degree = node.edges.length + 1; // the dividing by the distance cubed instead of squared allows us to get the fx and fy components without sines and cosines
29365 // it is shorthand for gravityforce with distance squared and fx = dx/distance * gravityForce
29366
29367 var gravityForce = this.options.gravitationalConstant * parentBranch.mass * node.options.mass * degree / Math.pow(distance, 2);
29368 var fx = dx * gravityForce;
29369 var fy = dy * gravityForce;
29370 this.physicsBody.forces[node.id].x += fx;
29371 this.physicsBody.forces[node.id].y += fy;
29372 }
29373 }]);
29374
29375 return ForceAtlas2BasedRepulsionSolver;
29376}(BarnesHutSolver);
29377
29378function _createSuper$2(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$2(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
29379
29380function _isNativeReflectConstruct$2() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
29381/**
29382 * @augments CentralGravitySolver
29383 */
29384
29385var ForceAtlas2BasedCentralGravitySolver = /*#__PURE__*/function (_CentralGravitySolver) {
29386 _inherits(ForceAtlas2BasedCentralGravitySolver, _CentralGravitySolver);
29387
29388 var _super = _createSuper$2(ForceAtlas2BasedCentralGravitySolver);
29389
29390 /**
29391 * @param {object} body
29392 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
29393 * @param {object} options
29394 */
29395 function ForceAtlas2BasedCentralGravitySolver(body, physicsBody, options) {
29396 _classCallCheck(this, ForceAtlas2BasedCentralGravitySolver);
29397
29398 return _super.call(this, body, physicsBody, options);
29399 }
29400 /**
29401 * Calculate the forces based on the distance.
29402 *
29403 * @param {number} distance
29404 * @param {number} dx
29405 * @param {number} dy
29406 * @param {object<Node.id, Node>} forces
29407 * @param {Node} node
29408 * @private
29409 */
29410
29411
29412 _createClass(ForceAtlas2BasedCentralGravitySolver, [{
29413 key: "_calculateForces",
29414 value: function _calculateForces(distance, dx, dy, forces, node) {
29415 if (distance > 0) {
29416 var degree = node.edges.length + 1;
29417 var gravityForce = this.options.centralGravity * degree * node.options.mass;
29418 forces[node.id].x = dx * gravityForce;
29419 forces[node.id].y = dy * gravityForce;
29420 }
29421 }
29422 }]);
29423
29424 return ForceAtlas2BasedCentralGravitySolver;
29425}(CentralGravitySolver);
29426
29427/**
29428 * The physics engine
29429 */
29430
29431var PhysicsEngine = /*#__PURE__*/function () {
29432 /**
29433 * @param {object} body
29434 */
29435 function PhysicsEngine(body) {
29436 _classCallCheck(this, PhysicsEngine);
29437
29438 this.body = body;
29439 this.physicsBody = {
29440 physicsNodeIndices: [],
29441 physicsEdgeIndices: [],
29442 forces: {},
29443 velocities: {}
29444 };
29445 this.physicsEnabled = true;
29446 this.simulationInterval = 1000 / 60;
29447 this.requiresTimeout = true;
29448 this.previousStates = {};
29449 this.referenceState = {};
29450 this.freezeCache = {};
29451 this.renderTimer = undefined; // parameters for the adaptive timestep
29452
29453 this.adaptiveTimestep = false;
29454 this.adaptiveTimestepEnabled = false;
29455 this.adaptiveCounter = 0;
29456 this.adaptiveInterval = 3;
29457 this.stabilized = false;
29458 this.startedStabilization = false;
29459 this.stabilizationIterations = 0;
29460 this.ready = false; // will be set to true if the stabilize
29461 // default options
29462
29463 this.options = {};
29464 this.defaultOptions = {
29465 enabled: true,
29466 barnesHut: {
29467 theta: 0.5,
29468 gravitationalConstant: -2000,
29469 centralGravity: 0.3,
29470 springLength: 95,
29471 springConstant: 0.04,
29472 damping: 0.09,
29473 avoidOverlap: 0
29474 },
29475 forceAtlas2Based: {
29476 theta: 0.5,
29477 gravitationalConstant: -50,
29478 centralGravity: 0.01,
29479 springConstant: 0.08,
29480 springLength: 100,
29481 damping: 0.4,
29482 avoidOverlap: 0
29483 },
29484 repulsion: {
29485 centralGravity: 0.2,
29486 springLength: 200,
29487 springConstant: 0.05,
29488 nodeDistance: 100,
29489 damping: 0.09,
29490 avoidOverlap: 0
29491 },
29492 hierarchicalRepulsion: {
29493 centralGravity: 0.0,
29494 springLength: 100,
29495 springConstant: 0.01,
29496 nodeDistance: 120,
29497 damping: 0.09
29498 },
29499 maxVelocity: 50,
29500 minVelocity: 0.75,
29501 // px/s
29502 solver: "barnesHut",
29503 stabilization: {
29504 enabled: true,
29505 iterations: 1000,
29506 // maximum number of iteration to stabilize
29507 updateInterval: 50,
29508 onlyDynamicEdges: false,
29509 fit: true
29510 },
29511 timestep: 0.5,
29512 adaptiveTimestep: true,
29513 wind: {
29514 x: 0,
29515 y: 0
29516 }
29517 };
29518
29519 assign$2(this.options, this.defaultOptions);
29520
29521 this.timestep = 0.5;
29522 this.layoutFailed = false;
29523 this.bindEventListeners();
29524 }
29525 /**
29526 * Binds event listeners
29527 */
29528
29529
29530 _createClass(PhysicsEngine, [{
29531 key: "bindEventListeners",
29532 value: function bindEventListeners() {
29533 var _this = this;
29534
29535 this.body.emitter.on("initPhysics", function () {
29536 _this.initPhysics();
29537 });
29538 this.body.emitter.on("_layoutFailed", function () {
29539 _this.layoutFailed = true;
29540 });
29541 this.body.emitter.on("resetPhysics", function () {
29542 _this.stopSimulation();
29543
29544 _this.ready = false;
29545 });
29546 this.body.emitter.on("disablePhysics", function () {
29547 _this.physicsEnabled = false;
29548
29549 _this.stopSimulation();
29550 });
29551 this.body.emitter.on("restorePhysics", function () {
29552 _this.setOptions(_this.options);
29553
29554 if (_this.ready === true) {
29555 _this.startSimulation();
29556 }
29557 });
29558 this.body.emitter.on("startSimulation", function () {
29559 if (_this.ready === true) {
29560 _this.startSimulation();
29561 }
29562 });
29563 this.body.emitter.on("stopSimulation", function () {
29564 _this.stopSimulation();
29565 });
29566 this.body.emitter.on("destroy", function () {
29567 _this.stopSimulation(false);
29568
29569 _this.body.emitter.off();
29570 });
29571 this.body.emitter.on("_dataChanged", function () {
29572 // Nodes and/or edges have been added or removed, update shortcut lists.
29573 _this.updatePhysicsData();
29574 }); // debug: show forces
29575 // this.body.emitter.on("afterDrawing", (ctx) => {this._drawForces(ctx);});
29576 }
29577 /**
29578 * set the physics options
29579 *
29580 * @param {object} options
29581 */
29582
29583 }, {
29584 key: "setOptions",
29585 value: function setOptions(options) {
29586 if (options !== undefined) {
29587 if (options === false) {
29588 this.options.enabled = false;
29589 this.physicsEnabled = false;
29590 this.stopSimulation();
29591 } else if (options === true) {
29592 this.options.enabled = true;
29593 this.physicsEnabled = true;
29594 this.startSimulation();
29595 } else {
29596 this.physicsEnabled = true;
29597 selectiveNotDeepExtend(["stabilization"], this.options, options);
29598 mergeOptions(this.options, options, "stabilization");
29599
29600 if (options.enabled === undefined) {
29601 this.options.enabled = true;
29602 }
29603
29604 if (this.options.enabled === false) {
29605 this.physicsEnabled = false;
29606 this.stopSimulation();
29607 }
29608
29609 var wind = this.options.wind;
29610
29611 if (wind) {
29612 if (typeof wind.x !== "number" || isNan(wind.x)) {
29613 wind.x = 0;
29614 }
29615
29616 if (typeof wind.y !== "number" || isNan(wind.y)) {
29617 wind.y = 0;
29618 }
29619 } // set the timestep
29620
29621
29622 this.timestep = this.options.timestep;
29623 }
29624 }
29625
29626 this.init();
29627 }
29628 /**
29629 * configure the engine.
29630 */
29631
29632 }, {
29633 key: "init",
29634 value: function init() {
29635 var options;
29636
29637 if (this.options.solver === "forceAtlas2Based") {
29638 options = this.options.forceAtlas2Based;
29639 this.nodesSolver = new ForceAtlas2BasedRepulsionSolver(this.body, this.physicsBody, options);
29640 this.edgesSolver = new SpringSolver(this.body, this.physicsBody, options);
29641 this.gravitySolver = new ForceAtlas2BasedCentralGravitySolver(this.body, this.physicsBody, options);
29642 } else if (this.options.solver === "repulsion") {
29643 options = this.options.repulsion;
29644 this.nodesSolver = new RepulsionSolver(this.body, this.physicsBody, options);
29645 this.edgesSolver = new SpringSolver(this.body, this.physicsBody, options);
29646 this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
29647 } else if (this.options.solver === "hierarchicalRepulsion") {
29648 options = this.options.hierarchicalRepulsion;
29649 this.nodesSolver = new HierarchicalRepulsionSolver(this.body, this.physicsBody, options);
29650 this.edgesSolver = new HierarchicalSpringSolver(this.body, this.physicsBody, options);
29651 this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
29652 } else {
29653 // barnesHut
29654 options = this.options.barnesHut;
29655 this.nodesSolver = new BarnesHutSolver(this.body, this.physicsBody, options);
29656 this.edgesSolver = new SpringSolver(this.body, this.physicsBody, options);
29657 this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
29658 }
29659
29660 this.modelOptions = options;
29661 }
29662 /**
29663 * initialize the engine
29664 */
29665
29666 }, {
29667 key: "initPhysics",
29668 value: function initPhysics() {
29669 if (this.physicsEnabled === true && this.options.enabled === true) {
29670 if (this.options.stabilization.enabled === true) {
29671 this.stabilize();
29672 } else {
29673 this.stabilized = false;
29674 this.ready = true;
29675 this.body.emitter.emit("fit", {}, this.layoutFailed); // if the layout failed, we use the approximation for the zoom
29676
29677 this.startSimulation();
29678 }
29679 } else {
29680 this.ready = true;
29681 this.body.emitter.emit("fit");
29682 }
29683 }
29684 /**
29685 * Start the simulation
29686 */
29687
29688 }, {
29689 key: "startSimulation",
29690 value: function startSimulation() {
29691 if (this.physicsEnabled === true && this.options.enabled === true) {
29692 this.stabilized = false; // when visible, adaptivity is disabled.
29693
29694 this.adaptiveTimestep = false; // this sets the width of all nodes initially which could be required for the avoidOverlap
29695
29696 this.body.emitter.emit("_resizeNodes");
29697
29698 if (this.viewFunction === undefined) {
29699 var _context;
29700
29701 this.viewFunction = bind$6(_context = this.simulationStep).call(_context, this);
29702 this.body.emitter.on("initRedraw", this.viewFunction);
29703 this.body.emitter.emit("_startRendering");
29704 }
29705 } else {
29706 this.body.emitter.emit("_redraw");
29707 }
29708 }
29709 /**
29710 * Stop the simulation, force stabilization.
29711 *
29712 * @param {boolean} [emit=true]
29713 */
29714
29715 }, {
29716 key: "stopSimulation",
29717 value: function stopSimulation() {
29718 var emit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
29719 this.stabilized = true;
29720
29721 if (emit === true) {
29722 this._emitStabilized();
29723 }
29724
29725 if (this.viewFunction !== undefined) {
29726 this.body.emitter.off("initRedraw", this.viewFunction);
29727 this.viewFunction = undefined;
29728
29729 if (emit === true) {
29730 this.body.emitter.emit("_stopRendering");
29731 }
29732 }
29733 }
29734 /**
29735 * The viewFunction inserts this step into each render loop. It calls the physics tick and handles the cleanup at stabilized.
29736 *
29737 */
29738
29739 }, {
29740 key: "simulationStep",
29741 value: function simulationStep() {
29742 // check if the physics have settled
29743 var startTime = now$1();
29744
29745 this.physicsTick();
29746 var physicsTime = now$1() - startTime; // run double speed if it is a little graph
29747
29748 if ((physicsTime < 0.4 * this.simulationInterval || this.runDoubleSpeed === true) && this.stabilized === false) {
29749 this.physicsTick(); // this makes sure there is no jitter. The decision is taken once to run it at double speed.
29750
29751 this.runDoubleSpeed = true;
29752 }
29753
29754 if (this.stabilized === true) {
29755 this.stopSimulation();
29756 }
29757 }
29758 /**
29759 * trigger the stabilized event.
29760 *
29761 * @param {number} [amountOfIterations=this.stabilizationIterations]
29762 * @private
29763 */
29764
29765 }, {
29766 key: "_emitStabilized",
29767 value: function _emitStabilized() {
29768 var _this2 = this;
29769
29770 var amountOfIterations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.stabilizationIterations;
29771
29772 if (this.stabilizationIterations > 1 || this.startedStabilization === true) {
29773 setTimeout$1(function () {
29774 _this2.body.emitter.emit("stabilized", {
29775 iterations: amountOfIterations
29776 });
29777
29778 _this2.startedStabilization = false;
29779 _this2.stabilizationIterations = 0;
29780 }, 0);
29781 }
29782 }
29783 /**
29784 * Calculate the forces for one physics iteration and move the nodes.
29785 *
29786 * @private
29787 */
29788
29789 }, {
29790 key: "physicsStep",
29791 value: function physicsStep() {
29792 this.gravitySolver.solve();
29793 this.nodesSolver.solve();
29794 this.edgesSolver.solve();
29795 this.moveNodes();
29796 }
29797 /**
29798 * Make dynamic adjustments to the timestep, based on current state.
29799 *
29800 * Helper function for physicsTick().
29801 *
29802 * @private
29803 */
29804
29805 }, {
29806 key: "adjustTimeStep",
29807 value: function adjustTimeStep() {
29808 var factor = 1.2; // Factor for increasing the timestep on success.
29809 // we compare the two steps. if it is acceptable we double the step.
29810
29811 if (this._evaluateStepQuality() === true) {
29812 this.timestep = factor * this.timestep;
29813 } else {
29814 // if not, we decrease the step to a minimum of the options timestep.
29815 // if the decreased timestep is smaller than the options step, we do not reset the counter
29816 // we assume that the options timestep is stable enough.
29817 if (this.timestep / factor < this.options.timestep) {
29818 this.timestep = this.options.timestep;
29819 } else {
29820 // if the timestep was larger than 2 times the option one we check the adaptivity again to ensure
29821 // that large instabilities do not form.
29822 this.adaptiveCounter = -1; // check again next iteration
29823
29824 this.timestep = Math.max(this.options.timestep, this.timestep / factor);
29825 }
29826 }
29827 }
29828 /**
29829 * A single simulation step (or 'tick') in the physics simulation
29830 *
29831 * @private
29832 */
29833
29834 }, {
29835 key: "physicsTick",
29836 value: function physicsTick() {
29837 this._startStabilizing(); // this ensures that there is no start event when the network is already stable.
29838
29839
29840 if (this.stabilized === true) return; // adaptivity means the timestep adapts to the situation, only applicable for stabilization
29841
29842 if (this.adaptiveTimestep === true && this.adaptiveTimestepEnabled === true) {
29843 // timestep remains stable for "interval" iterations.
29844 var doAdaptive = this.adaptiveCounter % this.adaptiveInterval === 0;
29845
29846 if (doAdaptive) {
29847 // first the big step and revert.
29848 this.timestep = 2 * this.timestep;
29849 this.physicsStep();
29850 this.revert(); // saves the reference state
29851 // now the normal step. Since this is the last step, it is the more stable one and we will take this.
29852
29853 this.timestep = 0.5 * this.timestep; // since it's half the step, we do it twice.
29854
29855 this.physicsStep();
29856 this.physicsStep();
29857 this.adjustTimeStep();
29858 } else {
29859 this.physicsStep(); // normal step, keeping timestep constant
29860 }
29861
29862 this.adaptiveCounter += 1;
29863 } else {
29864 // case for the static timestep, we reset it to the one in options and take a normal step.
29865 this.timestep = this.options.timestep;
29866 this.physicsStep();
29867 }
29868
29869 if (this.stabilized === true) this.revert();
29870 this.stabilizationIterations++;
29871 }
29872 /**
29873 * Nodes and edges can have the physics toggles on or off. A collection of indices is created here so we can skip the check all the time.
29874 *
29875 * @private
29876 */
29877
29878 }, {
29879 key: "updatePhysicsData",
29880 value: function updatePhysicsData() {
29881 this.physicsBody.forces = {};
29882 this.physicsBody.physicsNodeIndices = [];
29883 this.physicsBody.physicsEdgeIndices = [];
29884 var nodes = this.body.nodes;
29885 var edges = this.body.edges; // get node indices for physics
29886
29887 for (var nodeId in nodes) {
29888 if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) {
29889 if (nodes[nodeId].options.physics === true) {
29890 this.physicsBody.physicsNodeIndices.push(nodes[nodeId].id);
29891 }
29892 }
29893 } // get edge indices for physics
29894
29895
29896 for (var edgeId in edges) {
29897 if (Object.prototype.hasOwnProperty.call(edges, edgeId)) {
29898 if (edges[edgeId].options.physics === true) {
29899 this.physicsBody.physicsEdgeIndices.push(edges[edgeId].id);
29900 }
29901 }
29902 } // get the velocity and the forces vector
29903
29904
29905 for (var i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) {
29906 var _nodeId = this.physicsBody.physicsNodeIndices[i];
29907 this.physicsBody.forces[_nodeId] = {
29908 x: 0,
29909 y: 0
29910 }; // forces can be reset because they are recalculated. Velocities have to persist.
29911
29912 if (this.physicsBody.velocities[_nodeId] === undefined) {
29913 this.physicsBody.velocities[_nodeId] = {
29914 x: 0,
29915 y: 0
29916 };
29917 }
29918 } // clean deleted nodes from the velocity vector
29919
29920
29921 for (var _nodeId2 in this.physicsBody.velocities) {
29922 if (nodes[_nodeId2] === undefined) {
29923 delete this.physicsBody.velocities[_nodeId2];
29924 }
29925 }
29926 }
29927 /**
29928 * Revert the simulation one step. This is done so after stabilization, every new start of the simulation will also say stabilized.
29929 */
29930
29931 }, {
29932 key: "revert",
29933 value: function revert() {
29934 var nodeIds = keys$4(this.previousStates);
29935
29936 var nodes = this.body.nodes;
29937 var velocities = this.physicsBody.velocities;
29938 this.referenceState = {};
29939
29940 for (var i = 0; i < nodeIds.length; i++) {
29941 var nodeId = nodeIds[i];
29942
29943 if (nodes[nodeId] !== undefined) {
29944 if (nodes[nodeId].options.physics === true) {
29945 this.referenceState[nodeId] = {
29946 positions: {
29947 x: nodes[nodeId].x,
29948 y: nodes[nodeId].y
29949 }
29950 };
29951 velocities[nodeId].x = this.previousStates[nodeId].vx;
29952 velocities[nodeId].y = this.previousStates[nodeId].vy;
29953 nodes[nodeId].x = this.previousStates[nodeId].x;
29954 nodes[nodeId].y = this.previousStates[nodeId].y;
29955 }
29956 } else {
29957 delete this.previousStates[nodeId];
29958 }
29959 }
29960 }
29961 /**
29962 * This compares the reference state to the current state
29963 *
29964 * @returns {boolean}
29965 * @private
29966 */
29967
29968 }, {
29969 key: "_evaluateStepQuality",
29970 value: function _evaluateStepQuality() {
29971 var dx, dy, dpos;
29972 var nodes = this.body.nodes;
29973 var reference = this.referenceState;
29974 var posThreshold = 0.3;
29975
29976 for (var nodeId in this.referenceState) {
29977 if (Object.prototype.hasOwnProperty.call(this.referenceState, nodeId) && nodes[nodeId] !== undefined) {
29978 dx = nodes[nodeId].x - reference[nodeId].positions.x;
29979 dy = nodes[nodeId].y - reference[nodeId].positions.y;
29980 dpos = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
29981
29982 if (dpos > posThreshold) {
29983 return false;
29984 }
29985 }
29986 }
29987
29988 return true;
29989 }
29990 /**
29991 * move the nodes one timestep and check if they are stabilized
29992 */
29993
29994 }, {
29995 key: "moveNodes",
29996 value: function moveNodes() {
29997 var nodeIndices = this.physicsBody.physicsNodeIndices;
29998 var maxNodeVelocity = 0;
29999 var averageNodeVelocity = 0; // the velocity threshold (energy in the system) for the adaptivity toggle
30000
30001 var velocityAdaptiveThreshold = 5;
30002
30003 for (var i = 0; i < nodeIndices.length; i++) {
30004 var nodeId = nodeIndices[i];
30005
30006 var nodeVelocity = this._performStep(nodeId); // stabilized is true if stabilized is true and velocity is smaller than vmin --> all nodes must be stabilized
30007
30008
30009 maxNodeVelocity = Math.max(maxNodeVelocity, nodeVelocity);
30010 averageNodeVelocity += nodeVelocity;
30011 } // evaluating the stabilized and adaptiveTimestepEnabled conditions
30012
30013
30014 this.adaptiveTimestepEnabled = averageNodeVelocity / nodeIndices.length < velocityAdaptiveThreshold;
30015 this.stabilized = maxNodeVelocity < this.options.minVelocity;
30016 }
30017 /**
30018 * Calculate new velocity for a coordinate direction
30019 *
30020 * @param {number} v velocity for current coordinate
30021 * @param {number} f regular force for current coordinate
30022 * @param {number} m mass of current node
30023 * @returns {number} new velocity for current coordinate
30024 * @private
30025 */
30026
30027 }, {
30028 key: "calculateComponentVelocity",
30029 value: function calculateComponentVelocity(v, f, m) {
30030 var df = this.modelOptions.damping * v; // damping force
30031
30032 var a = (f - df) / m; // acceleration
30033
30034 v += a * this.timestep; // Put a limit on the velocities if it is really high
30035
30036 var maxV = this.options.maxVelocity || 1e9;
30037
30038 if (Math.abs(v) > maxV) {
30039 v = v > 0 ? maxV : -maxV;
30040 }
30041
30042 return v;
30043 }
30044 /**
30045 * Perform the actual step
30046 *
30047 * @param {Node.id} nodeId
30048 * @returns {number} the new velocity of given node
30049 * @private
30050 */
30051
30052 }, {
30053 key: "_performStep",
30054 value: function _performStep(nodeId) {
30055 var node = this.body.nodes[nodeId];
30056 var force = this.physicsBody.forces[nodeId];
30057
30058 if (this.options.wind) {
30059 force.x += this.options.wind.x;
30060 force.y += this.options.wind.y;
30061 }
30062
30063 var velocity = this.physicsBody.velocities[nodeId]; // store the state so we can revert
30064
30065 this.previousStates[nodeId] = {
30066 x: node.x,
30067 y: node.y,
30068 vx: velocity.x,
30069 vy: velocity.y
30070 };
30071
30072 if (node.options.fixed.x === false) {
30073 velocity.x = this.calculateComponentVelocity(velocity.x, force.x, node.options.mass);
30074 node.x += velocity.x * this.timestep;
30075 } else {
30076 force.x = 0;
30077 velocity.x = 0;
30078 }
30079
30080 if (node.options.fixed.y === false) {
30081 velocity.y = this.calculateComponentVelocity(velocity.y, force.y, node.options.mass);
30082 node.y += velocity.y * this.timestep;
30083 } else {
30084 force.y = 0;
30085 velocity.y = 0;
30086 }
30087
30088 var totalVelocity = Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(velocity.y, 2));
30089 return totalVelocity;
30090 }
30091 /**
30092 * When initializing and stabilizing, we can freeze nodes with a predefined position.
30093 * This greatly speeds up stabilization because only the supportnodes for the smoothCurves have to settle.
30094 *
30095 * @private
30096 */
30097
30098 }, {
30099 key: "_freezeNodes",
30100 value: function _freezeNodes() {
30101 var nodes = this.body.nodes;
30102
30103 for (var id in nodes) {
30104 if (Object.prototype.hasOwnProperty.call(nodes, id)) {
30105 if (nodes[id].x && nodes[id].y) {
30106 var fixed = nodes[id].options.fixed;
30107 this.freezeCache[id] = {
30108 x: fixed.x,
30109 y: fixed.y
30110 };
30111 fixed.x = true;
30112 fixed.y = true;
30113 }
30114 }
30115 }
30116 }
30117 /**
30118 * Unfreezes the nodes that have been frozen by _freezeDefinedNodes.
30119 *
30120 * @private
30121 */
30122
30123 }, {
30124 key: "_restoreFrozenNodes",
30125 value: function _restoreFrozenNodes() {
30126 var nodes = this.body.nodes;
30127
30128 for (var id in nodes) {
30129 if (Object.prototype.hasOwnProperty.call(nodes, id)) {
30130 if (this.freezeCache[id] !== undefined) {
30131 nodes[id].options.fixed.x = this.freezeCache[id].x;
30132 nodes[id].options.fixed.y = this.freezeCache[id].y;
30133 }
30134 }
30135 }
30136
30137 this.freezeCache = {};
30138 }
30139 /**
30140 * Find a stable position for all nodes
30141 *
30142 * @param {number} [iterations=this.options.stabilization.iterations]
30143 */
30144
30145 }, {
30146 key: "stabilize",
30147 value: function stabilize() {
30148 var _this3 = this;
30149
30150 var iterations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.stabilization.iterations;
30151
30152 if (typeof iterations !== "number") {
30153 iterations = this.options.stabilization.iterations;
30154 console.error("The stabilize method needs a numeric amount of iterations. Switching to default: ", iterations);
30155 }
30156
30157 if (this.physicsBody.physicsNodeIndices.length === 0) {
30158 this.ready = true;
30159 return;
30160 } // enable adaptive timesteps
30161
30162
30163 this.adaptiveTimestep = this.options.adaptiveTimestep; // this sets the width of all nodes initially which could be required for the avoidOverlap
30164
30165 this.body.emitter.emit("_resizeNodes");
30166 this.stopSimulation(); // stop the render loop
30167
30168 this.stabilized = false; // block redraw requests
30169
30170 this.body.emitter.emit("_blockRedraw");
30171 this.targetIterations = iterations; // start the stabilization
30172
30173 if (this.options.stabilization.onlyDynamicEdges === true) {
30174 this._freezeNodes();
30175 }
30176
30177 this.stabilizationIterations = 0;
30178
30179 setTimeout$1(function () {
30180 return _this3._stabilizationBatch();
30181 }, 0);
30182 }
30183 /**
30184 * If not already stabilizing, start it and emit a start event.
30185 *
30186 * @returns {boolean} true if stabilization started with this call
30187 * @private
30188 */
30189
30190 }, {
30191 key: "_startStabilizing",
30192 value: function _startStabilizing() {
30193 if (this.startedStabilization === true) return false;
30194 this.body.emitter.emit("startStabilizing");
30195 this.startedStabilization = true;
30196 return true;
30197 }
30198 /**
30199 * One batch of stabilization
30200 *
30201 * @private
30202 */
30203
30204 }, {
30205 key: "_stabilizationBatch",
30206 value: function _stabilizationBatch() {
30207 var _this4 = this;
30208
30209 var running = function running() {
30210 return _this4.stabilized === false && _this4.stabilizationIterations < _this4.targetIterations;
30211 };
30212
30213 var sendProgress = function sendProgress() {
30214 _this4.body.emitter.emit("stabilizationProgress", {
30215 iterations: _this4.stabilizationIterations,
30216 total: _this4.targetIterations
30217 });
30218 };
30219
30220 if (this._startStabilizing()) {
30221 sendProgress(); // Ensure that there is at least one start event.
30222 }
30223
30224 var count = 0;
30225
30226 while (running() && count < this.options.stabilization.updateInterval) {
30227 this.physicsTick();
30228 count++;
30229 }
30230
30231 sendProgress();
30232
30233 if (running()) {
30234 var _context2;
30235
30236 setTimeout$1(bind$6(_context2 = this._stabilizationBatch).call(_context2, this), 0);
30237 } else {
30238 this._finalizeStabilization();
30239 }
30240 }
30241 /**
30242 * Wrap up the stabilization, fit and emit the events.
30243 *
30244 * @private
30245 */
30246
30247 }, {
30248 key: "_finalizeStabilization",
30249 value: function _finalizeStabilization() {
30250 this.body.emitter.emit("_allowRedraw");
30251
30252 if (this.options.stabilization.fit === true) {
30253 this.body.emitter.emit("fit");
30254 }
30255
30256 if (this.options.stabilization.onlyDynamicEdges === true) {
30257 this._restoreFrozenNodes();
30258 }
30259
30260 this.body.emitter.emit("stabilizationIterationsDone");
30261 this.body.emitter.emit("_requestRedraw");
30262
30263 if (this.stabilized === true) {
30264 this._emitStabilized();
30265 } else {
30266 this.startSimulation();
30267 }
30268
30269 this.ready = true;
30270 } //--------------------------- DEBUGGING BELOW ---------------------------//
30271
30272 /**
30273 * Debug function that display arrows for the forces currently active in the network.
30274 *
30275 * Use this when debugging only.
30276 *
30277 * @param {CanvasRenderingContext2D} ctx
30278 * @private
30279 */
30280
30281 }, {
30282 key: "_drawForces",
30283 value: function _drawForces(ctx) {
30284 for (var i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) {
30285 var index = this.physicsBody.physicsNodeIndices[i];
30286 var node = this.body.nodes[index];
30287 var force = this.physicsBody.forces[index];
30288 var factor = 20;
30289 var colorFactor = 0.03;
30290 var forceSize = Math.sqrt(Math.pow(force.x, 2) + Math.pow(force.x, 2));
30291 var size = Math.min(Math.max(5, forceSize), 15);
30292 var arrowSize = 3 * size;
30293 var color = HSVToHex((180 - Math.min(1, Math.max(0, colorFactor * forceSize)) * 180) / 360, 1, 1);
30294 var point = {
30295 x: node.x + factor * force.x,
30296 y: node.y + factor * force.y
30297 };
30298 ctx.lineWidth = size;
30299 ctx.strokeStyle = color;
30300 ctx.beginPath();
30301 ctx.moveTo(node.x, node.y);
30302 ctx.lineTo(point.x, point.y);
30303 ctx.stroke();
30304 var angle = Math.atan2(force.y, force.x);
30305 ctx.fillStyle = color;
30306 EndPoints.draw(ctx, {
30307 type: "arrow",
30308 point: point,
30309 angle: angle,
30310 length: arrowSize
30311 });
30312
30313 fill(ctx).call(ctx);
30314 }
30315 }
30316 }]);
30317
30318 return PhysicsEngine;
30319}();
30320
30321/**
30322 * Utility Class
30323 */
30324
30325var NetworkUtil = /*#__PURE__*/function () {
30326 /**
30327 * @ignore
30328 */
30329 function NetworkUtil() {
30330 _classCallCheck(this, NetworkUtil);
30331 }
30332 /**
30333 * Find the center position of the network considering the bounding boxes
30334 *
30335 * @param {Array.<Node>} allNodes
30336 * @param {Array.<Node>} [specificNodes=[]]
30337 * @returns {{minX: number, maxX: number, minY: number, maxY: number}}
30338 * @static
30339 */
30340
30341
30342 _createClass(NetworkUtil, null, [{
30343 key: "getRange",
30344 value: function getRange(allNodes) {
30345 var specificNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
30346 var minY = 1e9,
30347 maxY = -1e9,
30348 minX = 1e9,
30349 maxX = -1e9,
30350 node;
30351
30352 if (specificNodes.length > 0) {
30353 for (var i = 0; i < specificNodes.length; i++) {
30354 node = allNodes[specificNodes[i]];
30355
30356 if (minX > node.shape.boundingBox.left) {
30357 minX = node.shape.boundingBox.left;
30358 }
30359
30360 if (maxX < node.shape.boundingBox.right) {
30361 maxX = node.shape.boundingBox.right;
30362 }
30363
30364 if (minY > node.shape.boundingBox.top) {
30365 minY = node.shape.boundingBox.top;
30366 } // top is negative, bottom is positive
30367
30368
30369 if (maxY < node.shape.boundingBox.bottom) {
30370 maxY = node.shape.boundingBox.bottom;
30371 } // top is negative, bottom is positive
30372
30373 }
30374 }
30375
30376 if (minX === 1e9 && maxX === -1e9 && minY === 1e9 && maxY === -1e9) {
30377 minY = 0, maxY = 0, minX = 0, maxX = 0;
30378 }
30379
30380 return {
30381 minX: minX,
30382 maxX: maxX,
30383 minY: minY,
30384 maxY: maxY
30385 };
30386 }
30387 /**
30388 * Find the center position of the network
30389 *
30390 * @param {Array.<Node>} allNodes
30391 * @param {Array.<Node>} [specificNodes=[]]
30392 * @returns {{minX: number, maxX: number, minY: number, maxY: number}}
30393 * @static
30394 */
30395
30396 }, {
30397 key: "getRangeCore",
30398 value: function getRangeCore(allNodes) {
30399 var specificNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
30400 var minY = 1e9,
30401 maxY = -1e9,
30402 minX = 1e9,
30403 maxX = -1e9,
30404 node;
30405
30406 if (specificNodes.length > 0) {
30407 for (var i = 0; i < specificNodes.length; i++) {
30408 node = allNodes[specificNodes[i]];
30409
30410 if (minX > node.x) {
30411 minX = node.x;
30412 }
30413
30414 if (maxX < node.x) {
30415 maxX = node.x;
30416 }
30417
30418 if (minY > node.y) {
30419 minY = node.y;
30420 } // top is negative, bottom is positive
30421
30422
30423 if (maxY < node.y) {
30424 maxY = node.y;
30425 } // top is negative, bottom is positive
30426
30427 }
30428 }
30429
30430 if (minX === 1e9 && maxX === -1e9 && minY === 1e9 && maxY === -1e9) {
30431 minY = 0, maxY = 0, minX = 0, maxX = 0;
30432 }
30433
30434 return {
30435 minX: minX,
30436 maxX: maxX,
30437 minY: minY,
30438 maxY: maxY
30439 };
30440 }
30441 /**
30442 * @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
30443 * @returns {{x: number, y: number}}
30444 * @static
30445 */
30446
30447 }, {
30448 key: "findCenter",
30449 value: function findCenter(range) {
30450 return {
30451 x: 0.5 * (range.maxX + range.minX),
30452 y: 0.5 * (range.maxY + range.minY)
30453 };
30454 }
30455 /**
30456 * This returns a clone of the options or options of the edge or node to be used for construction of new edges or check functions for new nodes.
30457 *
30458 * @param {vis.Item} item
30459 * @param {'node'|undefined} type
30460 * @returns {{}}
30461 * @static
30462 */
30463
30464 }, {
30465 key: "cloneOptions",
30466 value: function cloneOptions(item, type) {
30467 var clonedOptions = {};
30468
30469 if (type === undefined || type === "node") {
30470 deepExtend(clonedOptions, item.options, true);
30471 clonedOptions.x = item.x;
30472 clonedOptions.y = item.y;
30473 clonedOptions.amountOfConnections = item.edges.length;
30474 } else {
30475 deepExtend(clonedOptions, item.options, true);
30476 }
30477
30478 return clonedOptions;
30479 }
30480 }]);
30481
30482 return NetworkUtil;
30483}();
30484
30485function _createSuper$1(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
30486
30487function _isNativeReflectConstruct$1() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
30488/**
30489 * A Cluster is a special Node that allows a group of Nodes positioned closely together
30490 * to be represented by a single Cluster Node.
30491 *
30492 * @augments Node
30493 */
30494
30495var Cluster = /*#__PURE__*/function (_Node) {
30496 _inherits(Cluster, _Node);
30497
30498 var _super = _createSuper$1(Cluster);
30499
30500 /**
30501 * @param {object} options
30502 * @param {object} body
30503 * @param {Array.<HTMLImageElement>}imagelist
30504 * @param {Array} grouplist
30505 * @param {object} globalOptions
30506 * @param {object} defaultOptions Global default options for nodes
30507 */
30508 function Cluster(options, body, imagelist, grouplist, globalOptions, defaultOptions) {
30509 var _this;
30510
30511 _classCallCheck(this, Cluster);
30512
30513 _this = _super.call(this, options, body, imagelist, grouplist, globalOptions, defaultOptions);
30514 _this.isCluster = true;
30515 _this.containedNodes = {};
30516 _this.containedEdges = {};
30517 return _this;
30518 }
30519 /**
30520 * Transfer child cluster data to current and disconnect the child cluster.
30521 *
30522 * Please consult the header comment in 'Clustering.js' for the fields set here.
30523 *
30524 * @param {string|number} childClusterId id of child cluster to open
30525 */
30526
30527
30528 _createClass(Cluster, [{
30529 key: "_openChildCluster",
30530 value: function _openChildCluster(childClusterId) {
30531 var _this2 = this;
30532
30533 var childCluster = this.body.nodes[childClusterId];
30534
30535 if (this.containedNodes[childClusterId] === undefined) {
30536 throw new Error("node with id: " + childClusterId + " not in current cluster");
30537 }
30538
30539 if (!childCluster.isCluster) {
30540 throw new Error("node with id: " + childClusterId + " is not a cluster");
30541 } // Disconnect child cluster from current cluster
30542
30543
30544 delete this.containedNodes[childClusterId];
30545 forEach$1(childCluster.edges, function (edge) {
30546 delete _this2.containedEdges[edge.id];
30547 }); // Transfer nodes and edges
30548
30549 forEach$1(childCluster.containedNodes, function (node, nodeId) {
30550 _this2.containedNodes[nodeId] = node;
30551 });
30552 childCluster.containedNodes = {};
30553 forEach$1(childCluster.containedEdges, function (edge, edgeId) {
30554 _this2.containedEdges[edgeId] = edge;
30555 });
30556 childCluster.containedEdges = {}; // Transfer edges within cluster edges which are clustered
30557
30558 forEach$1(childCluster.edges, function (clusterEdge) {
30559 forEach$1(_this2.edges, function (parentClusterEdge) {
30560 var _context, _context2;
30561
30562 // Assumption: a clustered edge can only be present in a single clustering edge
30563 // Not tested here
30564 var index = indexOf(_context = parentClusterEdge.clusteringEdgeReplacingIds).call(_context, clusterEdge.id);
30565
30566 if (index === -1) return;
30567 forEach$1(clusterEdge.clusteringEdgeReplacingIds, function (srcId) {
30568 parentClusterEdge.clusteringEdgeReplacingIds.push(srcId); // Maintain correct bookkeeping for transferred edge
30569
30570 _this2.body.edges[srcId].edgeReplacedById = parentClusterEdge.id;
30571 }); // Remove cluster edge from parent cluster edge
30572
30573 splice(_context2 = parentClusterEdge.clusteringEdgeReplacingIds).call(_context2, index, 1);
30574 });
30575 });
30576 childCluster.edges = [];
30577 }
30578 }]);
30579
30580 return Cluster;
30581}(Node);
30582
30583/**
30584 * The clustering engine
30585 */
30586
30587var ClusterEngine = /*#__PURE__*/function () {
30588 /**
30589 * @param {object} body
30590 */
30591 function ClusterEngine(body) {
30592 var _this = this;
30593
30594 _classCallCheck(this, ClusterEngine);
30595
30596 this.body = body;
30597 this.clusteredNodes = {}; // key: node id, value: { clusterId: <id of cluster>, node: <node instance>}
30598
30599 this.clusteredEdges = {}; // key: edge id, value: restore information for given edge
30600
30601 this.options = {};
30602 this.defaultOptions = {};
30603
30604 assign$2(this.options, this.defaultOptions);
30605
30606 this.body.emitter.on("_resetData", function () {
30607 _this.clusteredNodes = {};
30608 _this.clusteredEdges = {};
30609 });
30610 }
30611 /**
30612 *
30613 * @param {number} hubsize
30614 * @param {object} options
30615 */
30616
30617
30618 _createClass(ClusterEngine, [{
30619 key: "clusterByHubsize",
30620 value: function clusterByHubsize(hubsize, options) {
30621 if (hubsize === undefined) {
30622 hubsize = this._getHubSize();
30623 } else if (_typeof(hubsize) === "object") {
30624 options = this._checkOptions(hubsize);
30625 hubsize = this._getHubSize();
30626 }
30627
30628 var nodesToCluster = [];
30629
30630 for (var i = 0; i < this.body.nodeIndices.length; i++) {
30631 var node = this.body.nodes[this.body.nodeIndices[i]];
30632
30633 if (node.edges.length >= hubsize) {
30634 nodesToCluster.push(node.id);
30635 }
30636 }
30637
30638 for (var _i = 0; _i < nodesToCluster.length; _i++) {
30639 this.clusterByConnection(nodesToCluster[_i], options, true);
30640 }
30641
30642 this.body.emitter.emit("_dataChanged");
30643 }
30644 /**
30645 * loop over all nodes, check if they adhere to the condition and cluster if needed.
30646 *
30647 * @param {object} options
30648 * @param {boolean} [refreshData=true]
30649 */
30650
30651 }, {
30652 key: "cluster",
30653 value: function cluster() {
30654 var _this2 = this;
30655
30656 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
30657 var refreshData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
30658
30659 if (options.joinCondition === undefined) {
30660 throw new Error("Cannot call clusterByNodeData without a joinCondition function in the options.");
30661 } // check if the options object is fine, append if needed
30662
30663
30664 options = this._checkOptions(options);
30665 var childNodesObj = {};
30666 var childEdgesObj = {}; // collect the nodes that will be in the cluster
30667
30668 forEach$1(this.body.nodes, function (node, nodeId) {
30669 if (node.options && options.joinCondition(node.options) === true) {
30670 childNodesObj[nodeId] = node; // collect the edges that will be in the cluster
30671
30672 forEach$1(node.edges, function (edge) {
30673 if (_this2.clusteredEdges[edge.id] === undefined) {
30674 childEdgesObj[edge.id] = edge;
30675 }
30676 });
30677 }
30678 });
30679
30680 this._cluster(childNodesObj, childEdgesObj, options, refreshData);
30681 }
30682 /**
30683 * Cluster all nodes in the network that have only X edges
30684 *
30685 * @param {number} edgeCount
30686 * @param {object} options
30687 * @param {boolean} [refreshData=true]
30688 */
30689
30690 }, {
30691 key: "clusterByEdgeCount",
30692 value: function clusterByEdgeCount(edgeCount, options) {
30693 var _this3 = this;
30694
30695 var refreshData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
30696 options = this._checkOptions(options);
30697 var clusters = [];
30698 var usedNodes = {};
30699 var edge, edges, relevantEdgeCount; // collect the nodes that will be in the cluster
30700
30701 var _loop = function _loop(i) {
30702 var childNodesObj = {};
30703 var childEdgesObj = {};
30704 var nodeId = _this3.body.nodeIndices[i];
30705 var node = _this3.body.nodes[nodeId]; // if this node is already used in another cluster this session, we do not have to re-evaluate it.
30706
30707 if (usedNodes[nodeId] === undefined) {
30708 relevantEdgeCount = 0;
30709 edges = [];
30710
30711 for (var j = 0; j < node.edges.length; j++) {
30712 edge = node.edges[j];
30713
30714 if (_this3.clusteredEdges[edge.id] === undefined) {
30715 if (edge.toId !== edge.fromId) {
30716 relevantEdgeCount++;
30717 }
30718
30719 edges.push(edge);
30720 }
30721 } // this node qualifies, we collect its neighbours to start the clustering process.
30722
30723
30724 if (relevantEdgeCount === edgeCount) {
30725 var checkJoinCondition = function checkJoinCondition(node) {
30726 if (options.joinCondition === undefined || options.joinCondition === null) {
30727 return true;
30728 }
30729
30730 var clonedOptions = NetworkUtil.cloneOptions(node);
30731 return options.joinCondition(clonedOptions);
30732 };
30733
30734 var gatheringSuccessful = true;
30735
30736 for (var _j = 0; _j < edges.length; _j++) {
30737 edge = edges[_j];
30738
30739 var childNodeId = _this3._getConnectedId(edge, nodeId); // add the nodes to the list by the join condition.
30740
30741
30742 if (checkJoinCondition(node)) {
30743 childEdgesObj[edge.id] = edge;
30744 childNodesObj[nodeId] = node;
30745 childNodesObj[childNodeId] = _this3.body.nodes[childNodeId];
30746 usedNodes[nodeId] = true;
30747 } else {
30748 // this node does not qualify after all.
30749 gatheringSuccessful = false;
30750 break;
30751 }
30752 } // add to the cluster queue
30753
30754
30755 if (keys$4(childNodesObj).length > 0 && keys$4(childEdgesObj).length > 0 && gatheringSuccessful === true) {
30756 /**
30757 * Search for cluster data that contains any of the node id's
30758 *
30759 * @returns {boolean} true if no joinCondition, otherwise return value of joinCondition
30760 */
30761 var findClusterData = function findClusterData() {
30762 for (var n = 0; n < clusters.length; ++n) {
30763 // Search for a cluster containing any of the node id's
30764 for (var m in childNodesObj) {
30765 if (clusters[n].nodes[m] !== undefined) {
30766 return clusters[n];
30767 }
30768 }
30769 }
30770
30771 return undefined;
30772 }; // If any of the found nodes is part of a cluster found in this method,
30773 // add the current values to that cluster
30774
30775
30776 var foundCluster = findClusterData();
30777
30778 if (foundCluster !== undefined) {
30779 // Add nodes to found cluster if not present
30780 for (var m in childNodesObj) {
30781 if (foundCluster.nodes[m] === undefined) {
30782 foundCluster.nodes[m] = childNodesObj[m];
30783 }
30784 } // Add edges to found cluster, if not present
30785
30786
30787 for (var _m in childEdgesObj) {
30788 if (foundCluster.edges[_m] === undefined) {
30789 foundCluster.edges[_m] = childEdgesObj[_m];
30790 }
30791 }
30792 } else {
30793 // Create a new cluster group
30794 clusters.push({
30795 nodes: childNodesObj,
30796 edges: childEdgesObj
30797 });
30798 }
30799 }
30800 }
30801 }
30802 };
30803
30804 for (var i = 0; i < this.body.nodeIndices.length; i++) {
30805 _loop(i);
30806 }
30807
30808 for (var _i2 = 0; _i2 < clusters.length; _i2++) {
30809 this._cluster(clusters[_i2].nodes, clusters[_i2].edges, options, false);
30810 }
30811
30812 if (refreshData === true) {
30813 this.body.emitter.emit("_dataChanged");
30814 }
30815 }
30816 /**
30817 * Cluster all nodes in the network that have only 1 edge
30818 *
30819 * @param {object} options
30820 * @param {boolean} [refreshData=true]
30821 */
30822
30823 }, {
30824 key: "clusterOutliers",
30825 value: function clusterOutliers(options) {
30826 var refreshData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
30827 this.clusterByEdgeCount(1, options, refreshData);
30828 }
30829 /**
30830 * Cluster all nodes in the network that have only 2 edge
30831 *
30832 * @param {object} options
30833 * @param {boolean} [refreshData=true]
30834 */
30835
30836 }, {
30837 key: "clusterBridges",
30838 value: function clusterBridges(options) {
30839 var refreshData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
30840 this.clusterByEdgeCount(2, options, refreshData);
30841 }
30842 /**
30843 * suck all connected nodes of a node into the node.
30844 *
30845 * @param {Node.id} nodeId
30846 * @param {object} options
30847 * @param {boolean} [refreshData=true]
30848 */
30849
30850 }, {
30851 key: "clusterByConnection",
30852 value: function clusterByConnection(nodeId, options) {
30853 var _context;
30854
30855 var refreshData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
30856
30857 // kill conditions
30858 if (nodeId === undefined) {
30859 throw new Error("No nodeId supplied to clusterByConnection!");
30860 }
30861
30862 if (this.body.nodes[nodeId] === undefined) {
30863 throw new Error("The nodeId given to clusterByConnection does not exist!");
30864 }
30865
30866 var node = this.body.nodes[nodeId];
30867 options = this._checkOptions(options, node);
30868
30869 if (options.clusterNodeProperties.x === undefined) {
30870 options.clusterNodeProperties.x = node.x;
30871 }
30872
30873 if (options.clusterNodeProperties.y === undefined) {
30874 options.clusterNodeProperties.y = node.y;
30875 }
30876
30877 if (options.clusterNodeProperties.fixed === undefined) {
30878 options.clusterNodeProperties.fixed = {};
30879 options.clusterNodeProperties.fixed.x = node.options.fixed.x;
30880 options.clusterNodeProperties.fixed.y = node.options.fixed.y;
30881 }
30882
30883 var childNodesObj = {};
30884 var childEdgesObj = {};
30885 var parentNodeId = node.id;
30886 var parentClonedOptions = NetworkUtil.cloneOptions(node);
30887 childNodesObj[parentNodeId] = node; // collect the nodes that will be in the cluster
30888
30889 for (var i = 0; i < node.edges.length; i++) {
30890 var edge = node.edges[i];
30891
30892 if (this.clusteredEdges[edge.id] === undefined) {
30893 var childNodeId = this._getConnectedId(edge, parentNodeId); // if the child node is not in a cluster
30894
30895
30896 if (this.clusteredNodes[childNodeId] === undefined) {
30897 if (childNodeId !== parentNodeId) {
30898 if (options.joinCondition === undefined) {
30899 childEdgesObj[edge.id] = edge;
30900 childNodesObj[childNodeId] = this.body.nodes[childNodeId];
30901 } else {
30902 // clone the options and insert some additional parameters that could be interesting.
30903 var childClonedOptions = NetworkUtil.cloneOptions(this.body.nodes[childNodeId]);
30904
30905 if (options.joinCondition(parentClonedOptions, childClonedOptions) === true) {
30906 childEdgesObj[edge.id] = edge;
30907 childNodesObj[childNodeId] = this.body.nodes[childNodeId];
30908 }
30909 }
30910 } else {
30911 // swallow the edge if it is self-referencing.
30912 childEdgesObj[edge.id] = edge;
30913 }
30914 }
30915 }
30916 }
30917
30918 var childNodeIDs = map$3(_context = keys$4(childNodesObj)).call(_context, function (childNode) {
30919 return childNodesObj[childNode].id;
30920 });
30921
30922 for (var childNodeKey in childNodesObj) {
30923 if (!Object.prototype.hasOwnProperty.call(childNodesObj, childNodeKey)) continue;
30924 var childNode = childNodesObj[childNodeKey];
30925
30926 for (var y = 0; y < childNode.edges.length; y++) {
30927 var childEdge = childNode.edges[y];
30928
30929 if (indexOf(childNodeIDs).call(childNodeIDs, this._getConnectedId(childEdge, childNode.id)) > -1) {
30930 childEdgesObj[childEdge.id] = childEdge;
30931 }
30932 }
30933 }
30934
30935 this._cluster(childNodesObj, childEdgesObj, options, refreshData);
30936 }
30937 /**
30938 * This function creates the edges that will be attached to the cluster
30939 * It looks for edges that are connected to the nodes from the "outside' of the cluster.
30940 *
30941 * @param {{Node.id: vis.Node}} childNodesObj
30942 * @param {{vis.Edge.id: vis.Edge}} childEdgesObj
30943 * @param {object} clusterNodeProperties
30944 * @param {object} clusterEdgeProperties
30945 * @private
30946 */
30947
30948 }, {
30949 key: "_createClusterEdges",
30950 value: function _createClusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, clusterEdgeProperties) {
30951 var edge, childNodeId, childNode, toId, fromId, otherNodeId; // loop over all child nodes and their edges to find edges going out of the cluster
30952 // these edges will be replaced by clusterEdges.
30953
30954 var childKeys = keys$4(childNodesObj);
30955
30956 var createEdges = [];
30957
30958 for (var i = 0; i < childKeys.length; i++) {
30959 childNodeId = childKeys[i];
30960 childNode = childNodesObj[childNodeId]; // construct new edges from the cluster to others
30961
30962 for (var j = 0; j < childNode.edges.length; j++) {
30963 edge = childNode.edges[j]; // we only handle edges that are visible to the system, not the disabled ones from the clustering process.
30964
30965 if (this.clusteredEdges[edge.id] === undefined) {
30966 // self-referencing edges will be added to the "hidden" list
30967 if (edge.toId == edge.fromId) {
30968 childEdgesObj[edge.id] = edge;
30969 } else {
30970 // set up the from and to.
30971 if (edge.toId == childNodeId) {
30972 // this is a double equals because ints and strings can be interchanged here.
30973 toId = clusterNodeProperties.id;
30974 fromId = edge.fromId;
30975 otherNodeId = fromId;
30976 } else {
30977 toId = edge.toId;
30978 fromId = clusterNodeProperties.id;
30979 otherNodeId = toId;
30980 }
30981 } // Only edges from the cluster outwards are being replaced.
30982
30983
30984 if (childNodesObj[otherNodeId] === undefined) {
30985 createEdges.push({
30986 edge: edge,
30987 fromId: fromId,
30988 toId: toId
30989 });
30990 }
30991 }
30992 }
30993 } //
30994 // Here we actually create the replacement edges.
30995 //
30996 // We could not do this in the loop above as the creation process
30997 // would add an edge to the edges array we are iterating over.
30998 //
30999 // NOTE: a clustered edge can have multiple base edges!
31000 //
31001
31002
31003 var newEdges = [];
31004 /**
31005 * Find a cluster edge which matches the given created edge.
31006 *
31007 * @param {vis.Edge} createdEdge
31008 * @returns {vis.Edge}
31009 */
31010
31011 var getNewEdge = function getNewEdge(createdEdge) {
31012 for (var _j2 = 0; _j2 < newEdges.length; _j2++) {
31013 var newEdge = newEdges[_j2]; // We replace both to and from edges with a single cluster edge
31014
31015 var matchToDirection = createdEdge.fromId === newEdge.fromId && createdEdge.toId === newEdge.toId;
31016 var matchFromDirection = createdEdge.fromId === newEdge.toId && createdEdge.toId === newEdge.fromId;
31017
31018 if (matchToDirection || matchFromDirection) {
31019 return newEdge;
31020 }
31021 }
31022
31023 return null;
31024 };
31025
31026 for (var _j3 = 0; _j3 < createEdges.length; _j3++) {
31027 var createdEdge = createEdges[_j3];
31028 var _edge = createdEdge.edge;
31029 var newEdge = getNewEdge(createdEdge);
31030
31031 if (newEdge === null) {
31032 // Create a clustered edge for this connection
31033 newEdge = this._createClusteredEdge(createdEdge.fromId, createdEdge.toId, _edge, clusterEdgeProperties);
31034 newEdges.push(newEdge);
31035 } else {
31036 newEdge.clusteringEdgeReplacingIds.push(_edge.id);
31037 } // also reference the new edge in the old edge
31038
31039
31040 this.body.edges[_edge.id].edgeReplacedById = newEdge.id; // hide the replaced edge
31041
31042 this._backupEdgeOptions(_edge);
31043
31044 _edge.setOptions({
31045 physics: false
31046 });
31047 }
31048 }
31049 /**
31050 * This function checks the options that can be supplied to the different cluster functions
31051 * for certain fields and inserts defaults if needed
31052 *
31053 * @param {object} options
31054 * @returns {*}
31055 * @private
31056 */
31057
31058 }, {
31059 key: "_checkOptions",
31060 value: function _checkOptions() {
31061 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
31062
31063 if (options.clusterEdgeProperties === undefined) {
31064 options.clusterEdgeProperties = {};
31065 }
31066
31067 if (options.clusterNodeProperties === undefined) {
31068 options.clusterNodeProperties = {};
31069 }
31070
31071 return options;
31072 }
31073 /**
31074 *
31075 * @param {object} childNodesObj | object with node objects, id as keys, same as childNodes except it also contains a source node
31076 * @param {object} childEdgesObj | object with edge objects, id as keys
31077 * @param {Array} options | object with {clusterNodeProperties, clusterEdgeProperties, processProperties}
31078 * @param {boolean} refreshData | when true, do not wrap up
31079 * @private
31080 */
31081
31082 }, {
31083 key: "_cluster",
31084 value: function _cluster(childNodesObj, childEdgesObj, options) {
31085 var refreshData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
31086 // Remove nodes which are already clustered
31087 var tmpNodesToRemove = [];
31088
31089 for (var nodeId in childNodesObj) {
31090 if (Object.prototype.hasOwnProperty.call(childNodesObj, nodeId)) {
31091 if (this.clusteredNodes[nodeId] !== undefined) {
31092 tmpNodesToRemove.push(nodeId);
31093 }
31094 }
31095 }
31096
31097 for (var n = 0; n < tmpNodesToRemove.length; ++n) {
31098 delete childNodesObj[tmpNodesToRemove[n]];
31099 } // kill condition: no nodes don't bother
31100
31101
31102 if (keys$4(childNodesObj).length == 0) {
31103 return;
31104 } // allow clusters of 1 if options allow
31105
31106
31107 if (keys$4(childNodesObj).length == 1 && options.clusterNodeProperties.allowSingleNodeCluster != true) {
31108 return;
31109 }
31110
31111 var clusterNodeProperties = deepExtend({}, options.clusterNodeProperties); // construct the clusterNodeProperties
31112
31113 if (options.processProperties !== undefined) {
31114 // get the childNode options
31115 var childNodesOptions = [];
31116
31117 for (var _nodeId in childNodesObj) {
31118 if (Object.prototype.hasOwnProperty.call(childNodesObj, _nodeId)) {
31119 var clonedOptions = NetworkUtil.cloneOptions(childNodesObj[_nodeId]);
31120 childNodesOptions.push(clonedOptions);
31121 }
31122 } // get cluster properties based on childNodes
31123
31124
31125 var childEdgesOptions = [];
31126
31127 for (var edgeId in childEdgesObj) {
31128 if (Object.prototype.hasOwnProperty.call(childEdgesObj, edgeId)) {
31129 // these cluster edges will be removed on creation of the cluster.
31130 if (edgeId.substr(0, 12) !== "clusterEdge:") {
31131 var _clonedOptions = NetworkUtil.cloneOptions(childEdgesObj[edgeId], "edge");
31132
31133 childEdgesOptions.push(_clonedOptions);
31134 }
31135 }
31136 }
31137
31138 clusterNodeProperties = options.processProperties(clusterNodeProperties, childNodesOptions, childEdgesOptions);
31139
31140 if (!clusterNodeProperties) {
31141 throw new Error("The processProperties function does not return properties!");
31142 }
31143 } // check if we have an unique id;
31144
31145
31146 if (clusterNodeProperties.id === undefined) {
31147 clusterNodeProperties.id = "cluster:" + v4();
31148 }
31149
31150 var clusterId = clusterNodeProperties.id;
31151
31152 if (clusterNodeProperties.label === undefined) {
31153 clusterNodeProperties.label = "cluster";
31154 } // give the clusterNode a position if it does not have one.
31155
31156
31157 var pos = undefined;
31158
31159 if (clusterNodeProperties.x === undefined) {
31160 pos = this._getClusterPosition(childNodesObj);
31161 clusterNodeProperties.x = pos.x;
31162 }
31163
31164 if (clusterNodeProperties.y === undefined) {
31165 if (pos === undefined) {
31166 pos = this._getClusterPosition(childNodesObj);
31167 }
31168
31169 clusterNodeProperties.y = pos.y;
31170 } // force the ID to remain the same
31171
31172
31173 clusterNodeProperties.id = clusterId; // create the cluster Node
31174 // Note that allowSingleNodeCluster, if present, is stored in the options as well
31175
31176 var clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster);
31177 clusterNode.containedNodes = childNodesObj;
31178 clusterNode.containedEdges = childEdgesObj; // cache a copy from the cluster edge properties if we have to reconnect others later on
31179
31180 clusterNode.clusterEdgeProperties = options.clusterEdgeProperties; // finally put the cluster node into global
31181
31182 this.body.nodes[clusterNodeProperties.id] = clusterNode;
31183
31184 this._clusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, options.clusterEdgeProperties); // set ID to undefined so no duplicates arise
31185
31186
31187 clusterNodeProperties.id = undefined; // wrap up
31188
31189 if (refreshData === true) {
31190 this.body.emitter.emit("_dataChanged");
31191 }
31192 }
31193 /**
31194 *
31195 * @param {Edge} edge
31196 * @private
31197 */
31198
31199 }, {
31200 key: "_backupEdgeOptions",
31201 value: function _backupEdgeOptions(edge) {
31202 if (this.clusteredEdges[edge.id] === undefined) {
31203 this.clusteredEdges[edge.id] = {
31204 physics: edge.options.physics
31205 };
31206 }
31207 }
31208 /**
31209 *
31210 * @param {Edge} edge
31211 * @private
31212 */
31213
31214 }, {
31215 key: "_restoreEdge",
31216 value: function _restoreEdge(edge) {
31217 var originalOptions = this.clusteredEdges[edge.id];
31218
31219 if (originalOptions !== undefined) {
31220 edge.setOptions({
31221 physics: originalOptions.physics
31222 });
31223 delete this.clusteredEdges[edge.id];
31224 }
31225 }
31226 /**
31227 * Check if a node is a cluster.
31228 *
31229 * @param {Node.id} nodeId
31230 * @returns {*}
31231 */
31232
31233 }, {
31234 key: "isCluster",
31235 value: function isCluster(nodeId) {
31236 if (this.body.nodes[nodeId] !== undefined) {
31237 return this.body.nodes[nodeId].isCluster === true;
31238 } else {
31239 console.error("Node does not exist.");
31240 return false;
31241 }
31242 }
31243 /**
31244 * get the position of the cluster node based on what's inside
31245 *
31246 * @param {object} childNodesObj | object with node objects, id as keys
31247 * @returns {{x: number, y: number}}
31248 * @private
31249 */
31250
31251 }, {
31252 key: "_getClusterPosition",
31253 value: function _getClusterPosition(childNodesObj) {
31254 var childKeys = keys$4(childNodesObj);
31255
31256 var minX = childNodesObj[childKeys[0]].x;
31257 var maxX = childNodesObj[childKeys[0]].x;
31258 var minY = childNodesObj[childKeys[0]].y;
31259 var maxY = childNodesObj[childKeys[0]].y;
31260 var node;
31261
31262 for (var i = 1; i < childKeys.length; i++) {
31263 node = childNodesObj[childKeys[i]];
31264 minX = node.x < minX ? node.x : minX;
31265 maxX = node.x > maxX ? node.x : maxX;
31266 minY = node.y < minY ? node.y : minY;
31267 maxY = node.y > maxY ? node.y : maxY;
31268 }
31269
31270 return {
31271 x: 0.5 * (minX + maxX),
31272 y: 0.5 * (minY + maxY)
31273 };
31274 }
31275 /**
31276 * Open a cluster by calling this function.
31277 *
31278 * @param {vis.Edge.id} clusterNodeId | the ID of the cluster node
31279 * @param {object} options
31280 * @param {boolean} refreshData | wrap up afterwards if not true
31281 */
31282
31283 }, {
31284 key: "openCluster",
31285 value: function openCluster(clusterNodeId, options) {
31286 var refreshData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
31287
31288 // kill conditions
31289 if (clusterNodeId === undefined) {
31290 throw new Error("No clusterNodeId supplied to openCluster.");
31291 }
31292
31293 var clusterNode = this.body.nodes[clusterNodeId];
31294
31295 if (clusterNode === undefined) {
31296 throw new Error("The clusterNodeId supplied to openCluster does not exist.");
31297 }
31298
31299 if (clusterNode.isCluster !== true || clusterNode.containedNodes === undefined || clusterNode.containedEdges === undefined) {
31300 throw new Error("The node:" + clusterNodeId + " is not a valid cluster.");
31301 } // Check if current cluster is clustered itself
31302
31303
31304 var stack = this.findNode(clusterNodeId);
31305 var parentIndex = indexOf(stack).call(stack, clusterNodeId) - 1;
31306
31307 if (parentIndex >= 0) {
31308 // Current cluster is clustered; transfer contained nodes and edges to parent
31309 var parentClusterNodeId = stack[parentIndex];
31310 var parentClusterNode = this.body.nodes[parentClusterNodeId]; // clustering.clusteredNodes and clustering.clusteredEdges remain unchanged
31311
31312 parentClusterNode._openChildCluster(clusterNodeId); // All components of child cluster node have been transferred. It can die now.
31313
31314
31315 delete this.body.nodes[clusterNodeId];
31316
31317 if (refreshData === true) {
31318 this.body.emitter.emit("_dataChanged");
31319 }
31320
31321 return;
31322 } // main body
31323
31324
31325 var containedNodes = clusterNode.containedNodes;
31326 var containedEdges = clusterNode.containedEdges; // allow the user to position the nodes after release.
31327
31328 if (options !== undefined && options.releaseFunction !== undefined && typeof options.releaseFunction === "function") {
31329 var positions = {};
31330 var clusterPosition = {
31331 x: clusterNode.x,
31332 y: clusterNode.y
31333 };
31334
31335 for (var nodeId in containedNodes) {
31336 if (Object.prototype.hasOwnProperty.call(containedNodes, nodeId)) {
31337 var containedNode = this.body.nodes[nodeId];
31338 positions[nodeId] = {
31339 x: containedNode.x,
31340 y: containedNode.y
31341 };
31342 }
31343 }
31344
31345 var newPositions = options.releaseFunction(clusterPosition, positions);
31346
31347 for (var _nodeId2 in containedNodes) {
31348 if (Object.prototype.hasOwnProperty.call(containedNodes, _nodeId2)) {
31349 var _containedNode = this.body.nodes[_nodeId2];
31350
31351 if (newPositions[_nodeId2] !== undefined) {
31352 _containedNode.x = newPositions[_nodeId2].x === undefined ? clusterNode.x : newPositions[_nodeId2].x;
31353 _containedNode.y = newPositions[_nodeId2].y === undefined ? clusterNode.y : newPositions[_nodeId2].y;
31354 }
31355 }
31356 }
31357 } else {
31358 // copy the position from the cluster
31359 forEach$1(containedNodes, function (containedNode) {
31360 // inherit position
31361 if (containedNode.options.fixed.x === false) {
31362 containedNode.x = clusterNode.x;
31363 }
31364
31365 if (containedNode.options.fixed.y === false) {
31366 containedNode.y = clusterNode.y;
31367 }
31368 });
31369 } // release nodes
31370
31371
31372 for (var _nodeId3 in containedNodes) {
31373 if (Object.prototype.hasOwnProperty.call(containedNodes, _nodeId3)) {
31374 var _containedNode2 = this.body.nodes[_nodeId3]; // inherit speed
31375
31376 _containedNode2.vx = clusterNode.vx;
31377 _containedNode2.vy = clusterNode.vy;
31378
31379 _containedNode2.setOptions({
31380 physics: true
31381 });
31382
31383 delete this.clusteredNodes[_nodeId3];
31384 }
31385 } // copy the clusterNode edges because we cannot iterate over an object that we add or remove from.
31386
31387
31388 var edgesToBeDeleted = [];
31389
31390 for (var i = 0; i < clusterNode.edges.length; i++) {
31391 edgesToBeDeleted.push(clusterNode.edges[i]);
31392 } // actually handling the deleting.
31393
31394
31395 for (var _i3 = 0; _i3 < edgesToBeDeleted.length; _i3++) {
31396 var edge = edgesToBeDeleted[_i3];
31397
31398 var otherNodeId = this._getConnectedId(edge, clusterNodeId);
31399
31400 var otherNode = this.clusteredNodes[otherNodeId];
31401
31402 for (var j = 0; j < edge.clusteringEdgeReplacingIds.length; j++) {
31403 var transferId = edge.clusteringEdgeReplacingIds[j];
31404 var transferEdge = this.body.edges[transferId];
31405 if (transferEdge === undefined) continue; // if the other node is in another cluster, we transfer ownership of this edge to the other cluster
31406
31407 if (otherNode !== undefined) {
31408 // transfer ownership:
31409 var otherCluster = this.body.nodes[otherNode.clusterId];
31410 otherCluster.containedEdges[transferEdge.id] = transferEdge; // delete local reference
31411
31412 delete containedEdges[transferEdge.id]; // get to and from
31413
31414 var fromId = transferEdge.fromId;
31415 var toId = transferEdge.toId;
31416
31417 if (transferEdge.toId == otherNodeId) {
31418 toId = otherNode.clusterId;
31419 } else {
31420 fromId = otherNode.clusterId;
31421 } // create new cluster edge from the otherCluster
31422
31423
31424 this._createClusteredEdge(fromId, toId, transferEdge, otherCluster.clusterEdgeProperties, {
31425 hidden: false,
31426 physics: true
31427 });
31428 } else {
31429 this._restoreEdge(transferEdge);
31430 }
31431 }
31432
31433 edge.remove();
31434 } // handle the releasing of the edges
31435
31436
31437 for (var edgeId in containedEdges) {
31438 if (Object.prototype.hasOwnProperty.call(containedEdges, edgeId)) {
31439 this._restoreEdge(containedEdges[edgeId]);
31440 }
31441 } // remove clusterNode
31442
31443
31444 delete this.body.nodes[clusterNodeId];
31445
31446 if (refreshData === true) {
31447 this.body.emitter.emit("_dataChanged");
31448 }
31449 }
31450 /**
31451 *
31452 * @param {Cluster.id} clusterId
31453 * @returns {Array.<Node.id>}
31454 */
31455
31456 }, {
31457 key: "getNodesInCluster",
31458 value: function getNodesInCluster(clusterId) {
31459 var nodesArray = [];
31460
31461 if (this.isCluster(clusterId) === true) {
31462 var containedNodes = this.body.nodes[clusterId].containedNodes;
31463
31464 for (var nodeId in containedNodes) {
31465 if (Object.prototype.hasOwnProperty.call(containedNodes, nodeId)) {
31466 nodesArray.push(this.body.nodes[nodeId].id);
31467 }
31468 }
31469 }
31470
31471 return nodesArray;
31472 }
31473 /**
31474 * Get the stack clusterId's that a certain node resides in. cluster A -> cluster B -> cluster C -> node
31475 *
31476 * If a node can't be found in the chain, return an empty array.
31477 *
31478 * @param {string|number} nodeId
31479 * @returns {Array}
31480 */
31481
31482 }, {
31483 key: "findNode",
31484 value: function findNode(nodeId) {
31485 var stack = [];
31486 var max = 100;
31487 var counter = 0;
31488 var node;
31489
31490 while (this.clusteredNodes[nodeId] !== undefined && counter < max) {
31491 node = this.body.nodes[nodeId];
31492 if (node === undefined) return [];
31493 stack.push(node.id);
31494 nodeId = this.clusteredNodes[nodeId].clusterId;
31495 counter++;
31496 }
31497
31498 node = this.body.nodes[nodeId];
31499 if (node === undefined) return [];
31500 stack.push(node.id);
31501
31502 reverse(stack).call(stack);
31503
31504 return stack;
31505 }
31506 /**
31507 * Using a clustered nodeId, update with the new options
31508 *
31509 * @param {Node.id} clusteredNodeId
31510 * @param {object} newOptions
31511 */
31512
31513 }, {
31514 key: "updateClusteredNode",
31515 value: function updateClusteredNode(clusteredNodeId, newOptions) {
31516 if (clusteredNodeId === undefined) {
31517 throw new Error("No clusteredNodeId supplied to updateClusteredNode.");
31518 }
31519
31520 if (newOptions === undefined) {
31521 throw new Error("No newOptions supplied to updateClusteredNode.");
31522 }
31523
31524 if (this.body.nodes[clusteredNodeId] === undefined) {
31525 throw new Error("The clusteredNodeId supplied to updateClusteredNode does not exist.");
31526 }
31527
31528 this.body.nodes[clusteredNodeId].setOptions(newOptions);
31529 this.body.emitter.emit("_dataChanged");
31530 }
31531 /**
31532 * Using a base edgeId, update all related clustered edges with the new options
31533 *
31534 * @param {vis.Edge.id} startEdgeId
31535 * @param {object} newOptions
31536 */
31537
31538 }, {
31539 key: "updateEdge",
31540 value: function updateEdge(startEdgeId, newOptions) {
31541 if (startEdgeId === undefined) {
31542 throw new Error("No startEdgeId supplied to updateEdge.");
31543 }
31544
31545 if (newOptions === undefined) {
31546 throw new Error("No newOptions supplied to updateEdge.");
31547 }
31548
31549 if (this.body.edges[startEdgeId] === undefined) {
31550 throw new Error("The startEdgeId supplied to updateEdge does not exist.");
31551 }
31552
31553 var allEdgeIds = this.getClusteredEdges(startEdgeId);
31554
31555 for (var i = 0; i < allEdgeIds.length; i++) {
31556 var edge = this.body.edges[allEdgeIds[i]];
31557 edge.setOptions(newOptions);
31558 }
31559
31560 this.body.emitter.emit("_dataChanged");
31561 }
31562 /**
31563 * Get a stack of clusterEdgeId's (+base edgeid) that a base edge is the same as. cluster edge C -> cluster edge B -> cluster edge A -> base edge(edgeId)
31564 *
31565 * @param {vis.Edge.id} edgeId
31566 * @returns {Array.<vis.Edge.id>}
31567 */
31568
31569 }, {
31570 key: "getClusteredEdges",
31571 value: function getClusteredEdges(edgeId) {
31572 var stack = [];
31573 var max = 100;
31574 var counter = 0;
31575
31576 while (edgeId !== undefined && this.body.edges[edgeId] !== undefined && counter < max) {
31577 stack.push(this.body.edges[edgeId].id);
31578 edgeId = this.body.edges[edgeId].edgeReplacedById;
31579 counter++;
31580 }
31581
31582 reverse(stack).call(stack);
31583
31584 return stack;
31585 }
31586 /**
31587 * Get the base edge id of clusterEdgeId. cluster edge (clusteredEdgeId) -> cluster edge B -> cluster edge C -> base edge
31588 *
31589 * @param {vis.Edge.id} clusteredEdgeId
31590 * @returns {vis.Edge.id} baseEdgeId
31591 *
31592 * TODO: deprecate in 5.0.0. Method getBaseEdges() is the correct one to use.
31593 */
31594
31595 }, {
31596 key: "getBaseEdge",
31597 value: function getBaseEdge(clusteredEdgeId) {
31598 // Just kludge this by returning the first base edge id found
31599 return this.getBaseEdges(clusteredEdgeId)[0];
31600 }
31601 /**
31602 * Get all regular edges for this clustered edge id.
31603 *
31604 * @param {vis.Edge.id} clusteredEdgeId
31605 * @returns {Array.<vis.Edge.id>} all baseEdgeId's under this clustered edge
31606 */
31607
31608 }, {
31609 key: "getBaseEdges",
31610 value: function getBaseEdges(clusteredEdgeId) {
31611 var IdsToHandle = [clusteredEdgeId];
31612 var doneIds = [];
31613 var foundIds = [];
31614 var max = 100;
31615 var counter = 0;
31616
31617 while (IdsToHandle.length > 0 && counter < max) {
31618 var nextId = IdsToHandle.pop();
31619 if (nextId === undefined) continue; // Paranoia here and onwards
31620
31621 var nextEdge = this.body.edges[nextId];
31622 if (nextEdge === undefined) continue;
31623 counter++;
31624 var replacingIds = nextEdge.clusteringEdgeReplacingIds;
31625
31626 if (replacingIds === undefined) {
31627 // nextId is a base id
31628 foundIds.push(nextId);
31629 } else {
31630 // Another cluster edge, unravel this one as well
31631 for (var i = 0; i < replacingIds.length; ++i) {
31632 var replacingId = replacingIds[i]; // Don't add if already handled
31633 // TODO: never triggers; find a test-case which does
31634
31635 if (indexOf(IdsToHandle).call(IdsToHandle, replacingIds) !== -1 || indexOf(doneIds).call(doneIds, replacingIds) !== -1) {
31636 continue;
31637 }
31638
31639 IdsToHandle.push(replacingId);
31640 }
31641 }
31642
31643 doneIds.push(nextId);
31644 }
31645
31646 return foundIds;
31647 }
31648 /**
31649 * Get the Id the node is connected to
31650 *
31651 * @param {vis.Edge} edge
31652 * @param {Node.id} nodeId
31653 * @returns {*}
31654 * @private
31655 */
31656
31657 }, {
31658 key: "_getConnectedId",
31659 value: function _getConnectedId(edge, nodeId) {
31660 if (edge.toId != nodeId) {
31661 return edge.toId;
31662 } else if (edge.fromId != nodeId) {
31663 return edge.fromId;
31664 } else {
31665 return edge.fromId;
31666 }
31667 }
31668 /**
31669 * We determine how many connections denote an important hub.
31670 * We take the mean + 2*std as the important hub size. (Assuming a normal distribution of data, ~2.2%)
31671 *
31672 * @returns {number}
31673 * @private
31674 */
31675
31676 }, {
31677 key: "_getHubSize",
31678 value: function _getHubSize() {
31679 var average = 0;
31680 var averageSquared = 0;
31681 var hubCounter = 0;
31682 var largestHub = 0;
31683
31684 for (var i = 0; i < this.body.nodeIndices.length; i++) {
31685 var node = this.body.nodes[this.body.nodeIndices[i]];
31686
31687 if (node.edges.length > largestHub) {
31688 largestHub = node.edges.length;
31689 }
31690
31691 average += node.edges.length;
31692 averageSquared += Math.pow(node.edges.length, 2);
31693 hubCounter += 1;
31694 }
31695
31696 average = average / hubCounter;
31697 averageSquared = averageSquared / hubCounter;
31698 var variance = averageSquared - Math.pow(average, 2);
31699 var standardDeviation = Math.sqrt(variance);
31700 var hubThreshold = Math.floor(average + 2 * standardDeviation); // always have at least one to cluster
31701
31702 if (hubThreshold > largestHub) {
31703 hubThreshold = largestHub;
31704 }
31705
31706 return hubThreshold;
31707 }
31708 /**
31709 * Create an edge for the cluster representation.
31710 *
31711 * @param {Node.id} fromId
31712 * @param {Node.id} toId
31713 * @param {vis.Edge} baseEdge
31714 * @param {object} clusterEdgeProperties
31715 * @param {object} extraOptions
31716 * @returns {Edge} newly created clustered edge
31717 * @private
31718 */
31719
31720 }, {
31721 key: "_createClusteredEdge",
31722 value: function _createClusteredEdge(fromId, toId, baseEdge, clusterEdgeProperties, extraOptions) {
31723 // copy the options of the edge we will replace
31724 var clonedOptions = NetworkUtil.cloneOptions(baseEdge, "edge"); // make sure the properties of clusterEdges are superimposed on it
31725
31726 deepExtend(clonedOptions, clusterEdgeProperties); // set up the edge
31727
31728 clonedOptions.from = fromId;
31729 clonedOptions.to = toId;
31730 clonedOptions.id = "clusterEdge:" + v4(); // apply the edge specific options to it if specified
31731
31732 if (extraOptions !== undefined) {
31733 deepExtend(clonedOptions, extraOptions);
31734 }
31735
31736 var newEdge = this.body.functions.createEdge(clonedOptions);
31737 newEdge.clusteringEdgeReplacingIds = [baseEdge.id];
31738 newEdge.connect(); // Register the new edge
31739
31740 this.body.edges[newEdge.id] = newEdge;
31741 return newEdge;
31742 }
31743 /**
31744 * Add the passed child nodes and edges to the given cluster node.
31745 *
31746 * @param {object | Node} childNodes hash of nodes or single node to add in cluster
31747 * @param {object | Edge} childEdges hash of edges or single edge to take into account when clustering
31748 * @param {Node} clusterNode cluster node to add nodes and edges to
31749 * @param {object} [clusterEdgeProperties]
31750 * @private
31751 */
31752
31753 }, {
31754 key: "_clusterEdges",
31755 value: function _clusterEdges(childNodes, childEdges, clusterNode, clusterEdgeProperties) {
31756 if (childEdges instanceof Edge) {
31757 var edge = childEdges;
31758 var obj = {};
31759 obj[edge.id] = edge;
31760 childEdges = obj;
31761 }
31762
31763 if (childNodes instanceof Node) {
31764 var node = childNodes;
31765 var _obj = {};
31766 _obj[node.id] = node;
31767 childNodes = _obj;
31768 }
31769
31770 if (clusterNode === undefined || clusterNode === null) {
31771 throw new Error("_clusterEdges: parameter clusterNode required");
31772 }
31773
31774 if (clusterEdgeProperties === undefined) {
31775 // Take the required properties from the cluster node
31776 clusterEdgeProperties = clusterNode.clusterEdgeProperties;
31777 } // create the new edges that will connect to the cluster.
31778 // All self-referencing edges will be added to childEdges here.
31779
31780
31781 this._createClusterEdges(childNodes, childEdges, clusterNode, clusterEdgeProperties); // disable the childEdges
31782
31783
31784 for (var edgeId in childEdges) {
31785 if (Object.prototype.hasOwnProperty.call(childEdges, edgeId)) {
31786 if (this.body.edges[edgeId] !== undefined) {
31787 var _edge2 = this.body.edges[edgeId]; // cache the options before changing
31788
31789 this._backupEdgeOptions(_edge2); // disable physics and hide the edge
31790
31791
31792 _edge2.setOptions({
31793 physics: false
31794 });
31795 }
31796 }
31797 } // disable the childNodes
31798
31799
31800 for (var nodeId in childNodes) {
31801 if (Object.prototype.hasOwnProperty.call(childNodes, nodeId)) {
31802 this.clusteredNodes[nodeId] = {
31803 clusterId: clusterNode.id,
31804 node: this.body.nodes[nodeId]
31805 };
31806 this.body.nodes[nodeId].setOptions({
31807 physics: false
31808 });
31809 }
31810 }
31811 }
31812 /**
31813 * Determine in which cluster given nodeId resides.
31814 *
31815 * If not in cluster, return undefined.
31816 *
31817 * NOTE: If you know a cleaner way to do this, please enlighten me (wimrijnders).
31818 *
31819 * @param {Node.id} nodeId
31820 * @returns {Node|undefined} Node instance for cluster, if present
31821 * @private
31822 */
31823
31824 }, {
31825 key: "_getClusterNodeForNode",
31826 value: function _getClusterNodeForNode(nodeId) {
31827 if (nodeId === undefined) return undefined;
31828 var clusteredNode = this.clusteredNodes[nodeId]; // NOTE: If no cluster info found, it should actually be an error
31829
31830 if (clusteredNode === undefined) return undefined;
31831 var clusterId = clusteredNode.clusterId;
31832 if (clusterId === undefined) return undefined;
31833 return this.body.nodes[clusterId];
31834 }
31835 /**
31836 * Internal helper function for conditionally removing items in array
31837 *
31838 * Done like this because Array.filter() is not fully supported by all IE's.
31839 *
31840 * @param {Array} arr
31841 * @param {Function} callback
31842 * @returns {Array}
31843 * @private
31844 */
31845
31846 }, {
31847 key: "_filter",
31848 value: function _filter(arr, callback) {
31849 var ret = [];
31850 forEach$1(arr, function (item) {
31851 if (callback(item)) {
31852 ret.push(item);
31853 }
31854 });
31855 return ret;
31856 }
31857 /**
31858 * Scan all edges for changes in clustering and adjust this if necessary.
31859 *
31860 * Call this (internally) after there has been a change in node or edge data.
31861 *
31862 * Pre: States of this.body.nodes and this.body.edges consistent
31863 * Pre: this.clusteredNodes and this.clusteredEdge consistent with containedNodes and containedEdges
31864 * of cluster nodes.
31865 */
31866
31867 }, {
31868 key: "_updateState",
31869 value: function _updateState() {
31870 var _this4 = this;
31871
31872 var nodeId;
31873 var deletedNodeIds = [];
31874 var deletedEdgeIds = {};
31875 /**
31876 * Utility function to iterate over clustering nodes only
31877 *
31878 * @param {Function} callback function to call for each cluster node
31879 */
31880
31881 var eachClusterNode = function eachClusterNode(callback) {
31882 forEach$1(_this4.body.nodes, function (node) {
31883 if (node.isCluster === true) {
31884 callback(node);
31885 }
31886 });
31887 }; //
31888 // Remove deleted regular nodes from clustering
31889 //
31890 // Determine the deleted nodes
31891
31892
31893 for (nodeId in this.clusteredNodes) {
31894 if (!Object.prototype.hasOwnProperty.call(this.clusteredNodes, nodeId)) continue;
31895 var node = this.body.nodes[nodeId];
31896
31897 if (node === undefined) {
31898 deletedNodeIds.push(nodeId);
31899 }
31900 } // Remove nodes from cluster nodes
31901
31902
31903 eachClusterNode(function (clusterNode) {
31904 for (var n = 0; n < deletedNodeIds.length; n++) {
31905 delete clusterNode.containedNodes[deletedNodeIds[n]];
31906 }
31907 }); // Remove nodes from cluster list
31908
31909 for (var n = 0; n < deletedNodeIds.length; n++) {
31910 delete this.clusteredNodes[deletedNodeIds[n]];
31911 } //
31912 // Remove deleted edges from clustering
31913 //
31914 // Add the deleted clustered edges to the list
31915
31916
31917 forEach$1(this.clusteredEdges, function (edgeId) {
31918 var edge = _this4.body.edges[edgeId];
31919
31920 if (edge === undefined || !edge.endPointsValid()) {
31921 deletedEdgeIds[edgeId] = edgeId;
31922 }
31923 }); // Cluster nodes can also contain edges which are not clustered,
31924 // i.e. nodes 1-2 within cluster with an edge in between.
31925 // So the cluster nodes also need to be scanned for invalid edges
31926
31927 eachClusterNode(function (clusterNode) {
31928 forEach$1(clusterNode.containedEdges, function (edge, edgeId) {
31929 if (!edge.endPointsValid() && !deletedEdgeIds[edgeId]) {
31930 deletedEdgeIds[edgeId] = edgeId;
31931 }
31932 });
31933 }); // Also scan for cluster edges which need to be removed in the active list.
31934 // Regular edges have been removed beforehand, so this only picks up the cluster edges.
31935
31936 forEach$1(this.body.edges, function (edge, edgeId) {
31937 // Explicitly scan the contained edges for validity
31938 var isValid = true;
31939 var replacedIds = edge.clusteringEdgeReplacingIds;
31940
31941 if (replacedIds !== undefined) {
31942 var numValid = 0;
31943 forEach$1(replacedIds, function (containedEdgeId) {
31944 var containedEdge = _this4.body.edges[containedEdgeId];
31945
31946 if (containedEdge !== undefined && containedEdge.endPointsValid()) {
31947 numValid += 1;
31948 }
31949 });
31950 isValid = numValid > 0;
31951 }
31952
31953 if (!edge.endPointsValid() || !isValid) {
31954 deletedEdgeIds[edgeId] = edgeId;
31955 }
31956 }); // Remove edges from cluster nodes
31957
31958 eachClusterNode(function (clusterNode) {
31959 forEach$1(deletedEdgeIds, function (deletedEdgeId) {
31960 delete clusterNode.containedEdges[deletedEdgeId];
31961 forEach$1(clusterNode.edges, function (edge, m) {
31962 if (edge.id === deletedEdgeId) {
31963 clusterNode.edges[m] = null; // Don't want to directly delete here, because in the loop
31964
31965 return;
31966 }
31967
31968 edge.clusteringEdgeReplacingIds = _this4._filter(edge.clusteringEdgeReplacingIds, function (id) {
31969 return !deletedEdgeIds[id];
31970 });
31971 }); // Clean up the nulls
31972
31973 clusterNode.edges = _this4._filter(clusterNode.edges, function (item) {
31974 return item !== null;
31975 });
31976 });
31977 }); // Remove from cluster list
31978
31979 forEach$1(deletedEdgeIds, function (edgeId) {
31980 delete _this4.clusteredEdges[edgeId];
31981 }); // Remove cluster edges from active list (this.body.edges).
31982 // deletedEdgeIds still contains id of regular edges, but these should all
31983 // be gone when you reach here.
31984
31985 forEach$1(deletedEdgeIds, function (edgeId) {
31986 delete _this4.body.edges[edgeId];
31987 }); //
31988 // Check changed cluster state of edges
31989 //
31990 // Iterating over keys here, because edges may be removed in the loop
31991
31992 var ids = keys$4(this.body.edges);
31993
31994 forEach$1(ids, function (edgeId) {
31995 var edge = _this4.body.edges[edgeId];
31996
31997 var shouldBeClustered = _this4._isClusteredNode(edge.fromId) || _this4._isClusteredNode(edge.toId);
31998
31999 if (shouldBeClustered === _this4._isClusteredEdge(edge.id)) {
32000 return; // all is well
32001 }
32002
32003 if (shouldBeClustered) {
32004 // add edge to clustering
32005 var clusterFrom = _this4._getClusterNodeForNode(edge.fromId);
32006
32007 if (clusterFrom !== undefined) {
32008 _this4._clusterEdges(_this4.body.nodes[edge.fromId], edge, clusterFrom);
32009 }
32010
32011 var clusterTo = _this4._getClusterNodeForNode(edge.toId);
32012
32013 if (clusterTo !== undefined) {
32014 _this4._clusterEdges(_this4.body.nodes[edge.toId], edge, clusterTo);
32015 } // TODO: check that it works for both edges clustered
32016 // (This might be paranoia)
32017
32018 } else {
32019 delete _this4._clusterEdges[edgeId];
32020
32021 _this4._restoreEdge(edge); // This should not be happening, the state should
32022 // be properly updated at this point.
32023 //
32024 // If it *is* reached during normal operation, then we have to implement
32025 // undo clustering for this edge here.
32026 // throw new Error('remove edge from clustering not implemented!')
32027
32028 }
32029 }); // Clusters may be nested to any level. Keep on opening until nothing to open
32030
32031 var changed = false;
32032 var continueLoop = true;
32033
32034 var _loop2 = function _loop2() {
32035 var clustersToOpen = []; // Determine the id's of clusters that need opening
32036
32037 eachClusterNode(function (clusterNode) {
32038 var numNodes = keys$4(clusterNode.containedNodes).length;
32039
32040 var allowSingle = clusterNode.options.allowSingleNodeCluster === true;
32041
32042 if (allowSingle && numNodes < 1 || !allowSingle && numNodes < 2) {
32043 clustersToOpen.push(clusterNode.id);
32044 }
32045 }); // Open them
32046
32047 for (var _n = 0; _n < clustersToOpen.length; ++_n) {
32048 _this4.openCluster(clustersToOpen[_n], {}, false
32049 /* Don't refresh, we're in an refresh/update already */
32050 );
32051 }
32052
32053 continueLoop = clustersToOpen.length > 0;
32054 changed = changed || continueLoop;
32055 };
32056
32057 while (continueLoop) {
32058 _loop2();
32059 }
32060
32061 if (changed) {
32062 this._updateState(); // Redo this method (recursion possible! should be safe)
32063
32064 }
32065 }
32066 /**
32067 * Determine if node with given id is part of a cluster.
32068 *
32069 * @param {Node.id} nodeId
32070 * @returns {boolean} true if part of a cluster.
32071 */
32072
32073 }, {
32074 key: "_isClusteredNode",
32075 value: function _isClusteredNode(nodeId) {
32076 return this.clusteredNodes[nodeId] !== undefined;
32077 }
32078 /**
32079 * Determine if edge with given id is not visible due to clustering.
32080 *
32081 * An edge is considered clustered if:
32082 * - it is directly replaced by a clustering edge
32083 * - any of its connecting nodes is in a cluster
32084 *
32085 * @param {vis.Edge.id} edgeId
32086 * @returns {boolean} true if part of a cluster.
32087 */
32088
32089 }, {
32090 key: "_isClusteredEdge",
32091 value: function _isClusteredEdge(edgeId) {
32092 return this.clusteredEdges[edgeId] !== undefined;
32093 }
32094 }]);
32095
32096 return ClusterEngine;
32097}();
32098
32099function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
32100
32101function _unsupportedIterableToArray$5(o, minLen) { var _context4; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(o, minLen); var n = slice$1(_context4 = Object.prototype.toString.call(o)).call(_context4, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$5(o, minLen); }
32102
32103function _arrayLikeToArray$5(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
32104/**
32105 * Initializes window.requestAnimationFrame() to a usable form.
32106 *
32107 * Specifically, set up this method for the case of running on node.js with jsdom enabled.
32108 *
32109 * NOTES:
32110 *
32111 * * On node.js, when calling this directly outside of this class, `window` is not defined.
32112 * This happens even if jsdom is used.
32113 * * For node.js + jsdom, `window` is available at the moment the constructor is called.
32114 * For this reason, the called is placed within the constructor.
32115 * * Even then, `window.requestAnimationFrame()` is not defined, so it still needs to be added.
32116 * * During unit testing, it happens that the window object is reset during execution, causing
32117 * a runtime error due to missing `requestAnimationFrame()`. This needs to be compensated for,
32118 * see `_requestNextFrame()`.
32119 * * Since this is a global object, it may affect other modules besides `Network`. With normal
32120 * usage, this does not cause any problems. During unit testing, errors may occur. These have
32121 * been compensated for, see comment block in _requestNextFrame().
32122 *
32123 * @private
32124 */
32125
32126function _initRequestAnimationFrame() {
32127 var func;
32128
32129 if (window !== undefined) {
32130 func = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
32131 }
32132
32133 if (func === undefined) {
32134 // window or method not present, setting mock requestAnimationFrame
32135 window.requestAnimationFrame = function (callback) {
32136 //console.log("Called mock requestAnimationFrame");
32137 callback();
32138 };
32139 } else {
32140 window.requestAnimationFrame = func;
32141 }
32142}
32143/**
32144 * The canvas renderer
32145 */
32146
32147
32148var CanvasRenderer = /*#__PURE__*/function () {
32149 /**
32150 * @param {object} body
32151 * @param {Canvas} canvas
32152 */
32153 function CanvasRenderer(body, canvas) {
32154 _classCallCheck(this, CanvasRenderer);
32155
32156 _initRequestAnimationFrame();
32157
32158 this.body = body;
32159 this.canvas = canvas;
32160 this.redrawRequested = false;
32161 this.renderTimer = undefined;
32162 this.requiresTimeout = true;
32163 this.renderingActive = false;
32164 this.renderRequests = 0;
32165 this.allowRedraw = true;
32166 this.dragging = false;
32167 this.zooming = false;
32168 this.options = {};
32169 this.defaultOptions = {
32170 hideEdgesOnDrag: false,
32171 hideEdgesOnZoom: false,
32172 hideNodesOnDrag: false
32173 };
32174
32175 assign$2(this.options, this.defaultOptions);
32176
32177 this._determineBrowserMethod();
32178
32179 this.bindEventListeners();
32180 }
32181 /**
32182 * Binds event listeners
32183 */
32184
32185
32186 _createClass(CanvasRenderer, [{
32187 key: "bindEventListeners",
32188 value: function bindEventListeners() {
32189 var _this = this,
32190 _context2;
32191
32192 this.body.emitter.on("dragStart", function () {
32193 _this.dragging = true;
32194 });
32195 this.body.emitter.on("dragEnd", function () {
32196 _this.dragging = false;
32197 });
32198 this.body.emitter.on("zoom", function () {
32199 _this.zooming = true;
32200 window.clearTimeout(_this.zoomTimeoutId);
32201 _this.zoomTimeoutId = setTimeout$1(function () {
32202 var _context;
32203
32204 _this.zooming = false;
32205
32206 bind$6(_context = _this._requestRedraw).call(_context, _this)();
32207 }, 250);
32208 });
32209 this.body.emitter.on("_resizeNodes", function () {
32210 _this._resizeNodes();
32211 });
32212 this.body.emitter.on("_redraw", function () {
32213 if (_this.renderingActive === false) {
32214 _this._redraw();
32215 }
32216 });
32217 this.body.emitter.on("_blockRedraw", function () {
32218 _this.allowRedraw = false;
32219 });
32220 this.body.emitter.on("_allowRedraw", function () {
32221 _this.allowRedraw = true;
32222 _this.redrawRequested = false;
32223 });
32224 this.body.emitter.on("_requestRedraw", bind$6(_context2 = this._requestRedraw).call(_context2, this));
32225 this.body.emitter.on("_startRendering", function () {
32226 _this.renderRequests += 1;
32227 _this.renderingActive = true;
32228
32229 _this._startRendering();
32230 });
32231 this.body.emitter.on("_stopRendering", function () {
32232 _this.renderRequests -= 1;
32233 _this.renderingActive = _this.renderRequests > 0;
32234 _this.renderTimer = undefined;
32235 });
32236 this.body.emitter.on("destroy", function () {
32237 _this.renderRequests = 0;
32238 _this.allowRedraw = false;
32239 _this.renderingActive = false;
32240
32241 if (_this.requiresTimeout === true) {
32242 clearTimeout(_this.renderTimer);
32243 } else {
32244 window.cancelAnimationFrame(_this.renderTimer);
32245 }
32246
32247 _this.body.emitter.off();
32248 });
32249 }
32250 /**
32251 *
32252 * @param {object} options
32253 */
32254
32255 }, {
32256 key: "setOptions",
32257 value: function setOptions(options) {
32258 if (options !== undefined) {
32259 var fields = ["hideEdgesOnDrag", "hideEdgesOnZoom", "hideNodesOnDrag"];
32260 selectiveDeepExtend(fields, this.options, options);
32261 }
32262 }
32263 /**
32264 * Prepare the drawing of the next frame.
32265 *
32266 * Calls the callback when the next frame can or will be drawn.
32267 *
32268 * @param {Function} callback
32269 * @param {number} delay - timeout case only, wait this number of milliseconds
32270 * @returns {Function | undefined}
32271 * @private
32272 */
32273
32274 }, {
32275 key: "_requestNextFrame",
32276 value: function _requestNextFrame(callback, delay) {
32277 // During unit testing, it happens that the mock window object is reset while
32278 // the next frame is still pending. Then, either 'window' is not present, or
32279 // 'requestAnimationFrame()' is not present because it is not defined on the
32280 // mock window object.
32281 //
32282 // As a consequence, unrelated unit tests may appear to fail, even if the problem
32283 // described happens in the current unit test.
32284 //
32285 // This is not something that will happen in normal operation, but we still need
32286 // to take it into account.
32287 //
32288 if (typeof window === "undefined") return; // Doing `if (window === undefined)` does not work here!
32289
32290 var timer;
32291 var myWindow = window; // Grab a reference to reduce the possibility that 'window' is reset
32292 // while running this method.
32293
32294 if (this.requiresTimeout === true) {
32295 // wait given number of milliseconds and perform the animation step function
32296 timer = setTimeout$1(callback, delay);
32297 } else {
32298 if (myWindow.requestAnimationFrame) {
32299 timer = myWindow.requestAnimationFrame(callback);
32300 }
32301 }
32302
32303 return timer;
32304 }
32305 /**
32306 *
32307 * @private
32308 */
32309
32310 }, {
32311 key: "_startRendering",
32312 value: function _startRendering() {
32313 if (this.renderingActive === true) {
32314 if (this.renderTimer === undefined) {
32315 var _context3;
32316
32317 this.renderTimer = this._requestNextFrame(bind$6(_context3 = this._renderStep).call(_context3, this), this.simulationInterval);
32318 }
32319 }
32320 }
32321 /**
32322 *
32323 * @private
32324 */
32325
32326 }, {
32327 key: "_renderStep",
32328 value: function _renderStep() {
32329 if (this.renderingActive === true) {
32330 // reset the renderTimer so a new scheduled animation step can be set
32331 this.renderTimer = undefined;
32332
32333 if (this.requiresTimeout === true) {
32334 // this schedules a new simulation step
32335 this._startRendering();
32336 }
32337
32338 this._redraw();
32339
32340 if (this.requiresTimeout === false) {
32341 // this schedules a new simulation step
32342 this._startRendering();
32343 }
32344 }
32345 }
32346 /**
32347 * Redraw the network with the current data
32348 * chart will be resized too.
32349 */
32350
32351 }, {
32352 key: "redraw",
32353 value: function redraw() {
32354 this.body.emitter.emit("setSize");
32355
32356 this._redraw();
32357 }
32358 /**
32359 * Redraw the network with the current data
32360 *
32361 * @private
32362 */
32363
32364 }, {
32365 key: "_requestRedraw",
32366 value: function _requestRedraw() {
32367 var _this2 = this;
32368
32369 if (this.redrawRequested !== true && this.renderingActive === false && this.allowRedraw === true) {
32370 this.redrawRequested = true;
32371
32372 this._requestNextFrame(function () {
32373 _this2._redraw(false);
32374 }, 0);
32375 }
32376 }
32377 /**
32378 * Redraw the network with the current data
32379 *
32380 * @param {boolean} [hidden=false] | Used to get the first estimate of the node sizes.
32381 * Only the nodes are drawn after which they are quickly drawn over.
32382 * @private
32383 */
32384
32385 }, {
32386 key: "_redraw",
32387 value: function _redraw() {
32388 var hidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
32389
32390 if (this.allowRedraw === true) {
32391 this.body.emitter.emit("initRedraw");
32392 this.redrawRequested = false;
32393 var drawLater = {
32394 drawExternalLabels: null
32395 }; // when the container div was hidden, this fixes it back up!
32396
32397 if (this.canvas.frame.canvas.width === 0 || this.canvas.frame.canvas.height === 0) {
32398 this.canvas.setSize();
32399 }
32400
32401 this.canvas.setTransform();
32402 var ctx = this.canvas.getContext(); // clear the canvas
32403
32404 var w = this.canvas.frame.canvas.clientWidth;
32405 var h = this.canvas.frame.canvas.clientHeight;
32406 ctx.clearRect(0, 0, w, h); // if the div is hidden, we stop the redraw here for performance.
32407
32408 if (this.canvas.frame.clientWidth === 0) {
32409 return;
32410 } // set scaling and translation
32411
32412
32413 ctx.save();
32414 ctx.translate(this.body.view.translation.x, this.body.view.translation.y);
32415 ctx.scale(this.body.view.scale, this.body.view.scale);
32416 ctx.beginPath();
32417 this.body.emitter.emit("beforeDrawing", ctx);
32418 ctx.closePath();
32419
32420 if (hidden === false) {
32421 if ((this.dragging === false || this.dragging === true && this.options.hideEdgesOnDrag === false) && (this.zooming === false || this.zooming === true && this.options.hideEdgesOnZoom === false)) {
32422 this._drawEdges(ctx);
32423 }
32424 }
32425
32426 if (this.dragging === false || this.dragging === true && this.options.hideNodesOnDrag === false) {
32427 var _this$_drawNodes = this._drawNodes(ctx, hidden),
32428 drawExternalLabels = _this$_drawNodes.drawExternalLabels;
32429
32430 drawLater.drawExternalLabels = drawExternalLabels;
32431 } // draw the arrows last so they will be at the top
32432
32433
32434 if (hidden === false) {
32435 if ((this.dragging === false || this.dragging === true && this.options.hideEdgesOnDrag === false) && (this.zooming === false || this.zooming === true && this.options.hideEdgesOnZoom === false)) {
32436 this._drawArrows(ctx);
32437 }
32438 }
32439
32440 if (drawLater.drawExternalLabels != null) {
32441 drawLater.drawExternalLabels();
32442 }
32443
32444 if (hidden === false) {
32445 this._drawSelectionBox(ctx);
32446 }
32447
32448 ctx.beginPath();
32449 this.body.emitter.emit("afterDrawing", ctx);
32450 ctx.closePath(); // restore original scaling and translation
32451
32452 ctx.restore();
32453
32454 if (hidden === true) {
32455 ctx.clearRect(0, 0, w, h);
32456 }
32457 }
32458 }
32459 /**
32460 * Redraw all nodes
32461 *
32462 * @param {CanvasRenderingContext2D} ctx
32463 * @param {boolean} [alwaysShow]
32464 * @private
32465 */
32466
32467 }, {
32468 key: "_resizeNodes",
32469 value: function _resizeNodes() {
32470 this.canvas.setTransform();
32471 var ctx = this.canvas.getContext();
32472 ctx.save();
32473 ctx.translate(this.body.view.translation.x, this.body.view.translation.y);
32474 ctx.scale(this.body.view.scale, this.body.view.scale);
32475 var nodes = this.body.nodes;
32476 var node; // resize all nodes
32477
32478 for (var nodeId in nodes) {
32479 if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) {
32480 node = nodes[nodeId];
32481 node.resize(ctx);
32482 node.updateBoundingBox(ctx, node.selected);
32483 }
32484 } // restore original scaling and translation
32485
32486
32487 ctx.restore();
32488 }
32489 /**
32490 * Redraw all nodes
32491 *
32492 * @param {CanvasRenderingContext2D} ctx 2D context of a HTML canvas
32493 * @param {boolean} [alwaysShow]
32494 * @private
32495 *
32496 * @returns {object} Callbacks to draw later on higher layers.
32497 */
32498
32499 }, {
32500 key: "_drawNodes",
32501 value: function _drawNodes(ctx) {
32502 var alwaysShow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
32503 var nodes = this.body.nodes;
32504 var nodeIndices = this.body.nodeIndices;
32505 var node;
32506 var selected = [];
32507 var hovered = [];
32508 var margin = 20;
32509 var topLeft = this.canvas.DOMtoCanvas({
32510 x: -margin,
32511 y: -margin
32512 });
32513 var bottomRight = this.canvas.DOMtoCanvas({
32514 x: this.canvas.frame.canvas.clientWidth + margin,
32515 y: this.canvas.frame.canvas.clientHeight + margin
32516 });
32517 var viewableArea = {
32518 top: topLeft.y,
32519 left: topLeft.x,
32520 bottom: bottomRight.y,
32521 right: bottomRight.x
32522 };
32523 var _drawExternalLabels = []; // draw unselected nodes;
32524
32525 for (var _i = 0; _i < nodeIndices.length; _i++) {
32526 node = nodes[nodeIndices[_i]]; // set selected and hovered nodes aside
32527
32528 if (node.hover) {
32529 hovered.push(nodeIndices[_i]);
32530 } else if (node.isSelected()) {
32531 selected.push(nodeIndices[_i]);
32532 } else {
32533 if (alwaysShow === true) {
32534 var drawLater = node.draw(ctx);
32535
32536 if (drawLater.drawExternalLabel != null) {
32537 _drawExternalLabels.push(drawLater.drawExternalLabel);
32538 }
32539 } else if (node.isBoundingBoxOverlappingWith(viewableArea) === true) {
32540 var _drawLater = node.draw(ctx);
32541
32542 if (_drawLater.drawExternalLabel != null) {
32543 _drawExternalLabels.push(_drawLater.drawExternalLabel);
32544 }
32545 } else {
32546 node.updateBoundingBox(ctx, node.selected);
32547 }
32548 }
32549 }
32550
32551 var i;
32552 var selectedLength = selected.length;
32553 var hoveredLength = hovered.length; // draw the selected nodes on top
32554
32555 for (i = 0; i < selectedLength; i++) {
32556 node = nodes[selected[i]];
32557
32558 var _drawLater2 = node.draw(ctx);
32559
32560 if (_drawLater2.drawExternalLabel != null) {
32561 _drawExternalLabels.push(_drawLater2.drawExternalLabel);
32562 }
32563 } // draw hovered nodes above everything else: fixes https://github.com/visjs/vis-network/issues/226
32564
32565
32566 for (i = 0; i < hoveredLength; i++) {
32567 node = nodes[hovered[i]];
32568
32569 var _drawLater3 = node.draw(ctx);
32570
32571 if (_drawLater3.drawExternalLabel != null) {
32572 _drawExternalLabels.push(_drawLater3.drawExternalLabel);
32573 }
32574 }
32575
32576 return {
32577 drawExternalLabels: function drawExternalLabels() {
32578 var _iterator = _createForOfIteratorHelper$5(_drawExternalLabels),
32579 _step;
32580
32581 try {
32582 for (_iterator.s(); !(_step = _iterator.n()).done;) {
32583 var draw = _step.value;
32584 draw();
32585 }
32586 } catch (err) {
32587 _iterator.e(err);
32588 } finally {
32589 _iterator.f();
32590 }
32591 }
32592 };
32593 }
32594 /**
32595 * Redraw all edges
32596 *
32597 * @param {CanvasRenderingContext2D} ctx 2D context of a HTML canvas
32598 * @private
32599 */
32600
32601 }, {
32602 key: "_drawEdges",
32603 value: function _drawEdges(ctx) {
32604 var edges = this.body.edges;
32605 var edgeIndices = this.body.edgeIndices;
32606
32607 for (var i = 0; i < edgeIndices.length; i++) {
32608 var edge = edges[edgeIndices[i]];
32609
32610 if (edge.connected === true) {
32611 edge.draw(ctx);
32612 }
32613 }
32614 }
32615 /**
32616 * Redraw all arrows
32617 *
32618 * @param {CanvasRenderingContext2D} ctx 2D context of a HTML canvas
32619 * @private
32620 */
32621
32622 }, {
32623 key: "_drawArrows",
32624 value: function _drawArrows(ctx) {
32625 var edges = this.body.edges;
32626 var edgeIndices = this.body.edgeIndices;
32627
32628 for (var i = 0; i < edgeIndices.length; i++) {
32629 var edge = edges[edgeIndices[i]];
32630
32631 if (edge.connected === true) {
32632 edge.drawArrows(ctx);
32633 }
32634 }
32635 }
32636 /**
32637 * Determine if the browser requires a setTimeout or a requestAnimationFrame. This was required because
32638 * some implementations (safari and IE9) did not support requestAnimationFrame
32639 *
32640 * @private
32641 */
32642
32643 }, {
32644 key: "_determineBrowserMethod",
32645 value: function _determineBrowserMethod() {
32646 if (typeof window !== "undefined") {
32647 var browserType = navigator.userAgent.toLowerCase();
32648 this.requiresTimeout = false;
32649
32650 if (indexOf(browserType).call(browserType, "msie 9.0") != -1) {
32651 // IE 9
32652 this.requiresTimeout = true;
32653 } else if (indexOf(browserType).call(browserType, "safari") != -1) {
32654 // safari
32655 if (indexOf(browserType).call(browserType, "chrome") <= -1) {
32656 this.requiresTimeout = true;
32657 }
32658 }
32659 } else {
32660 this.requiresTimeout = true;
32661 }
32662 }
32663 /**
32664 * Redraw selection box
32665 *
32666 * @param {CanvasRenderingContext2D} ctx 2D context of a HTML canvas
32667 * @private
32668 */
32669
32670 }, {
32671 key: "_drawSelectionBox",
32672 value: function _drawSelectionBox(ctx) {
32673 if (this.body.selectionBox.show) {
32674 ctx.beginPath();
32675 var width = this.body.selectionBox.position.end.x - this.body.selectionBox.position.start.x;
32676 var height = this.body.selectionBox.position.end.y - this.body.selectionBox.position.start.y;
32677 ctx.rect(this.body.selectionBox.position.start.x, this.body.selectionBox.position.start.y, width, height);
32678 ctx.fillStyle = "rgba(151, 194, 252, 0.2)";
32679 ctx.fillRect(this.body.selectionBox.position.start.x, this.body.selectionBox.position.start.y, width, height);
32680 ctx.strokeStyle = "rgba(151, 194, 252, 1)";
32681 ctx.stroke();
32682 } else {
32683 ctx.closePath();
32684 }
32685 }
32686 }]);
32687
32688 return CanvasRenderer;
32689}();
32690
32691var path$1 = path$x;
32692var setInterval$1 = path$1.setInterval;
32693
32694var setInterval = setInterval$1;
32695
32696/**
32697 * Register a touch event, taking place before a gesture
32698 *
32699 * @param {Hammer} hammer A hammer instance
32700 * @param {Function} callback Callback, called as callback(event)
32701 */
32702function onTouch(hammer, callback) {
32703 callback.inputHandler = function (event) {
32704 if (event.isFirst) {
32705 callback(event);
32706 }
32707 };
32708
32709 hammer.on("hammer.input", callback.inputHandler);
32710}
32711/**
32712 * Register a release event, taking place after a gesture
32713 *
32714 * @param {Hammer} hammer A hammer instance
32715 * @param {Function} callback Callback, called as callback(event)
32716 * @returns {*}
32717 */
32718
32719function onRelease(hammer, callback) {
32720 callback.inputHandler = function (event) {
32721 if (event.isFinal) {
32722 callback(event);
32723 }
32724 };
32725
32726 return hammer.on("hammer.input", callback.inputHandler);
32727}
32728
32729/**
32730 * Create the main frame for the Network.
32731 * This function is executed once when a Network object is created. The frame
32732 * contains a canvas, and this canvas contains all objects like the axis and
32733 * nodes.
32734 */
32735
32736var Canvas = /*#__PURE__*/function () {
32737 /**
32738 * @param {object} body
32739 */
32740 function Canvas(body) {
32741 _classCallCheck(this, Canvas);
32742
32743 this.body = body;
32744 this.pixelRatio = 1;
32745 this.cameraState = {};
32746 this.initialized = false;
32747 this.canvasViewCenter = {};
32748 this._cleanupCallbacks = [];
32749 this.options = {};
32750 this.defaultOptions = {
32751 autoResize: true,
32752 height: "100%",
32753 width: "100%"
32754 };
32755
32756 assign$2(this.options, this.defaultOptions);
32757
32758 this.bindEventListeners();
32759 }
32760 /**
32761 * Binds event listeners
32762 */
32763
32764
32765 _createClass(Canvas, [{
32766 key: "bindEventListeners",
32767 value: function bindEventListeners() {
32768 var _this = this,
32769 _context;
32770
32771 // bind the events
32772 this.body.emitter.once("resize", function (obj) {
32773 if (obj.width !== 0) {
32774 _this.body.view.translation.x = obj.width * 0.5;
32775 }
32776
32777 if (obj.height !== 0) {
32778 _this.body.view.translation.y = obj.height * 0.5;
32779 }
32780 });
32781 this.body.emitter.on("setSize", bind$6(_context = this.setSize).call(_context, this));
32782 this.body.emitter.on("destroy", function () {
32783 _this.hammerFrame.destroy();
32784
32785 _this.hammer.destroy();
32786
32787 _this._cleanUp();
32788 });
32789 }
32790 /**
32791 * @param {object} options
32792 */
32793
32794 }, {
32795 key: "setOptions",
32796 value: function setOptions(options) {
32797 var _this2 = this;
32798
32799 if (options !== undefined) {
32800 var fields = ["width", "height", "autoResize"];
32801 selectiveDeepExtend(fields, this.options, options);
32802 } // Automatically adapt to changing size of the container element.
32803
32804
32805 this._cleanUp();
32806
32807 if (this.options.autoResize === true) {
32808 var _context2;
32809
32810 if (window.ResizeObserver) {
32811 // decent browsers, immediate reactions
32812 var observer = new ResizeObserver(function () {
32813 var changed = _this2.setSize();
32814
32815 if (changed === true) {
32816 _this2.body.emitter.emit("_requestRedraw");
32817 }
32818 });
32819 var frame = this.frame;
32820 observer.observe(frame);
32821
32822 this._cleanupCallbacks.push(function () {
32823 observer.unobserve(frame);
32824 });
32825 } else {
32826 // IE11, continous polling
32827 var resizeTimer = setInterval(function () {
32828 var changed = _this2.setSize();
32829
32830 if (changed === true) {
32831 _this2.body.emitter.emit("_requestRedraw");
32832 }
32833 }, 1000);
32834
32835 this._cleanupCallbacks.push(function () {
32836 clearInterval(resizeTimer);
32837 });
32838 } // Automatically adapt to changing size of the browser.
32839
32840
32841 var resizeFunction = bind$6(_context2 = this._onResize).call(_context2, this);
32842
32843 addEventListener(window, "resize", resizeFunction);
32844
32845 this._cleanupCallbacks.push(function () {
32846 removeEventListener(window, "resize", resizeFunction);
32847 });
32848 }
32849 }
32850 /**
32851 * @private
32852 */
32853
32854 }, {
32855 key: "_cleanUp",
32856 value: function _cleanUp() {
32857 var _context3, _context4, _context5;
32858
32859 forEach$2(_context3 = reverse(_context4 = splice(_context5 = this._cleanupCallbacks).call(_context5, 0)).call(_context4)).call(_context3, function (callback) {
32860 try {
32861 callback();
32862 } catch (error) {
32863 console.error(error);
32864 }
32865 });
32866 }
32867 /**
32868 * @private
32869 */
32870
32871 }, {
32872 key: "_onResize",
32873 value: function _onResize() {
32874 this.setSize();
32875 this.body.emitter.emit("_redraw");
32876 }
32877 /**
32878 * Get and store the cameraState
32879 *
32880 * @param {number} [pixelRatio=this.pixelRatio]
32881 * @private
32882 */
32883
32884 }, {
32885 key: "_getCameraState",
32886 value: function _getCameraState() {
32887 var pixelRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.pixelRatio;
32888
32889 if (this.initialized === true) {
32890 this.cameraState.previousWidth = this.frame.canvas.width / pixelRatio;
32891 this.cameraState.previousHeight = this.frame.canvas.height / pixelRatio;
32892 this.cameraState.scale = this.body.view.scale;
32893 this.cameraState.position = this.DOMtoCanvas({
32894 x: 0.5 * this.frame.canvas.width / pixelRatio,
32895 y: 0.5 * this.frame.canvas.height / pixelRatio
32896 });
32897 }
32898 }
32899 /**
32900 * Set the cameraState
32901 *
32902 * @private
32903 */
32904
32905 }, {
32906 key: "_setCameraState",
32907 value: function _setCameraState() {
32908 if (this.cameraState.scale !== undefined && this.frame.canvas.clientWidth !== 0 && this.frame.canvas.clientHeight !== 0 && this.pixelRatio !== 0 && this.cameraState.previousWidth > 0 && this.cameraState.previousHeight > 0) {
32909 var widthRatio = this.frame.canvas.width / this.pixelRatio / this.cameraState.previousWidth;
32910 var heightRatio = this.frame.canvas.height / this.pixelRatio / this.cameraState.previousHeight;
32911 var newScale = this.cameraState.scale;
32912
32913 if (widthRatio != 1 && heightRatio != 1) {
32914 newScale = this.cameraState.scale * 0.5 * (widthRatio + heightRatio);
32915 } else if (widthRatio != 1) {
32916 newScale = this.cameraState.scale * widthRatio;
32917 } else if (heightRatio != 1) {
32918 newScale = this.cameraState.scale * heightRatio;
32919 }
32920
32921 this.body.view.scale = newScale; // this comes from the view module.
32922
32923 var currentViewCenter = this.DOMtoCanvas({
32924 x: 0.5 * this.frame.canvas.clientWidth,
32925 y: 0.5 * this.frame.canvas.clientHeight
32926 });
32927 var distanceFromCenter = {
32928 // offset from view, distance view has to change by these x and y to center the node
32929 x: currentViewCenter.x - this.cameraState.position.x,
32930 y: currentViewCenter.y - this.cameraState.position.y
32931 };
32932 this.body.view.translation.x += distanceFromCenter.x * this.body.view.scale;
32933 this.body.view.translation.y += distanceFromCenter.y * this.body.view.scale;
32934 }
32935 }
32936 /**
32937 *
32938 * @param {number|string} value
32939 * @returns {string}
32940 * @private
32941 */
32942
32943 }, {
32944 key: "_prepareValue",
32945 value: function _prepareValue(value) {
32946 if (typeof value === "number") {
32947 return value + "px";
32948 } else if (typeof value === "string") {
32949 if (indexOf(value).call(value, "%") !== -1 || indexOf(value).call(value, "px") !== -1) {
32950 return value;
32951 } else if (indexOf(value).call(value, "%") === -1) {
32952 return value + "px";
32953 }
32954 }
32955
32956 throw new Error("Could not use the value supplied for width or height:" + value);
32957 }
32958 /**
32959 * Create the HTML
32960 */
32961
32962 }, {
32963 key: "_create",
32964 value: function _create() {
32965 // remove all elements from the container element.
32966 while (this.body.container.hasChildNodes()) {
32967 this.body.container.removeChild(this.body.container.firstChild);
32968 }
32969
32970 this.frame = document.createElement("div");
32971 this.frame.className = "vis-network";
32972 this.frame.style.position = "relative";
32973 this.frame.style.overflow = "hidden";
32974 this.frame.tabIndex = 0; // tab index is required for keycharm to bind keystrokes to the div instead of the window
32975 //////////////////////////////////////////////////////////////////
32976
32977 this.frame.canvas = document.createElement("canvas");
32978 this.frame.canvas.style.position = "relative";
32979 this.frame.appendChild(this.frame.canvas);
32980
32981 if (!this.frame.canvas.getContext) {
32982 var noCanvas = document.createElement("DIV");
32983 noCanvas.style.color = "red";
32984 noCanvas.style.fontWeight = "bold";
32985 noCanvas.style.padding = "10px";
32986 noCanvas.innerText = "Error: your browser does not support HTML canvas";
32987 this.frame.canvas.appendChild(noCanvas);
32988 } else {
32989 this._setPixelRatio();
32990
32991 this.setTransform();
32992 } // add the frame to the container element
32993
32994
32995 this.body.container.appendChild(this.frame);
32996 this.body.view.scale = 1;
32997 this.body.view.translation = {
32998 x: 0.5 * this.frame.canvas.clientWidth,
32999 y: 0.5 * this.frame.canvas.clientHeight
33000 };
33001
33002 this._bindHammer();
33003 }
33004 /**
33005 * This function binds hammer, it can be repeated over and over due to the uniqueness check.
33006 *
33007 * @private
33008 */
33009
33010 }, {
33011 key: "_bindHammer",
33012 value: function _bindHammer() {
33013 var _this3 = this;
33014
33015 if (this.hammer !== undefined) {
33016 this.hammer.destroy();
33017 }
33018
33019 this.drag = {};
33020 this.pinch = {}; // init hammer
33021
33022 this.hammer = new Hammer$1(this.frame.canvas);
33023 this.hammer.get("pinch").set({
33024 enable: true
33025 }); // enable to get better response, todo: test on mobile.
33026
33027 this.hammer.get("pan").set({
33028 threshold: 5,
33029 direction: Hammer$1.DIRECTION_ALL
33030 });
33031 onTouch(this.hammer, function (event) {
33032 _this3.body.eventListeners.onTouch(event);
33033 });
33034 this.hammer.on("tap", function (event) {
33035 _this3.body.eventListeners.onTap(event);
33036 });
33037 this.hammer.on("doubletap", function (event) {
33038 _this3.body.eventListeners.onDoubleTap(event);
33039 });
33040 this.hammer.on("press", function (event) {
33041 _this3.body.eventListeners.onHold(event);
33042 });
33043 this.hammer.on("panstart", function (event) {
33044 _this3.body.eventListeners.onDragStart(event);
33045 });
33046 this.hammer.on("panmove", function (event) {
33047 _this3.body.eventListeners.onDrag(event);
33048 });
33049 this.hammer.on("panend", function (event) {
33050 _this3.body.eventListeners.onDragEnd(event);
33051 });
33052 this.hammer.on("pinch", function (event) {
33053 _this3.body.eventListeners.onPinch(event);
33054 }); // TODO: neatly cleanup these handlers when re-creating the Canvas, IF these are done with hammer, event.stopPropagation will not work?
33055
33056 this.frame.canvas.addEventListener("wheel", function (event) {
33057 _this3.body.eventListeners.onMouseWheel(event);
33058 });
33059 this.frame.canvas.addEventListener("mousemove", function (event) {
33060 _this3.body.eventListeners.onMouseMove(event);
33061 });
33062 this.frame.canvas.addEventListener("contextmenu", function (event) {
33063 _this3.body.eventListeners.onContext(event);
33064 });
33065 this.hammerFrame = new Hammer$1(this.frame);
33066 onRelease(this.hammerFrame, function (event) {
33067 _this3.body.eventListeners.onRelease(event);
33068 });
33069 }
33070 /**
33071 * Set a new size for the network
33072 *
33073 * @param {string} width Width in pixels or percentage (for example '800px'
33074 * or '50%')
33075 * @param {string} height Height in pixels or percentage (for example '400px'
33076 * or '30%')
33077 * @returns {boolean}
33078 */
33079
33080 }, {
33081 key: "setSize",
33082 value: function setSize() {
33083 var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.width;
33084 var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.height;
33085 width = this._prepareValue(width);
33086 height = this._prepareValue(height);
33087 var emitEvent = false;
33088 var oldWidth = this.frame.canvas.width;
33089 var oldHeight = this.frame.canvas.height; // update the pixel ratio
33090 //
33091 // NOTE: Comment in following is rather inconsistent; this is the ONLY place in the code
33092 // where it is assumed that the pixel ratio could change at runtime.
33093 // The only way I can think of this happening is a rotating screen or tablet; but then
33094 // there should be a mechanism for reloading the data (TODO: check if this is present).
33095 //
33096 // If the assumption is true (i.e. pixel ratio can change at runtime), then *all* usage
33097 // of pixel ratio must be overhauled for this.
33098 //
33099 // For the time being, I will humor the assumption here, and in the rest of the code assume it is
33100 // constant.
33101
33102 var previousRatio = this.pixelRatio; // we cache this because the camera state storage needs the old value
33103
33104 this._setPixelRatio();
33105
33106 if (width != this.options.width || height != this.options.height || this.frame.style.width != width || this.frame.style.height != height) {
33107 this._getCameraState(previousRatio);
33108
33109 this.frame.style.width = width;
33110 this.frame.style.height = height;
33111 this.frame.canvas.style.width = "100%";
33112 this.frame.canvas.style.height = "100%";
33113 this.frame.canvas.width = Math.round(this.frame.canvas.clientWidth * this.pixelRatio);
33114 this.frame.canvas.height = Math.round(this.frame.canvas.clientHeight * this.pixelRatio);
33115 this.options.width = width;
33116 this.options.height = height;
33117 this.canvasViewCenter = {
33118 x: 0.5 * this.frame.clientWidth,
33119 y: 0.5 * this.frame.clientHeight
33120 };
33121 emitEvent = true;
33122 } else {
33123 // this would adapt the width of the canvas to the width from 100% if and only if
33124 // there is a change.
33125 var newWidth = Math.round(this.frame.canvas.clientWidth * this.pixelRatio);
33126 var newHeight = Math.round(this.frame.canvas.clientHeight * this.pixelRatio); // store the camera if there is a change in size.
33127
33128 if (this.frame.canvas.width !== newWidth || this.frame.canvas.height !== newHeight) {
33129 this._getCameraState(previousRatio);
33130 }
33131
33132 if (this.frame.canvas.width !== newWidth) {
33133 this.frame.canvas.width = newWidth;
33134 emitEvent = true;
33135 }
33136
33137 if (this.frame.canvas.height !== newHeight) {
33138 this.frame.canvas.height = newHeight;
33139 emitEvent = true;
33140 }
33141 }
33142
33143 if (emitEvent === true) {
33144 this.body.emitter.emit("resize", {
33145 width: Math.round(this.frame.canvas.width / this.pixelRatio),
33146 height: Math.round(this.frame.canvas.height / this.pixelRatio),
33147 oldWidth: Math.round(oldWidth / this.pixelRatio),
33148 oldHeight: Math.round(oldHeight / this.pixelRatio)
33149 }); // restore the camera on change.
33150
33151 this._setCameraState();
33152 } // set initialized so the get and set camera will work from now on.
33153
33154
33155 this.initialized = true;
33156 return emitEvent;
33157 }
33158 /**
33159 *
33160 * @returns {CanvasRenderingContext2D}
33161 */
33162
33163 }, {
33164 key: "getContext",
33165 value: function getContext() {
33166 return this.frame.canvas.getContext("2d");
33167 }
33168 /**
33169 * Determine the pixel ratio for various browsers.
33170 *
33171 * @returns {number}
33172 * @private
33173 */
33174
33175 }, {
33176 key: "_determinePixelRatio",
33177 value: function _determinePixelRatio() {
33178 var ctx = this.getContext();
33179
33180 if (ctx === undefined) {
33181 throw new Error("Could not get canvax context");
33182 }
33183
33184 var numerator = 1;
33185
33186 if (typeof window !== "undefined") {
33187 // (window !== undefined) doesn't work here!
33188 // Protection during unit tests, where 'window' can be missing
33189 numerator = window.devicePixelRatio || 1;
33190 }
33191
33192 var denominator = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
33193 return numerator / denominator;
33194 }
33195 /**
33196 * Lazy determination of pixel ratio.
33197 *
33198 * @private
33199 */
33200
33201 }, {
33202 key: "_setPixelRatio",
33203 value: function _setPixelRatio() {
33204 this.pixelRatio = this._determinePixelRatio();
33205 }
33206 /**
33207 * Set the transform in the contained context, based on its pixelRatio
33208 */
33209
33210 }, {
33211 key: "setTransform",
33212 value: function setTransform() {
33213 var ctx = this.getContext();
33214
33215 if (ctx === undefined) {
33216 throw new Error("Could not get canvax context");
33217 }
33218
33219 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
33220 }
33221 /**
33222 * Convert the X coordinate in DOM-space (coordinate point in browser relative to the container div) to
33223 * the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon)
33224 *
33225 * @param {number} x
33226 * @returns {number}
33227 * @private
33228 */
33229
33230 }, {
33231 key: "_XconvertDOMtoCanvas",
33232 value: function _XconvertDOMtoCanvas(x) {
33233 return (x - this.body.view.translation.x) / this.body.view.scale;
33234 }
33235 /**
33236 * Convert the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to
33237 * the X coordinate in DOM-space (coordinate point in browser relative to the container div)
33238 *
33239 * @param {number} x
33240 * @returns {number}
33241 * @private
33242 */
33243
33244 }, {
33245 key: "_XconvertCanvasToDOM",
33246 value: function _XconvertCanvasToDOM(x) {
33247 return x * this.body.view.scale + this.body.view.translation.x;
33248 }
33249 /**
33250 * Convert the Y coordinate in DOM-space (coordinate point in browser relative to the container div) to
33251 * the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon)
33252 *
33253 * @param {number} y
33254 * @returns {number}
33255 * @private
33256 */
33257
33258 }, {
33259 key: "_YconvertDOMtoCanvas",
33260 value: function _YconvertDOMtoCanvas(y) {
33261 return (y - this.body.view.translation.y) / this.body.view.scale;
33262 }
33263 /**
33264 * Convert the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to
33265 * the Y coordinate in DOM-space (coordinate point in browser relative to the container div)
33266 *
33267 * @param {number} y
33268 * @returns {number}
33269 * @private
33270 */
33271
33272 }, {
33273 key: "_YconvertCanvasToDOM",
33274 value: function _YconvertCanvasToDOM(y) {
33275 return y * this.body.view.scale + this.body.view.translation.y;
33276 }
33277 /**
33278 * @param {point} pos
33279 * @returns {point}
33280 */
33281
33282 }, {
33283 key: "canvasToDOM",
33284 value: function canvasToDOM(pos) {
33285 return {
33286 x: this._XconvertCanvasToDOM(pos.x),
33287 y: this._YconvertCanvasToDOM(pos.y)
33288 };
33289 }
33290 /**
33291 *
33292 * @param {point} pos
33293 * @returns {point}
33294 */
33295
33296 }, {
33297 key: "DOMtoCanvas",
33298 value: function DOMtoCanvas(pos) {
33299 return {
33300 x: this._XconvertDOMtoCanvas(pos.x),
33301 y: this._YconvertDOMtoCanvas(pos.y)
33302 };
33303 }
33304 }]);
33305
33306 return Canvas;
33307}();
33308
33309/**
33310 * Validate the fit options, replace missing optional values by defaults etc.
33311 *
33312 * @param rawOptions - The raw options.
33313 * @param allNodeIds - All node ids that will be used if nodes are omitted in
33314 * the raw options.
33315 *
33316 * @returns Options with everything filled in and validated.
33317 */
33318function normalizeFitOptions(rawOptions, allNodeIds) {
33319 var options = assign$2({
33320 nodes: allNodeIds,
33321 minZoomLevel: Number.MIN_VALUE,
33322 maxZoomLevel: 1
33323 }, rawOptions !== null && rawOptions !== void 0 ? rawOptions : {});
33324
33325 if (!isArray$2(options.nodes)) {
33326 throw new TypeError("Nodes has to be an array of ids.");
33327 }
33328
33329 if (options.nodes.length === 0) {
33330 options.nodes = allNodeIds;
33331 }
33332
33333 if (!(typeof options.minZoomLevel === "number" && options.minZoomLevel > 0)) {
33334 throw new TypeError("Min zoom level has to be a number higher than zero.");
33335 }
33336
33337 if (!(typeof options.maxZoomLevel === "number" && options.minZoomLevel <= options.maxZoomLevel)) {
33338 throw new TypeError("Max zoom level has to be a number higher than min zoom level.");
33339 }
33340
33341 return options;
33342}
33343
33344/**
33345 * The view
33346 */
33347
33348var View = /*#__PURE__*/function () {
33349 /**
33350 * @param {object} body
33351 * @param {Canvas} canvas
33352 */
33353 function View(body, canvas) {
33354 var _context,
33355 _this = this,
33356 _context2;
33357
33358 _classCallCheck(this, View);
33359
33360 this.body = body;
33361 this.canvas = canvas;
33362 this.animationSpeed = 1 / this.renderRefreshRate;
33363 this.animationEasingFunction = "easeInOutQuint";
33364 this.easingTime = 0;
33365 this.sourceScale = 0;
33366 this.targetScale = 0;
33367 this.sourceTranslation = 0;
33368 this.targetTranslation = 0;
33369 this.lockedOnNodeId = undefined;
33370 this.lockedOnNodeOffset = undefined;
33371 this.touchTime = 0;
33372 this.viewFunction = undefined;
33373 this.body.emitter.on("fit", bind$6(_context = this.fit).call(_context, this));
33374 this.body.emitter.on("animationFinished", function () {
33375 _this.body.emitter.emit("_stopRendering");
33376 });
33377 this.body.emitter.on("unlockNode", bind$6(_context2 = this.releaseNode).call(_context2, this));
33378 }
33379 /**
33380 *
33381 * @param {object} [options={}]
33382 */
33383
33384
33385 _createClass(View, [{
33386 key: "setOptions",
33387 value: function setOptions() {
33388 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
33389 this.options = options;
33390 }
33391 /**
33392 * This function zooms out to fit all data on screen based on amount of nodes
33393 *
33394 * @param {object} [options={{nodes=Array}}]
33395 * @param options
33396 * @param {boolean} [initialZoom=false] | zoom based on fitted formula or range, true = fitted, default = false;
33397 */
33398
33399 }, {
33400 key: "fit",
33401 value: function fit(options) {
33402 var initialZoom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
33403 options = normalizeFitOptions(options, this.body.nodeIndices);
33404 var canvasWidth = this.canvas.frame.canvas.clientWidth;
33405 var canvasHeight = this.canvas.frame.canvas.clientHeight;
33406 var range;
33407 var zoomLevel;
33408
33409 if (canvasWidth === 0 || canvasHeight === 0) {
33410 // There's no point in trying to fit into zero sized canvas. This could
33411 // potentially even result in invalid values being computed. For example
33412 // for network without nodes and zero sized canvas the zoom level would
33413 // end up being computed as 0/0 which results in NaN. In any other case
33414 // this would be 0/something which is again pointless to compute.
33415 zoomLevel = 1;
33416 range = NetworkUtil.getRange(this.body.nodes, options.nodes);
33417 } else if (initialZoom === true) {
33418 // check if more than half of the nodes have a predefined position. If so, we use the range, not the approximation.
33419 var positionDefined = 0;
33420
33421 for (var nodeId in this.body.nodes) {
33422 if (Object.prototype.hasOwnProperty.call(this.body.nodes, nodeId)) {
33423 var node = this.body.nodes[nodeId];
33424
33425 if (node.predefinedPosition === true) {
33426 positionDefined += 1;
33427 }
33428 }
33429 }
33430
33431 if (positionDefined > 0.5 * this.body.nodeIndices.length) {
33432 this.fit(options, false);
33433 return;
33434 }
33435
33436 range = NetworkUtil.getRange(this.body.nodes, options.nodes);
33437 var numberOfNodes = this.body.nodeIndices.length;
33438 zoomLevel = 12.662 / (numberOfNodes + 7.4147) + 0.0964822; // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
33439 // correct for larger canvasses.
33440
33441 var factor = Math.min(canvasWidth / 600, canvasHeight / 600);
33442 zoomLevel *= factor;
33443 } else {
33444 this.body.emitter.emit("_resizeNodes");
33445 range = NetworkUtil.getRange(this.body.nodes, options.nodes);
33446 var xDistance = Math.abs(range.maxX - range.minX) * 1.1;
33447 var yDistance = Math.abs(range.maxY - range.minY) * 1.1;
33448 var xZoomLevel = canvasWidth / xDistance;
33449 var yZoomLevel = canvasHeight / yDistance;
33450 zoomLevel = xZoomLevel <= yZoomLevel ? xZoomLevel : yZoomLevel;
33451 }
33452
33453 if (zoomLevel > options.maxZoomLevel) {
33454 zoomLevel = options.maxZoomLevel;
33455 } else if (zoomLevel < options.minZoomLevel) {
33456 zoomLevel = options.minZoomLevel;
33457 }
33458
33459 var center = NetworkUtil.findCenter(range);
33460 var animationOptions = {
33461 position: center,
33462 scale: zoomLevel,
33463 animation: options.animation
33464 };
33465 this.moveTo(animationOptions);
33466 } // animation
33467
33468 /**
33469 * Center a node in view.
33470 *
33471 * @param {number} nodeId
33472 * @param {number} [options]
33473 */
33474
33475 }, {
33476 key: "focus",
33477 value: function focus(nodeId) {
33478 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
33479
33480 if (this.body.nodes[nodeId] !== undefined) {
33481 var nodePosition = {
33482 x: this.body.nodes[nodeId].x,
33483 y: this.body.nodes[nodeId].y
33484 };
33485 options.position = nodePosition;
33486 options.lockedOnNode = nodeId;
33487 this.moveTo(options);
33488 } else {
33489 console.error("Node: " + nodeId + " cannot be found.");
33490 }
33491 }
33492 /**
33493 *
33494 * @param {object} options | options.offset = {x:number, y:number} // offset from the center in DOM pixels
33495 * | options.scale = number // scale to move to
33496 * | options.position = {x:number, y:number} // position to move to
33497 * | options.animation = {duration:number, easingFunction:String} || Boolean // position to move to
33498 */
33499
33500 }, {
33501 key: "moveTo",
33502 value: function moveTo(options) {
33503 if (options === undefined) {
33504 options = {};
33505 return;
33506 }
33507
33508 if (options.offset != null) {
33509 if (options.offset.x != null) {
33510 // Coerce and verify that x is valid.
33511 options.offset.x = +options.offset.x;
33512
33513 if (!_isFinite(options.offset.x)) {
33514 throw new TypeError('The option "offset.x" has to be a finite number.');
33515 }
33516 } else {
33517 options.offset.x = 0;
33518 }
33519
33520 if (options.offset.y != null) {
33521 // Coerce and verify that y is valid.
33522 options.offset.y = +options.offset.y;
33523
33524 if (!_isFinite(options.offset.y)) {
33525 throw new TypeError('The option "offset.y" has to be a finite number.');
33526 }
33527 } else {
33528 options.offset.x = 0;
33529 }
33530 } else {
33531 options.offset = {
33532 x: 0,
33533 y: 0
33534 };
33535 }
33536
33537 if (options.position != null) {
33538 if (options.position.x != null) {
33539 // Coerce and verify that x is valid.
33540 options.position.x = +options.position.x;
33541
33542 if (!_isFinite(options.position.x)) {
33543 throw new TypeError('The option "position.x" has to be a finite number.');
33544 }
33545 } else {
33546 options.position.x = 0;
33547 }
33548
33549 if (options.position.y != null) {
33550 // Coerce and verify that y is valid.
33551 options.position.y = +options.position.y;
33552
33553 if (!_isFinite(options.position.y)) {
33554 throw new TypeError('The option "position.y" has to be a finite number.');
33555 }
33556 } else {
33557 options.position.x = 0;
33558 }
33559 } else {
33560 options.position = this.getViewPosition();
33561 }
33562
33563 if (options.scale != null) {
33564 // Coerce and verify that the scale is valid.
33565 options.scale = +options.scale;
33566
33567 if (!(options.scale > 0)) {
33568 throw new TypeError('The option "scale" has to be a number greater than zero.');
33569 }
33570 } else {
33571 options.scale = this.body.view.scale;
33572 }
33573
33574 if (options.animation === undefined) {
33575 options.animation = {
33576 duration: 0
33577 };
33578 }
33579
33580 if (options.animation === false) {
33581 options.animation = {
33582 duration: 0
33583 };
33584 }
33585
33586 if (options.animation === true) {
33587 options.animation = {};
33588 }
33589
33590 if (options.animation.duration === undefined) {
33591 options.animation.duration = 1000;
33592 } // default duration
33593
33594
33595 if (options.animation.easingFunction === undefined) {
33596 options.animation.easingFunction = "easeInOutQuad";
33597 } // default easing function
33598
33599
33600 this.animateView(options);
33601 }
33602 /**
33603 *
33604 * @param {object} options | options.offset = {x:number, y:number} // offset from the center in DOM pixels
33605 * | options.time = number // animation time in milliseconds
33606 * | options.scale = number // scale to animate to
33607 * | options.position = {x:number, y:number} // position to animate to
33608 * | options.easingFunction = String // linear, easeInQuad, easeOutQuad, easeInOutQuad,
33609 * // easeInCubic, easeOutCubic, easeInOutCubic,
33610 * // easeInQuart, easeOutQuart, easeInOutQuart,
33611 * // easeInQuint, easeOutQuint, easeInOutQuint
33612 */
33613
33614 }, {
33615 key: "animateView",
33616 value: function animateView(options) {
33617 if (options === undefined) {
33618 return;
33619 }
33620
33621 this.animationEasingFunction = options.animation.easingFunction; // release if something focussed on the node
33622
33623 this.releaseNode();
33624
33625 if (options.locked === true) {
33626 this.lockedOnNodeId = options.lockedOnNode;
33627 this.lockedOnNodeOffset = options.offset;
33628 } // forcefully complete the old animation if it was still running
33629
33630
33631 if (this.easingTime != 0) {
33632 this._transitionRedraw(true); // by setting easingtime to 1, we finish the animation.
33633
33634 }
33635
33636 this.sourceScale = this.body.view.scale;
33637 this.sourceTranslation = this.body.view.translation;
33638 this.targetScale = options.scale; // set the scale so the viewCenter is based on the correct zoom level. This is overridden in the transitionRedraw
33639 // but at least then we'll have the target transition
33640
33641 this.body.view.scale = this.targetScale;
33642 var viewCenter = this.canvas.DOMtoCanvas({
33643 x: 0.5 * this.canvas.frame.canvas.clientWidth,
33644 y: 0.5 * this.canvas.frame.canvas.clientHeight
33645 });
33646 var distanceFromCenter = {
33647 // offset from view, distance view has to change by these x and y to center the node
33648 x: viewCenter.x - options.position.x,
33649 y: viewCenter.y - options.position.y
33650 };
33651 this.targetTranslation = {
33652 x: this.sourceTranslation.x + distanceFromCenter.x * this.targetScale + options.offset.x,
33653 y: this.sourceTranslation.y + distanceFromCenter.y * this.targetScale + options.offset.y
33654 }; // if the time is set to 0, don't do an animation
33655
33656 if (options.animation.duration === 0) {
33657 if (this.lockedOnNodeId != undefined) {
33658 var _context3;
33659
33660 this.viewFunction = bind$6(_context3 = this._lockedRedraw).call(_context3, this);
33661 this.body.emitter.on("initRedraw", this.viewFunction);
33662 } else {
33663 this.body.view.scale = this.targetScale;
33664 this.body.view.translation = this.targetTranslation;
33665 this.body.emitter.emit("_requestRedraw");
33666 }
33667 } else {
33668 var _context4;
33669
33670 this.animationSpeed = 1 / (60 * options.animation.duration * 0.001) || 1 / 60; // 60 for 60 seconds, 0.001 for milli's
33671
33672 this.animationEasingFunction = options.animation.easingFunction;
33673 this.viewFunction = bind$6(_context4 = this._transitionRedraw).call(_context4, this);
33674 this.body.emitter.on("initRedraw", this.viewFunction);
33675 this.body.emitter.emit("_startRendering");
33676 }
33677 }
33678 /**
33679 * used to animate smoothly by hijacking the redraw function.
33680 *
33681 * @private
33682 */
33683
33684 }, {
33685 key: "_lockedRedraw",
33686 value: function _lockedRedraw() {
33687 var nodePosition = {
33688 x: this.body.nodes[this.lockedOnNodeId].x,
33689 y: this.body.nodes[this.lockedOnNodeId].y
33690 };
33691 var viewCenter = this.canvas.DOMtoCanvas({
33692 x: 0.5 * this.canvas.frame.canvas.clientWidth,
33693 y: 0.5 * this.canvas.frame.canvas.clientHeight
33694 });
33695 var distanceFromCenter = {
33696 // offset from view, distance view has to change by these x and y to center the node
33697 x: viewCenter.x - nodePosition.x,
33698 y: viewCenter.y - nodePosition.y
33699 };
33700 var sourceTranslation = this.body.view.translation;
33701 var targetTranslation = {
33702 x: sourceTranslation.x + distanceFromCenter.x * this.body.view.scale + this.lockedOnNodeOffset.x,
33703 y: sourceTranslation.y + distanceFromCenter.y * this.body.view.scale + this.lockedOnNodeOffset.y
33704 };
33705 this.body.view.translation = targetTranslation;
33706 }
33707 /**
33708 * Resets state of a locked on Node
33709 */
33710
33711 }, {
33712 key: "releaseNode",
33713 value: function releaseNode() {
33714 if (this.lockedOnNodeId !== undefined && this.viewFunction !== undefined) {
33715 this.body.emitter.off("initRedraw", this.viewFunction);
33716 this.lockedOnNodeId = undefined;
33717 this.lockedOnNodeOffset = undefined;
33718 }
33719 }
33720 /**
33721 * @param {boolean} [finished=false]
33722 * @private
33723 */
33724
33725 }, {
33726 key: "_transitionRedraw",
33727 value: function _transitionRedraw() {
33728 var finished = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
33729 this.easingTime += this.animationSpeed;
33730 this.easingTime = finished === true ? 1.0 : this.easingTime;
33731 var progress = easingFunctions[this.animationEasingFunction](this.easingTime);
33732 this.body.view.scale = this.sourceScale + (this.targetScale - this.sourceScale) * progress;
33733 this.body.view.translation = {
33734 x: this.sourceTranslation.x + (this.targetTranslation.x - this.sourceTranslation.x) * progress,
33735 y: this.sourceTranslation.y + (this.targetTranslation.y - this.sourceTranslation.y) * progress
33736 }; // cleanup
33737
33738 if (this.easingTime >= 1.0) {
33739 this.body.emitter.off("initRedraw", this.viewFunction);
33740 this.easingTime = 0;
33741
33742 if (this.lockedOnNodeId != undefined) {
33743 var _context5;
33744
33745 this.viewFunction = bind$6(_context5 = this._lockedRedraw).call(_context5, this);
33746 this.body.emitter.on("initRedraw", this.viewFunction);
33747 }
33748
33749 this.body.emitter.emit("animationFinished");
33750 }
33751 }
33752 /**
33753 *
33754 * @returns {number}
33755 */
33756
33757 }, {
33758 key: "getScale",
33759 value: function getScale() {
33760 return this.body.view.scale;
33761 }
33762 /**
33763 *
33764 * @returns {{x: number, y: number}}
33765 */
33766
33767 }, {
33768 key: "getViewPosition",
33769 value: function getViewPosition() {
33770 return this.canvas.DOMtoCanvas({
33771 x: 0.5 * this.canvas.frame.canvas.clientWidth,
33772 y: 0.5 * this.canvas.frame.canvas.clientHeight
33773 });
33774 }
33775 }]);
33776
33777 return View;
33778}();
33779
33780var css_248z$1 = "div.vis-network div.vis-navigation div.vis-button {\n width: 34px;\n height: 34px;\n -moz-border-radius: 17px;\n border-radius: 17px;\n position: absolute;\n display: inline-block;\n background-position: 2px 2px;\n background-repeat: no-repeat;\n cursor: pointer;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\ndiv.vis-network div.vis-navigation div.vis-button:hover {\n box-shadow: 0 0 3px 3px rgba(56, 207, 21, 0.3);\n}\n\ndiv.vis-network div.vis-navigation div.vis-button:active {\n box-shadow: 0 0 1px 3px rgba(56, 207, 21, 0.95);\n}\n\ndiv.vis-network div.vis-navigation div.vis-button.vis-up {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABphJREFUeNqcV2twU9cR/nbPlVTHxpKRbNnBLyEbPyJisLEcPwgwUMKQtjNJAzNJZkgNNJOmJaZAaDKlxaXDTIBAcJtOOzSYKSkdiimhAdIMjyT4bYgBYxA2BgcUQPLrCiGDR4qt2x+yXTASFt1/957d7zt3z3d39xDCMQWUfgAz/RI/T4pSTAJpAGL8rECAXX7QFQGq9wOHOxYO1oCgjAdJj1wtB095Giv9TFuZAIWHAziATMPhTAwiHgUkYPXFJu92lMP/2MTpB1AKUCVEgNAcleUo1M+2F8TO6crSTncb1QleAOj2OTSX3Ge1p+Va42m5JrnzbnsCE8Ov+EHgpa0LPLvCJjZ/whuIlN8wAcXG+e1LUn9hm238QU84p1Ld83nsXvuO7Lq+LzKYGAT6/dn58m/HJTYf4O3EShkT8Irpzab1Uz9sGevT5+tWn+j6NB4A5hp/5NSr43xjfd5rW5tT9e3OAhCBiCua5/WsDEls/hdvYklZSwDefmrT8eXmtzuDkb5YZ33p9ndylICAVjWxf39xw/5g5Luv/9H84ZWNcwNEypZT87rXjqyJB85UYDMJYN3U7UdLJ6/6JlgqV517teRqf9uTlug8e1zEk27HgD22o98WsTBh8fWxvjm6ApdONbGvse8LM5NUPOm1Cfabuz3nACAgxX0QEFTJAnjNvLJ+Sepb14KRHnN+Ev+1XJOhZs3Qu1mbG97J2NQgsXroa1dtxrGuf8cHi1mUtPTay0lv1DMJSCRVLtoX+FgGgDQNysBAcez89l9nbbsQSji7rlXkEhjPxb/QatHOcFu0M9zz419oFSRhj/3PuaHiyqasv1Con9NGxHAYUsoCxAqImbYSgCWmFbZQwdsur7N0eC4m6tT6/jUZ750Zeb82c+OZGLWh/2p/W+Kfrmy0hIp/aVKpTSIJEqu2QgFx2iE8CwDp0RbH7Ljng/4yXr+XT3QdyhYsodS0slGr0g2OrEUK7eCrKW82SqzCVz3/yfb6vRwM4xn9rN7JkRkOQRLmfJn2LBPxQjDBqp9lD7XbX7X8pKTP160zR2bdeiX5jYeU/nLSTztNkem3XL5eXbltRUkonBxdgZ2IIUmahUxERQSCVT+rK5hzQ89xQ6P8VaaK1f5VmRvqQ4G+lba+nlnlb5brMhvlk7FBiaPzuwQEmEQhg5BOxMjWTncHc2501cQLkjDTsMCWpyuRQxFP0xXIJfp5FyVW4Zy7KajC06ItbiIGg6ZITBxDxIgbrr1jTSM0fibGIHz8O9sKK0GAibEua9spANh4aY2VmcEg+DEkiBgR/L2hYFgGtcErkQQAMVJgBxyy9hboZzv32v+Kpr7qbEECTAIMAoaJa3qPTmNiiAAgJAjk6J5xhu6HDAIgQYGLmI29PocmMcI8MNYvT1ckfzD9H/ub5br4e4Me9WfOKqtyX6Ud2cwC449PRamifDm6Auc0rTXokci+Xo1EAgBckiDuYGLjpTvntcGIA+SFcp6uUAaAI879VhWrRteYAqn/edq758brXJ1327QMhgJcZjA3EBjNrgZjOG1PkAjyTGENMjZPq5ECQ0MDE9ERBqFZrk0OJ3i4x/7vyIjBxGERt3takgVJEAp9xq3f769WiPDNvSsJdT3HDOEASPelmoBRYT3Kzt5uMtwauJEgSOCpwrk1DIJCoNUMwj9v7MweP9XSQ8/hJPp496fZTAICvLqcyv2B7nRbrgCA03JN5h8ub7A8VqpB437xHvsOy3l3cyaB4L2uqxhti1WLMcSgZQCw7+bOooO3Pk4JBZIYYXISMV5sKH59UePM10GESRGpIf/bE92HU452HywSJIGIllctrhp6YAK5+fHds0lLtJFMXNwkV6fFqA29mROefqiMJj1h6um4a5vY/92dKGaBxIhU5zJTWW2cJmEgGOmeb3c8FxAfb9mdf2RzyGGv5MvU7QwuEySwKHFp/c/M71zA/2F7b1RajnYdLAqMukMVu2YcfmDYE2MD7H+7/Xlq6cRIJqm4zXM+qd3TGjVBir43KSLlXjiELe5TsX+3/yW/ST45PaAHbKmccWh12AP93JNZywj0kSABIobpiXRHjtZ6faout2tyZMadGLXBCxBcvl6NfaAz+tKdFmObpzWl2+tIIBACYy0t/yj34M7HvsKUK+CGassvicX7alYDwwq+vykIEqPVa+Q9gdYk5+V+UE7lj3+FGbuBM/X5JUT8QwIVSSSZiTgmoFR2MfiqYFFPfjpkyrfWPopwxP47AP1pK1g9/dqeAAAAAElFTkSuQmCC');\n bottom: 50px;\n left: 55px;\n}\ndiv.vis-network div.vis-navigation div.vis-button.vis-down {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABpdJREFUeNqcV21QlNcVfp5zX9ikoAvLEsAIIgsoHwpqWAQUNKLNaNv8iZ1JMkNG6/Qj/dDUyCSTtCHpmEkwVk3TToZRMjXj5MOG2KidjIkxQYSAQUAtX6IgIN8su8KCoOzbH4sk4q5g77/33uee555z7rnneYmZDB2MKcJKlyYbqOsZVIgGEOgSHQoy4AKbFFjqAo5dWn/rNAh9OpO852oeJHYxtrmEu4WALhMbxG2ZE9uFAlImDRLY/t/y0b3Ig+u+iWOKsAlgIZSb0OIf15kWtKo1NXh1d5xxiSPEN2wUAHrGOg11jirjWVtJyFnb6YgrzoYwocClu0DI5guPDb43Y2LLp/Iaqf9JCGSErGvIifxd7aqQn/TOJCvFvZ8Hf9haEH+m/6sFQgHBv1Sts/15WmJLkeyl6FuFwFPzny1/ZdE7Nfg/xhv1uUmH2w6kggQp+yqze7d5JbZ8Im+KpucSwI6EN7/cYtlxZarBCts3ptfrtq9odjaGKihE+sV0vRC3u8RqWmmbij149W+Wd5p2rnET6bsqsntyb6+pO3KqkE8FvLxo74lNUX9s9uTJb8/9fG2L81KoogJFYfCm3b9usNq0MXxzw1RsUkDqQICPqf/b/q8sQi3j4WdmtV47OFgNAO6r+DEUFAtFAc9YtpXmRP6hxVsI24cvhyoqnFtrK6jM7isgBa3Dl0O94TeGb255MvzXpUIFjVrhxo/dzgoARBuwFQJkBK9reCnurxfvXX8CRW3yW1G749vT2Br7ysW0oNX1pKDTPG+rm1gHRbibAHLm/7522sKnQCZqFgCUaBCqaS/bEw9vqtWoQROf3dBBiT6KTACImZ3YueqhDdOWjDbFQ4IzIl4elNUX5begU1HD6lPRmULKeghhDcpqnUmZuD3+nkgTH6gZEE9ctlZSoGmG9UIynSCsQVndMyX+IZGiBoHMjHh2SreCglClaSBiSEG8cYnD24bv7CWms/3FocO3hnw13plTggAFb196NdlPM44tC0zrSg5ItXmyEz070UEKCMRqQgkkBQ9NvL2eSJ+revoJTORSpoT6do4/7/7UShBFHQexM+HdfyUHWO8iN/uaRzX3/QjUSLlnqM72F4cCRIY5u9Zf+Y+BAv4AvzpkQ7WAIBRujA/7Vg6cia9xlId6InafVEAAGnQMUCSkb6zTMPdBy8hU3JjrphIq+CrD+Mvxeyumrr+4IH9y7o2GF5eDghuuGx4L2zbWZ9Dc0RoQRbkkFNRdP2/0BH7EtLJLKCjr+zqh2l5u8haZ847vTBW24kRFQXKAtcsT5oqz3igQENIoECkjBJUDZSGewBlBj/ammjLrdX1c/t70ero34gMte9IByLLAjPrUwKweT5jawQshdIuGMiF5XEBU2koivBl9NeEfJeYHwuxtI81zPrn2z6ip60c6DkV1jLTOCTaE2HNjd5Z4s9MwWBOhqEHp/I9cWDtUrJNoHm4KO9P7hdnTBoMYXI8Gb6gVCg63FS53jg9O5tA57tSOdHywnCAygrJrfcTgUe5U2cvNHSPtYYoKCWlrTgsIneB2AfFR+4F4b6f9ZdTzF6P8Ytud407/dy/nL7k9X9i8J9l5y+Ef6RfbnjPvWa8N5suez+KFCgqyPY95Lnd3stv2AcBZ2+mFbze+lui1xc3dXCUUlPafXNx4/aKxcajWWNp/MklRw8/mPFntbd+h1oLE847KhQQxejVg36QQqD0MPTzHv42Ux+uGasJNBnPfwllJd71kkX7RQ3WDNf7dox3BLcNNs6vt34bbbvYHJhlTGp6O+JVHb0/2HJtX1PH+aqECqG/5YN1nlXcokGvvO6vCc4x+QskotxVHB/qa+xbOWuzw8NB3nuo+Ht0z2hHsuGU3GrWAoZfi3jrxgHpw3BPpobaCH7vbqOw6mHI836vYW3Eqcq9AtioqbJy7ufQ3lhfu8sR+s9+3vL8klACsQSu7AnxMY1MxH7YXJp7oPpLulrrj+9575Ni2aeVt1teWfEWfHQLCaspseHzOU7VWU+aM5G2NoyL4i+6j8XWDNQsmGsKu/cv+nTtjQb/mm7hfENyvqEAK5v8opjPJaL26KGBpd5TfguuBvuZRgBgY6zO0jlyZXXe9JqR+8MK8ntHOMHfHIkhu2b/0yIH7/oXJ0yFlxYnPUdRbvuILgO7+y+91l6Ka6M+cnCf4fMSypXvymHf/vzBTD3CuNGUFKT8lmK5Rs5ASqKiBlAGBXFaiSuni0fkp1pJ7Ed4e/xsAqLk46EWsG1EAAAAASUVORK5CYII=');\n bottom: 10px;\n left: 55px;\n}\ndiv.vis-network div.vis-navigation div.vis-button.vis-left {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABt5JREFUeNqsl2lUlOcVx//3Pi9DZRsGBgYiS2RYBQKIjAhEJW4pNrXNMbZpWtTGNkttYmJMG5soSZckRk+0p+dYPYY0Gk0ihlhRj63GhVUgBhDD5oIOy8AAMwzD4lCYtx+GqCQKuNyP7/Pc+3u2+7/3JUzEZFBYLh62S7yIZDmVBEIBqOwsQ4DNdtBFASq2A4cuZAwVgCCPF5LGHM0Chz+E1XamzUyAzCMO7IhMI+5MDCK+HpCANd+U2rYgC/Y7BoflYgVA2RAOoNYtyjDTe45+hk96e5QywaJR+NsAwDhocK61VCjLTYWaclNB0OW+en8mhl22g8C/rn7U+uGEwdov+C0i+Q0mIFWzoD7zwVU1czQ/6pjIreR3HPX5VL9jalHXiQgmBoH+XLHAtH5csDaXtxDLLzIBv5jyfOmG2H9U4S7snbpX43KaPpgBIhDx1rPzOlbfPC5GQT/nd1mS1zABa6PfPf5y5F/rcJeWpp7fPkly6f7KXBRCoOSATFfXll19x74HDsvFCghsJAG8HrvlvytCXm7EPVqc5wyzp5NX15muE1omKXXyMnd9yy5r5Q3wPghvJzrLAlimXV38+7D1DbhPFq1M6O4b6rPVWKsCBfHi5EWWv9TkQBYAEPpLvERMC9N8FtRvjt9dPl6wwo5jPvuas7WV5jNqEjz8wA+CBsaan+w9x1hrrXJtuaZX97ooLfqPLCUEGRR+iOwAsF2X98Uc30W3fb02u41frVqeVmo6FUkkwCAwCWxJ2Ls/0TPFNBb8TNdp9WvnVz4OAKdmX2QOzcMsAAjziDGMBd3asCF6SXHyknJTfqQTK+zpvhnVKT5zawCgzFTgN94pJXvP7gxxjTAIkpB+MnSWRMQZYEDnPVt/K4ejbZ/77726Lb6h95tAAiPELaJ1bcTbRfGeM8xv1azWSeyEa0P9igk+Nr1+oNFfkpwzJCJKIQA679ntN08yDXYo3qh+LuUrc0E4EcNL4dP7VNDzpU8FP3vpekoQQ5CEw4bPdEfa9+sAgEZUmkmAAAS5hLQ9p11XGO+pM8V5JLUfMeQARDMlEMKIGFOVCZYb0C7Fz0oeXmIZ6nZzYoV9od/jVS+GbahUOnn9b7T6sEOviUGyA8bMDlUa0W79wBW/bZf+lrY98cDBUI8YCxGDgHCJiVVEDN8R7QWAE8Z/+1mGut2i3eP1r0S+XRztkdBzq6NbF7WpbF3UprKxjvfHxbrfttla/QBArVDbJJIAQCURMRg8ugrKIAKBSNxzHtN3VdmxY0iQYSZmTeegwTlgknYAAB7RZBh2Nm7urbeeC1r19ROT52kWn3shfH2Fu1AO3RxjY/0fdac7/hPPJMDE11GC+HpBJmIEuAS3Oa6w01lybMbMgvgCE6O255zy24DeCr/Bvckn9+u8ZjXYIYvjxoMJy8oeXZrT9GHIqMWTwA2oI6cFMeDIcAiSEOyibXsmZG0hAFzuq1OyY6xBAnMJgdPOmks08zU/bbsB9x18P37PqS/b8+o/a96ZcLm3PmBH46Z5x40HW1eFvl4Uq0w0MwiCBOb7/qTsd6GvVY537DXWas1Iw1AiNJnOgwJi+bXhAbE08OnvaXSIW0TvYw88eaF/uM/WNdju3m5r9TlhPBzVNNDoPGC/5tRma/GJ80xqjPPUjVuvP2narrMOWd1Jlv/E1fN782UiNPZf9C/qOKa+ndOz2j+cz046sn+6KrVOsODirpOxld0lUxmEBK/ktvGgFd2l6taBZn9BAtEz5xYIvAn4/8rFKkgstAyZ6Yf+S67ezlkiSU73XXRV6xqh93TyssR4JF75efBvymLdE03jgT/Wb5tutLWpGbTm7wHZxQQAT+yDuKLyHRIk4cnAZ4pfCF9/HvfR9uh3xBxtz00BANsVDylnac6wAICaHMiBmW5NRLy4trcq0MtZ3RnpHme5H9AvjYeCc1t3pzMJgOSVnyw4eHZUB9Kyu68iMFPpysSppab8UJVC3Rnp/pDlXqF7mnYsdKQbv7cr6fDGW/Zczbt6jgUtV6kIlFxuyg/tH+6zJXmlGe8G+mlzdsyB1j3pTAwZ9q3/Sspbc9tmDwD0H3UffXCFlyuTlFpnPRdYb612c5c8+idPCu6fCLDKUubzsf6fSaWm0wmO9hbvZU8fDR2zoZ97OuppAu0UJEDEmOISZohT6q7Gek5rD3GN6FEp1DaAYB7sdNYPXPao7anS1Fmrg402g7+jYhGIaOXOaQc+uONfmCwZXJIf8xKx2KRgxYgOS+CROuyoyQKCxIhkOr4T6JWgxGnvZ1HWnf/CfHcBXxcnpRHxYwRKkUjSErFKkAQiNjP4kmBRTHbKm5KkKxwL+K39fwDX1XGF8ct++QAAAABJRU5ErkJggg==');\n bottom: 10px;\n left: 15px;\n}\ndiv.vis-network div.vis-navigation div.vis-button.vis-right {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABs1JREFUeNqsl3tQlOcVxp9z3m+XygK7C4sLxkW5o4CAkYssFSkRjabjJEOSJm1IbZx2krapiZdeprW0NVVJ0pqMM0kYJQlqkoZImGioE1ItiCAgIsFwE4Es99vCslwChf36xy5EW1A0Pn9+73fO772e93kJC5EMCszFd20SbyFZNpJAAACtjWUI8KAN1CRAJTbg9LXNU+dBkG+Xkm7Zmg4OWoUdNqZXmQCZHQFsz0yOcCYGEc8mJGDnl2UTh5AO2x2DA3OxDaAsCDvQ32VF11qP9aZYz6SeFeooi17pPQEAvZNdTnWWKnWFuVhfYT7v0zza4M3EsMk2EPgnNZusby8Y7P8x/5lI/gMTYNSnNKQt/0Xtev1DfQtZlaK+M54fmDJXXhg4G8zEINBfqlLMe28L9s/lQ8Tyr5iAJ32fK/tj+OFq3IUO1O+JyGk7GgsiEPFrlQ/07bixXdwEPckHWZJ3MgG7Qw9+/mLIS/W4SyXoNvQskpyHLg1e8CNQ3NI0laoje7Tg/8CBudgGgQwSwO/DD322ze/FFnxLRWhiBzUK94GLA2f9mSTjfU+7mjqyrVe+AX8I4aGgShbA0/47Sn4ZuLcR90ih6qih0anRiVprtUEQb43bYtlXmwNZAEDAj/ACMW1M8ExpeDXyWMVCEl4yF7vntR/zLeov8JJlWfZR+Y3N92+cx/reOmu1quNrk27EWW0xvWspJcigoNNkA4C3Yk59vH7xltvu3ktDxe7PX34ilQCQfeci1j2xfn94ZrGCneY8uxcHCnW/vbr9EQD4d2ITc8AprAOAQLewroVAAaB8oMiLiRHvmVy7znNTjWCFrXKoJOSHFQ+kvnF9f+jco07s91MFdwmSkHQuYB0T8WYwIcYj0bTQdRufGlFKJMFVaCb/GvZW6aGI4yeXOwd2mr/u05zsyDY+W5X64Nm+fO85NpuJiCFJTpslIoonADEeiT2zIzIXuh+o25PQNtbsNVMOBUn2g08MiSTHN3uZjNTEDr4dnX/6H+1H/XPasmKvW+sMGfW/MXzende4K3h/ibvSYxIAItyie/K7cgCitQxCIBFjpTrKMgM+WPfrhLbxFi9iMQtlYjAJSCSBSYBAIPBNI3p86TPXj8bk56R4PVylFE626uFLQc9efiTVPDmgBIAAtzALEYNBQRITa4kYix21FwBax655CVagPLk7806Pj1qo/7MraF/FQ14/aMhszYhvGqn3KTef89rklWrSKXUTkn3mtJK9Bzf3XJA0e/PcrdgxIwSCDPmbZMQgABJkDBKzvn+yy2npIv9xAPB1Ceo2jTZ7Gc8afipIgEhAkACDwcSQQZBIIGnx5it7gg+U3wgcnbZKR1r+FnW+v2DVtDwtXCXNSKz797oAwDzZ7ySRAIBBFsTXmBh1w1+oZ4J3h+wv9lUFdbMDOrO+5IAqWIGZthuV13nC77nKRx8r7PssyibLIkoT1/h65HsfzWyu5tF6NYNB4EYJzKUETqgcLNVv0D/cDQBrNAnm9+LOfTLfNB5u2hf5z+6TMexYji+tVdrM5leMbWOtSwQx/F1C2rcuebIqwSO568a4WmuN3mEYSiUi+pRl2l1pLvYBsKArUKVwnZRYgdHpMWVG4+/WXhwoDBXE7OmkHzJ6JNemLfv51bniGqzVPoIkyLbpfK7ZMFIkE6FlrMn7Ql+BbiHg+zXGbgLjylDpyosD58KZmKM0cfWHI9//aD5o1VCZrnO83VuQQOja5PMCfwK8n3K2ChIbLVOD9KB36le3A+u/s2Q81C2yRavQmQNdVnamLnmq4nHD9jpB0rwm77jpjTW9E906Bu18fWlWCQHAox9CtGoXTwmS8IThZyXPB+29inuoE6bMsDM9ufEAMNHqJuU8ljMtAKA2B7IhzaWNiLfWjVQb3J10/SGuEZZ7Af1X7+lluZ3HkpgEQPL291M+qbzJgXQcG60ypKlVTGwsMxcFaJW6/hDXVZZvCz3RlrmRiQHwy9nRn2bM6bnas4cLfH6s1RIorsJcFDA2PToR7Z7QezfQD9qzwvI6TyTZC47ttXeiT+2c1+wBgOndoTPLt7mrmCRjvfULQ4O1xsVVchu7b9GysYUAqy3lnsdNb0aXmQuj7PYWL2etuRl6S0OfXLjiGQIdEY6K5esc2BWhjvkqXLO6x08VPKxV6iYAwuBkv5NpvNmtbrhaX2+tWdY70eVNINhtLW0/sjrv6B0/YdJlcGlR2AvE4hUlKwHQ7BU5cz8LRx0HaPY7gXb53L/67+mUfudPmP/twOWS6AQi/j6B4iWS/IlYK+yGYJDB1wWLErLRKd/omOJbAWf03wEAyO9m+/TtS3AAAAAASUVORK5CYII=');\n bottom: 10px;\n left: 95px;\n}\ndiv.vis-network div.vis-navigation div.vis-button.vis-zoomIn {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABiBJREFUeNqkV2tQlOcVfp7zvgvDRe66y8htXUBR1GoFI+BtFJvRtjPJBGeaH2a8DGmbttgSTWbSJEw6TWOsrbbpTIeJZGqaTipTa6LJZDTVUTYQdNAohoso6qLucnERN0Axcb/8+HaJUHDX9Pz6vnnPe57vXJ5zzkeEIwaYcwBL/VrW0TCKqZANINEvBhSk3w9eUmC9HzjcsfarOhBGKJN84GkVJHcetvqFu4SAIYELYlpm4LpQQMqoQQKVnzeO7EYV/A8NnHMAGwHWQJmAjtg895LkFa7FU1d258UvGLBGpI4AQM9dd2TrwNn4016n9bS3LqNzsD1VKPAbfhCyqflR31thAzv+La+QxotCoNi6pn1D1s9aVli/3xtOVk72fjT1XVf17E9uHZspFBD8zdk13pdCAjsOyG6KUSEEnrT/tPHluW+cw7eQ19q2z6/t2rsYJEjZ07S6d+ukwI5/yQ7RxnYC2DZnx8dbHNs6xxs85T2R9GprZcmVwYs2BYWsmBzP83m7nIVJS73jdfdd+7PjjUu/XWUCGTtPre7ZHjxTY3Kq8DoV8Ou5u49snPGrKxN58syZ9aVXBztsigoUBd+Xt2NbfZ8llaVvah+vOz9hcX+CJenWp7eOOYS6ePpTU1w39vk+AwCzFPdDQbFGFPCUY2v9hqxfXJ0shNeHLtsUFc6UequbVvdVkwLX0GXbZPpl6Zuu/ij9x/VCBU1dU7bfdFYAIDsSFRCgeOqa9hfy/nDhwfwTKOrRd0U95n0iqch9+cKS5JVtpMCdkllhAhugCHcRwAb7z1tCEp8CCXAWAJRoCFXIYnti+sYWTQ0tll0wQMk+hGUAkBOX714xbV1IyuhxHhIMC/iR5OV9M2JmuhU1Vh7PXiakrIUQhcnLXeHQxPT4GyAtFqgwgAPF5iIFWkeu1SSLCKAweXn3/ZR5rXV7SddQpy3YDoNems9qTI5hGCitm1MOAAx0aaFCerTd84zjBed3Egq9ADA/rqD7Q3ctQC4REDmkYHb8goGgsR2tz5V0DV+xUdQoqAQ81RybU4IgFWgACgpaLLCIBUo0bv63y/aXy6+WBHWz4/IHSIGAuVooiaRgWqD3AsDVoQ6bEgtOrfJUhwrf0WUtk+r8sL6wvHvk5ijVUiJSRrQZuURtfoGMuaCoRyfP/yMy0XykgAA0DPRTxNp31x2ZFuUYBgB7bK7HNdhpKz6WXq6oQCooKghMKhkgji77vBoA1jkXlAvVfRQjFMUcmxSkRWd6gpjeu32R2kxTvyhKh1DQeud8fFBh26zfOe0xuR4JgAbzywCoRSzfeDUKatJKUQK+CjKiHZ6nZ2xzBnU7B9vixTy7qCHSQEhJU3+DtdT6mAcAFiWUeP/xyPH3Jwrfo3XzysemRcEA8F5RY8h6aPE1WwMLQ4OQ/EBANHmdGWHlzZyxk3ayB0m771yGooYy+KE0l35x0iBxZehS6ie9R1PCMaDvCzWDXA4hZ283ptwcvp6qqDBnyao6AWEQrBQQ/7y+d3YoA+NBTAaElo973p8tVFCQyipW+c3pdNu7BwBOe+tm/eniK/kPFWowpMfvuKrzzw80zSKIkWsJe0bHYu163BNwMwDsv7G36ODNtzMnM5IWZfeQgscbisvLPl1aDhLTo7I8k+n/p+dw5pGeg0WKGiS31K6vvTdmA7nx9uDZ9A3xMUIpbvSezE6MSOmbNWXewHhD6dH23o7BlqQvvrwTK6KQFpXl2WyvcE6LTB2eCPSdrurvmcUnO/cVfPD6pMteyfGs3QKpUFQoS9tU/xPH8xe+Tdd693pN/pHug0Xmqntvz1uLDo9Z9v5nnrn+dvujrI1JMUJd3OY7n97ua46douOGpkdlDoUDeG7g1NS/u/5a0Og9scCsB+ysWXSoMuyFftWJvM0E31SBjmWPznHPjy+8NjdhYfeMmJl3EiNSRgCi/25fpGu4M671zjlrm685s2fEnUoQ5lrLLW8uPLj3oX9hqgxIw8n8X1LU7yMkItCHzREZrGQV6ONmy5TggHk247sL/1jFqof/hRn/AWfqC0pI+QHBIk3tICXRrFTpF8hlJaqefh6yFxQ6HwQYlK8HAKyt3WsWxl7fAAAAAElFTkSuQmCC');\n bottom: 10px;\n right: 15px;\n}\ndiv.vis-network div.vis-navigation div.vis-button.vis-zoomOut {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABV5JREFUeNq0l2tQVVUYht/3W/vACMr16IFRQDiAgChpgiikMqY1WjnN9KsfGOXYTOVgkvbDUsZuXrK0qZmGUSvNspjI8TZOmo6AGBoZYly8YB6Qw80DBwQ6jJ3dj30OZZmiwvtv77XW96y91l7v9y1iMNLBuCI84tZkIXU9gwqxAILdokNBOtzgJQWWuYEDFxfcLAGh3y0k79iaD4mfjOVu4WYhoItngBiR6RkuFJAyEJBA3m/lri3Ih/uewXFFyAG4A8oAWkcm2meEzrFNH53Vkhg4xWnxCXcBQGu/3bfGeTbwjKPUcsZRElnfUxcuFLh1Nwh5vurx7s8GDbZ+L+tI/U0hkGGZX5c9/pXqOZYn2gazK8Vth0fvsRUknbx+bIJQQPCts/Mda+4KthbJFoqeKwSejX6pfO2kjytxH1pfuyqlsGH7dJAgZWvFo23L/9muboF+JxtE0/OEwMqJG46uSHinFvepTPO8lhGaX+fPHSdjCKaPy/b3v7az58h/wHFFyIHCRirgjUlbfsiJWXEFD6iUoOkdQaaQ6z9dP2YVahljF4+yXdvZ/evf4G+hQk2sEAUsti4vWxa35gKGSBMDp3T23OxxVXdXRijKovSFzrerC6ELAMT6IhcCZIyeX7c68YPzGGLlxq89PyM0q5YU2M1RuQAg0EERbiaA7Ohl1RgmPTM2p1qjBk1Mm6GDErsfswAgLiDZPmfMwrbhAqeHzm6P8Z9gV9SQdTx2lpCyAEKkhc62YZiVEjTdRgo0zXeBRnImAaSFzm7xdjjtOBGyvmZVZkNvfZjXDhU14+BToFEDKRAQpAJ0HRTjP6XHpYUKEX7RzS9bV5c+FJTmAICUgNSWQ/ZCgJwhIOJIQVLgFKcXvKHm9cyGvithFDUAFQqECho1CBUIggYapAJ1QEFBExNMYoISDU1/NIR9cvndTG/c2IBkp2fC8ZpQgknBGI/3AsDvvRfDlJhwem5zwYMs7VNlaUtbXE1h3mezj9mlGSsXrBkzkFsGKGoDmedBJLfLjxQQgAYdHRSxtPfbfceNsPYBQPTI+GZbT31YxrGIpYoKpIKigkAgFOggNBrbQBBCBaEM2L+iGGmTgnF+Uc1epqO/3VejAoAOUZSLQkFN17lAb4eVCe+VRvvHN4sH6t1feqAmMUGoPHvvhdLzTjzfKoj0sza/GLOy1Bu3vqc20Pgl5YIGkVOEZFZ0nLLMszzdDADTgjIdX6Uf3zfUx6m6u8riKRhOCcmDAqLCURo53Oe4rrsyUlGD0nlIqubdKNZJXOm9FH6y7Yh5uKBnO8vNTX2N4YoKE2fMLREQOsE8AfFN4/ak4QIfbd2XJFRQkLx85ruN7NTp2AoAZxwlCR9dWJc81NDdtoLkc86KBIJwXQ3aOpCPqwuhR2SPbCBlUc2NyogQX3N7wqgU51BAf2w9EFXUtCtLqADqS76ev6/ilgrk2q6esxHZgf5CySh3FMcG+5jbE0ZNdj4odHdDwWPGcZNNO1MPbrxtzdW4s+tI5HPBwQTTzziKY3v/7HGlhmS23g90T+OO5L1Nu7MMw3Fv/Tx1f97/FnsAYPui8/D4nBB/oZZR230uoq67auQoLaB37Iio3sEAK52nR39p+zS13HFiilHeYtOOabdC71jQzz2R+ALBbcrjWNF+cfaUwLSrk4KmtsT4T+gK9jG7AKKjv93X1lcfUNNVaantropqddnDCcIoa7lk29S92+/5CpOvQ04VJ79KUe/7iI/Hh40U6c3PyuPjhmWKN8G8Fvnw1A/zmX/vV5h/T+CXstRMUp4kOFOjZiUlWBkFQYdALitRZXRzf3RqWumdgF79NQDBOa2V/iYSHAAAAABJRU5ErkJggg==');\n bottom: 10px;\n right: 55px;\n}\ndiv.vis-network div.vis-navigation div.vis-button.vis-zoomExtends {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABptJREFUeNqsl21QlNcVx///cx9hIipuAJHasgHlRdw0xay7yK7smg6sb2DSdtqZduLUNENmOk1tQuM4U7UzTvshSRlFZzoNCWSSSTJp+6VNkLCAeQHBoCCgqNBE0wUqL+KuwIiiZZ9+eHa3aAS3Sf8zO8/L3nt+95x7z7n3YWlpKUQEJAEgch9+Jola9xEC2ADBVgAOKqwCYAqKDgUJBIHPBWwFWQNdbyZFBwAC0GGIAHQSj3/8HHRdhzYbdDfwg4IjAsGvICgXAroYBiCEDkBBACBZoyST4gDwQqh7mQ4cEkhQD0EBIIggRMQAh2EiEvEYAGrdR3YSqIYCIEDaotVDeYnu/ryEjSOr43PHl8WmTBPA6PRQ7IWJrvhT/ubkU/7m1EvX+1KEUh7Ug+WkPEXgdUSkR+xrd0NJ4qjr8AEI9pGAI7mo78mHfnF+Y/K2K7iHUheuvJG6cOUNz/LvDwPobrpSl/Ruf2VOy9UPs4RSTSANwH4Y449EVdnt9ojHIeghCHYLgR+n/7zt4Np32tIWZU4hSpnjVk1t/caPfOO3/f++MNH5TVJcisoEoo4ksgbsXwYfdR1+kQplQuCFNS82Pp/9+158RTkTC0ce0OKutQeOp5PME0qcUBqyBmwGOC8vz4AWVOyE4CUqYO/Dh+p3pj//Bb6mHllqCyxd8ODVT69+uFKoOYTSnzFg7SJpzHFNQYWiQrUIsCN9V+uOh375zz179pSGI1FSUuK12+2+aGDt7e3muro6T/h57969lZdvDrT+ZbA6n0B1nfPVN7e0PjMjIgIIdkEAR1JR329yDvaE0+l/hQKA1Wr1bd682SsikUW7K+O3PesTNvaSAiXaLhGBvO86RFEoJ4Adac+eDxsgiZKSEm9NTY3n5MmT5mjBHR0d5vr6es+mTZu8SqnI+x+s+Ol5jRo0auX1jtepQaEAADKWWIbcy7ZGUmb79u1eu93uI+mtra31HLj5TGDs9rBJICCNn1GRCKGCUJAUuzzw6CfbTB6Px7t27VofAG/YXl6Ceyw9LmvIN3UxZUafKRACWyCELcHVP3vk4fDabDZf+2N/D9g+fsLEEFSooFGDogZNFkBRgSCsTcWm066jgRAU4et/F5u9nxRosmCLRmE+QdgSXCNzhW/s9rDJ63wVJx77V+V8YS6UNaW8BdOcqzx+3Ujt0F8Bcr1GMIMU5CzJHZ+rg6IGCYV2PimoyIK6lzIWrxkPTVGmRoqJFCyLTZmeq4MB5f3BVADnbpcQkzStUQMAk0YKBPfzxlhA95NQQe43QBotBECAFFyZHo6dz6CKCizAPFPivzUWqxm2AqIgnwkFvZNn4uczGK3Hah7wpet98UZ85R8aKScIcXYEWpMLkx8fvleHpNjlAWtTsakQa0pVKGcJQqMGUqCHBvfdjp/gTP6xwFzg85PdyaH2J4SUowKiw3889e4KBACnT582W5uKTV2uusAdUFlgzBcFQoFGDT35HwW+82mhqaenxwwA4WtYfRNnUkMZUqsJpEkn8cXU5yktYw2JjsTCMQDwer0ekt6GhgZPUVGRd3fu7qjqdU9Mj7mlpcVD0tvS0uKxWCyVANB5rS3x8s3BFEUFgTTLtuZndQHLBMSfB6pyZtfqMDQ3NzfqTcJisficTqc3BI+8bxh9L8corarM3fnDoIT+rACAU/7m7MOfHbCEwQDQ2Njo6erqinqTOHfuXNjjiI23+ystZ8c7smmkWgVJcN++fRARfLDhlacEUqVEQ1nm77xPrHjSh/+Djo3WmN/s/6OHEOgIPr2h63tVuq5Dud1ukETWoK3zorkzTiiONn/TKlNM4lj24m+Pf13o2wOVHqGA5MsAXjKPrDaqnMvlQnjTzhy0Nlw0d5oI5p3yN62amrk+ve5B5+hXgb47WGX52+V3NgoFOvQKAGUkkTqcbZy5XC7XHYf4zEFr3aXU7jih5uidPPOtvsmzixZr8VMrHjBHddLsHj+Z9Fb/n9a1+T/JDaXey0IpEzEKkHnU8Jj79++PeEwSSimQRGP+Gz8j5DVFBVKQtjBj6JGlNt/D8Y+OpMdlTphiEqcB4tqtsVjfjUtLLkx0J/dOnjWPTg+lEARIEHwaQJVQIYggACC/qxi6rn8ZHL4XETSsf0MU1HOk/CFGYgAwskUqY5eBitRxzn7/a0V1EEBwdqkN6jPI7y4xPmHmC5unbWdQRMqP2d86qANOksU6gvmArNQRNClqABnQgYuK0krI+wCOAyH3DK/vqOXhaf3PAO7mIRjDNV25AAAAAElFTkSuQmCC');\n bottom: 50px;\n right: 15px;\n}\n";
33781styleInject(css_248z$1);
33782
33783/**
33784 * Created by Alex on 11/6/2014.
33785 */
33786function keycharm(options) {
33787 var preventDefault = options && options.preventDefault || false;
33788 var container = options && options.container || window;
33789 var _exportFunctions = {};
33790 var _bound = {
33791 keydown: {},
33792 keyup: {}
33793 };
33794 var _keys = {};
33795 var i; // a - z
33796
33797 for (i = 97; i <= 122; i++) {
33798 _keys[String.fromCharCode(i)] = {
33799 code: 65 + (i - 97),
33800 shift: false
33801 };
33802 } // A - Z
33803
33804
33805 for (i = 65; i <= 90; i++) {
33806 _keys[String.fromCharCode(i)] = {
33807 code: i,
33808 shift: true
33809 };
33810 } // 0 - 9
33811
33812
33813 for (i = 0; i <= 9; i++) {
33814 _keys['' + i] = {
33815 code: 48 + i,
33816 shift: false
33817 };
33818 } // F1 - F12
33819
33820
33821 for (i = 1; i <= 12; i++) {
33822 _keys['F' + i] = {
33823 code: 111 + i,
33824 shift: false
33825 };
33826 } // num0 - num9
33827
33828
33829 for (i = 0; i <= 9; i++) {
33830 _keys['num' + i] = {
33831 code: 96 + i,
33832 shift: false
33833 };
33834 } // numpad misc
33835
33836
33837 _keys['num*'] = {
33838 code: 106,
33839 shift: false
33840 };
33841 _keys['num+'] = {
33842 code: 107,
33843 shift: false
33844 };
33845 _keys['num-'] = {
33846 code: 109,
33847 shift: false
33848 };
33849 _keys['num/'] = {
33850 code: 111,
33851 shift: false
33852 };
33853 _keys['num.'] = {
33854 code: 110,
33855 shift: false
33856 }; // arrows
33857
33858 _keys['left'] = {
33859 code: 37,
33860 shift: false
33861 };
33862 _keys['up'] = {
33863 code: 38,
33864 shift: false
33865 };
33866 _keys['right'] = {
33867 code: 39,
33868 shift: false
33869 };
33870 _keys['down'] = {
33871 code: 40,
33872 shift: false
33873 }; // extra keys
33874
33875 _keys['space'] = {
33876 code: 32,
33877 shift: false
33878 };
33879 _keys['enter'] = {
33880 code: 13,
33881 shift: false
33882 };
33883 _keys['shift'] = {
33884 code: 16,
33885 shift: undefined
33886 };
33887 _keys['esc'] = {
33888 code: 27,
33889 shift: false
33890 };
33891 _keys['backspace'] = {
33892 code: 8,
33893 shift: false
33894 };
33895 _keys['tab'] = {
33896 code: 9,
33897 shift: false
33898 };
33899 _keys['ctrl'] = {
33900 code: 17,
33901 shift: false
33902 };
33903 _keys['alt'] = {
33904 code: 18,
33905 shift: false
33906 };
33907 _keys['delete'] = {
33908 code: 46,
33909 shift: false
33910 };
33911 _keys['pageup'] = {
33912 code: 33,
33913 shift: false
33914 };
33915 _keys['pagedown'] = {
33916 code: 34,
33917 shift: false
33918 }; // symbols
33919
33920 _keys['='] = {
33921 code: 187,
33922 shift: false
33923 };
33924 _keys['-'] = {
33925 code: 189,
33926 shift: false
33927 };
33928 _keys[']'] = {
33929 code: 221,
33930 shift: false
33931 };
33932 _keys['['] = {
33933 code: 219,
33934 shift: false
33935 };
33936
33937 var down = function (event) {
33938 handleEvent(event, 'keydown');
33939 };
33940
33941 var up = function (event) {
33942 handleEvent(event, 'keyup');
33943 }; // handle the actualy bound key with the event
33944
33945
33946 var handleEvent = function (event, type) {
33947 if (_bound[type][event.keyCode] !== undefined) {
33948 var bound = _bound[type][event.keyCode];
33949
33950 for (var i = 0; i < bound.length; i++) {
33951 if (bound[i].shift === undefined) {
33952 bound[i].fn(event);
33953 } else if (bound[i].shift == true && event.shiftKey == true) {
33954 bound[i].fn(event);
33955 } else if (bound[i].shift == false && event.shiftKey == false) {
33956 bound[i].fn(event);
33957 }
33958 }
33959
33960 if (preventDefault == true) {
33961 event.preventDefault();
33962 }
33963 }
33964 }; // bind a key to a callback
33965
33966
33967 _exportFunctions.bind = function (key, callback, type) {
33968 if (type === undefined) {
33969 type = 'keydown';
33970 }
33971
33972 if (_keys[key] === undefined) {
33973 throw new Error("unsupported key: " + key);
33974 }
33975
33976 if (_bound[type][_keys[key].code] === undefined) {
33977 _bound[type][_keys[key].code] = [];
33978 }
33979
33980 _bound[type][_keys[key].code].push({
33981 fn: callback,
33982 shift: _keys[key].shift
33983 });
33984 }; // bind all keys to a call back (demo purposes)
33985
33986
33987 _exportFunctions.bindAll = function (callback, type) {
33988 if (type === undefined) {
33989 type = 'keydown';
33990 }
33991
33992 for (var key in _keys) {
33993 if (_keys.hasOwnProperty(key)) {
33994 _exportFunctions.bind(key, callback, type);
33995 }
33996 }
33997 }; // get the key label from an event
33998
33999
34000 _exportFunctions.getKey = function (event) {
34001 for (var key in _keys) {
34002 if (_keys.hasOwnProperty(key)) {
34003 if (event.shiftKey == true && _keys[key].shift == true && event.keyCode == _keys[key].code) {
34004 return key;
34005 } else if (event.shiftKey == false && _keys[key].shift == false && event.keyCode == _keys[key].code) {
34006 return key;
34007 } else if (event.keyCode == _keys[key].code && key == 'shift') {
34008 return key;
34009 }
34010 }
34011 }
34012
34013 return "unknown key, currently not supported";
34014 }; // unbind either a specific callback from a key or all of them (by leaving callback undefined)
34015
34016
34017 _exportFunctions.unbind = function (key, callback, type) {
34018 if (type === undefined) {
34019 type = 'keydown';
34020 }
34021
34022 if (_keys[key] === undefined) {
34023 throw new Error("unsupported key: " + key);
34024 }
34025
34026 if (callback !== undefined) {
34027 var newBindings = [];
34028 var bound = _bound[type][_keys[key].code];
34029
34030 if (bound !== undefined) {
34031 for (var i = 0; i < bound.length; i++) {
34032 if (!(bound[i].fn == callback && bound[i].shift == _keys[key].shift)) {
34033 newBindings.push(_bound[type][_keys[key].code][i]);
34034 }
34035 }
34036 }
34037
34038 _bound[type][_keys[key].code] = newBindings;
34039 } else {
34040 _bound[type][_keys[key].code] = [];
34041 }
34042 }; // reset all bound variables.
34043
34044
34045 _exportFunctions.reset = function () {
34046 _bound = {
34047 keydown: {},
34048 keyup: {}
34049 };
34050 }; // unbind all listeners and reset all variables.
34051
34052
34053 _exportFunctions.destroy = function () {
34054 _bound = {
34055 keydown: {},
34056 keyup: {}
34057 };
34058 container.removeEventListener('keydown', down, true);
34059 container.removeEventListener('keyup', up, true);
34060 }; // create listeners.
34061
34062
34063 container.addEventListener('keydown', down, true);
34064 container.addEventListener('keyup', up, true); // return the public functions.
34065
34066 return _exportFunctions;
34067}
34068
34069/**
34070 * Navigation Handler
34071 */
34072
34073var NavigationHandler = /*#__PURE__*/function () {
34074 /**
34075 * @param {object} body
34076 * @param {Canvas} canvas
34077 */
34078 function NavigationHandler(body, canvas) {
34079 var _this = this;
34080
34081 _classCallCheck(this, NavigationHandler);
34082
34083 this.body = body;
34084 this.canvas = canvas;
34085 this.iconsCreated = false;
34086 this.navigationHammers = [];
34087 this.boundFunctions = {};
34088 this.touchTime = 0;
34089 this.activated = false;
34090 this.body.emitter.on("activate", function () {
34091 _this.activated = true;
34092
34093 _this.configureKeyboardBindings();
34094 });
34095 this.body.emitter.on("deactivate", function () {
34096 _this.activated = false;
34097
34098 _this.configureKeyboardBindings();
34099 });
34100 this.body.emitter.on("destroy", function () {
34101 if (_this.keycharm !== undefined) {
34102 _this.keycharm.destroy();
34103 }
34104 });
34105 this.options = {};
34106 }
34107 /**
34108 *
34109 * @param {object} options
34110 */
34111
34112
34113 _createClass(NavigationHandler, [{
34114 key: "setOptions",
34115 value: function setOptions(options) {
34116 if (options !== undefined) {
34117 this.options = options;
34118 this.create();
34119 }
34120 }
34121 /**
34122 * Creates or refreshes navigation and sets key bindings
34123 */
34124
34125 }, {
34126 key: "create",
34127 value: function create() {
34128 if (this.options.navigationButtons === true) {
34129 if (this.iconsCreated === false) {
34130 this.loadNavigationElements();
34131 }
34132 } else if (this.iconsCreated === true) {
34133 this.cleanNavigation();
34134 }
34135
34136 this.configureKeyboardBindings();
34137 }
34138 /**
34139 * Cleans up previous navigation items
34140 */
34141
34142 }, {
34143 key: "cleanNavigation",
34144 value: function cleanNavigation() {
34145 // clean hammer bindings
34146 if (this.navigationHammers.length != 0) {
34147 for (var i = 0; i < this.navigationHammers.length; i++) {
34148 this.navigationHammers[i].destroy();
34149 }
34150
34151 this.navigationHammers = [];
34152 } // clean up previous navigation items
34153
34154
34155 if (this.navigationDOM && this.navigationDOM["wrapper"] && this.navigationDOM["wrapper"].parentNode) {
34156 this.navigationDOM["wrapper"].parentNode.removeChild(this.navigationDOM["wrapper"]);
34157 }
34158
34159 this.iconsCreated = false;
34160 }
34161 /**
34162 * Creation of the navigation controls nodes. They are drawn over the rest of the nodes and are not affected by scale and translation
34163 * they have a triggerFunction which is called on click. If the position of the navigation controls is dependent
34164 * on this.frame.canvas.clientWidth or this.frame.canvas.clientHeight, we flag horizontalAlignLeft and verticalAlignTop false.
34165 * This means that the location will be corrected by the _relocateNavigation function on a size change of the canvas.
34166 *
34167 * @private
34168 */
34169
34170 }, {
34171 key: "loadNavigationElements",
34172 value: function loadNavigationElements() {
34173 var _this2 = this;
34174
34175 this.cleanNavigation();
34176 this.navigationDOM = {};
34177 var navigationDivs = ["up", "down", "left", "right", "zoomIn", "zoomOut", "zoomExtends"];
34178 var navigationDivActions = ["_moveUp", "_moveDown", "_moveLeft", "_moveRight", "_zoomIn", "_zoomOut", "_fit"];
34179 this.navigationDOM["wrapper"] = document.createElement("div");
34180 this.navigationDOM["wrapper"].className = "vis-navigation";
34181 this.canvas.frame.appendChild(this.navigationDOM["wrapper"]);
34182
34183 for (var i = 0; i < navigationDivs.length; i++) {
34184 this.navigationDOM[navigationDivs[i]] = document.createElement("div");
34185 this.navigationDOM[navigationDivs[i]].className = "vis-button vis-" + navigationDivs[i];
34186 this.navigationDOM["wrapper"].appendChild(this.navigationDOM[navigationDivs[i]]);
34187 var hammer = new Hammer$1(this.navigationDOM[navigationDivs[i]]);
34188
34189 if (navigationDivActions[i] === "_fit") {
34190 var _context;
34191
34192 onTouch(hammer, bind$6(_context = this._fit).call(_context, this));
34193 } else {
34194 var _context2;
34195
34196 onTouch(hammer, bind$6(_context2 = this.bindToRedraw).call(_context2, this, navigationDivActions[i]));
34197 }
34198
34199 this.navigationHammers.push(hammer);
34200 } // use a hammer for the release so we do not require the one used in the rest of the network
34201 // the one the rest uses can be overloaded by the manipulation system.
34202
34203
34204 var hammerFrame = new Hammer$1(this.canvas.frame);
34205 onRelease(hammerFrame, function () {
34206 _this2._stopMovement();
34207 });
34208 this.navigationHammers.push(hammerFrame);
34209 this.iconsCreated = true;
34210 }
34211 /**
34212 *
34213 * @param {string} action
34214 */
34215
34216 }, {
34217 key: "bindToRedraw",
34218 value: function bindToRedraw(action) {
34219 if (this.boundFunctions[action] === undefined) {
34220 var _context3;
34221
34222 this.boundFunctions[action] = bind$6(_context3 = this[action]).call(_context3, this);
34223 this.body.emitter.on("initRedraw", this.boundFunctions[action]);
34224 this.body.emitter.emit("_startRendering");
34225 }
34226 }
34227 /**
34228 *
34229 * @param {string} action
34230 */
34231
34232 }, {
34233 key: "unbindFromRedraw",
34234 value: function unbindFromRedraw(action) {
34235 if (this.boundFunctions[action] !== undefined) {
34236 this.body.emitter.off("initRedraw", this.boundFunctions[action]);
34237 this.body.emitter.emit("_stopRendering");
34238 delete this.boundFunctions[action];
34239 }
34240 }
34241 /**
34242 * this stops all movement induced by the navigation buttons
34243 *
34244 * @private
34245 */
34246
34247 }, {
34248 key: "_fit",
34249 value: function _fit() {
34250 if (new Date().valueOf() - this.touchTime > 700) {
34251 // TODO: fix ugly hack to avoid hammer's double fireing of event (because we use release?)
34252 this.body.emitter.emit("fit", {
34253 duration: 700
34254 });
34255 this.touchTime = new Date().valueOf();
34256 }
34257 }
34258 /**
34259 * this stops all movement induced by the navigation buttons
34260 *
34261 * @private
34262 */
34263
34264 }, {
34265 key: "_stopMovement",
34266 value: function _stopMovement() {
34267 for (var boundAction in this.boundFunctions) {
34268 if (Object.prototype.hasOwnProperty.call(this.boundFunctions, boundAction)) {
34269 this.body.emitter.off("initRedraw", this.boundFunctions[boundAction]);
34270 this.body.emitter.emit("_stopRendering");
34271 }
34272 }
34273
34274 this.boundFunctions = {};
34275 }
34276 /**
34277 *
34278 * @private
34279 */
34280
34281 }, {
34282 key: "_moveUp",
34283 value: function _moveUp() {
34284 this.body.view.translation.y += this.options.keyboard.speed.y;
34285 }
34286 /**
34287 *
34288 * @private
34289 */
34290
34291 }, {
34292 key: "_moveDown",
34293 value: function _moveDown() {
34294 this.body.view.translation.y -= this.options.keyboard.speed.y;
34295 }
34296 /**
34297 *
34298 * @private
34299 */
34300
34301 }, {
34302 key: "_moveLeft",
34303 value: function _moveLeft() {
34304 this.body.view.translation.x += this.options.keyboard.speed.x;
34305 }
34306 /**
34307 *
34308 * @private
34309 */
34310
34311 }, {
34312 key: "_moveRight",
34313 value: function _moveRight() {
34314 this.body.view.translation.x -= this.options.keyboard.speed.x;
34315 }
34316 /**
34317 *
34318 * @private
34319 */
34320
34321 }, {
34322 key: "_zoomIn",
34323 value: function _zoomIn() {
34324 var scaleOld = this.body.view.scale;
34325 var scale = this.body.view.scale * (1 + this.options.keyboard.speed.zoom);
34326 var translation = this.body.view.translation;
34327 var scaleFrac = scale / scaleOld;
34328 var tx = (1 - scaleFrac) * this.canvas.canvasViewCenter.x + translation.x * scaleFrac;
34329 var ty = (1 - scaleFrac) * this.canvas.canvasViewCenter.y + translation.y * scaleFrac;
34330 this.body.view.scale = scale;
34331 this.body.view.translation = {
34332 x: tx,
34333 y: ty
34334 };
34335 this.body.emitter.emit("zoom", {
34336 direction: "+",
34337 scale: this.body.view.scale,
34338 pointer: null
34339 });
34340 }
34341 /**
34342 *
34343 * @private
34344 */
34345
34346 }, {
34347 key: "_zoomOut",
34348 value: function _zoomOut() {
34349 var scaleOld = this.body.view.scale;
34350 var scale = this.body.view.scale / (1 + this.options.keyboard.speed.zoom);
34351 var translation = this.body.view.translation;
34352 var scaleFrac = scale / scaleOld;
34353 var tx = (1 - scaleFrac) * this.canvas.canvasViewCenter.x + translation.x * scaleFrac;
34354 var ty = (1 - scaleFrac) * this.canvas.canvasViewCenter.y + translation.y * scaleFrac;
34355 this.body.view.scale = scale;
34356 this.body.view.translation = {
34357 x: tx,
34358 y: ty
34359 };
34360 this.body.emitter.emit("zoom", {
34361 direction: "-",
34362 scale: this.body.view.scale,
34363 pointer: null
34364 });
34365 }
34366 /**
34367 * bind all keys using keycharm.
34368 */
34369
34370 }, {
34371 key: "configureKeyboardBindings",
34372 value: function configureKeyboardBindings() {
34373 var _this3 = this;
34374
34375 if (this.keycharm !== undefined) {
34376 this.keycharm.destroy();
34377 }
34378
34379 if (this.options.keyboard.enabled === true) {
34380 if (this.options.keyboard.bindToWindow === true) {
34381 this.keycharm = keycharm({
34382 container: window,
34383 preventDefault: true
34384 });
34385 } else {
34386 this.keycharm = keycharm({
34387 container: this.canvas.frame,
34388 preventDefault: true
34389 });
34390 }
34391
34392 this.keycharm.reset();
34393
34394 if (this.activated === true) {
34395 var _context4, _context5, _context6, _context7, _context8, _context9, _context10, _context11, _context12, _context13, _context14, _context15, _context16, _context17, _context18, _context19, _context20, _context21, _context22, _context23, _context24, _context25, _context26, _context27;
34396
34397 bind$6(_context4 = this.keycharm).call(_context4, "up", function () {
34398 _this3.bindToRedraw("_moveUp");
34399 }, "keydown");
34400
34401 bind$6(_context5 = this.keycharm).call(_context5, "down", function () {
34402 _this3.bindToRedraw("_moveDown");
34403 }, "keydown");
34404
34405 bind$6(_context6 = this.keycharm).call(_context6, "left", function () {
34406 _this3.bindToRedraw("_moveLeft");
34407 }, "keydown");
34408
34409 bind$6(_context7 = this.keycharm).call(_context7, "right", function () {
34410 _this3.bindToRedraw("_moveRight");
34411 }, "keydown");
34412
34413 bind$6(_context8 = this.keycharm).call(_context8, "=", function () {
34414 _this3.bindToRedraw("_zoomIn");
34415 }, "keydown");
34416
34417 bind$6(_context9 = this.keycharm).call(_context9, "num+", function () {
34418 _this3.bindToRedraw("_zoomIn");
34419 }, "keydown");
34420
34421 bind$6(_context10 = this.keycharm).call(_context10, "num-", function () {
34422 _this3.bindToRedraw("_zoomOut");
34423 }, "keydown");
34424
34425 bind$6(_context11 = this.keycharm).call(_context11, "-", function () {
34426 _this3.bindToRedraw("_zoomOut");
34427 }, "keydown");
34428
34429 bind$6(_context12 = this.keycharm).call(_context12, "[", function () {
34430 _this3.bindToRedraw("_zoomOut");
34431 }, "keydown");
34432
34433 bind$6(_context13 = this.keycharm).call(_context13, "]", function () {
34434 _this3.bindToRedraw("_zoomIn");
34435 }, "keydown");
34436
34437 bind$6(_context14 = this.keycharm).call(_context14, "pageup", function () {
34438 _this3.bindToRedraw("_zoomIn");
34439 }, "keydown");
34440
34441 bind$6(_context15 = this.keycharm).call(_context15, "pagedown", function () {
34442 _this3.bindToRedraw("_zoomOut");
34443 }, "keydown");
34444
34445 bind$6(_context16 = this.keycharm).call(_context16, "up", function () {
34446 _this3.unbindFromRedraw("_moveUp");
34447 }, "keyup");
34448
34449 bind$6(_context17 = this.keycharm).call(_context17, "down", function () {
34450 _this3.unbindFromRedraw("_moveDown");
34451 }, "keyup");
34452
34453 bind$6(_context18 = this.keycharm).call(_context18, "left", function () {
34454 _this3.unbindFromRedraw("_moveLeft");
34455 }, "keyup");
34456
34457 bind$6(_context19 = this.keycharm).call(_context19, "right", function () {
34458 _this3.unbindFromRedraw("_moveRight");
34459 }, "keyup");
34460
34461 bind$6(_context20 = this.keycharm).call(_context20, "=", function () {
34462 _this3.unbindFromRedraw("_zoomIn");
34463 }, "keyup");
34464
34465 bind$6(_context21 = this.keycharm).call(_context21, "num+", function () {
34466 _this3.unbindFromRedraw("_zoomIn");
34467 }, "keyup");
34468
34469 bind$6(_context22 = this.keycharm).call(_context22, "num-", function () {
34470 _this3.unbindFromRedraw("_zoomOut");
34471 }, "keyup");
34472
34473 bind$6(_context23 = this.keycharm).call(_context23, "-", function () {
34474 _this3.unbindFromRedraw("_zoomOut");
34475 }, "keyup");
34476
34477 bind$6(_context24 = this.keycharm).call(_context24, "[", function () {
34478 _this3.unbindFromRedraw("_zoomOut");
34479 }, "keyup");
34480
34481 bind$6(_context25 = this.keycharm).call(_context25, "]", function () {
34482 _this3.unbindFromRedraw("_zoomIn");
34483 }, "keyup");
34484
34485 bind$6(_context26 = this.keycharm).call(_context26, "pageup", function () {
34486 _this3.unbindFromRedraw("_zoomIn");
34487 }, "keyup");
34488
34489 bind$6(_context27 = this.keycharm).call(_context27, "pagedown", function () {
34490 _this3.unbindFromRedraw("_zoomOut");
34491 }, "keyup");
34492 }
34493 }
34494 }
34495 }]);
34496
34497 return NavigationHandler;
34498}();
34499
34500function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
34501
34502function _unsupportedIterableToArray$4(o, minLen) { var _context15; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(o, minLen); var n = slice$1(_context15 = Object.prototype.toString.call(o)).call(_context15, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$4(o, minLen); }
34503
34504function _arrayLikeToArray$4(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
34505/**
34506 * Handler for interactions
34507 */
34508
34509var InteractionHandler = /*#__PURE__*/function () {
34510 /**
34511 * @param {object} body
34512 * @param {Canvas} canvas
34513 * @param {SelectionHandler} selectionHandler
34514 */
34515 function InteractionHandler(body, canvas, selectionHandler) {
34516 var _context, _context2, _context3, _context4, _context5, _context6, _context7, _context8, _context9, _context10, _context11, _context12, _context13;
34517
34518 _classCallCheck(this, InteractionHandler);
34519
34520 this.body = body;
34521 this.canvas = canvas;
34522 this.selectionHandler = selectionHandler;
34523 this.navigationHandler = new NavigationHandler(body, canvas); // bind the events from hammer to functions in this object
34524
34525 this.body.eventListeners.onTap = bind$6(_context = this.onTap).call(_context, this);
34526 this.body.eventListeners.onTouch = bind$6(_context2 = this.onTouch).call(_context2, this);
34527 this.body.eventListeners.onDoubleTap = bind$6(_context3 = this.onDoubleTap).call(_context3, this);
34528 this.body.eventListeners.onHold = bind$6(_context4 = this.onHold).call(_context4, this);
34529 this.body.eventListeners.onDragStart = bind$6(_context5 = this.onDragStart).call(_context5, this);
34530 this.body.eventListeners.onDrag = bind$6(_context6 = this.onDrag).call(_context6, this);
34531 this.body.eventListeners.onDragEnd = bind$6(_context7 = this.onDragEnd).call(_context7, this);
34532 this.body.eventListeners.onMouseWheel = bind$6(_context8 = this.onMouseWheel).call(_context8, this);
34533 this.body.eventListeners.onPinch = bind$6(_context9 = this.onPinch).call(_context9, this);
34534 this.body.eventListeners.onMouseMove = bind$6(_context10 = this.onMouseMove).call(_context10, this);
34535 this.body.eventListeners.onRelease = bind$6(_context11 = this.onRelease).call(_context11, this);
34536 this.body.eventListeners.onContext = bind$6(_context12 = this.onContext).call(_context12, this);
34537 this.touchTime = 0;
34538 this.drag = {};
34539 this.pinch = {};
34540 this.popup = undefined;
34541 this.popupObj = undefined;
34542 this.popupTimer = undefined;
34543 this.body.functions.getPointer = bind$6(_context13 = this.getPointer).call(_context13, this);
34544 this.options = {};
34545 this.defaultOptions = {
34546 dragNodes: true,
34547 dragView: true,
34548 hover: false,
34549 keyboard: {
34550 enabled: false,
34551 speed: {
34552 x: 10,
34553 y: 10,
34554 zoom: 0.02
34555 },
34556 bindToWindow: true,
34557 autoFocus: true
34558 },
34559 navigationButtons: false,
34560 tooltipDelay: 300,
34561 zoomView: true,
34562 zoomSpeed: 1
34563 };
34564
34565 assign$2(this.options, this.defaultOptions);
34566
34567 this.bindEventListeners();
34568 }
34569 /**
34570 * Binds event listeners
34571 */
34572
34573
34574 _createClass(InteractionHandler, [{
34575 key: "bindEventListeners",
34576 value: function bindEventListeners() {
34577 var _this = this;
34578
34579 this.body.emitter.on("destroy", function () {
34580 clearTimeout(_this.popupTimer);
34581 delete _this.body.functions.getPointer;
34582 });
34583 }
34584 /**
34585 *
34586 * @param {object} options
34587 */
34588
34589 }, {
34590 key: "setOptions",
34591 value: function setOptions(options) {
34592 if (options !== undefined) {
34593 // extend all but the values in fields
34594 var fields = ["hideEdgesOnDrag", "hideEdgesOnZoom", "hideNodesOnDrag", "keyboard", "multiselect", "selectable", "selectConnectedEdges"];
34595 selectiveNotDeepExtend(fields, this.options, options); // merge the keyboard options in.
34596
34597 mergeOptions(this.options, options, "keyboard");
34598
34599 if (options.tooltip) {
34600 assign$2(this.options.tooltip, options.tooltip);
34601
34602 if (options.tooltip.color) {
34603 this.options.tooltip.color = parseColor(options.tooltip.color);
34604 }
34605 }
34606 }
34607
34608 this.navigationHandler.setOptions(this.options);
34609 }
34610 /**
34611 * Get the pointer location from a touch location
34612 *
34613 * @param {{x: number, y: number}} touch
34614 * @returns {{x: number, y: number}} pointer
34615 * @private
34616 */
34617
34618 }, {
34619 key: "getPointer",
34620 value: function getPointer(touch) {
34621 return {
34622 x: touch.x - getAbsoluteLeft(this.canvas.frame.canvas),
34623 y: touch.y - getAbsoluteTop(this.canvas.frame.canvas)
34624 };
34625 }
34626 /**
34627 * On start of a touch gesture, store the pointer
34628 *
34629 * @param {Event} event The event
34630 * @private
34631 */
34632
34633 }, {
34634 key: "onTouch",
34635 value: function onTouch(event) {
34636 if (new Date().valueOf() - this.touchTime > 50) {
34637 this.drag.pointer = this.getPointer(event.center);
34638 this.drag.pinched = false;
34639 this.pinch.scale = this.body.view.scale; // to avoid double fireing of this event because we have two hammer instances. (on canvas and on frame)
34640
34641 this.touchTime = new Date().valueOf();
34642 }
34643 }
34644 /**
34645 * handle tap/click event: select/unselect a node
34646 *
34647 * @param {Event} event
34648 * @private
34649 */
34650
34651 }, {
34652 key: "onTap",
34653 value: function onTap(event) {
34654 var pointer = this.getPointer(event.center);
34655 var multiselect = this.selectionHandler.options.multiselect && (event.changedPointers[0].ctrlKey || event.changedPointers[0].metaKey);
34656 this.checkSelectionChanges(pointer, multiselect);
34657 this.selectionHandler.commitAndEmit(pointer, event);
34658 this.selectionHandler.generateClickEvent("click", event, pointer);
34659 }
34660 /**
34661 * handle doubletap event
34662 *
34663 * @param {Event} event
34664 * @private
34665 */
34666
34667 }, {
34668 key: "onDoubleTap",
34669 value: function onDoubleTap(event) {
34670 var pointer = this.getPointer(event.center);
34671 this.selectionHandler.generateClickEvent("doubleClick", event, pointer);
34672 }
34673 /**
34674 * handle long tap event: multi select nodes
34675 *
34676 * @param {Event} event
34677 * @private
34678 */
34679
34680 }, {
34681 key: "onHold",
34682 value: function onHold(event) {
34683 var pointer = this.getPointer(event.center);
34684 var multiselect = this.selectionHandler.options.multiselect;
34685 this.checkSelectionChanges(pointer, multiselect);
34686 this.selectionHandler.commitAndEmit(pointer, event);
34687 this.selectionHandler.generateClickEvent("click", event, pointer);
34688 this.selectionHandler.generateClickEvent("hold", event, pointer);
34689 }
34690 /**
34691 * handle the release of the screen
34692 *
34693 * @param {Event} event
34694 * @private
34695 */
34696
34697 }, {
34698 key: "onRelease",
34699 value: function onRelease(event) {
34700 if (new Date().valueOf() - this.touchTime > 10) {
34701 var pointer = this.getPointer(event.center);
34702 this.selectionHandler.generateClickEvent("release", event, pointer); // to avoid double fireing of this event because we have two hammer instances. (on canvas and on frame)
34703
34704 this.touchTime = new Date().valueOf();
34705 }
34706 }
34707 /**
34708 *
34709 * @param {Event} event
34710 */
34711
34712 }, {
34713 key: "onContext",
34714 value: function onContext(event) {
34715 var pointer = this.getPointer({
34716 x: event.clientX,
34717 y: event.clientY
34718 });
34719 this.selectionHandler.generateClickEvent("oncontext", event, pointer);
34720 }
34721 /**
34722 * Select and deselect nodes depending current selection change.
34723 *
34724 * @param {{x: number, y: number}} pointer
34725 * @param {boolean} [add=false]
34726 */
34727
34728 }, {
34729 key: "checkSelectionChanges",
34730 value: function checkSelectionChanges(pointer) {
34731 var add = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
34732
34733 if (add === true) {
34734 this.selectionHandler.selectAdditionalOnPoint(pointer);
34735 } else {
34736 this.selectionHandler.selectOnPoint(pointer);
34737 }
34738 }
34739 /**
34740 * Remove all node and edge id's from the first set that are present in the second one.
34741 *
34742 * @param {{nodes: Array.<Node>, edges: Array.<vis.Edge>}} firstSet
34743 * @param {{nodes: Array.<Node>, edges: Array.<vis.Edge>}} secondSet
34744 * @returns {{nodes: Array.<Node>, edges: Array.<vis.Edge>}}
34745 * @private
34746 */
34747
34748 }, {
34749 key: "_determineDifference",
34750 value: function _determineDifference(firstSet, secondSet) {
34751 var arrayDiff = function arrayDiff(firstArr, secondArr) {
34752 var result = [];
34753
34754 for (var i = 0; i < firstArr.length; i++) {
34755 var value = firstArr[i];
34756
34757 if (indexOf(secondArr).call(secondArr, value) === -1) {
34758 result.push(value);
34759 }
34760 }
34761
34762 return result;
34763 };
34764
34765 return {
34766 nodes: arrayDiff(firstSet.nodes, secondSet.nodes),
34767 edges: arrayDiff(firstSet.edges, secondSet.edges)
34768 };
34769 }
34770 /**
34771 * This function is called by onDragStart.
34772 * It is separated out because we can then overload it for the datamanipulation system.
34773 *
34774 * @param {Event} event
34775 * @private
34776 */
34777
34778 }, {
34779 key: "onDragStart",
34780 value: function onDragStart(event) {
34781 // if already dragging, do not start
34782 // this can happen on touch screens with multiple fingers
34783 if (this.drag.dragging) {
34784 return;
34785 } //in case the touch event was triggered on an external div, do the initial touch now.
34786
34787
34788 if (this.drag.pointer === undefined) {
34789 this.onTouch(event);
34790 } // note: drag.pointer is set in onTouch to get the initial touch location
34791
34792
34793 var node = this.selectionHandler.getNodeAt(this.drag.pointer);
34794 this.drag.dragging = true;
34795 this.drag.selection = [];
34796 this.drag.translation = assign$2({}, this.body.view.translation); // copy the object
34797
34798 this.drag.nodeId = undefined;
34799
34800 if (event.srcEvent.shiftKey) {
34801 this.body.selectionBox.show = true;
34802 var pointer = this.getPointer(event.center);
34803 this.body.selectionBox.position.start = {
34804 x: this.canvas._XconvertDOMtoCanvas(pointer.x),
34805 y: this.canvas._YconvertDOMtoCanvas(pointer.y)
34806 };
34807 this.body.selectionBox.position.end = {
34808 x: this.canvas._XconvertDOMtoCanvas(pointer.x),
34809 y: this.canvas._YconvertDOMtoCanvas(pointer.y)
34810 };
34811 }
34812
34813 if (node !== undefined && this.options.dragNodes === true) {
34814 this.drag.nodeId = node.id; // select the clicked node if not yet selected
34815
34816 if (node.isSelected() === false) {
34817 this.selectionHandler.unselectAll();
34818 this.selectionHandler.selectObject(node);
34819 } // after select to contain the node
34820
34821
34822 this.selectionHandler.generateClickEvent("dragStart", event, this.drag.pointer); // create an array with the selected nodes and their original location and status
34823
34824 var _iterator = _createForOfIteratorHelper$4(this.selectionHandler.getSelectedNodes()),
34825 _step;
34826
34827 try {
34828 for (_iterator.s(); !(_step = _iterator.n()).done;) {
34829 var _node = _step.value;
34830 var s = {
34831 id: _node.id,
34832 node: _node,
34833 // store original x, y, xFixed and yFixed, make the node temporarily Fixed
34834 x: _node.x,
34835 y: _node.y,
34836 xFixed: _node.options.fixed.x,
34837 yFixed: _node.options.fixed.y
34838 };
34839 _node.options.fixed.x = true;
34840 _node.options.fixed.y = true;
34841 this.drag.selection.push(s);
34842 }
34843 } catch (err) {
34844 _iterator.e(err);
34845 } finally {
34846 _iterator.f();
34847 }
34848 } else {
34849 // fallback if no node is selected and thus the view is dragged.
34850 this.selectionHandler.generateClickEvent("dragStart", event, this.drag.pointer, undefined, true);
34851 }
34852 }
34853 /**
34854 * handle drag event
34855 *
34856 * @param {Event} event
34857 * @private
34858 */
34859
34860 }, {
34861 key: "onDrag",
34862 value: function onDrag(event) {
34863 var _this2 = this;
34864
34865 if (this.drag.pinched === true) {
34866 return;
34867 } // remove the focus on node if it is focussed on by the focusOnNode
34868
34869
34870 this.body.emitter.emit("unlockNode");
34871 var pointer = this.getPointer(event.center);
34872 var selection = this.drag.selection;
34873
34874 if (selection && selection.length && this.options.dragNodes === true) {
34875 this.selectionHandler.generateClickEvent("dragging", event, pointer); // calculate delta's and new location
34876
34877 var deltaX = pointer.x - this.drag.pointer.x;
34878 var deltaY = pointer.y - this.drag.pointer.y; // update position of all selected nodes
34879
34880 forEach$2(selection).call(selection, function (selection) {
34881 var node = selection.node; // only move the node if it was not fixed initially
34882
34883 if (selection.xFixed === false) {
34884 node.x = _this2.canvas._XconvertDOMtoCanvas(_this2.canvas._XconvertCanvasToDOM(selection.x) + deltaX);
34885 } // only move the node if it was not fixed initially
34886
34887
34888 if (selection.yFixed === false) {
34889 node.y = _this2.canvas._YconvertDOMtoCanvas(_this2.canvas._YconvertCanvasToDOM(selection.y) + deltaY);
34890 }
34891 }); // start the simulation of the physics
34892
34893
34894 this.body.emitter.emit("startSimulation");
34895 } else {
34896 // create selection box
34897 if (event.srcEvent.shiftKey) {
34898 this.selectionHandler.generateClickEvent("dragging", event, pointer, undefined, true); // if the drag was not started properly because the click started outside the network div, start it now.
34899
34900 if (this.drag.pointer === undefined) {
34901 this.onDragStart(event);
34902 return;
34903 }
34904
34905 this.body.selectionBox.position.end = {
34906 x: this.canvas._XconvertDOMtoCanvas(pointer.x),
34907 y: this.canvas._YconvertDOMtoCanvas(pointer.y)
34908 };
34909 this.body.emitter.emit("_requestRedraw");
34910 } // move the network
34911
34912
34913 if (this.options.dragView === true && !event.srcEvent.shiftKey) {
34914 this.selectionHandler.generateClickEvent("dragging", event, pointer, undefined, true); // if the drag was not started properly because the click started outside the network div, start it now.
34915
34916 if (this.drag.pointer === undefined) {
34917 this.onDragStart(event);
34918 return;
34919 }
34920
34921 var diffX = pointer.x - this.drag.pointer.x;
34922 var diffY = pointer.y - this.drag.pointer.y;
34923 this.body.view.translation = {
34924 x: this.drag.translation.x + diffX,
34925 y: this.drag.translation.y + diffY
34926 };
34927 this.body.emitter.emit("_requestRedraw");
34928 }
34929 }
34930 }
34931 /**
34932 * handle drag start event
34933 *
34934 * @param {Event} event
34935 * @private
34936 */
34937
34938 }, {
34939 key: "onDragEnd",
34940 value: function onDragEnd(event) {
34941 var _this3 = this;
34942
34943 this.drag.dragging = false;
34944
34945 if (this.body.selectionBox.show) {
34946 var _context14;
34947
34948 this.body.selectionBox.show = false;
34949 var selectionBoxPosition = this.body.selectionBox.position;
34950 var selectionBoxPositionMinMax = {
34951 minX: Math.min(selectionBoxPosition.start.x, selectionBoxPosition.end.x),
34952 minY: Math.min(selectionBoxPosition.start.y, selectionBoxPosition.end.y),
34953 maxX: Math.max(selectionBoxPosition.start.x, selectionBoxPosition.end.x),
34954 maxY: Math.max(selectionBoxPosition.start.y, selectionBoxPosition.end.y)
34955 };
34956
34957 var toBeSelectedNodes = filter(_context14 = this.body.nodeIndices).call(_context14, function (nodeId) {
34958 var node = _this3.body.nodes[nodeId];
34959 return node.x >= selectionBoxPositionMinMax.minX && node.x <= selectionBoxPositionMinMax.maxX && node.y >= selectionBoxPositionMinMax.minY && node.y <= selectionBoxPositionMinMax.maxY;
34960 });
34961
34962 forEach$2(toBeSelectedNodes).call(toBeSelectedNodes, function (nodeId) {
34963 return _this3.selectionHandler.selectObject(_this3.body.nodes[nodeId]);
34964 });
34965
34966 var pointer = this.getPointer(event.center);
34967 this.selectionHandler.commitAndEmit(pointer, event);
34968 this.selectionHandler.generateClickEvent("dragEnd", event, this.getPointer(event.center), undefined, true);
34969 this.body.emitter.emit("_requestRedraw");
34970 } else {
34971 var selection = this.drag.selection;
34972
34973 if (selection && selection.length) {
34974 forEach$2(selection).call(selection, function (s) {
34975 // restore original xFixed and yFixed
34976 s.node.options.fixed.x = s.xFixed;
34977 s.node.options.fixed.y = s.yFixed;
34978 });
34979
34980 this.selectionHandler.generateClickEvent("dragEnd", event, this.getPointer(event.center));
34981 this.body.emitter.emit("startSimulation");
34982 } else {
34983 this.selectionHandler.generateClickEvent("dragEnd", event, this.getPointer(event.center), undefined, true);
34984 this.body.emitter.emit("_requestRedraw");
34985 }
34986 }
34987 }
34988 /**
34989 * Handle pinch event
34990 *
34991 * @param {Event} event The event
34992 * @private
34993 */
34994
34995 }, {
34996 key: "onPinch",
34997 value: function onPinch(event) {
34998 var pointer = this.getPointer(event.center);
34999 this.drag.pinched = true;
35000
35001 if (this.pinch["scale"] === undefined) {
35002 this.pinch.scale = 1;
35003 } // TODO: enabled moving while pinching?
35004
35005
35006 var scale = this.pinch.scale * event.scale;
35007 this.zoom(scale, pointer);
35008 }
35009 /**
35010 * Zoom the network in or out
35011 *
35012 * @param {number} scale a number around 1, and between 0.01 and 10
35013 * @param {{x: number, y: number}} pointer Position on screen
35014 * @private
35015 */
35016
35017 }, {
35018 key: "zoom",
35019 value: function zoom(scale, pointer) {
35020 if (this.options.zoomView === true) {
35021 var scaleOld = this.body.view.scale;
35022
35023 if (scale < 0.00001) {
35024 scale = 0.00001;
35025 }
35026
35027 if (scale > 10) {
35028 scale = 10;
35029 }
35030
35031 var preScaleDragPointer = undefined;
35032
35033 if (this.drag !== undefined) {
35034 if (this.drag.dragging === true) {
35035 preScaleDragPointer = this.canvas.DOMtoCanvas(this.drag.pointer);
35036 }
35037 } // + this.canvas.frame.canvas.clientHeight / 2
35038
35039
35040 var translation = this.body.view.translation;
35041 var scaleFrac = scale / scaleOld;
35042 var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac;
35043 var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac;
35044 this.body.view.scale = scale;
35045 this.body.view.translation = {
35046 x: tx,
35047 y: ty
35048 };
35049
35050 if (preScaleDragPointer != undefined) {
35051 var postScaleDragPointer = this.canvas.canvasToDOM(preScaleDragPointer);
35052 this.drag.pointer.x = postScaleDragPointer.x;
35053 this.drag.pointer.y = postScaleDragPointer.y;
35054 }
35055
35056 this.body.emitter.emit("_requestRedraw");
35057
35058 if (scaleOld < scale) {
35059 this.body.emitter.emit("zoom", {
35060 direction: "+",
35061 scale: this.body.view.scale,
35062 pointer: pointer
35063 });
35064 } else {
35065 this.body.emitter.emit("zoom", {
35066 direction: "-",
35067 scale: this.body.view.scale,
35068 pointer: pointer
35069 });
35070 }
35071 }
35072 }
35073 /**
35074 * Event handler for mouse wheel event, used to zoom the timeline
35075 * See http://adomas.org/javascript-mouse-wheel/
35076 * https://github.com/EightMedia/hammer.js/issues/256
35077 *
35078 * @param {MouseEvent} event
35079 * @private
35080 */
35081
35082 }, {
35083 key: "onMouseWheel",
35084 value: function onMouseWheel(event) {
35085 if (this.options.zoomView === true) {
35086 // If delta is nonzero, handle it.
35087 // Basically, delta is now positive if wheel was scrolled up,
35088 // and negative, if wheel was scrolled down.
35089 if (event.deltaY !== 0) {
35090 // calculate the new scale
35091 var scale = this.body.view.scale;
35092 scale *= 1 + (event.deltaY < 0 ? 1 : -1) * (this.options.zoomSpeed * 0.1); // calculate the pointer location
35093
35094 var pointer = this.getPointer({
35095 x: event.clientX,
35096 y: event.clientY
35097 }); // apply the new scale
35098
35099 this.zoom(scale, pointer);
35100 } // Prevent default actions caused by mouse wheel.
35101
35102
35103 event.preventDefault();
35104 }
35105 }
35106 /**
35107 * Mouse move handler for checking whether the title moves over a node with a title.
35108 *
35109 * @param {Event} event
35110 * @private
35111 */
35112
35113 }, {
35114 key: "onMouseMove",
35115 value: function onMouseMove(event) {
35116 var _this4 = this;
35117
35118 var pointer = this.getPointer({
35119 x: event.clientX,
35120 y: event.clientY
35121 });
35122 var popupVisible = false; // check if the previously selected node is still selected
35123
35124 if (this.popup !== undefined) {
35125 if (this.popup.hidden === false) {
35126 this._checkHidePopup(pointer);
35127 } // if the popup was not hidden above
35128
35129
35130 if (this.popup.hidden === false) {
35131 popupVisible = true;
35132 this.popup.setPosition(pointer.x + 3, pointer.y - 5);
35133 this.popup.show();
35134 }
35135 } // if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over.
35136
35137
35138 if (this.options.keyboard.autoFocus && this.options.keyboard.bindToWindow === false && this.options.keyboard.enabled === true) {
35139 this.canvas.frame.focus();
35140 } // start a timeout that will check if the mouse is positioned above an element
35141
35142
35143 if (popupVisible === false) {
35144 if (this.popupTimer !== undefined) {
35145 clearInterval(this.popupTimer); // stop any running calculationTimer
35146
35147 this.popupTimer = undefined;
35148 }
35149
35150 if (!this.drag.dragging) {
35151 this.popupTimer = setTimeout$1(function () {
35152 return _this4._checkShowPopup(pointer);
35153 }, this.options.tooltipDelay);
35154 }
35155 } // adding hover highlights
35156
35157
35158 if (this.options.hover === true) {
35159 this.selectionHandler.hoverObject(event, pointer);
35160 }
35161 }
35162 /**
35163 * Check if there is an element on the given position in the network
35164 * (a node or edge). If so, and if this element has a title,
35165 * show a popup window with its title.
35166 *
35167 * @param {{x:number, y:number}} pointer
35168 * @private
35169 */
35170
35171 }, {
35172 key: "_checkShowPopup",
35173 value: function _checkShowPopup(pointer) {
35174 var x = this.canvas._XconvertDOMtoCanvas(pointer.x);
35175
35176 var y = this.canvas._YconvertDOMtoCanvas(pointer.y);
35177
35178 var pointerObj = {
35179 left: x,
35180 top: y,
35181 right: x,
35182 bottom: y
35183 };
35184 var previousPopupObjId = this.popupObj === undefined ? undefined : this.popupObj.id;
35185 var nodeUnderCursor = false;
35186 var popupType = "node"; // check if a node is under the cursor.
35187
35188 if (this.popupObj === undefined) {
35189 // search the nodes for overlap, select the top one in case of multiple nodes
35190 var nodeIndices = this.body.nodeIndices;
35191 var nodes = this.body.nodes;
35192 var node;
35193 var overlappingNodes = [];
35194
35195 for (var i = 0; i < nodeIndices.length; i++) {
35196 node = nodes[nodeIndices[i]];
35197
35198 if (node.isOverlappingWith(pointerObj) === true) {
35199 nodeUnderCursor = true;
35200
35201 if (node.getTitle() !== undefined) {
35202 overlappingNodes.push(nodeIndices[i]);
35203 }
35204 }
35205 }
35206
35207 if (overlappingNodes.length > 0) {
35208 // if there are overlapping nodes, select the last one, this is the one which is drawn on top of the others
35209 this.popupObj = nodes[overlappingNodes[overlappingNodes.length - 1]]; // if you hover over a node, the title of the edge is not supposed to be shown.
35210
35211 nodeUnderCursor = true;
35212 }
35213 }
35214
35215 if (this.popupObj === undefined && nodeUnderCursor === false) {
35216 // search the edges for overlap
35217 var edgeIndices = this.body.edgeIndices;
35218 var edges = this.body.edges;
35219 var edge;
35220 var overlappingEdges = [];
35221
35222 for (var _i = 0; _i < edgeIndices.length; _i++) {
35223 edge = edges[edgeIndices[_i]];
35224
35225 if (edge.isOverlappingWith(pointerObj) === true) {
35226 if (edge.connected === true && edge.getTitle() !== undefined) {
35227 overlappingEdges.push(edgeIndices[_i]);
35228 }
35229 }
35230 }
35231
35232 if (overlappingEdges.length > 0) {
35233 this.popupObj = edges[overlappingEdges[overlappingEdges.length - 1]];
35234 popupType = "edge";
35235 }
35236 }
35237
35238 if (this.popupObj !== undefined) {
35239 // show popup message window
35240 if (this.popupObj.id !== previousPopupObjId) {
35241 if (this.popup === undefined) {
35242 this.popup = new Popup$1(this.canvas.frame);
35243 }
35244
35245 this.popup.popupTargetType = popupType;
35246 this.popup.popupTargetId = this.popupObj.id; // adjust a small offset such that the mouse cursor is located in the
35247 // bottom left location of the popup, and you can easily move over the
35248 // popup area
35249
35250 this.popup.setPosition(pointer.x + 3, pointer.y - 5);
35251 this.popup.setText(this.popupObj.getTitle());
35252 this.popup.show();
35253 this.body.emitter.emit("showPopup", this.popupObj.id);
35254 }
35255 } else {
35256 if (this.popup !== undefined) {
35257 this.popup.hide();
35258 this.body.emitter.emit("hidePopup");
35259 }
35260 }
35261 }
35262 /**
35263 * Check if the popup must be hidden, which is the case when the mouse is no
35264 * longer hovering on the object
35265 *
35266 * @param {{x:number, y:number}} pointer
35267 * @private
35268 */
35269
35270 }, {
35271 key: "_checkHidePopup",
35272 value: function _checkHidePopup(pointer) {
35273 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer);
35274
35275 var stillOnObj = false;
35276
35277 if (this.popup.popupTargetType === "node") {
35278 if (this.body.nodes[this.popup.popupTargetId] !== undefined) {
35279 stillOnObj = this.body.nodes[this.popup.popupTargetId].isOverlappingWith(pointerObj); // if the mouse is still one the node, we have to check if it is not also on one that is drawn on top of it.
35280 // we initially only check stillOnObj because this is much faster.
35281
35282 if (stillOnObj === true) {
35283 var overNode = this.selectionHandler.getNodeAt(pointer);
35284 stillOnObj = overNode === undefined ? false : overNode.id === this.popup.popupTargetId;
35285 }
35286 }
35287 } else {
35288 if (this.selectionHandler.getNodeAt(pointer) === undefined) {
35289 if (this.body.edges[this.popup.popupTargetId] !== undefined) {
35290 stillOnObj = this.body.edges[this.popup.popupTargetId].isOverlappingWith(pointerObj);
35291 }
35292 }
35293 }
35294
35295 if (stillOnObj === false) {
35296 this.popupObj = undefined;
35297 this.popup.hide();
35298 this.body.emitter.emit("hidePopup");
35299 }
35300 }
35301 }]);
35302
35303 return InteractionHandler;
35304}();
35305
35306var redefineAll$1 = redefineAll$3;
35307var getWeakData = internalMetadata.exports.getWeakData;
35308var anObject = anObject$d;
35309var isObject$1 = isObject$j;
35310var anInstance = anInstance$3;
35311var iterate = iterate$3;
35312var ArrayIterationModule = arrayIteration;
35313var $has = has$c;
35314var InternalStateModule = internalState;
35315var setInternalState = InternalStateModule.set;
35316var internalStateGetterFor = InternalStateModule.getterFor;
35317var find = ArrayIterationModule.find;
35318var findIndex = ArrayIterationModule.findIndex;
35319var id = 0; // fallback for uncaught frozen keys
35320
35321var uncaughtFrozenStore = function (store) {
35322 return store.frozen || (store.frozen = new UncaughtFrozenStore());
35323};
35324
35325var UncaughtFrozenStore = function () {
35326 this.entries = [];
35327};
35328
35329var findUncaughtFrozen = function (store, key) {
35330 return find(store.entries, function (it) {
35331 return it[0] === key;
35332 });
35333};
35334
35335UncaughtFrozenStore.prototype = {
35336 get: function (key) {
35337 var entry = findUncaughtFrozen(this, key);
35338 if (entry) return entry[1];
35339 },
35340 has: function (key) {
35341 return !!findUncaughtFrozen(this, key);
35342 },
35343 set: function (key, value) {
35344 var entry = findUncaughtFrozen(this, key);
35345 if (entry) entry[1] = value;else this.entries.push([key, value]);
35346 },
35347 'delete': function (key) {
35348 var index = findIndex(this.entries, function (it) {
35349 return it[0] === key;
35350 });
35351 if (~index) this.entries.splice(index, 1);
35352 return !!~index;
35353 }
35354};
35355var collectionWeak$1 = {
35356 getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
35357 var C = wrapper(function (that, iterable) {
35358 anInstance(that, C, CONSTRUCTOR_NAME);
35359 setInternalState(that, {
35360 type: CONSTRUCTOR_NAME,
35361 id: id++,
35362 frozen: undefined
35363 });
35364 if (iterable != undefined) iterate(iterable, that[ADDER], {
35365 that: that,
35366 AS_ENTRIES: IS_MAP
35367 });
35368 });
35369 var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);
35370
35371 var define = function (that, key, value) {
35372 var state = getInternalState(that);
35373 var data = getWeakData(anObject(key), true);
35374 if (data === true) uncaughtFrozenStore(state).set(key, value);else data[state.id] = value;
35375 return that;
35376 };
35377
35378 redefineAll$1(C.prototype, {
35379 // `{ WeakMap, WeakSet }.prototype.delete(key)` methods
35380 // https://tc39.es/ecma262/#sec-weakmap.prototype.delete
35381 // https://tc39.es/ecma262/#sec-weakset.prototype.delete
35382 'delete': function (key) {
35383 var state = getInternalState(this);
35384 if (!isObject$1(key)) return false;
35385 var data = getWeakData(key);
35386 if (data === true) return uncaughtFrozenStore(state)['delete'](key);
35387 return data && $has(data, state.id) && delete data[state.id];
35388 },
35389 // `{ WeakMap, WeakSet }.prototype.has(key)` methods
35390 // https://tc39.es/ecma262/#sec-weakmap.prototype.has
35391 // https://tc39.es/ecma262/#sec-weakset.prototype.has
35392 has: function has(key) {
35393 var state = getInternalState(this);
35394 if (!isObject$1(key)) return false;
35395 var data = getWeakData(key);
35396 if (data === true) return uncaughtFrozenStore(state).has(key);
35397 return data && $has(data, state.id);
35398 }
35399 });
35400 redefineAll$1(C.prototype, IS_MAP ? {
35401 // `WeakMap.prototype.get(key)` method
35402 // https://tc39.es/ecma262/#sec-weakmap.prototype.get
35403 get: function get(key) {
35404 var state = getInternalState(this);
35405
35406 if (isObject$1(key)) {
35407 var data = getWeakData(key);
35408 if (data === true) return uncaughtFrozenStore(state).get(key);
35409 return data ? data[state.id] : undefined;
35410 }
35411 },
35412 // `WeakMap.prototype.set(key, value)` method
35413 // https://tc39.es/ecma262/#sec-weakmap.prototype.set
35414 set: function set(key, value) {
35415 return define(this, key, value);
35416 }
35417 } : {
35418 // `WeakSet.prototype.add(value)` method
35419 // https://tc39.es/ecma262/#sec-weakset.prototype.add
35420 add: function add(value) {
35421 return define(this, value, true);
35422 }
35423 });
35424 return C;
35425 }
35426};
35427
35428var global$1 = global$k;
35429var redefineAll = redefineAll$3;
35430var InternalMetadataModule = internalMetadata.exports;
35431var collection = collection$3;
35432var collectionWeak = collectionWeak$1;
35433var isObject = isObject$j;
35434var enforceIternalState = internalState.enforce;
35435var NATIVE_WEAK_MAP = nativeWeakMap;
35436var IS_IE11 = !global$1.ActiveXObject && 'ActiveXObject' in global$1; // eslint-disable-next-line es/no-object-isextensible -- safe
35437
35438var isExtensible = Object.isExtensible;
35439var InternalWeakMap;
35440
35441var wrapper = function (init) {
35442 return function WeakMap() {
35443 return init(this, arguments.length ? arguments[0] : undefined);
35444 };
35445}; // `WeakMap` constructor
35446// https://tc39.es/ecma262/#sec-weakmap-constructor
35447
35448
35449var $WeakMap = collection('WeakMap', wrapper, collectionWeak); // IE11 WeakMap frozen keys fix
35450// We can't use feature detection because it crash some old IE builds
35451// https://github.com/zloirock/core-js/issues/485
35452
35453if (NATIVE_WEAK_MAP && IS_IE11) {
35454 InternalWeakMap = collectionWeak.getConstructor(wrapper, 'WeakMap', true);
35455 InternalMetadataModule.enable();
35456 var WeakMapPrototype = $WeakMap.prototype;
35457 var nativeDelete = WeakMapPrototype['delete'];
35458 var nativeHas = WeakMapPrototype.has;
35459 var nativeGet = WeakMapPrototype.get;
35460 var nativeSet = WeakMapPrototype.set;
35461 redefineAll(WeakMapPrototype, {
35462 'delete': function (key) {
35463 if (isObject(key) && !isExtensible(key)) {
35464 var state = enforceIternalState(this);
35465 if (!state.frozen) state.frozen = new InternalWeakMap();
35466 return nativeDelete.call(this, key) || state.frozen['delete'](key);
35467 }
35468
35469 return nativeDelete.call(this, key);
35470 },
35471 has: function has(key) {
35472 if (isObject(key) && !isExtensible(key)) {
35473 var state = enforceIternalState(this);
35474 if (!state.frozen) state.frozen = new InternalWeakMap();
35475 return nativeHas.call(this, key) || state.frozen.has(key);
35476 }
35477
35478 return nativeHas.call(this, key);
35479 },
35480 get: function get(key) {
35481 if (isObject(key) && !isExtensible(key)) {
35482 var state = enforceIternalState(this);
35483 if (!state.frozen) state.frozen = new InternalWeakMap();
35484 return nativeHas.call(this, key) ? nativeGet.call(this, key) : state.frozen.get(key);
35485 }
35486
35487 return nativeGet.call(this, key);
35488 },
35489 set: function set(key, value) {
35490 if (isObject(key) && !isExtensible(key)) {
35491 var state = enforceIternalState(this);
35492 if (!state.frozen) state.frozen = new InternalWeakMap();
35493 nativeHas.call(this, key) ? nativeSet.call(this, key, value) : state.frozen.set(key, value);
35494 } else nativeSet.call(this, key, value);
35495
35496 return this;
35497 }
35498 });
35499}
35500
35501var path = path$x;
35502var weakMap$2 = path.WeakMap;
35503
35504var parent$1 = weakMap$2;
35505var weakMap$1 = parent$1;
35506
35507var weakMap = weakMap$1;
35508
35509/*! *****************************************************************************
35510Copyright (c) Microsoft Corporation.
35511
35512Permission to use, copy, modify, and/or distribute this software for any
35513purpose with or without fee is hereby granted.
35514
35515THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
35516REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
35517AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
35518INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
35519LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
35520OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
35521PERFORMANCE OF THIS SOFTWARE.
35522***************************************************************************** */
35523function __classPrivateFieldGet(receiver, state, kind, f) {
35524 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
35525 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
35526 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
35527}
35528function __classPrivateFieldSet(receiver, state, value, kind, f) {
35529 if (kind === "m") throw new TypeError("Private method is not writable");
35530 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
35531 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
35532 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
35533}
35534
35535function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
35536
35537function _unsupportedIterableToArray$3(o, minLen) { var _context2; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(o, minLen); var n = slice$1(_context2 = Object.prototype.toString.call(o)).call(_context2, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$3(o, minLen); }
35538
35539function _arrayLikeToArray$3(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
35540
35541var _SingleTypeSelectionAccumulator_previousSelection, _SingleTypeSelectionAccumulator_selection, _SelectionAccumulator_nodes, _SelectionAccumulator_edges, _SelectionAccumulator_commitHandler;
35542/**
35543 * @param prev
35544 * @param next
35545 */
35546
35547function diffSets(prev, next) {
35548 var diff = new set();
35549
35550 var _iterator = _createForOfIteratorHelper$3(next),
35551 _step;
35552
35553 try {
35554 for (_iterator.s(); !(_step = _iterator.n()).done;) {
35555 var item = _step.value;
35556
35557 if (!prev.has(item)) {
35558 diff.add(item);
35559 }
35560 }
35561 } catch (err) {
35562 _iterator.e(err);
35563 } finally {
35564 _iterator.f();
35565 }
35566
35567 return diff;
35568}
35569
35570var SingleTypeSelectionAccumulator = /*#__PURE__*/function () {
35571 function SingleTypeSelectionAccumulator() {
35572 _classCallCheck(this, SingleTypeSelectionAccumulator);
35573
35574 _SingleTypeSelectionAccumulator_previousSelection.set(this, new set());
35575
35576 _SingleTypeSelectionAccumulator_selection.set(this, new set());
35577 }
35578
35579 _createClass(SingleTypeSelectionAccumulator, [{
35580 key: "size",
35581 get: function get() {
35582 return __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f").size;
35583 }
35584 }, {
35585 key: "add",
35586 value: function add() {
35587 for (var _len = arguments.length, items = new Array(_len), _key = 0; _key < _len; _key++) {
35588 items[_key] = arguments[_key];
35589 }
35590
35591 for (var _i = 0, _items = items; _i < _items.length; _i++) {
35592 var item = _items[_i];
35593
35594 __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f").add(item);
35595 }
35596 }
35597 }, {
35598 key: "delete",
35599 value: function _delete() {
35600 for (var _len2 = arguments.length, items = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
35601 items[_key2] = arguments[_key2];
35602 }
35603
35604 for (var _i2 = 0, _items2 = items; _i2 < _items2.length; _i2++) {
35605 var item = _items2[_i2];
35606
35607 __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f").delete(item);
35608 }
35609 }
35610 }, {
35611 key: "clear",
35612 value: function clear() {
35613 __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f").clear();
35614 }
35615 }, {
35616 key: "getSelection",
35617 value: function getSelection() {
35618 return _toConsumableArray(__classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f"));
35619 }
35620 }, {
35621 key: "getChanges",
35622 value: function getChanges() {
35623 return {
35624 added: _toConsumableArray(diffSets(__classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_previousSelection, "f"), __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f"))),
35625 deleted: _toConsumableArray(diffSets(__classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f"), __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_previousSelection, "f"))),
35626 previous: _toConsumableArray(new set(__classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_previousSelection, "f"))),
35627 current: _toConsumableArray(new set(__classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f")))
35628 };
35629 }
35630 }, {
35631 key: "commit",
35632 value: function commit() {
35633 var changes = this.getChanges();
35634
35635 __classPrivateFieldSet(this, _SingleTypeSelectionAccumulator_previousSelection, __classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_selection, "f"), "f");
35636
35637 __classPrivateFieldSet(this, _SingleTypeSelectionAccumulator_selection, new set(__classPrivateFieldGet(this, _SingleTypeSelectionAccumulator_previousSelection, "f")), "f");
35638
35639 var _iterator2 = _createForOfIteratorHelper$3(changes.added),
35640 _step2;
35641
35642 try {
35643 for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
35644 var item = _step2.value;
35645 item.select();
35646 }
35647 } catch (err) {
35648 _iterator2.e(err);
35649 } finally {
35650 _iterator2.f();
35651 }
35652
35653 var _iterator3 = _createForOfIteratorHelper$3(changes.deleted),
35654 _step3;
35655
35656 try {
35657 for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
35658 var _item = _step3.value;
35659
35660 _item.unselect();
35661 }
35662 } catch (err) {
35663 _iterator3.e(err);
35664 } finally {
35665 _iterator3.f();
35666 }
35667
35668 return changes;
35669 }
35670 }]);
35671
35672 return SingleTypeSelectionAccumulator;
35673}();
35674
35675_SingleTypeSelectionAccumulator_previousSelection = new weakMap(), _SingleTypeSelectionAccumulator_selection = new weakMap();
35676var SelectionAccumulator = /*#__PURE__*/function () {
35677 function SelectionAccumulator() {
35678 var commitHandler = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
35679
35680 _classCallCheck(this, SelectionAccumulator);
35681
35682 _SelectionAccumulator_nodes.set(this, new SingleTypeSelectionAccumulator());
35683
35684 _SelectionAccumulator_edges.set(this, new SingleTypeSelectionAccumulator());
35685
35686 _SelectionAccumulator_commitHandler.set(this, void 0);
35687
35688 __classPrivateFieldSet(this, _SelectionAccumulator_commitHandler, commitHandler, "f");
35689 }
35690
35691 _createClass(SelectionAccumulator, [{
35692 key: "sizeNodes",
35693 get: function get() {
35694 return __classPrivateFieldGet(this, _SelectionAccumulator_nodes, "f").size;
35695 }
35696 }, {
35697 key: "sizeEdges",
35698 get: function get() {
35699 return __classPrivateFieldGet(this, _SelectionAccumulator_edges, "f").size;
35700 }
35701 }, {
35702 key: "getNodes",
35703 value: function getNodes() {
35704 return __classPrivateFieldGet(this, _SelectionAccumulator_nodes, "f").getSelection();
35705 }
35706 }, {
35707 key: "getEdges",
35708 value: function getEdges() {
35709 return __classPrivateFieldGet(this, _SelectionAccumulator_edges, "f").getSelection();
35710 }
35711 }, {
35712 key: "addNodes",
35713 value: function addNodes() {
35714 var _classPrivateFieldGe;
35715
35716 (_classPrivateFieldGe = __classPrivateFieldGet(this, _SelectionAccumulator_nodes, "f")).add.apply(_classPrivateFieldGe, arguments);
35717 }
35718 }, {
35719 key: "addEdges",
35720 value: function addEdges() {
35721 var _classPrivateFieldGe2;
35722
35723 (_classPrivateFieldGe2 = __classPrivateFieldGet(this, _SelectionAccumulator_edges, "f")).add.apply(_classPrivateFieldGe2, arguments);
35724 }
35725 }, {
35726 key: "deleteNodes",
35727 value: function deleteNodes(node) {
35728 __classPrivateFieldGet(this, _SelectionAccumulator_nodes, "f").delete(node);
35729 }
35730 }, {
35731 key: "deleteEdges",
35732 value: function deleteEdges(edge) {
35733 __classPrivateFieldGet(this, _SelectionAccumulator_edges, "f").delete(edge);
35734 }
35735 }, {
35736 key: "clear",
35737 value: function clear() {
35738 __classPrivateFieldGet(this, _SelectionAccumulator_nodes, "f").clear();
35739
35740 __classPrivateFieldGet(this, _SelectionAccumulator_edges, "f").clear();
35741 }
35742 }, {
35743 key: "commit",
35744 value: function commit() {
35745 var _classPrivateFieldGe3, _context;
35746
35747 var summary = {
35748 nodes: __classPrivateFieldGet(this, _SelectionAccumulator_nodes, "f").commit(),
35749 edges: __classPrivateFieldGet(this, _SelectionAccumulator_edges, "f").commit()
35750 };
35751
35752 for (var _len3 = arguments.length, rest = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
35753 rest[_key3] = arguments[_key3];
35754 }
35755
35756 (_classPrivateFieldGe3 = __classPrivateFieldGet(this, _SelectionAccumulator_commitHandler, "f")).call.apply(_classPrivateFieldGe3, concat(_context = [this, summary]).call(_context, rest));
35757
35758 return summary;
35759 }
35760 }]);
35761
35762 return SelectionAccumulator;
35763}();
35764_SelectionAccumulator_nodes = new weakMap(), _SelectionAccumulator_edges = new weakMap(), _SelectionAccumulator_commitHandler = new weakMap();
35765
35766function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
35767
35768function _unsupportedIterableToArray$2(o, minLen) { var _context3; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(o, minLen); var n = slice$1(_context3 = Object.prototype.toString.call(o)).call(_context3, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$2(o, minLen); }
35769
35770function _arrayLikeToArray$2(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
35771/**
35772 * The handler for selections
35773 */
35774
35775var SelectionHandler = /*#__PURE__*/function () {
35776 /**
35777 * @param {object} body
35778 * @param {Canvas} canvas
35779 */
35780 function SelectionHandler(body, canvas) {
35781 var _this = this;
35782
35783 _classCallCheck(this, SelectionHandler);
35784
35785 this.body = body;
35786 this.canvas = canvas; // TODO: Consider firing an event on any change to the selection, not
35787 // only those caused by clicks and taps. It would be easy to implement
35788 // now and (at least to me) it seems like something that could be
35789 // quite useful.
35790
35791 this._selectionAccumulator = new SelectionAccumulator();
35792 this.hoverObj = {
35793 nodes: {},
35794 edges: {}
35795 };
35796 this.options = {};
35797 this.defaultOptions = {
35798 multiselect: false,
35799 selectable: true,
35800 selectConnectedEdges: true,
35801 hoverConnectedEdges: true
35802 };
35803
35804 assign$2(this.options, this.defaultOptions);
35805
35806 this.body.emitter.on("_dataChanged", function () {
35807 _this.updateSelection();
35808 });
35809 }
35810 /**
35811 *
35812 * @param {object} [options]
35813 */
35814
35815
35816 _createClass(SelectionHandler, [{
35817 key: "setOptions",
35818 value: function setOptions(options) {
35819 if (options !== undefined) {
35820 var fields = ["multiselect", "hoverConnectedEdges", "selectable", "selectConnectedEdges"];
35821 selectiveDeepExtend(fields, this.options, options);
35822 }
35823 }
35824 /**
35825 * handles the selection part of the tap;
35826 *
35827 * @param {{x: number, y: number}} pointer
35828 * @returns {boolean}
35829 */
35830
35831 }, {
35832 key: "selectOnPoint",
35833 value: function selectOnPoint(pointer) {
35834 var selected = false;
35835
35836 if (this.options.selectable === true) {
35837 var obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer); // unselect after getting the objects in order to restore width and height.
35838
35839 this.unselectAll();
35840
35841 if (obj !== undefined) {
35842 selected = this.selectObject(obj);
35843 }
35844
35845 this.body.emitter.emit("_requestRedraw");
35846 }
35847
35848 return selected;
35849 }
35850 /**
35851 *
35852 * @param {{x: number, y: number}} pointer
35853 * @returns {boolean}
35854 */
35855
35856 }, {
35857 key: "selectAdditionalOnPoint",
35858 value: function selectAdditionalOnPoint(pointer) {
35859 var selectionChanged = false;
35860
35861 if (this.options.selectable === true) {
35862 var obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer);
35863
35864 if (obj !== undefined) {
35865 selectionChanged = true;
35866
35867 if (obj.isSelected() === true) {
35868 this.deselectObject(obj);
35869 } else {
35870 this.selectObject(obj);
35871 }
35872
35873 this.body.emitter.emit("_requestRedraw");
35874 }
35875 }
35876
35877 return selectionChanged;
35878 }
35879 /**
35880 * Create an object containing the standard fields for an event.
35881 *
35882 * @param {Event} event
35883 * @param {{x: number, y: number}} pointer Object with the x and y screen coordinates of the mouse
35884 * @returns {{}}
35885 * @private
35886 */
35887
35888 }, {
35889 key: "_initBaseEvent",
35890 value: function _initBaseEvent(event, pointer) {
35891 var properties = {};
35892 properties["pointer"] = {
35893 DOM: {
35894 x: pointer.x,
35895 y: pointer.y
35896 },
35897 canvas: this.canvas.DOMtoCanvas(pointer)
35898 };
35899 properties["event"] = event;
35900 return properties;
35901 }
35902 /**
35903 * Generate an event which the user can catch.
35904 *
35905 * This adds some extra data to the event with respect to cursor position and
35906 * selected nodes and edges.
35907 *
35908 * @param {string} eventType Name of event to send
35909 * @param {Event} event
35910 * @param {{x: number, y: number}} pointer Object with the x and y screen coordinates of the mouse
35911 * @param {object | undefined} oldSelection If present, selection state before event occured
35912 * @param {boolean|undefined} [emptySelection=false] Indicate if selection data should be passed
35913 */
35914
35915 }, {
35916 key: "generateClickEvent",
35917 value: function generateClickEvent(eventType, event, pointer, oldSelection) {
35918 var emptySelection = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
35919
35920 var properties = this._initBaseEvent(event, pointer);
35921
35922 if (emptySelection === true) {
35923 properties.nodes = [];
35924 properties.edges = [];
35925 } else {
35926 var tmp = this.getSelection();
35927 properties.nodes = tmp.nodes;
35928 properties.edges = tmp.edges;
35929 }
35930
35931 if (oldSelection !== undefined) {
35932 properties["previousSelection"] = oldSelection;
35933 }
35934
35935 if (eventType == "click") {
35936 // For the time being, restrict this functionality to
35937 // just the click event.
35938 properties.items = this.getClickedItems(pointer);
35939 }
35940
35941 if (event.controlEdge !== undefined) {
35942 properties.controlEdge = event.controlEdge;
35943 }
35944
35945 this.body.emitter.emit(eventType, properties);
35946 }
35947 /**
35948 *
35949 * @param {object} obj
35950 * @param {boolean} [highlightEdges=this.options.selectConnectedEdges]
35951 * @returns {boolean}
35952 */
35953
35954 }, {
35955 key: "selectObject",
35956 value: function selectObject(obj) {
35957 var highlightEdges = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.selectConnectedEdges;
35958
35959 if (obj !== undefined) {
35960 if (obj instanceof Node) {
35961 if (highlightEdges === true) {
35962 var _this$_selectionAccum;
35963
35964 (_this$_selectionAccum = this._selectionAccumulator).addEdges.apply(_this$_selectionAccum, _toConsumableArray(obj.edges));
35965 }
35966
35967 this._selectionAccumulator.addNodes(obj);
35968 } else {
35969 this._selectionAccumulator.addEdges(obj);
35970 }
35971
35972 return true;
35973 }
35974
35975 return false;
35976 }
35977 /**
35978 *
35979 * @param {object} obj
35980 */
35981
35982 }, {
35983 key: "deselectObject",
35984 value: function deselectObject(obj) {
35985 if (obj.isSelected() === true) {
35986 obj.selected = false;
35987
35988 this._removeFromSelection(obj);
35989 }
35990 }
35991 /**
35992 * retrieve all nodes overlapping with given object
35993 *
35994 * @param {object} object An object with parameters left, top, right, bottom
35995 * @returns {number[]} An array with id's of the overlapping nodes
35996 * @private
35997 */
35998
35999 }, {
36000 key: "_getAllNodesOverlappingWith",
36001 value: function _getAllNodesOverlappingWith(object) {
36002 var overlappingNodes = [];
36003 var nodes = this.body.nodes;
36004
36005 for (var i = 0; i < this.body.nodeIndices.length; i++) {
36006 var nodeId = this.body.nodeIndices[i];
36007
36008 if (nodes[nodeId].isOverlappingWith(object)) {
36009 overlappingNodes.push(nodeId);
36010 }
36011 }
36012
36013 return overlappingNodes;
36014 }
36015 /**
36016 * Return a position object in canvasspace from a single point in screenspace
36017 *
36018 * @param {{x: number, y: number}} pointer
36019 * @returns {{left: number, top: number, right: number, bottom: number}}
36020 * @private
36021 */
36022
36023 }, {
36024 key: "_pointerToPositionObject",
36025 value: function _pointerToPositionObject(pointer) {
36026 var canvasPos = this.canvas.DOMtoCanvas(pointer);
36027 return {
36028 left: canvasPos.x - 1,
36029 top: canvasPos.y + 1,
36030 right: canvasPos.x + 1,
36031 bottom: canvasPos.y - 1
36032 };
36033 }
36034 /**
36035 * Get the top node at the passed point (like a click)
36036 *
36037 * @param {{x: number, y: number}} pointer
36038 * @param {boolean} [returnNode=true]
36039 * @returns {Node | undefined} node
36040 */
36041
36042 }, {
36043 key: "getNodeAt",
36044 value: function getNodeAt(pointer) {
36045 var returnNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
36046
36047 // we first check if this is an navigation controls element
36048 var positionObject = this._pointerToPositionObject(pointer);
36049
36050 var overlappingNodes = this._getAllNodesOverlappingWith(positionObject); // if there are overlapping nodes, select the last one, this is the
36051 // one which is drawn on top of the others
36052
36053
36054 if (overlappingNodes.length > 0) {
36055 if (returnNode === true) {
36056 return this.body.nodes[overlappingNodes[overlappingNodes.length - 1]];
36057 } else {
36058 return overlappingNodes[overlappingNodes.length - 1];
36059 }
36060 } else {
36061 return undefined;
36062 }
36063 }
36064 /**
36065 * retrieve all edges overlapping with given object, selector is around center
36066 *
36067 * @param {object} object An object with parameters left, top, right, bottom
36068 * @param {number[]} overlappingEdges An array with id's of the overlapping nodes
36069 * @private
36070 */
36071
36072 }, {
36073 key: "_getEdgesOverlappingWith",
36074 value: function _getEdgesOverlappingWith(object, overlappingEdges) {
36075 var edges = this.body.edges;
36076
36077 for (var i = 0; i < this.body.edgeIndices.length; i++) {
36078 var edgeId = this.body.edgeIndices[i];
36079
36080 if (edges[edgeId].isOverlappingWith(object)) {
36081 overlappingEdges.push(edgeId);
36082 }
36083 }
36084 }
36085 /**
36086 * retrieve all nodes overlapping with given object
36087 *
36088 * @param {object} object An object with parameters left, top, right, bottom
36089 * @returns {number[]} An array with id's of the overlapping nodes
36090 * @private
36091 */
36092
36093 }, {
36094 key: "_getAllEdgesOverlappingWith",
36095 value: function _getAllEdgesOverlappingWith(object) {
36096 var overlappingEdges = [];
36097
36098 this._getEdgesOverlappingWith(object, overlappingEdges);
36099
36100 return overlappingEdges;
36101 }
36102 /**
36103 * Get the edges nearest to the passed point (like a click)
36104 *
36105 * @param {{x: number, y: number}} pointer
36106 * @param {boolean} [returnEdge=true]
36107 * @returns {Edge | undefined} node
36108 */
36109
36110 }, {
36111 key: "getEdgeAt",
36112 value: function getEdgeAt(pointer) {
36113 var returnEdge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
36114 // Iterate over edges, pick closest within 10
36115 var canvasPos = this.canvas.DOMtoCanvas(pointer);
36116 var mindist = 10;
36117 var overlappingEdge = null;
36118 var edges = this.body.edges;
36119
36120 for (var i = 0; i < this.body.edgeIndices.length; i++) {
36121 var edgeId = this.body.edgeIndices[i];
36122 var edge = edges[edgeId];
36123
36124 if (edge.connected) {
36125 var xFrom = edge.from.x;
36126 var yFrom = edge.from.y;
36127 var xTo = edge.to.x;
36128 var yTo = edge.to.y;
36129 var dist = edge.edgeType.getDistanceToEdge(xFrom, yFrom, xTo, yTo, canvasPos.x, canvasPos.y);
36130
36131 if (dist < mindist) {
36132 overlappingEdge = edgeId;
36133 mindist = dist;
36134 }
36135 }
36136 }
36137
36138 if (overlappingEdge !== null) {
36139 if (returnEdge === true) {
36140 return this.body.edges[overlappingEdge];
36141 } else {
36142 return overlappingEdge;
36143 }
36144 } else {
36145 return undefined;
36146 }
36147 }
36148 /**
36149 * Add object to the selection array.
36150 *
36151 * @param {object} obj
36152 * @private
36153 */
36154
36155 }, {
36156 key: "_addToHover",
36157 value: function _addToHover(obj) {
36158 if (obj instanceof Node) {
36159 this.hoverObj.nodes[obj.id] = obj;
36160 } else {
36161 this.hoverObj.edges[obj.id] = obj;
36162 }
36163 }
36164 /**
36165 * Remove a single option from selection.
36166 *
36167 * @param {object} obj
36168 * @private
36169 */
36170
36171 }, {
36172 key: "_removeFromSelection",
36173 value: function _removeFromSelection(obj) {
36174 if (obj instanceof Node) {
36175 var _this$_selectionAccum2;
36176
36177 this._selectionAccumulator.deleteNodes(obj);
36178
36179 (_this$_selectionAccum2 = this._selectionAccumulator).deleteEdges.apply(_this$_selectionAccum2, _toConsumableArray(obj.edges));
36180 } else {
36181 this._selectionAccumulator.deleteEdges(obj);
36182 }
36183 }
36184 /**
36185 * Unselect all nodes and edges.
36186 */
36187
36188 }, {
36189 key: "unselectAll",
36190 value: function unselectAll() {
36191 this._selectionAccumulator.clear();
36192 }
36193 /**
36194 * return the number of selected nodes
36195 *
36196 * @returns {number}
36197 */
36198
36199 }, {
36200 key: "getSelectedNodeCount",
36201 value: function getSelectedNodeCount() {
36202 return this._selectionAccumulator.sizeNodes;
36203 }
36204 /**
36205 * return the number of selected edges
36206 *
36207 * @returns {number}
36208 */
36209
36210 }, {
36211 key: "getSelectedEdgeCount",
36212 value: function getSelectedEdgeCount() {
36213 return this._selectionAccumulator.sizeEdges;
36214 }
36215 /**
36216 * select the edges connected to the node that is being selected
36217 *
36218 * @param {Node} node
36219 * @private
36220 */
36221
36222 }, {
36223 key: "_hoverConnectedEdges",
36224 value: function _hoverConnectedEdges(node) {
36225 for (var i = 0; i < node.edges.length; i++) {
36226 var edge = node.edges[i];
36227 edge.hover = true;
36228
36229 this._addToHover(edge);
36230 }
36231 }
36232 /**
36233 * Remove the highlight from a node or edge, in response to mouse movement
36234 *
36235 * @param {Event} event
36236 * @param {{x: number, y: number}} pointer object with the x and y screen coordinates of the mouse
36237 * @param {Node|vis.Edge} object
36238 * @private
36239 */
36240
36241 }, {
36242 key: "emitBlurEvent",
36243 value: function emitBlurEvent(event, pointer, object) {
36244 var properties = this._initBaseEvent(event, pointer);
36245
36246 if (object.hover === true) {
36247 object.hover = false;
36248
36249 if (object instanceof Node) {
36250 properties.node = object.id;
36251 this.body.emitter.emit("blurNode", properties);
36252 } else {
36253 properties.edge = object.id;
36254 this.body.emitter.emit("blurEdge", properties);
36255 }
36256 }
36257 }
36258 /**
36259 * Create the highlight for a node or edge, in response to mouse movement
36260 *
36261 * @param {Event} event
36262 * @param {{x: number, y: number}} pointer object with the x and y screen coordinates of the mouse
36263 * @param {Node|vis.Edge} object
36264 * @returns {boolean} hoverChanged
36265 * @private
36266 */
36267
36268 }, {
36269 key: "emitHoverEvent",
36270 value: function emitHoverEvent(event, pointer, object) {
36271 var properties = this._initBaseEvent(event, pointer);
36272
36273 var hoverChanged = false;
36274
36275 if (object.hover === false) {
36276 object.hover = true;
36277
36278 this._addToHover(object);
36279
36280 hoverChanged = true;
36281
36282 if (object instanceof Node) {
36283 properties.node = object.id;
36284 this.body.emitter.emit("hoverNode", properties);
36285 } else {
36286 properties.edge = object.id;
36287 this.body.emitter.emit("hoverEdge", properties);
36288 }
36289 }
36290
36291 return hoverChanged;
36292 }
36293 /**
36294 * Perform actions in response to a mouse movement.
36295 *
36296 * @param {Event} event
36297 * @param {{x: number, y: number}} pointer | object with the x and y screen coordinates of the mouse
36298 */
36299
36300 }, {
36301 key: "hoverObject",
36302 value: function hoverObject(event, pointer) {
36303 var object = this.getNodeAt(pointer);
36304
36305 if (object === undefined) {
36306 object = this.getEdgeAt(pointer);
36307 }
36308
36309 var hoverChanged = false; // remove all node hover highlights
36310
36311 for (var nodeId in this.hoverObj.nodes) {
36312 if (Object.prototype.hasOwnProperty.call(this.hoverObj.nodes, nodeId)) {
36313 if (object === undefined || object instanceof Node && object.id != nodeId || object instanceof Edge) {
36314 this.emitBlurEvent(event, pointer, this.hoverObj.nodes[nodeId]);
36315 delete this.hoverObj.nodes[nodeId];
36316 hoverChanged = true;
36317 }
36318 }
36319 } // removing all edge hover highlights
36320
36321
36322 for (var edgeId in this.hoverObj.edges) {
36323 if (Object.prototype.hasOwnProperty.call(this.hoverObj.edges, edgeId)) {
36324 // if the hover has been changed here it means that the node has been hovered over or off
36325 // we then do not use the emitBlurEvent method here.
36326 if (hoverChanged === true) {
36327 this.hoverObj.edges[edgeId].hover = false;
36328 delete this.hoverObj.edges[edgeId];
36329 } // if the blur remains the same and the object is undefined (mouse off) or another
36330 // edge has been hovered, or another node has been hovered we blur the edge.
36331 else if (object === undefined || object instanceof Edge && object.id != edgeId || object instanceof Node && !object.hover) {
36332 this.emitBlurEvent(event, pointer, this.hoverObj.edges[edgeId]);
36333 delete this.hoverObj.edges[edgeId];
36334 hoverChanged = true;
36335 }
36336 }
36337 }
36338
36339 if (object !== undefined) {
36340 var hoveredEdgesCount = keys$4(this.hoverObj.edges).length;
36341
36342 var hoveredNodesCount = keys$4(this.hoverObj.nodes).length;
36343
36344 var newOnlyHoveredEdge = object instanceof Edge && hoveredEdgesCount === 0 && hoveredNodesCount === 0;
36345 var newOnlyHoveredNode = object instanceof Node && hoveredEdgesCount === 0 && hoveredNodesCount === 0;
36346
36347 if (hoverChanged || newOnlyHoveredEdge || newOnlyHoveredNode) {
36348 hoverChanged = this.emitHoverEvent(event, pointer, object);
36349 }
36350
36351 if (object instanceof Node && this.options.hoverConnectedEdges === true) {
36352 this._hoverConnectedEdges(object);
36353 }
36354 }
36355
36356 if (hoverChanged === true) {
36357 this.body.emitter.emit("_requestRedraw");
36358 }
36359 }
36360 /**
36361 * Commit the selection changes but don't emit any events.
36362 */
36363
36364 }, {
36365 key: "commitWithoutEmitting",
36366 value: function commitWithoutEmitting() {
36367 this._selectionAccumulator.commit();
36368 }
36369 /**
36370 * Select and deselect nodes depending current selection change.
36371 *
36372 * For changing nodes, select/deselect events are fired.
36373 *
36374 * NOTE: For a given edge, if one connecting node is deselected and with the
36375 * same click the other node is selected, no events for the edge will fire. It
36376 * was selected and it will remain selected.
36377 *
36378 * @param {{x: number, y: number}} pointer - The x and y coordinates of the
36379 * click, tap, dragend… that triggered this.
36380 * @param {UIEvent} event - The event that triggered this.
36381 */
36382
36383 }, {
36384 key: "commitAndEmit",
36385 value: function commitAndEmit(pointer, event) {
36386 var selected = false;
36387
36388 var selectionChanges = this._selectionAccumulator.commit();
36389
36390 var previousSelection = {
36391 nodes: selectionChanges.nodes.previous,
36392 edges: selectionChanges.edges.previous
36393 };
36394
36395 if (selectionChanges.edges.deleted.length > 0) {
36396 this.generateClickEvent("deselectEdge", event, pointer, previousSelection);
36397 selected = true;
36398 }
36399
36400 if (selectionChanges.nodes.deleted.length > 0) {
36401 this.generateClickEvent("deselectNode", event, pointer, previousSelection);
36402 selected = true;
36403 }
36404
36405 if (selectionChanges.nodes.added.length > 0) {
36406 this.generateClickEvent("selectNode", event, pointer);
36407 selected = true;
36408 }
36409
36410 if (selectionChanges.edges.added.length > 0) {
36411 this.generateClickEvent("selectEdge", event, pointer);
36412 selected = true;
36413 } // fire the select event if anything has been selected or deselected
36414
36415
36416 if (selected === true) {
36417 // select or unselect
36418 this.generateClickEvent("select", event, pointer);
36419 }
36420 }
36421 /**
36422 * Retrieve the currently selected node and edge ids.
36423 *
36424 * @returns {{nodes: Array.<string>, edges: Array.<string>}} Arrays with the
36425 * ids of the selected nodes and edges.
36426 */
36427
36428 }, {
36429 key: "getSelection",
36430 value: function getSelection() {
36431 return {
36432 nodes: this.getSelectedNodeIds(),
36433 edges: this.getSelectedEdgeIds()
36434 };
36435 }
36436 /**
36437 * Retrieve the currently selected nodes.
36438 *
36439 * @returns {Array} An array with selected nodes.
36440 */
36441
36442 }, {
36443 key: "getSelectedNodes",
36444 value: function getSelectedNodes() {
36445 return this._selectionAccumulator.getNodes();
36446 }
36447 /**
36448 * Retrieve the currently selected edges.
36449 *
36450 * @returns {Array} An array with selected edges.
36451 */
36452
36453 }, {
36454 key: "getSelectedEdges",
36455 value: function getSelectedEdges() {
36456 return this._selectionAccumulator.getEdges();
36457 }
36458 /**
36459 * Retrieve the currently selected node ids.
36460 *
36461 * @returns {Array} An array with the ids of the selected nodes.
36462 */
36463
36464 }, {
36465 key: "getSelectedNodeIds",
36466 value: function getSelectedNodeIds() {
36467 var _context;
36468
36469 return map$3(_context = this._selectionAccumulator.getNodes()).call(_context, function (node) {
36470 return node.id;
36471 });
36472 }
36473 /**
36474 * Retrieve the currently selected edge ids.
36475 *
36476 * @returns {Array} An array with the ids of the selected edges.
36477 */
36478
36479 }, {
36480 key: "getSelectedEdgeIds",
36481 value: function getSelectedEdgeIds() {
36482 var _context2;
36483
36484 return map$3(_context2 = this._selectionAccumulator.getEdges()).call(_context2, function (edge) {
36485 return edge.id;
36486 });
36487 }
36488 /**
36489 * Updates the current selection
36490 *
36491 * @param {{nodes: Array.<string>, edges: Array.<string>}} selection
36492 * @param {object} options Options
36493 */
36494
36495 }, {
36496 key: "setSelection",
36497 value: function setSelection(selection) {
36498 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
36499
36500 if (!selection || !selection.nodes && !selection.edges) {
36501 throw new TypeError("Selection must be an object with nodes and/or edges properties");
36502 } // first unselect any selected node, if option is true or undefined
36503
36504
36505 if (options.unselectAll || options.unselectAll === undefined) {
36506 this.unselectAll();
36507 }
36508
36509 if (selection.nodes) {
36510 var _iterator = _createForOfIteratorHelper$2(selection.nodes),
36511 _step;
36512
36513 try {
36514 for (_iterator.s(); !(_step = _iterator.n()).done;) {
36515 var id = _step.value;
36516 var node = this.body.nodes[id];
36517
36518 if (!node) {
36519 throw new RangeError('Node with id "' + id + '" not found');
36520 } // don't select edges with it
36521
36522
36523 this.selectObject(node, options.highlightEdges);
36524 }
36525 } catch (err) {
36526 _iterator.e(err);
36527 } finally {
36528 _iterator.f();
36529 }
36530 }
36531
36532 if (selection.edges) {
36533 var _iterator2 = _createForOfIteratorHelper$2(selection.edges),
36534 _step2;
36535
36536 try {
36537 for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
36538 var _id = _step2.value;
36539 var edge = this.body.edges[_id];
36540
36541 if (!edge) {
36542 throw new RangeError('Edge with id "' + _id + '" not found');
36543 }
36544
36545 this.selectObject(edge);
36546 }
36547 } catch (err) {
36548 _iterator2.e(err);
36549 } finally {
36550 _iterator2.f();
36551 }
36552 }
36553
36554 this.body.emitter.emit("_requestRedraw");
36555
36556 this._selectionAccumulator.commit();
36557 }
36558 /**
36559 * select zero or more nodes with the option to highlight edges
36560 *
36561 * @param {number[] | string[]} selection An array with the ids of the
36562 * selected nodes.
36563 * @param {boolean} [highlightEdges]
36564 */
36565
36566 }, {
36567 key: "selectNodes",
36568 value: function selectNodes(selection) {
36569 var highlightEdges = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
36570 if (!selection || selection.length === undefined) throw "Selection must be an array with ids";
36571 this.setSelection({
36572 nodes: selection
36573 }, {
36574 highlightEdges: highlightEdges
36575 });
36576 }
36577 /**
36578 * select zero or more edges
36579 *
36580 * @param {number[] | string[]} selection An array with the ids of the
36581 * selected nodes.
36582 */
36583
36584 }, {
36585 key: "selectEdges",
36586 value: function selectEdges(selection) {
36587 if (!selection || selection.length === undefined) throw "Selection must be an array with ids";
36588 this.setSelection({
36589 edges: selection
36590 });
36591 }
36592 /**
36593 * Validate the selection: remove ids of nodes which no longer exist
36594 *
36595 * @private
36596 */
36597
36598 }, {
36599 key: "updateSelection",
36600 value: function updateSelection() {
36601 for (var node in this._selectionAccumulator.getNodes()) {
36602 if (!Object.prototype.hasOwnProperty.call(this.body.nodes, node.id)) {
36603 this._selectionAccumulator.deleteNodes(node);
36604 }
36605 }
36606
36607 for (var edge in this._selectionAccumulator.getEdges()) {
36608 if (!Object.prototype.hasOwnProperty.call(this.body.edges, edge.id)) {
36609 this._selectionAccumulator.deleteEdges(edge);
36610 }
36611 }
36612 }
36613 /**
36614 * Determine all the visual elements clicked which are on the given point.
36615 *
36616 * All elements are returned; this includes nodes, edges and their labels.
36617 * The order returned is from highest to lowest, i.e. element 0 of the return
36618 * value is the topmost item clicked on.
36619 *
36620 * The return value consists of an array of the following possible elements:
36621 *
36622 * - `{nodeId:number}` - node with given id clicked on
36623 * - `{nodeId:number, labelId:0}` - label of node with given id clicked on
36624 * - `{edgeId:number}` - edge with given id clicked on
36625 * - `{edge:number, labelId:0}` - label of edge with given id clicked on
36626 *
36627 * ## NOTES
36628 *
36629 * - Currently, there is only one label associated with a node or an edge,
36630 * but this is expected to change somewhere in the future.
36631 * - Since there is no z-indexing yet, it is not really possible to set the nodes and
36632 * edges in the correct order. For the time being, nodes come first.
36633 *
36634 * @param {point} pointer mouse position in screen coordinates
36635 * @returns {Array.<nodeClickItem|nodeLabelClickItem|edgeClickItem|edgeLabelClickItem>}
36636 * @private
36637 */
36638
36639 }, {
36640 key: "getClickedItems",
36641 value: function getClickedItems(pointer) {
36642 var point = this.canvas.DOMtoCanvas(pointer);
36643 var items = []; // Note reverse order; we want the topmost clicked items to be first in the array
36644 // Also note that selected nodes are disregarded here; these normally display on top
36645
36646 var nodeIndices = this.body.nodeIndices;
36647 var nodes = this.body.nodes;
36648
36649 for (var i = nodeIndices.length - 1; i >= 0; i--) {
36650 var node = nodes[nodeIndices[i]];
36651 var ret = node.getItemsOnPoint(point);
36652 items.push.apply(items, ret); // Append the return value to the running list.
36653 }
36654
36655 var edgeIndices = this.body.edgeIndices;
36656 var edges = this.body.edges;
36657
36658 for (var _i = edgeIndices.length - 1; _i >= 0; _i--) {
36659 var edge = edges[edgeIndices[_i]];
36660
36661 var _ret = edge.getItemsOnPoint(point);
36662
36663 items.push.apply(items, _ret); // Append the return value to the running list.
36664 }
36665
36666 return items;
36667 }
36668 }]);
36669
36670 return SelectionHandler;
36671}();
36672
36673var timsort$1 = {};
36674
36675/****
36676 * The MIT License
36677 *
36678 * Copyright (c) 2015 Marco Ziccardi
36679 *
36680 * Permission is hereby granted, free of charge, to any person obtaining a copy
36681 * of this software and associated documentation files (the "Software"), to deal
36682 * in the Software without restriction, including without limitation the rights
36683 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36684 * copies of the Software, and to permit persons to whom the Software is
36685 * furnished to do so, subject to the following conditions:
36686 *
36687 * The above copyright notice and this permission notice shall be included in
36688 * all copies or substantial portions of the Software.
36689 *
36690 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36691 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36692 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36693 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36694 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36695 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36696 * THE SOFTWARE.
36697 *
36698 ****/
36699
36700(function (exports) {
36701 (function (global, factory) {
36702 {
36703 factory(exports);
36704 }
36705 })(commonjsGlobal, function (exports) {
36706
36707 exports.__esModule = true;
36708 exports.sort = sort;
36709
36710 function _classCallCheck(instance, Constructor) {
36711 if (!(instance instanceof Constructor)) {
36712 throw new TypeError('Cannot call a class as a function');
36713 }
36714 }
36715
36716 var DEFAULT_MIN_MERGE = 32;
36717 var DEFAULT_MIN_GALLOPING = 7;
36718 var DEFAULT_TMP_STORAGE_LENGTH = 256;
36719 var POWERS_OF_TEN = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9];
36720
36721 function log10(x) {
36722 if (x < 1e5) {
36723 if (x < 1e2) {
36724 return x < 1e1 ? 0 : 1;
36725 }
36726
36727 if (x < 1e4) {
36728 return x < 1e3 ? 2 : 3;
36729 }
36730
36731 return 4;
36732 }
36733
36734 if (x < 1e7) {
36735 return x < 1e6 ? 5 : 6;
36736 }
36737
36738 if (x < 1e9) {
36739 return x < 1e8 ? 7 : 8;
36740 }
36741
36742 return 9;
36743 }
36744
36745 function alphabeticalCompare(a, b) {
36746 if (a === b) {
36747 return 0;
36748 }
36749
36750 if (~~a === a && ~~b === b) {
36751 if (a === 0 || b === 0) {
36752 return a < b ? -1 : 1;
36753 }
36754
36755 if (a < 0 || b < 0) {
36756 if (b >= 0) {
36757 return -1;
36758 }
36759
36760 if (a >= 0) {
36761 return 1;
36762 }
36763
36764 a = -a;
36765 b = -b;
36766 }
36767
36768 var al = log10(a);
36769 var bl = log10(b);
36770 var t = 0;
36771
36772 if (al < bl) {
36773 a *= POWERS_OF_TEN[bl - al - 1];
36774 b /= 10;
36775 t = -1;
36776 } else if (al > bl) {
36777 b *= POWERS_OF_TEN[al - bl - 1];
36778 a /= 10;
36779 t = 1;
36780 }
36781
36782 if (a === b) {
36783 return t;
36784 }
36785
36786 return a < b ? -1 : 1;
36787 }
36788
36789 var aStr = String(a);
36790 var bStr = String(b);
36791
36792 if (aStr === bStr) {
36793 return 0;
36794 }
36795
36796 return aStr < bStr ? -1 : 1;
36797 }
36798
36799 function minRunLength(n) {
36800 var r = 0;
36801
36802 while (n >= DEFAULT_MIN_MERGE) {
36803 r |= n & 1;
36804 n >>= 1;
36805 }
36806
36807 return n + r;
36808 }
36809
36810 function makeAscendingRun(array, lo, hi, compare) {
36811 var runHi = lo + 1;
36812
36813 if (runHi === hi) {
36814 return 1;
36815 }
36816
36817 if (compare(array[runHi++], array[lo]) < 0) {
36818 while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
36819 runHi++;
36820 }
36821
36822 reverseRun(array, lo, runHi);
36823 } else {
36824 while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
36825 runHi++;
36826 }
36827 }
36828
36829 return runHi - lo;
36830 }
36831
36832 function reverseRun(array, lo, hi) {
36833 hi--;
36834
36835 while (lo < hi) {
36836 var t = array[lo];
36837 array[lo++] = array[hi];
36838 array[hi--] = t;
36839 }
36840 }
36841
36842 function binaryInsertionSort(array, lo, hi, start, compare) {
36843 if (start === lo) {
36844 start++;
36845 }
36846
36847 for (; start < hi; start++) {
36848 var pivot = array[start];
36849 var left = lo;
36850 var right = start;
36851
36852 while (left < right) {
36853 var mid = left + right >>> 1;
36854
36855 if (compare(pivot, array[mid]) < 0) {
36856 right = mid;
36857 } else {
36858 left = mid + 1;
36859 }
36860 }
36861
36862 var n = start - left;
36863
36864 switch (n) {
36865 case 3:
36866 array[left + 3] = array[left + 2];
36867
36868 case 2:
36869 array[left + 2] = array[left + 1];
36870
36871 case 1:
36872 array[left + 1] = array[left];
36873 break;
36874
36875 default:
36876 while (n > 0) {
36877 array[left + n] = array[left + n - 1];
36878 n--;
36879 }
36880
36881 }
36882
36883 array[left] = pivot;
36884 }
36885 }
36886
36887 function gallopLeft(value, array, start, length, hint, compare) {
36888 var lastOffset = 0;
36889 var maxOffset = 0;
36890 var offset = 1;
36891
36892 if (compare(value, array[start + hint]) > 0) {
36893 maxOffset = length - hint;
36894
36895 while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
36896 lastOffset = offset;
36897 offset = (offset << 1) + 1;
36898
36899 if (offset <= 0) {
36900 offset = maxOffset;
36901 }
36902 }
36903
36904 if (offset > maxOffset) {
36905 offset = maxOffset;
36906 }
36907
36908 lastOffset += hint;
36909 offset += hint;
36910 } else {
36911 maxOffset = hint + 1;
36912
36913 while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
36914 lastOffset = offset;
36915 offset = (offset << 1) + 1;
36916
36917 if (offset <= 0) {
36918 offset = maxOffset;
36919 }
36920 }
36921
36922 if (offset > maxOffset) {
36923 offset = maxOffset;
36924 }
36925
36926 var tmp = lastOffset;
36927 lastOffset = hint - offset;
36928 offset = hint - tmp;
36929 }
36930
36931 lastOffset++;
36932
36933 while (lastOffset < offset) {
36934 var m = lastOffset + (offset - lastOffset >>> 1);
36935
36936 if (compare(value, array[start + m]) > 0) {
36937 lastOffset = m + 1;
36938 } else {
36939 offset = m;
36940 }
36941 }
36942
36943 return offset;
36944 }
36945
36946 function gallopRight(value, array, start, length, hint, compare) {
36947 var lastOffset = 0;
36948 var maxOffset = 0;
36949 var offset = 1;
36950
36951 if (compare(value, array[start + hint]) < 0) {
36952 maxOffset = hint + 1;
36953
36954 while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
36955 lastOffset = offset;
36956 offset = (offset << 1) + 1;
36957
36958 if (offset <= 0) {
36959 offset = maxOffset;
36960 }
36961 }
36962
36963 if (offset > maxOffset) {
36964 offset = maxOffset;
36965 }
36966
36967 var tmp = lastOffset;
36968 lastOffset = hint - offset;
36969 offset = hint - tmp;
36970 } else {
36971 maxOffset = length - hint;
36972
36973 while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
36974 lastOffset = offset;
36975 offset = (offset << 1) + 1;
36976
36977 if (offset <= 0) {
36978 offset = maxOffset;
36979 }
36980 }
36981
36982 if (offset > maxOffset) {
36983 offset = maxOffset;
36984 }
36985
36986 lastOffset += hint;
36987 offset += hint;
36988 }
36989
36990 lastOffset++;
36991
36992 while (lastOffset < offset) {
36993 var m = lastOffset + (offset - lastOffset >>> 1);
36994
36995 if (compare(value, array[start + m]) < 0) {
36996 offset = m;
36997 } else {
36998 lastOffset = m + 1;
36999 }
37000 }
37001
37002 return offset;
37003 }
37004
37005 var TimSort = function () {
37006 function TimSort(array, compare) {
37007 _classCallCheck(this, TimSort);
37008
37009 this.array = null;
37010 this.compare = null;
37011 this.minGallop = DEFAULT_MIN_GALLOPING;
37012 this.length = 0;
37013 this.tmpStorageLength = DEFAULT_TMP_STORAGE_LENGTH;
37014 this.stackLength = 0;
37015 this.runStart = null;
37016 this.runLength = null;
37017 this.stackSize = 0;
37018 this.array = array;
37019 this.compare = compare;
37020 this.length = array.length;
37021
37022 if (this.length < 2 * DEFAULT_TMP_STORAGE_LENGTH) {
37023 this.tmpStorageLength = this.length >>> 1;
37024 }
37025
37026 this.tmp = new Array(this.tmpStorageLength);
37027 this.stackLength = this.length < 120 ? 5 : this.length < 1542 ? 10 : this.length < 119151 ? 19 : 40;
37028 this.runStart = new Array(this.stackLength);
37029 this.runLength = new Array(this.stackLength);
37030 }
37031
37032 TimSort.prototype.pushRun = function pushRun(runStart, runLength) {
37033 this.runStart[this.stackSize] = runStart;
37034 this.runLength[this.stackSize] = runLength;
37035 this.stackSize += 1;
37036 };
37037
37038 TimSort.prototype.mergeRuns = function mergeRuns() {
37039 while (this.stackSize > 1) {
37040 var n = this.stackSize - 2;
37041
37042 if (n >= 1 && this.runLength[n - 1] <= this.runLength[n] + this.runLength[n + 1] || n >= 2 && this.runLength[n - 2] <= this.runLength[n] + this.runLength[n - 1]) {
37043 if (this.runLength[n - 1] < this.runLength[n + 1]) {
37044 n--;
37045 }
37046 } else if (this.runLength[n] > this.runLength[n + 1]) {
37047 break;
37048 }
37049
37050 this.mergeAt(n);
37051 }
37052 };
37053
37054 TimSort.prototype.forceMergeRuns = function forceMergeRuns() {
37055 while (this.stackSize > 1) {
37056 var n = this.stackSize - 2;
37057
37058 if (n > 0 && this.runLength[n - 1] < this.runLength[n + 1]) {
37059 n--;
37060 }
37061
37062 this.mergeAt(n);
37063 }
37064 };
37065
37066 TimSort.prototype.mergeAt = function mergeAt(i) {
37067 var compare = this.compare;
37068 var array = this.array;
37069 var start1 = this.runStart[i];
37070 var length1 = this.runLength[i];
37071 var start2 = this.runStart[i + 1];
37072 var length2 = this.runLength[i + 1];
37073 this.runLength[i] = length1 + length2;
37074
37075 if (i === this.stackSize - 3) {
37076 this.runStart[i + 1] = this.runStart[i + 2];
37077 this.runLength[i + 1] = this.runLength[i + 2];
37078 }
37079
37080 this.stackSize--;
37081 var k = gallopRight(array[start2], array, start1, length1, 0, compare);
37082 start1 += k;
37083 length1 -= k;
37084
37085 if (length1 === 0) {
37086 return;
37087 }
37088
37089 length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);
37090
37091 if (length2 === 0) {
37092 return;
37093 }
37094
37095 if (length1 <= length2) {
37096 this.mergeLow(start1, length1, start2, length2);
37097 } else {
37098 this.mergeHigh(start1, length1, start2, length2);
37099 }
37100 };
37101
37102 TimSort.prototype.mergeLow = function mergeLow(start1, length1, start2, length2) {
37103 var compare = this.compare;
37104 var array = this.array;
37105 var tmp = this.tmp;
37106 var i = 0;
37107
37108 for (i = 0; i < length1; i++) {
37109 tmp[i] = array[start1 + i];
37110 }
37111
37112 var cursor1 = 0;
37113 var cursor2 = start2;
37114 var dest = start1;
37115 array[dest++] = array[cursor2++];
37116
37117 if (--length2 === 0) {
37118 for (i = 0; i < length1; i++) {
37119 array[dest + i] = tmp[cursor1 + i];
37120 }
37121
37122 return;
37123 }
37124
37125 if (length1 === 1) {
37126 for (i = 0; i < length2; i++) {
37127 array[dest + i] = array[cursor2 + i];
37128 }
37129
37130 array[dest + length2] = tmp[cursor1];
37131 return;
37132 }
37133
37134 var minGallop = this.minGallop;
37135
37136 while (true) {
37137 var count1 = 0;
37138 var count2 = 0;
37139 var exit = false;
37140
37141 do {
37142 if (compare(array[cursor2], tmp[cursor1]) < 0) {
37143 array[dest++] = array[cursor2++];
37144 count2++;
37145 count1 = 0;
37146
37147 if (--length2 === 0) {
37148 exit = true;
37149 break;
37150 }
37151 } else {
37152 array[dest++] = tmp[cursor1++];
37153 count1++;
37154 count2 = 0;
37155
37156 if (--length1 === 1) {
37157 exit = true;
37158 break;
37159 }
37160 }
37161 } while ((count1 | count2) < minGallop);
37162
37163 if (exit) {
37164 break;
37165 }
37166
37167 do {
37168 count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);
37169
37170 if (count1 !== 0) {
37171 for (i = 0; i < count1; i++) {
37172 array[dest + i] = tmp[cursor1 + i];
37173 }
37174
37175 dest += count1;
37176 cursor1 += count1;
37177 length1 -= count1;
37178
37179 if (length1 <= 1) {
37180 exit = true;
37181 break;
37182 }
37183 }
37184
37185 array[dest++] = array[cursor2++];
37186
37187 if (--length2 === 0) {
37188 exit = true;
37189 break;
37190 }
37191
37192 count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);
37193
37194 if (count2 !== 0) {
37195 for (i = 0; i < count2; i++) {
37196 array[dest + i] = array[cursor2 + i];
37197 }
37198
37199 dest += count2;
37200 cursor2 += count2;
37201 length2 -= count2;
37202
37203 if (length2 === 0) {
37204 exit = true;
37205 break;
37206 }
37207 }
37208
37209 array[dest++] = tmp[cursor1++];
37210
37211 if (--length1 === 1) {
37212 exit = true;
37213 break;
37214 }
37215
37216 minGallop--;
37217 } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
37218
37219 if (exit) {
37220 break;
37221 }
37222
37223 if (minGallop < 0) {
37224 minGallop = 0;
37225 }
37226
37227 minGallop += 2;
37228 }
37229
37230 this.minGallop = minGallop;
37231
37232 if (minGallop < 1) {
37233 this.minGallop = 1;
37234 }
37235
37236 if (length1 === 1) {
37237 for (i = 0; i < length2; i++) {
37238 array[dest + i] = array[cursor2 + i];
37239 }
37240
37241 array[dest + length2] = tmp[cursor1];
37242 } else if (length1 === 0) {
37243 throw new Error('mergeLow preconditions were not respected');
37244 } else {
37245 for (i = 0; i < length1; i++) {
37246 array[dest + i] = tmp[cursor1 + i];
37247 }
37248 }
37249 };
37250
37251 TimSort.prototype.mergeHigh = function mergeHigh(start1, length1, start2, length2) {
37252 var compare = this.compare;
37253 var array = this.array;
37254 var tmp = this.tmp;
37255 var i = 0;
37256
37257 for (i = 0; i < length2; i++) {
37258 tmp[i] = array[start2 + i];
37259 }
37260
37261 var cursor1 = start1 + length1 - 1;
37262 var cursor2 = length2 - 1;
37263 var dest = start2 + length2 - 1;
37264 var customCursor = 0;
37265 var customDest = 0;
37266 array[dest--] = array[cursor1--];
37267
37268 if (--length1 === 0) {
37269 customCursor = dest - (length2 - 1);
37270
37271 for (i = 0; i < length2; i++) {
37272 array[customCursor + i] = tmp[i];
37273 }
37274
37275 return;
37276 }
37277
37278 if (length2 === 1) {
37279 dest -= length1;
37280 cursor1 -= length1;
37281 customDest = dest + 1;
37282 customCursor = cursor1 + 1;
37283
37284 for (i = length1 - 1; i >= 0; i--) {
37285 array[customDest + i] = array[customCursor + i];
37286 }
37287
37288 array[dest] = tmp[cursor2];
37289 return;
37290 }
37291
37292 var minGallop = this.minGallop;
37293
37294 while (true) {
37295 var count1 = 0;
37296 var count2 = 0;
37297 var exit = false;
37298
37299 do {
37300 if (compare(tmp[cursor2], array[cursor1]) < 0) {
37301 array[dest--] = array[cursor1--];
37302 count1++;
37303 count2 = 0;
37304
37305 if (--length1 === 0) {
37306 exit = true;
37307 break;
37308 }
37309 } else {
37310 array[dest--] = tmp[cursor2--];
37311 count2++;
37312 count1 = 0;
37313
37314 if (--length2 === 1) {
37315 exit = true;
37316 break;
37317 }
37318 }
37319 } while ((count1 | count2) < minGallop);
37320
37321 if (exit) {
37322 break;
37323 }
37324
37325 do {
37326 count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);
37327
37328 if (count1 !== 0) {
37329 dest -= count1;
37330 cursor1 -= count1;
37331 length1 -= count1;
37332 customDest = dest + 1;
37333 customCursor = cursor1 + 1;
37334
37335 for (i = count1 - 1; i >= 0; i--) {
37336 array[customDest + i] = array[customCursor + i];
37337 }
37338
37339 if (length1 === 0) {
37340 exit = true;
37341 break;
37342 }
37343 }
37344
37345 array[dest--] = tmp[cursor2--];
37346
37347 if (--length2 === 1) {
37348 exit = true;
37349 break;
37350 }
37351
37352 count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);
37353
37354 if (count2 !== 0) {
37355 dest -= count2;
37356 cursor2 -= count2;
37357 length2 -= count2;
37358 customDest = dest + 1;
37359 customCursor = cursor2 + 1;
37360
37361 for (i = 0; i < count2; i++) {
37362 array[customDest + i] = tmp[customCursor + i];
37363 }
37364
37365 if (length2 <= 1) {
37366 exit = true;
37367 break;
37368 }
37369 }
37370
37371 array[dest--] = array[cursor1--];
37372
37373 if (--length1 === 0) {
37374 exit = true;
37375 break;
37376 }
37377
37378 minGallop--;
37379 } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
37380
37381 if (exit) {
37382 break;
37383 }
37384
37385 if (minGallop < 0) {
37386 minGallop = 0;
37387 }
37388
37389 minGallop += 2;
37390 }
37391
37392 this.minGallop = minGallop;
37393
37394 if (minGallop < 1) {
37395 this.minGallop = 1;
37396 }
37397
37398 if (length2 === 1) {
37399 dest -= length1;
37400 cursor1 -= length1;
37401 customDest = dest + 1;
37402 customCursor = cursor1 + 1;
37403
37404 for (i = length1 - 1; i >= 0; i--) {
37405 array[customDest + i] = array[customCursor + i];
37406 }
37407
37408 array[dest] = tmp[cursor2];
37409 } else if (length2 === 0) {
37410 throw new Error('mergeHigh preconditions were not respected');
37411 } else {
37412 customCursor = dest - (length2 - 1);
37413
37414 for (i = 0; i < length2; i++) {
37415 array[customCursor + i] = tmp[i];
37416 }
37417 }
37418 };
37419
37420 return TimSort;
37421 }();
37422
37423 function sort(array, compare, lo, hi) {
37424 if (!Array.isArray(array)) {
37425 throw new TypeError('Can only sort arrays');
37426 }
37427
37428 if (!compare) {
37429 compare = alphabeticalCompare;
37430 } else if (typeof compare !== 'function') {
37431 hi = lo;
37432 lo = compare;
37433 compare = alphabeticalCompare;
37434 }
37435
37436 if (!lo) {
37437 lo = 0;
37438 }
37439
37440 if (!hi) {
37441 hi = array.length;
37442 }
37443
37444 var remaining = hi - lo;
37445
37446 if (remaining < 2) {
37447 return;
37448 }
37449
37450 var runLength = 0;
37451
37452 if (remaining < DEFAULT_MIN_MERGE) {
37453 runLength = makeAscendingRun(array, lo, hi, compare);
37454 binaryInsertionSort(array, lo, hi, lo + runLength, compare);
37455 return;
37456 }
37457
37458 var ts = new TimSort(array, compare);
37459 var minRun = minRunLength(remaining);
37460
37461 do {
37462 runLength = makeAscendingRun(array, lo, hi, compare);
37463
37464 if (runLength < minRun) {
37465 var force = remaining;
37466
37467 if (force > minRun) {
37468 force = minRun;
37469 }
37470
37471 binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
37472 runLength = force;
37473 }
37474
37475 ts.pushRun(lo, runLength);
37476 ts.mergeRuns();
37477 remaining -= runLength;
37478 lo += runLength;
37479 } while (remaining !== 0);
37480
37481 ts.forceMergeRuns();
37482 }
37483 });
37484})(timsort$1);
37485
37486var timsort = timsort$1;
37487
37488function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
37489
37490function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !construct) return false; if (construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
37491/**
37492 * Interface definition for direction strategy classes.
37493 *
37494 * This class describes the interface for the Strategy
37495 * pattern classes used to differentiate horizontal and vertical
37496 * direction of hierarchical results.
37497 *
37498 * For a given direction, one coordinate will be 'fixed', meaning that it is
37499 * determined by level.
37500 * The other coordinate is 'unfixed', meaning that the nodes on a given level
37501 * can still move along that coordinate. So:
37502 *
37503 * - `vertical` layout: `x` unfixed, `y` fixed per level
37504 * - `horizontal` layout: `x` fixed per level, `y` unfixed
37505 *
37506 * The local methods are stubs and should be regarded as abstract.
37507 * Derived classes **must** implement all the methods themselves.
37508 *
37509 * @private
37510 */
37511
37512var DirectionInterface = /*#__PURE__*/function () {
37513 function DirectionInterface() {
37514 _classCallCheck(this, DirectionInterface);
37515 }
37516
37517 _createClass(DirectionInterface, [{
37518 key: "abstract",
37519 value:
37520 /**
37521 * @ignore
37522 */
37523 function abstract() {
37524 throw new Error("Can't instantiate abstract class!");
37525 }
37526 /**
37527 * This is a dummy call which is used to suppress the jsdoc errors of type:
37528 *
37529 * "'param' is assigned a value but never used"
37530 *
37531 * @ignore
37532 **/
37533
37534 }, {
37535 key: "fake_use",
37536 value: function fake_use() {// Do nothing special
37537 }
37538 /**
37539 * Type to use to translate dynamic curves to, in the case of hierarchical layout.
37540 * Dynamic curves do not work for these.
37541 *
37542 * The value should be perpendicular to the actual direction of the layout.
37543 *
37544 * @returns {string} Direction, either 'vertical' or 'horizontal'
37545 */
37546
37547 }, {
37548 key: "curveType",
37549 value: function curveType() {
37550 return this.abstract();
37551 }
37552 /**
37553 * Return the value of the coordinate that is not fixed for this direction.
37554 *
37555 * @param {Node} node The node to read
37556 * @returns {number} Value of the unfixed coordinate
37557 */
37558
37559 }, {
37560 key: "getPosition",
37561 value: function getPosition(node) {
37562 this.fake_use(node);
37563 return this.abstract();
37564 }
37565 /**
37566 * Set the value of the coordinate that is not fixed for this direction.
37567 *
37568 * @param {Node} node The node to adjust
37569 * @param {number} position
37570 * @param {number} [level] if specified, the hierarchy level that this node should be fixed to
37571 */
37572
37573 }, {
37574 key: "setPosition",
37575 value: function setPosition(node, position) {
37576 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
37577 this.fake_use(node, position, level);
37578 this.abstract();
37579 }
37580 /**
37581 * Get the width of a tree.
37582 *
37583 * A `tree` here is a subset of nodes within the network which are not connected to other nodes,
37584 * only among themselves. In essence, it is a sub-network.
37585 *
37586 * @param {number} index The index number of a tree
37587 * @returns {number} the width of a tree in the view coordinates
37588 */
37589
37590 }, {
37591 key: "getTreeSize",
37592 value: function getTreeSize(index) {
37593 this.fake_use(index);
37594 return this.abstract();
37595 }
37596 /**
37597 * Sort array of nodes on the unfixed coordinates.
37598 *
37599 * **Note:** chrome has non-stable sorting implementation, which
37600 * has a tendency to change the order of the array items,
37601 * even if the custom sort function returns 0.
37602 *
37603 * For this reason, an external sort implementation is used,
37604 * which has the added benefit of being faster than the standard
37605 * platforms implementation. This has been verified on `node.js`,
37606 * `firefox` and `chrome` (all linux).
37607 *
37608 * @param {Array.<Node>} nodeArray array of nodes to sort
37609 */
37610
37611 }, {
37612 key: "sort",
37613 value: function sort(nodeArray) {
37614 this.fake_use(nodeArray);
37615 this.abstract();
37616 }
37617 /**
37618 * Assign the fixed coordinate of the node to the given level
37619 *
37620 * @param {Node} node The node to adjust
37621 * @param {number} level The level to fix to
37622 */
37623
37624 }, {
37625 key: "fix",
37626 value: function fix(node, level) {
37627 this.fake_use(node, level);
37628 this.abstract();
37629 }
37630 /**
37631 * Add an offset to the unfixed coordinate of the given node.
37632 *
37633 * @param {NodeId} nodeId Id of the node to adjust
37634 * @param {number} diff Offset to add to the unfixed coordinate
37635 */
37636
37637 }, {
37638 key: "shift",
37639 value: function shift(nodeId, diff) {
37640 this.fake_use(nodeId, diff);
37641 this.abstract();
37642 }
37643 }]);
37644
37645 return DirectionInterface;
37646}();
37647/**
37648 * Vertical Strategy
37649 *
37650 * Coordinate `y` is fixed on levels, coordinate `x` is unfixed.
37651 *
37652 * @augments DirectionInterface
37653 * @private
37654 */
37655
37656
37657var VerticalStrategy = /*#__PURE__*/function (_DirectionInterface) {
37658 _inherits(VerticalStrategy, _DirectionInterface);
37659
37660 var _super = _createSuper(VerticalStrategy);
37661
37662 /**
37663 * Constructor
37664 *
37665 * @param {object} layout reference to the parent LayoutEngine instance.
37666 */
37667 function VerticalStrategy(layout) {
37668 var _this;
37669
37670 _classCallCheck(this, VerticalStrategy);
37671
37672 _this = _super.call(this);
37673 _this.layout = layout;
37674 return _this;
37675 }
37676 /** @inheritDoc */
37677
37678
37679 _createClass(VerticalStrategy, [{
37680 key: "curveType",
37681 value: function curveType() {
37682 return "horizontal";
37683 }
37684 /** @inheritDoc */
37685
37686 }, {
37687 key: "getPosition",
37688 value: function getPosition(node) {
37689 return node.x;
37690 }
37691 /** @inheritDoc */
37692
37693 }, {
37694 key: "setPosition",
37695 value: function setPosition(node, position) {
37696 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
37697
37698 if (level !== undefined) {
37699 this.layout.hierarchical.addToOrdering(node, level);
37700 }
37701
37702 node.x = position;
37703 }
37704 /** @inheritDoc */
37705
37706 }, {
37707 key: "getTreeSize",
37708 value: function getTreeSize(index) {
37709 var res = this.layout.hierarchical.getTreeSize(this.layout.body.nodes, index);
37710 return {
37711 min: res.min_x,
37712 max: res.max_x
37713 };
37714 }
37715 /** @inheritDoc */
37716
37717 }, {
37718 key: "sort",
37719 value: function sort(nodeArray) {
37720 timsort.sort(nodeArray, function (a, b) {
37721 return a.x - b.x;
37722 });
37723 }
37724 /** @inheritDoc */
37725
37726 }, {
37727 key: "fix",
37728 value: function fix(node, level) {
37729 node.y = this.layout.options.hierarchical.levelSeparation * level;
37730 node.options.fixed.y = true;
37731 }
37732 /** @inheritDoc */
37733
37734 }, {
37735 key: "shift",
37736 value: function shift(nodeId, diff) {
37737 this.layout.body.nodes[nodeId].x += diff;
37738 }
37739 }]);
37740
37741 return VerticalStrategy;
37742}(DirectionInterface);
37743/**
37744 * Horizontal Strategy
37745 *
37746 * Coordinate `x` is fixed on levels, coordinate `y` is unfixed.
37747 *
37748 * @augments DirectionInterface
37749 * @private
37750 */
37751
37752
37753var HorizontalStrategy = /*#__PURE__*/function (_DirectionInterface2) {
37754 _inherits(HorizontalStrategy, _DirectionInterface2);
37755
37756 var _super2 = _createSuper(HorizontalStrategy);
37757
37758 /**
37759 * Constructor
37760 *
37761 * @param {object} layout reference to the parent LayoutEngine instance.
37762 */
37763 function HorizontalStrategy(layout) {
37764 var _this2;
37765
37766 _classCallCheck(this, HorizontalStrategy);
37767
37768 _this2 = _super2.call(this);
37769 _this2.layout = layout;
37770 return _this2;
37771 }
37772 /** @inheritDoc */
37773
37774
37775 _createClass(HorizontalStrategy, [{
37776 key: "curveType",
37777 value: function curveType() {
37778 return "vertical";
37779 }
37780 /** @inheritDoc */
37781
37782 }, {
37783 key: "getPosition",
37784 value: function getPosition(node) {
37785 return node.y;
37786 }
37787 /** @inheritDoc */
37788
37789 }, {
37790 key: "setPosition",
37791 value: function setPosition(node, position) {
37792 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
37793
37794 if (level !== undefined) {
37795 this.layout.hierarchical.addToOrdering(node, level);
37796 }
37797
37798 node.y = position;
37799 }
37800 /** @inheritDoc */
37801
37802 }, {
37803 key: "getTreeSize",
37804 value: function getTreeSize(index) {
37805 var res = this.layout.hierarchical.getTreeSize(this.layout.body.nodes, index);
37806 return {
37807 min: res.min_y,
37808 max: res.max_y
37809 };
37810 }
37811 /** @inheritDoc */
37812
37813 }, {
37814 key: "sort",
37815 value: function sort(nodeArray) {
37816 timsort.sort(nodeArray, function (a, b) {
37817 return a.y - b.y;
37818 });
37819 }
37820 /** @inheritDoc */
37821
37822 }, {
37823 key: "fix",
37824 value: function fix(node, level) {
37825 node.x = this.layout.options.hierarchical.levelSeparation * level;
37826 node.options.fixed.x = true;
37827 }
37828 /** @inheritDoc */
37829
37830 }, {
37831 key: "shift",
37832 value: function shift(nodeId, diff) {
37833 this.layout.body.nodes[nodeId].y += diff;
37834 }
37835 }]);
37836
37837 return HorizontalStrategy;
37838}(DirectionInterface);
37839
37840var $ = _export;
37841var $every = arrayIteration.every;
37842var arrayMethodIsStrict = arrayMethodIsStrict$6;
37843var STRICT_METHOD = arrayMethodIsStrict('every'); // `Array.prototype.every` method
37844// https://tc39.es/ecma262/#sec-array.prototype.every
37845
37846$({
37847 target: 'Array',
37848 proto: true,
37849 forced: !STRICT_METHOD
37850}, {
37851 every: function every(callbackfn
37852 /* , thisArg */
37853 ) {
37854 return $every(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
37855 }
37856});
37857
37858var entryVirtual = entryVirtual$l;
37859var every$3 = entryVirtual('Array').every;
37860
37861var every$2 = every$3;
37862var ArrayPrototype = Array.prototype;
37863
37864var every_1 = function (it) {
37865 var own = it.every;
37866 return it === ArrayPrototype || it instanceof Array && own === ArrayPrototype.every ? every$2 : own;
37867};
37868
37869var parent = every_1;
37870var every$1 = parent;
37871
37872var every = every$1;
37873
37874function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
37875
37876function _unsupportedIterableToArray$1(o, minLen) { var _context9; if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = slice$1(_context9 = Object.prototype.toString.call(o)).call(_context9, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); }
37877
37878function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
37879
37880/**
37881 * Try to assign levels to nodes according to their positions in the cyclic “hierarchy”.
37882 *
37883 * @param nodes - Visible nodes of the graph.
37884 * @param levels - If present levels will be added to it, if not a new object will be created.
37885 *
37886 * @returns Populated node levels.
37887 */
37888function fillLevelsByDirectionCyclic(nodes, levels) {
37889 var edges = new set();
37890
37891 forEach$2(nodes).call(nodes, function (node) {
37892 var _context;
37893
37894 forEach$2(_context = node.edges).call(_context, function (edge) {
37895 if (edge.connected) {
37896 edges.add(edge);
37897 }
37898 });
37899 });
37900
37901 forEach$2(edges).call(edges, function (edge) {
37902 var fromId = edge.from.id;
37903 var toId = edge.to.id;
37904
37905 if (levels[fromId] == null) {
37906 levels[fromId] = 0;
37907 }
37908
37909 if (levels[toId] == null || levels[fromId] >= levels[toId]) {
37910 levels[toId] = levels[fromId] + 1;
37911 }
37912 });
37913
37914 return levels;
37915}
37916/**
37917 * Assign levels to nodes according to their positions in the hierarchy. Leaves will be lined up at the bottom and all other nodes as close to their children as possible.
37918 *
37919 * @param nodes - Visible nodes of the graph.
37920 *
37921 * @returns Populated node levels.
37922 */
37923
37924
37925function fillLevelsByDirectionLeaves(nodes) {
37926 return fillLevelsByDirection( // Pick only leaves (nodes without children).
37927 function (node) {
37928 var _context2, _context3;
37929
37930 return every(_context2 = filter(_context3 = node.edges // Take only visible nodes into account.
37931 ).call(_context3, function (edge) {
37932 return nodes.has(edge.toId);
37933 }) // Check that all edges lead to this node (leaf).
37934 ).call(_context2, function (edge) {
37935 return edge.to === node;
37936 });
37937 }, // Use the lowest level.
37938 function (newLevel, oldLevel) {
37939 return oldLevel > newLevel;
37940 }, // Go against the direction of the edges.
37941 "from", nodes);
37942}
37943/**
37944 * Assign levels to nodes according to their positions in the hierarchy. Roots will be lined up at the top and all nodes as close to their parents as possible.
37945 *
37946 * @param nodes - Visible nodes of the graph.
37947 *
37948 * @returns Populated node levels.
37949 */
37950
37951function fillLevelsByDirectionRoots(nodes) {
37952 return fillLevelsByDirection( // Pick only roots (nodes without parents).
37953 function (node) {
37954 var _context4, _context5;
37955
37956 return every(_context4 = filter(_context5 = node.edges // Take only visible nodes into account.
37957 ).call(_context5, function (edge) {
37958 return nodes.has(edge.toId);
37959 }) // Check that all edges lead from this node (root).
37960 ).call(_context4, function (edge) {
37961 return edge.from === node;
37962 });
37963 }, // Use the highest level.
37964 function (newLevel, oldLevel) {
37965 return oldLevel < newLevel;
37966 }, // Go in the direction of the edges.
37967 "to", nodes);
37968}
37969/**
37970 * Assign levels to nodes according to their positions in the hierarchy.
37971 *
37972 * @param isEntryNode - Checks and return true if the graph should be traversed from this node.
37973 * @param shouldLevelBeReplaced - Checks and returns true if the level of given node should be updated to the new value.
37974 * @param direction - Wheter the graph should be traversed in the direction of the edges `"to"` or in the other way `"from"`.
37975 * @param nodes - Visible nodes of the graph.
37976 *
37977 * @returns Populated node levels.
37978 */
37979
37980function fillLevelsByDirection(isEntryNode, shouldLevelBeReplaced, direction, nodes) {
37981 var _context6;
37982
37983 var levels = create$4(null); // If acyclic, the graph can be walked through with (most likely way) fewer
37984 // steps than the number bellow. The exact value isn't too important as long
37985 // as it's quick to compute (doesn't impact acyclic graphs too much), is
37986 // higher than the number of steps actually needed (doesn't cut off before
37987 // acyclic graph is walked through) and prevents infinite loops (cuts off for
37988 // cyclic graphs).
37989
37990
37991 var limit = reduce(_context6 = _toConsumableArray(values(nodes).call(nodes))).call(_context6, function (acc, node) {
37992 return acc + 1 + node.edges.length;
37993 }, 0);
37994
37995 var edgeIdProp = direction + "Id";
37996 var newLevelDiff = direction === "to" ? 1 : -1;
37997
37998 var _iterator = _createForOfIteratorHelper$1(nodes),
37999 _step;
38000
38001 try {
38002 var _loop = function _loop() {
38003 var _step$value = _slicedToArray(_step.value, 2),
38004 entryNodeId = _step$value[0],
38005 entryNode = _step$value[1];
38006
38007 if ( // Skip if the node is not visible.
38008 !nodes.has(entryNodeId) || // Skip if the node is not an entry node.
38009 !isEntryNode(entryNode)) {
38010 return "continue";
38011 } // Line up all the entry nodes on level 0.
38012
38013
38014 levels[entryNodeId] = 0;
38015 var stack = [entryNode];
38016 var done = 0;
38017 var node = void 0;
38018
38019 var _loop2 = function _loop2() {
38020 var _context7, _context8;
38021
38022 if (!nodes.has(entryNodeId)) {
38023 // Skip if the node is not visible.
38024 return "continue";
38025 }
38026
38027 var newLevel = levels[node.id] + newLevelDiff;
38028
38029 forEach$2(_context7 = filter(_context8 = node.edges).call(_context8, function (edge) {
38030 return (// Ignore disconnected edges.
38031 edge.connected && // Ignore circular edges.
38032 edge.to !== edge.from && // Ignore edges leading to the node that's currently being processed.
38033 edge[direction] !== node && // Ignore edges connecting to an invisible node.
38034 nodes.has(edge.toId) && // Ignore edges connecting from an invisible node.
38035 nodes.has(edge.fromId)
38036 );
38037 })).call(_context7, function (edge) {
38038 var targetNodeId = edge[edgeIdProp];
38039 var oldLevel = levels[targetNodeId];
38040
38041 if (oldLevel == null || shouldLevelBeReplaced(newLevel, oldLevel)) {
38042 levels[targetNodeId] = newLevel;
38043 stack.push(edge[direction]);
38044 }
38045 });
38046
38047 if (done > limit) {
38048 // This would run forever on a cyclic graph.
38049 return {
38050 v: {
38051 v: fillLevelsByDirectionCyclic(nodes, levels)
38052 }
38053 };
38054 } else {
38055 ++done;
38056 }
38057 };
38058
38059 while (node = stack.pop()) {
38060 var _ret2 = _loop2();
38061
38062 if (_ret2 === "continue") continue;
38063 if (_typeof(_ret2) === "object") return _ret2.v;
38064 }
38065 };
38066
38067 for (_iterator.s(); !(_step = _iterator.n()).done;) {
38068 var _ret = _loop();
38069
38070 if (_ret === "continue") continue;
38071 if (_typeof(_ret) === "object") return _ret.v;
38072 }
38073 } catch (err) {
38074 _iterator.e(err);
38075 } finally {
38076 _iterator.f();
38077 }
38078
38079 return levels;
38080}
38081
38082/**
38083 * There's a mix-up with terms in the code. Following are the formal definitions:
38084 *
38085 * tree - a strict hierarchical network, i.e. every node has at most one parent
38086 * forest - a collection of trees. These distinct trees are thus not connected.
38087 *
38088 * So:
38089 * - in a network that is not a tree, there exist nodes with multiple parents.
38090 * - a network consisting of unconnected sub-networks, of which at least one
38091 * is not a tree, is not a forest.
38092 *
38093 * In the code, the definitions are:
38094 *
38095 * tree - any disconnected sub-network, strict hierarchical or not.
38096 * forest - a bunch of these sub-networks
38097 *
38098 * The difference between tree and not-tree is important in the code, notably within
38099 * to the block-shifting algorithm. The algorithm assumes formal trees and fails
38100 * for not-trees, often in a spectacular manner (search for 'exploding network' in the issues).
38101 *
38102 * In order to distinguish the definitions in the following code, the adjective 'formal' is
38103 * used. If 'formal' is absent, you must assume the non-formal definition.
38104 *
38105 * ----------------------------------------------------------------------------------
38106 * NOTES
38107 * =====
38108 *
38109 * A hierarchical layout is a different thing from a hierarchical network.
38110 * The layout is a way to arrange the nodes in the view; this can be done
38111 * on non-hierarchical networks as well. The converse is also possible.
38112 */
38113/**
38114 * Container for derived data on current network, relating to hierarchy.
38115 *
38116 * @private
38117 */
38118
38119var HierarchicalStatus = /*#__PURE__*/function () {
38120 /**
38121 * @ignore
38122 */
38123 function HierarchicalStatus() {
38124 _classCallCheck(this, HierarchicalStatus);
38125
38126 this.childrenReference = {}; // child id's per node id
38127
38128 this.parentReference = {}; // parent id's per node id
38129
38130 this.trees = {}; // tree id per node id; i.e. to which tree does given node id belong
38131
38132 this.distributionOrdering = {}; // The nodes per level, in the display order
38133
38134 this.levels = {}; // hierarchy level per node id
38135
38136 this.distributionIndex = {}; // The position of the node in the level sorting order, per node id.
38137
38138 this.isTree = false; // True if current network is a formal tree
38139
38140 this.treeIndex = -1; // Highest tree id in current network.
38141 }
38142 /**
38143 * Add the relation between given nodes to the current state.
38144 *
38145 * @param {Node.id} parentNodeId
38146 * @param {Node.id} childNodeId
38147 */
38148
38149
38150 _createClass(HierarchicalStatus, [{
38151 key: "addRelation",
38152 value: function addRelation(parentNodeId, childNodeId) {
38153 if (this.childrenReference[parentNodeId] === undefined) {
38154 this.childrenReference[parentNodeId] = [];
38155 }
38156
38157 this.childrenReference[parentNodeId].push(childNodeId);
38158
38159 if (this.parentReference[childNodeId] === undefined) {
38160 this.parentReference[childNodeId] = [];
38161 }
38162
38163 this.parentReference[childNodeId].push(parentNodeId);
38164 }
38165 /**
38166 * Check if the current state is for a formal tree or formal forest.
38167 *
38168 * This is the case if every node has at most one parent.
38169 *
38170 * Pre: parentReference init'ed properly for current network
38171 */
38172
38173 }, {
38174 key: "checkIfTree",
38175 value: function checkIfTree() {
38176 for (var i in this.parentReference) {
38177 if (this.parentReference[i].length > 1) {
38178 this.isTree = false;
38179 return;
38180 }
38181 }
38182
38183 this.isTree = true;
38184 }
38185 /**
38186 * Return the number of separate trees in the current network.
38187 *
38188 * @returns {number}
38189 */
38190
38191 }, {
38192 key: "numTrees",
38193 value: function numTrees() {
38194 return this.treeIndex + 1; // This assumes the indexes are assigned consecitively
38195 }
38196 /**
38197 * Assign a tree id to a node
38198 *
38199 * @param {Node} node
38200 * @param {string|number} treeId
38201 */
38202
38203 }, {
38204 key: "setTreeIndex",
38205 value: function setTreeIndex(node, treeId) {
38206 if (treeId === undefined) return; // Don't bother
38207
38208 if (this.trees[node.id] === undefined) {
38209 this.trees[node.id] = treeId;
38210 this.treeIndex = Math.max(treeId, this.treeIndex);
38211 }
38212 }
38213 /**
38214 * Ensure level for given id is defined.
38215 *
38216 * Sets level to zero for given node id if not already present
38217 *
38218 * @param {Node.id} nodeId
38219 */
38220
38221 }, {
38222 key: "ensureLevel",
38223 value: function ensureLevel(nodeId) {
38224 if (this.levels[nodeId] === undefined) {
38225 this.levels[nodeId] = 0;
38226 }
38227 }
38228 /**
38229 * get the maximum level of a branch.
38230 *
38231 * TODO: Never entered; find a test case to test this!
38232 *
38233 * @param {Node.id} nodeId
38234 * @returns {number}
38235 */
38236
38237 }, {
38238 key: "getMaxLevel",
38239 value: function getMaxLevel(nodeId) {
38240 var _this = this;
38241
38242 var accumulator = {};
38243
38244 var _getMaxLevel = function _getMaxLevel(nodeId) {
38245 if (accumulator[nodeId] !== undefined) {
38246 return accumulator[nodeId];
38247 }
38248
38249 var level = _this.levels[nodeId];
38250
38251 if (_this.childrenReference[nodeId]) {
38252 var children = _this.childrenReference[nodeId];
38253
38254 if (children.length > 0) {
38255 for (var i = 0; i < children.length; i++) {
38256 level = Math.max(level, _getMaxLevel(children[i]));
38257 }
38258 }
38259 }
38260
38261 accumulator[nodeId] = level;
38262 return level;
38263 };
38264
38265 return _getMaxLevel(nodeId);
38266 }
38267 /**
38268 *
38269 * @param {Node} nodeA
38270 * @param {Node} nodeB
38271 */
38272
38273 }, {
38274 key: "levelDownstream",
38275 value: function levelDownstream(nodeA, nodeB) {
38276 if (this.levels[nodeB.id] === undefined) {
38277 // set initial level
38278 if (this.levels[nodeA.id] === undefined) {
38279 this.levels[nodeA.id] = 0;
38280 } // set level
38281
38282
38283 this.levels[nodeB.id] = this.levels[nodeA.id] + 1;
38284 }
38285 }
38286 /**
38287 * Small util method to set the minimum levels of the nodes to zero.
38288 *
38289 * @param {Array.<Node>} nodes
38290 */
38291
38292 }, {
38293 key: "setMinLevelToZero",
38294 value: function setMinLevelToZero(nodes) {
38295 var minLevel = 1e9; // get the minimum level
38296
38297 for (var nodeId in nodes) {
38298 if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) {
38299 if (this.levels[nodeId] !== undefined) {
38300 minLevel = Math.min(this.levels[nodeId], minLevel);
38301 }
38302 }
38303 } // subtract the minimum from the set so we have a range starting from 0
38304
38305
38306 for (var _nodeId in nodes) {
38307 if (Object.prototype.hasOwnProperty.call(nodes, _nodeId)) {
38308 if (this.levels[_nodeId] !== undefined) {
38309 this.levels[_nodeId] -= minLevel;
38310 }
38311 }
38312 }
38313 }
38314 /**
38315 * Get the min and max xy-coordinates of a given tree
38316 *
38317 * @param {Array.<Node>} nodes
38318 * @param {number} index
38319 * @returns {{min_x: number, max_x: number, min_y: number, max_y: number}}
38320 */
38321
38322 }, {
38323 key: "getTreeSize",
38324 value: function getTreeSize(nodes, index) {
38325 var min_x = 1e9;
38326 var max_x = -1e9;
38327 var min_y = 1e9;
38328 var max_y = -1e9;
38329
38330 for (var nodeId in this.trees) {
38331 if (Object.prototype.hasOwnProperty.call(this.trees, nodeId)) {
38332 if (this.trees[nodeId] === index) {
38333 var node = nodes[nodeId];
38334 min_x = Math.min(node.x, min_x);
38335 max_x = Math.max(node.x, max_x);
38336 min_y = Math.min(node.y, min_y);
38337 max_y = Math.max(node.y, max_y);
38338 }
38339 }
38340 }
38341
38342 return {
38343 min_x: min_x,
38344 max_x: max_x,
38345 min_y: min_y,
38346 max_y: max_y
38347 };
38348 }
38349 /**
38350 * Check if two nodes have the same parent(s)
38351 *
38352 * @param {Node} node1
38353 * @param {Node} node2
38354 * @returns {boolean} true if the two nodes have a same ancestor node, false otherwise
38355 */
38356
38357 }, {
38358 key: "hasSameParent",
38359 value: function hasSameParent(node1, node2) {
38360 var parents1 = this.parentReference[node1.id];
38361 var parents2 = this.parentReference[node2.id];
38362
38363 if (parents1 === undefined || parents2 === undefined) {
38364 return false;
38365 }
38366
38367 for (var i = 0; i < parents1.length; i++) {
38368 for (var j = 0; j < parents2.length; j++) {
38369 if (parents1[i] == parents2[j]) {
38370 return true;
38371 }
38372 }
38373 }
38374
38375 return false;
38376 }
38377 /**
38378 * Check if two nodes are in the same tree.
38379 *
38380 * @param {Node} node1
38381 * @param {Node} node2
38382 * @returns {boolean} true if this is so, false otherwise
38383 */
38384
38385 }, {
38386 key: "inSameSubNetwork",
38387 value: function inSameSubNetwork(node1, node2) {
38388 return this.trees[node1.id] === this.trees[node2.id];
38389 }
38390 /**
38391 * Get a list of the distinct levels in the current network
38392 *
38393 * @returns {Array}
38394 */
38395
38396 }, {
38397 key: "getLevels",
38398 value: function getLevels() {
38399 return keys$4(this.distributionOrdering);
38400 }
38401 /**
38402 * Add a node to the ordering per level
38403 *
38404 * @param {Node} node
38405 * @param {number} level
38406 */
38407
38408 }, {
38409 key: "addToOrdering",
38410 value: function addToOrdering(node, level) {
38411 if (this.distributionOrdering[level] === undefined) {
38412 this.distributionOrdering[level] = [];
38413 }
38414
38415 var isPresent = false;
38416 var curLevel = this.distributionOrdering[level];
38417
38418 for (var n in curLevel) {
38419 //if (curLevel[n].id === node.id) {
38420 if (curLevel[n] === node) {
38421 isPresent = true;
38422 break;
38423 }
38424 }
38425
38426 if (!isPresent) {
38427 this.distributionOrdering[level].push(node);
38428 this.distributionIndex[node.id] = this.distributionOrdering[level].length - 1;
38429 }
38430 }
38431 }]);
38432
38433 return HierarchicalStatus;
38434}();
38435/**
38436 * The Layout Engine
38437 */
38438
38439
38440var LayoutEngine = /*#__PURE__*/function () {
38441 /**
38442 * @param {object} body
38443 */
38444 function LayoutEngine(body) {
38445 _classCallCheck(this, LayoutEngine);
38446
38447 this.body = body; // Make sure there always is some RNG because the setOptions method won't
38448 // set it unless there's a seed for it.
38449
38450 this._resetRNG(Math.random() + ":" + now$1());
38451
38452 this.setPhysics = false;
38453 this.options = {};
38454 this.optionsBackup = {
38455 physics: {}
38456 };
38457 this.defaultOptions = {
38458 randomSeed: undefined,
38459 improvedLayout: true,
38460 clusterThreshold: 150,
38461 hierarchical: {
38462 enabled: false,
38463 levelSeparation: 150,
38464 nodeSpacing: 100,
38465 treeSpacing: 200,
38466 blockShifting: true,
38467 edgeMinimization: true,
38468 parentCentralization: true,
38469 direction: "UD",
38470 // UD, DU, LR, RL
38471 sortMethod: "hubsize" // hubsize, directed
38472
38473 }
38474 };
38475
38476 assign$2(this.options, this.defaultOptions);
38477
38478 this.bindEventListeners();
38479 }
38480 /**
38481 * Binds event listeners
38482 */
38483
38484
38485 _createClass(LayoutEngine, [{
38486 key: "bindEventListeners",
38487 value: function bindEventListeners() {
38488 var _this2 = this;
38489
38490 this.body.emitter.on("_dataChanged", function () {
38491 _this2.setupHierarchicalLayout();
38492 });
38493 this.body.emitter.on("_dataLoaded", function () {
38494 _this2.layoutNetwork();
38495 });
38496 this.body.emitter.on("_resetHierarchicalLayout", function () {
38497 _this2.setupHierarchicalLayout();
38498 });
38499 this.body.emitter.on("_adjustEdgesForHierarchicalLayout", function () {
38500 if (_this2.options.hierarchical.enabled !== true) {
38501 return;
38502 } // get the type of static smooth curve in case it is required
38503
38504
38505 var type = _this2.direction.curveType(); // force all edges into static smooth curves.
38506
38507
38508 _this2.body.emitter.emit("_forceDisableDynamicCurves", type, false);
38509 });
38510 }
38511 /**
38512 *
38513 * @param {object} options
38514 * @param {object} allOptions
38515 * @returns {object}
38516 */
38517
38518 }, {
38519 key: "setOptions",
38520 value: function setOptions(options, allOptions) {
38521 if (options !== undefined) {
38522 var hierarchical = this.options.hierarchical;
38523 var prevHierarchicalState = hierarchical.enabled;
38524 selectiveDeepExtend(["randomSeed", "improvedLayout", "clusterThreshold"], this.options, options);
38525 mergeOptions(this.options, options, "hierarchical");
38526
38527 if (options.randomSeed !== undefined) {
38528 this._resetRNG(options.randomSeed);
38529 }
38530
38531 if (hierarchical.enabled === true) {
38532 if (prevHierarchicalState === true) {
38533 // refresh the overridden options for nodes and edges.
38534 this.body.emitter.emit("refresh", true);
38535 } // make sure the level separation is the right way up
38536
38537
38538 if (hierarchical.direction === "RL" || hierarchical.direction === "DU") {
38539 if (hierarchical.levelSeparation > 0) {
38540 hierarchical.levelSeparation *= -1;
38541 }
38542 } else {
38543 if (hierarchical.levelSeparation < 0) {
38544 hierarchical.levelSeparation *= -1;
38545 }
38546 }
38547
38548 this.setDirectionStrategy();
38549 this.body.emitter.emit("_resetHierarchicalLayout"); // because the hierarchical system needs it's own physics and smooth curve settings,
38550 // we adapt the other options if needed.
38551
38552 return this.adaptAllOptionsForHierarchicalLayout(allOptions);
38553 } else {
38554 if (prevHierarchicalState === true) {
38555 // refresh the overridden options for nodes and edges.
38556 this.body.emitter.emit("refresh");
38557 return deepExtend(allOptions, this.optionsBackup);
38558 }
38559 }
38560 }
38561
38562 return allOptions;
38563 }
38564 /**
38565 * Reset the random number generator with given seed.
38566 *
38567 * @param {any} seed - The seed that will be forwarded the the RNG.
38568 */
38569
38570 }, {
38571 key: "_resetRNG",
38572 value: function _resetRNG(seed) {
38573 this.initialRandomSeed = seed;
38574 this._rng = Alea(this.initialRandomSeed);
38575 }
38576 /**
38577 *
38578 * @param {object} allOptions
38579 * @returns {object}
38580 */
38581
38582 }, {
38583 key: "adaptAllOptionsForHierarchicalLayout",
38584 value: function adaptAllOptionsForHierarchicalLayout(allOptions) {
38585 if (this.options.hierarchical.enabled === true) {
38586 var backupPhysics = this.optionsBackup.physics; // set the physics
38587
38588 if (allOptions.physics === undefined || allOptions.physics === true) {
38589 allOptions.physics = {
38590 enabled: backupPhysics.enabled === undefined ? true : backupPhysics.enabled,
38591 solver: "hierarchicalRepulsion"
38592 };
38593 backupPhysics.enabled = backupPhysics.enabled === undefined ? true : backupPhysics.enabled;
38594 backupPhysics.solver = backupPhysics.solver || "barnesHut";
38595 } else if (_typeof(allOptions.physics) === "object") {
38596 backupPhysics.enabled = allOptions.physics.enabled === undefined ? true : allOptions.physics.enabled;
38597 backupPhysics.solver = allOptions.physics.solver || "barnesHut";
38598 allOptions.physics.solver = "hierarchicalRepulsion";
38599 } else if (allOptions.physics !== false) {
38600 backupPhysics.solver = "barnesHut";
38601 allOptions.physics = {
38602 solver: "hierarchicalRepulsion"
38603 };
38604 } // get the type of static smooth curve in case it is required
38605
38606
38607 var type = this.direction.curveType(); // disable smooth curves if nothing is defined. If smooth curves have been turned on,
38608 // turn them into static smooth curves.
38609
38610 if (allOptions.edges === undefined) {
38611 this.optionsBackup.edges = {
38612 smooth: {
38613 enabled: true,
38614 type: "dynamic"
38615 }
38616 };
38617 allOptions.edges = {
38618 smooth: false
38619 };
38620 } else if (allOptions.edges.smooth === undefined) {
38621 this.optionsBackup.edges = {
38622 smooth: {
38623 enabled: true,
38624 type: "dynamic"
38625 }
38626 };
38627 allOptions.edges.smooth = false;
38628 } else {
38629 if (typeof allOptions.edges.smooth === "boolean") {
38630 this.optionsBackup.edges = {
38631 smooth: allOptions.edges.smooth
38632 };
38633 allOptions.edges.smooth = {
38634 enabled: allOptions.edges.smooth,
38635 type: type
38636 };
38637 } else {
38638 var smooth = allOptions.edges.smooth; // allow custom types except for dynamic
38639
38640 if (smooth.type !== undefined && smooth.type !== "dynamic") {
38641 type = smooth.type;
38642 } // TODO: this is options merging; see if the standard routines can be used here.
38643
38644
38645 this.optionsBackup.edges = {
38646 smooth: {
38647 enabled: smooth.enabled === undefined ? true : smooth.enabled,
38648 type: smooth.type === undefined ? "dynamic" : smooth.type,
38649 roundness: smooth.roundness === undefined ? 0.5 : smooth.roundness,
38650 forceDirection: smooth.forceDirection === undefined ? false : smooth.forceDirection
38651 }
38652 }; // NOTE: Copying an object to self; this is basically setting defaults for undefined variables
38653
38654 allOptions.edges.smooth = {
38655 enabled: smooth.enabled === undefined ? true : smooth.enabled,
38656 type: type,
38657 roundness: smooth.roundness === undefined ? 0.5 : smooth.roundness,
38658 forceDirection: smooth.forceDirection === undefined ? false : smooth.forceDirection
38659 };
38660 }
38661 } // Force all edges into static smooth curves.
38662 // Only applies to edges that do not use the global options for smooth.
38663
38664
38665 this.body.emitter.emit("_forceDisableDynamicCurves", type);
38666 }
38667
38668 return allOptions;
38669 }
38670 /**
38671 *
38672 * @param {Array.<Node>} nodesArray
38673 */
38674
38675 }, {
38676 key: "positionInitially",
38677 value: function positionInitially(nodesArray) {
38678 if (this.options.hierarchical.enabled !== true) {
38679 this._resetRNG(this.initialRandomSeed);
38680
38681 var radius = nodesArray.length + 50;
38682
38683 for (var i = 0; i < nodesArray.length; i++) {
38684 var node = nodesArray[i];
38685
38686 var angle = 2 * Math.PI * this._rng();
38687
38688 if (node.x === undefined) {
38689 node.x = radius * Math.cos(angle);
38690 }
38691
38692 if (node.y === undefined) {
38693 node.y = radius * Math.sin(angle);
38694 }
38695 }
38696 }
38697 }
38698 /**
38699 * Use Kamada Kawai to position nodes. This is quite a heavy algorithm so if there are a lot of nodes we
38700 * cluster them first to reduce the amount.
38701 */
38702
38703 }, {
38704 key: "layoutNetwork",
38705 value: function layoutNetwork() {
38706 if (this.options.hierarchical.enabled !== true && this.options.improvedLayout === true) {
38707 var indices = this.body.nodeIndices; // first check if we should Kamada Kawai to layout. The threshold is if less than half of the visible
38708 // nodes have predefined positions we use this.
38709
38710 var positionDefined = 0;
38711
38712 for (var i = 0; i < indices.length; i++) {
38713 var node = this.body.nodes[indices[i]];
38714
38715 if (node.predefinedPosition === true) {
38716 positionDefined += 1;
38717 }
38718 } // if less than half of the nodes have a predefined position we continue
38719
38720
38721 if (positionDefined < 0.5 * indices.length) {
38722 var MAX_LEVELS = 10;
38723 var level = 0;
38724 var clusterThreshold = this.options.clusterThreshold; //
38725 // Define the options for the hidden cluster nodes
38726 // These options don't propagate outside the clustering phase.
38727 //
38728 // Some options are explicitly disabled, because they may be set in group or default node options.
38729 // The clusters are never displayed, so most explicit settings here serve as performance optimizations.
38730 //
38731 // The explicit setting of 'shape' is to avoid `shape: 'image'`; images are not passed to the hidden
38732 // cluster nodes, leading to an exception on creation.
38733 //
38734 // All settings here are performance related, except when noted otherwise.
38735 //
38736
38737 var clusterOptions = {
38738 clusterNodeProperties: {
38739 shape: "ellipse",
38740 // Bugfix: avoid type 'image', no images supplied
38741 label: "",
38742 // avoid label handling
38743 group: "",
38744 // avoid group handling
38745 font: {
38746 multi: false
38747 } // avoid font propagation
38748
38749 },
38750 clusterEdgeProperties: {
38751 label: "",
38752 // avoid label handling
38753 font: {
38754 multi: false
38755 },
38756 // avoid font propagation
38757 smooth: {
38758 enabled: false // avoid drawing penalty for complex edges
38759
38760 }
38761 }
38762 }; // if there are a lot of nodes, we cluster before we run the algorithm.
38763 // NOTE: this part fails to find clusters for large scale-free networks, which should
38764 // be easily clusterable.
38765 // TODO: examine why this is so
38766
38767 if (indices.length > clusterThreshold) {
38768 var startLength = indices.length;
38769
38770 while (indices.length > clusterThreshold && level <= MAX_LEVELS) {
38771 //console.time("clustering")
38772 level += 1;
38773 var before = indices.length; // if there are many nodes we do a hubsize cluster
38774
38775 if (level % 3 === 0) {
38776 this.body.modules.clustering.clusterBridges(clusterOptions);
38777 } else {
38778 this.body.modules.clustering.clusterOutliers(clusterOptions);
38779 }
38780
38781 var after = indices.length;
38782
38783 if (before == after && level % 3 !== 0) {
38784 this._declusterAll();
38785
38786 this.body.emitter.emit("_layoutFailed");
38787 console.info("This network could not be positioned by this version of the improved layout algorithm." + " Please disable improvedLayout for better performance.");
38788 return;
38789 } //console.timeEnd("clustering")
38790 //console.log(before,level,after);
38791
38792 } // increase the size of the edges
38793
38794
38795 this.body.modules.kamadaKawai.setOptions({
38796 springLength: Math.max(150, 2 * startLength)
38797 });
38798 }
38799
38800 if (level > MAX_LEVELS) {
38801 console.info("The clustering didn't succeed within the amount of interations allowed," + " progressing with partial result.");
38802 } // position the system for these nodes and edges
38803
38804
38805 this.body.modules.kamadaKawai.solve(indices, this.body.edgeIndices, true); // shift to center point
38806
38807 this._shiftToCenter(); // perturb the nodes a little bit to force the physics to kick in
38808
38809
38810 var offset = 70;
38811
38812 for (var _i = 0; _i < indices.length; _i++) {
38813 // Only perturb the nodes that aren't fixed
38814 var _node = this.body.nodes[indices[_i]];
38815
38816 if (_node.predefinedPosition === false) {
38817 _node.x += (0.5 - this._rng()) * offset;
38818 _node.y += (0.5 - this._rng()) * offset;
38819 }
38820 } // uncluster all clusters
38821
38822
38823 this._declusterAll(); // reposition all bezier nodes.
38824
38825
38826 this.body.emitter.emit("_repositionBezierNodes");
38827 }
38828 }
38829 }
38830 /**
38831 * Move all the nodes towards to the center so gravitational pull wil not move the nodes away from view
38832 *
38833 * @private
38834 */
38835
38836 }, {
38837 key: "_shiftToCenter",
38838 value: function _shiftToCenter() {
38839 var range = NetworkUtil.getRangeCore(this.body.nodes, this.body.nodeIndices);
38840 var center = NetworkUtil.findCenter(range);
38841
38842 for (var i = 0; i < this.body.nodeIndices.length; i++) {
38843 var node = this.body.nodes[this.body.nodeIndices[i]];
38844 node.x -= center.x;
38845 node.y -= center.y;
38846 }
38847 }
38848 /**
38849 * Expands all clusters
38850 *
38851 * @private
38852 */
38853
38854 }, {
38855 key: "_declusterAll",
38856 value: function _declusterAll() {
38857 var clustersPresent = true;
38858
38859 while (clustersPresent === true) {
38860 clustersPresent = false;
38861
38862 for (var i = 0; i < this.body.nodeIndices.length; i++) {
38863 if (this.body.nodes[this.body.nodeIndices[i]].isCluster === true) {
38864 clustersPresent = true;
38865 this.body.modules.clustering.openCluster(this.body.nodeIndices[i], {}, false);
38866 }
38867 }
38868
38869 if (clustersPresent === true) {
38870 this.body.emitter.emit("_dataChanged");
38871 }
38872 }
38873 }
38874 /**
38875 *
38876 * @returns {number|*}
38877 */
38878
38879 }, {
38880 key: "getSeed",
38881 value: function getSeed() {
38882 return this.initialRandomSeed;
38883 }
38884 /**
38885 * This is the main function to layout the nodes in a hierarchical way.
38886 * It checks if the node details are supplied correctly
38887 *
38888 * @private
38889 */
38890
38891 }, {
38892 key: "setupHierarchicalLayout",
38893 value: function setupHierarchicalLayout() {
38894 if (this.options.hierarchical.enabled === true && this.body.nodeIndices.length > 0) {
38895 // get the size of the largest hubs and check if the user has defined a level for a node.
38896 var node, nodeId;
38897 var definedLevel = false;
38898 var undefinedLevel = false;
38899 this.lastNodeOnLevel = {};
38900 this.hierarchical = new HierarchicalStatus();
38901
38902 for (nodeId in this.body.nodes) {
38903 if (Object.prototype.hasOwnProperty.call(this.body.nodes, nodeId)) {
38904 node = this.body.nodes[nodeId];
38905
38906 if (node.options.level !== undefined) {
38907 definedLevel = true;
38908 this.hierarchical.levels[nodeId] = node.options.level;
38909 } else {
38910 undefinedLevel = true;
38911 }
38912 }
38913 } // if the user defined some levels but not all, alert and run without hierarchical layout
38914
38915
38916 if (undefinedLevel === true && definedLevel === true) {
38917 throw new Error("To use the hierarchical layout, nodes require either no predefined levels" + " or levels have to be defined for all nodes.");
38918 } else {
38919 // define levels if undefined by the users. Based on hubsize.
38920 if (undefinedLevel === true) {
38921 var sortMethod = this.options.hierarchical.sortMethod;
38922
38923 if (sortMethod === "hubsize") {
38924 this._determineLevelsByHubsize();
38925 } else if (sortMethod === "directed") {
38926 this._determineLevelsDirected();
38927 } else if (sortMethod === "custom") {
38928 this._determineLevelsCustomCallback();
38929 }
38930 } // fallback for cases where there are nodes but no edges
38931
38932
38933 for (var _nodeId2 in this.body.nodes) {
38934 if (Object.prototype.hasOwnProperty.call(this.body.nodes, _nodeId2)) {
38935 this.hierarchical.ensureLevel(_nodeId2);
38936 }
38937 } // check the distribution of the nodes per level.
38938
38939
38940 var distribution = this._getDistribution(); // get the parent children relations.
38941
38942
38943 this._generateMap(); // place the nodes on the canvas.
38944
38945
38946 this._placeNodesByHierarchy(distribution); // condense the whitespace.
38947
38948
38949 this._condenseHierarchy(); // shift to center so gravity does not have to do much
38950
38951
38952 this._shiftToCenter();
38953 }
38954 }
38955 }
38956 /**
38957 * @private
38958 */
38959
38960 }, {
38961 key: "_condenseHierarchy",
38962 value: function _condenseHierarchy() {
38963 var _this3 = this;
38964
38965 // Global var in this scope to define when the movement has stopped.
38966 var stillShifting = false;
38967 var branches = {}; // first we have some methods to help shifting trees around.
38968 // the main method to shift the trees
38969
38970 var shiftTrees = function shiftTrees() {
38971 var treeSizes = getTreeSizes();
38972 var shiftBy = 0;
38973
38974 for (var i = 0; i < treeSizes.length - 1; i++) {
38975 var diff = treeSizes[i].max - treeSizes[i + 1].min;
38976 shiftBy += diff + _this3.options.hierarchical.treeSpacing;
38977 shiftTree(i + 1, shiftBy);
38978 }
38979 }; // shift a single tree by an offset
38980
38981
38982 var shiftTree = function shiftTree(index, offset) {
38983 var trees = _this3.hierarchical.trees;
38984
38985 for (var nodeId in trees) {
38986 if (Object.prototype.hasOwnProperty.call(trees, nodeId)) {
38987 if (trees[nodeId] === index) {
38988 _this3.direction.shift(nodeId, offset);
38989 }
38990 }
38991 }
38992 }; // get the width of all trees
38993
38994
38995 var getTreeSizes = function getTreeSizes() {
38996 var treeWidths = [];
38997
38998 for (var i = 0; i < _this3.hierarchical.numTrees(); i++) {
38999 treeWidths.push(_this3.direction.getTreeSize(i));
39000 }
39001
39002 return treeWidths;
39003 }; // get a map of all nodes in this branch
39004
39005
39006 var getBranchNodes = function getBranchNodes(source, map) {
39007 if (map[source.id]) {
39008 return;
39009 }
39010
39011 map[source.id] = true;
39012
39013 if (_this3.hierarchical.childrenReference[source.id]) {
39014 var children = _this3.hierarchical.childrenReference[source.id];
39015
39016 if (children.length > 0) {
39017 for (var i = 0; i < children.length; i++) {
39018 getBranchNodes(_this3.body.nodes[children[i]], map);
39019 }
39020 }
39021 }
39022 }; // get a min max width as well as the maximum movement space it has on either sides
39023 // we use min max terminology because width and height can interchange depending on the direction of the layout
39024
39025
39026 var getBranchBoundary = function getBranchBoundary(branchMap) {
39027 var maxLevel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1e9;
39028 var minSpace = 1e9;
39029 var maxSpace = 1e9;
39030 var min = 1e9;
39031 var max = -1e9;
39032
39033 for (var branchNode in branchMap) {
39034 if (Object.prototype.hasOwnProperty.call(branchMap, branchNode)) {
39035 var node = _this3.body.nodes[branchNode];
39036 var level = _this3.hierarchical.levels[node.id];
39037
39038 var position = _this3.direction.getPosition(node); // get the space around the node.
39039
39040
39041 var _this3$_getSpaceAroun = _this3._getSpaceAroundNode(node, branchMap),
39042 _this3$_getSpaceAroun2 = _slicedToArray(_this3$_getSpaceAroun, 2),
39043 minSpaceNode = _this3$_getSpaceAroun2[0],
39044 maxSpaceNode = _this3$_getSpaceAroun2[1];
39045
39046 minSpace = Math.min(minSpaceNode, minSpace);
39047 maxSpace = Math.min(maxSpaceNode, maxSpace); // the width is only relevant for the levels two nodes have in common. This is why we filter on this.
39048
39049 if (level <= maxLevel) {
39050 min = Math.min(position, min);
39051 max = Math.max(position, max);
39052 }
39053 }
39054 }
39055
39056 return [min, max, minSpace, maxSpace];
39057 }; // check what the maximum level is these nodes have in common.
39058
39059
39060 var getCollisionLevel = function getCollisionLevel(node1, node2) {
39061 var maxLevel1 = _this3.hierarchical.getMaxLevel(node1.id);
39062
39063 var maxLevel2 = _this3.hierarchical.getMaxLevel(node2.id);
39064
39065 return Math.min(maxLevel1, maxLevel2);
39066 };
39067 /**
39068 * Condense elements. These can be nodes or branches depending on the callback.
39069 *
39070 * @param {Function} callback
39071 * @param {Array.<number>} levels
39072 * @param {*} centerParents
39073 */
39074
39075
39076 var shiftElementsCloser = function shiftElementsCloser(callback, levels, centerParents) {
39077 var hier = _this3.hierarchical;
39078
39079 for (var i = 0; i < levels.length; i++) {
39080 var level = levels[i];
39081 var levelNodes = hier.distributionOrdering[level];
39082
39083 if (levelNodes.length > 1) {
39084 for (var j = 0; j < levelNodes.length - 1; j++) {
39085 var node1 = levelNodes[j];
39086 var node2 = levelNodes[j + 1]; // NOTE: logic maintained as it was; if nodes have same ancestor,
39087 // then of course they are in the same sub-network.
39088
39089 if (hier.hasSameParent(node1, node2) && hier.inSameSubNetwork(node1, node2)) {
39090 callback(node1, node2, centerParents);
39091 }
39092 }
39093 }
39094 }
39095 }; // callback for shifting branches
39096
39097
39098 var branchShiftCallback = function branchShiftCallback(node1, node2) {
39099 var centerParent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
39100
39101 //window.CALLBACKS.push(() => {
39102 var pos1 = _this3.direction.getPosition(node1);
39103
39104 var pos2 = _this3.direction.getPosition(node2);
39105
39106 var diffAbs = Math.abs(pos2 - pos1);
39107 var nodeSpacing = _this3.options.hierarchical.nodeSpacing; //console.log("NOW CHECKING:", node1.id, node2.id, diffAbs);
39108
39109 if (diffAbs > nodeSpacing) {
39110 var branchNodes1 = {};
39111 var branchNodes2 = {};
39112 getBranchNodes(node1, branchNodes1);
39113 getBranchNodes(node2, branchNodes2); // check the largest distance between the branches
39114
39115 var maxLevel = getCollisionLevel(node1, node2);
39116 var branchNodeBoundary1 = getBranchBoundary(branchNodes1, maxLevel);
39117 var branchNodeBoundary2 = getBranchBoundary(branchNodes2, maxLevel);
39118 var max1 = branchNodeBoundary1[1];
39119 var min2 = branchNodeBoundary2[0];
39120 var minSpace2 = branchNodeBoundary2[2]; //console.log(node1.id, getBranchBoundary(branchNodes1, maxLevel), node2.id,
39121 // getBranchBoundary(branchNodes2, maxLevel), maxLevel);
39122
39123 var diffBranch = Math.abs(max1 - min2);
39124
39125 if (diffBranch > nodeSpacing) {
39126 var offset = max1 - min2 + nodeSpacing;
39127
39128 if (offset < -minSpace2 + nodeSpacing) {
39129 offset = -minSpace2 + nodeSpacing; //console.log("RESETTING OFFSET", max1 - min2 + this.options.hierarchical.nodeSpacing, -minSpace2, offset);
39130 }
39131
39132 if (offset < 0) {
39133 //console.log("SHIFTING", node2.id, offset);
39134 _this3._shiftBlock(node2.id, offset);
39135
39136 stillShifting = true;
39137 if (centerParent === true) _this3._centerParent(node2);
39138 }
39139 }
39140 } //this.body.emitter.emit("_redraw");})
39141
39142 };
39143
39144 var minimizeEdgeLength = function minimizeEdgeLength(iterations, node) {
39145 //window.CALLBACKS.push(() => {
39146 // console.log("ts",node.id);
39147 var nodeId = node.id;
39148 var allEdges = node.edges;
39149 var nodeLevel = _this3.hierarchical.levels[node.id]; // gather constants
39150
39151 var C2 = _this3.options.hierarchical.levelSeparation * _this3.options.hierarchical.levelSeparation;
39152 var referenceNodes = {};
39153 var aboveEdges = [];
39154
39155 for (var i = 0; i < allEdges.length; i++) {
39156 var edge = allEdges[i];
39157
39158 if (edge.toId != edge.fromId) {
39159 var otherNode = edge.toId == nodeId ? edge.from : edge.to;
39160 referenceNodes[allEdges[i].id] = otherNode;
39161
39162 if (_this3.hierarchical.levels[otherNode.id] < nodeLevel) {
39163 aboveEdges.push(edge);
39164 }
39165 }
39166 } // differentiated sum of lengths based on only moving one node over one axis
39167
39168
39169 var getFx = function getFx(point, edges) {
39170 var sum = 0;
39171
39172 for (var _i2 = 0; _i2 < edges.length; _i2++) {
39173 if (referenceNodes[edges[_i2].id] !== undefined) {
39174 var a = _this3.direction.getPosition(referenceNodes[edges[_i2].id]) - point;
39175 sum += a / Math.sqrt(a * a + C2);
39176 }
39177 }
39178
39179 return sum;
39180 }; // doubly differentiated sum of lengths based on only moving one node over one axis
39181
39182
39183 var getDFx = function getDFx(point, edges) {
39184 var sum = 0;
39185
39186 for (var _i3 = 0; _i3 < edges.length; _i3++) {
39187 if (referenceNodes[edges[_i3].id] !== undefined) {
39188 var a = _this3.direction.getPosition(referenceNodes[edges[_i3].id]) - point;
39189 sum -= C2 * Math.pow(a * a + C2, -1.5);
39190 }
39191 }
39192
39193 return sum;
39194 };
39195
39196 var getGuess = function getGuess(iterations, edges) {
39197 var guess = _this3.direction.getPosition(node); // Newton's method for optimization
39198
39199
39200 var guessMap = {};
39201
39202 for (var _i4 = 0; _i4 < iterations; _i4++) {
39203 var fx = getFx(guess, edges);
39204 var dfx = getDFx(guess, edges); // we limit the movement to avoid instability.
39205
39206 var limit = 40;
39207 var ratio = Math.max(-limit, Math.min(limit, Math.round(fx / dfx)));
39208 guess = guess - ratio; // reduce duplicates
39209
39210 if (guessMap[guess] !== undefined) {
39211 break;
39212 }
39213
39214 guessMap[guess] = _i4;
39215 }
39216
39217 return guess;
39218 };
39219
39220 var moveBranch = function moveBranch(guess) {
39221 // position node if there is space
39222 var nodePosition = _this3.direction.getPosition(node); // check movable area of the branch
39223
39224
39225 if (branches[node.id] === undefined) {
39226 var branchNodes = {};
39227 getBranchNodes(node, branchNodes);
39228 branches[node.id] = branchNodes;
39229 }
39230
39231 var branchBoundary = getBranchBoundary(branches[node.id]);
39232 var minSpaceBranch = branchBoundary[2];
39233 var maxSpaceBranch = branchBoundary[3];
39234 var diff = guess - nodePosition; // check if we are allowed to move the node:
39235
39236 var branchOffset = 0;
39237
39238 if (diff > 0) {
39239 branchOffset = Math.min(diff, maxSpaceBranch - _this3.options.hierarchical.nodeSpacing);
39240 } else if (diff < 0) {
39241 branchOffset = -Math.min(-diff, minSpaceBranch - _this3.options.hierarchical.nodeSpacing);
39242 }
39243
39244 if (branchOffset != 0) {
39245 //console.log("moving branch:",branchOffset, maxSpaceBranch, minSpaceBranch)
39246 _this3._shiftBlock(node.id, branchOffset); //this.body.emitter.emit("_redraw");
39247
39248
39249 stillShifting = true;
39250 }
39251 };
39252
39253 var moveNode = function moveNode(guess) {
39254 var nodePosition = _this3.direction.getPosition(node); // position node if there is space
39255
39256
39257 var _this3$_getSpaceAroun3 = _this3._getSpaceAroundNode(node),
39258 _this3$_getSpaceAroun4 = _slicedToArray(_this3$_getSpaceAroun3, 2),
39259 minSpace = _this3$_getSpaceAroun4[0],
39260 maxSpace = _this3$_getSpaceAroun4[1];
39261
39262 var diff = guess - nodePosition; // check if we are allowed to move the node:
39263
39264 var newPosition = nodePosition;
39265
39266 if (diff > 0) {
39267 newPosition = Math.min(nodePosition + (maxSpace - _this3.options.hierarchical.nodeSpacing), guess);
39268 } else if (diff < 0) {
39269 newPosition = Math.max(nodePosition - (minSpace - _this3.options.hierarchical.nodeSpacing), guess);
39270 }
39271
39272 if (newPosition !== nodePosition) {
39273 //console.log("moving Node:",diff, minSpace, maxSpace);
39274 _this3.direction.setPosition(node, newPosition); //this.body.emitter.emit("_redraw");
39275
39276
39277 stillShifting = true;
39278 }
39279 };
39280
39281 var guess = getGuess(iterations, aboveEdges);
39282 moveBranch(guess);
39283 guess = getGuess(iterations, allEdges);
39284 moveNode(guess); //})
39285 }; // method to remove whitespace between branches. Because we do bottom up, we can center the parents.
39286
39287
39288 var minimizeEdgeLengthBottomUp = function minimizeEdgeLengthBottomUp(iterations) {
39289 var levels = _this3.hierarchical.getLevels();
39290
39291 levels = reverse(levels).call(levels);
39292
39293 for (var i = 0; i < iterations; i++) {
39294 stillShifting = false;
39295
39296 for (var j = 0; j < levels.length; j++) {
39297 var level = levels[j];
39298 var levelNodes = _this3.hierarchical.distributionOrdering[level];
39299
39300 for (var k = 0; k < levelNodes.length; k++) {
39301 minimizeEdgeLength(1000, levelNodes[k]);
39302 }
39303 }
39304
39305 if (stillShifting !== true) {
39306 //console.log("FINISHED minimizeEdgeLengthBottomUp IN " + i);
39307 break;
39308 }
39309 }
39310 }; // method to remove whitespace between branches. Because we do bottom up, we can center the parents.
39311
39312
39313 var shiftBranchesCloserBottomUp = function shiftBranchesCloserBottomUp(iterations) {
39314 var levels = _this3.hierarchical.getLevels();
39315
39316 levels = reverse(levels).call(levels);
39317
39318 for (var i = 0; i < iterations; i++) {
39319 stillShifting = false;
39320 shiftElementsCloser(branchShiftCallback, levels, true);
39321
39322 if (stillShifting !== true) {
39323 //console.log("FINISHED shiftBranchesCloserBottomUp IN " + (i+1));
39324 break;
39325 }
39326 }
39327 }; // center all parents
39328
39329
39330 var centerAllParents = function centerAllParents() {
39331 for (var nodeId in _this3.body.nodes) {
39332 if (Object.prototype.hasOwnProperty.call(_this3.body.nodes, nodeId)) _this3._centerParent(_this3.body.nodes[nodeId]);
39333 }
39334 }; // center all parents
39335
39336
39337 var centerAllParentsBottomUp = function centerAllParentsBottomUp() {
39338 var levels = _this3.hierarchical.getLevels();
39339
39340 levels = reverse(levels).call(levels);
39341
39342 for (var i = 0; i < levels.length; i++) {
39343 var level = levels[i];
39344 var levelNodes = _this3.hierarchical.distributionOrdering[level];
39345
39346 for (var j = 0; j < levelNodes.length; j++) {
39347 _this3._centerParent(levelNodes[j]);
39348 }
39349 }
39350 }; // the actual work is done here.
39351
39352
39353 if (this.options.hierarchical.blockShifting === true) {
39354 shiftBranchesCloserBottomUp(5);
39355 centerAllParents();
39356 } // minimize edge length
39357
39358
39359 if (this.options.hierarchical.edgeMinimization === true) {
39360 minimizeEdgeLengthBottomUp(20);
39361 }
39362
39363 if (this.options.hierarchical.parentCentralization === true) {
39364 centerAllParentsBottomUp();
39365 }
39366
39367 shiftTrees();
39368 }
39369 /**
39370 * This gives the space around the node. IF a map is supplied, it will only check against nodes NOT in the map.
39371 * This is used to only get the distances to nodes outside of a branch.
39372 *
39373 * @param {Node} node
39374 * @param {{Node.id: vis.Node}} map
39375 * @returns {number[]}
39376 * @private
39377 */
39378
39379 }, {
39380 key: "_getSpaceAroundNode",
39381 value: function _getSpaceAroundNode(node, map) {
39382 var useMap = true;
39383
39384 if (map === undefined) {
39385 useMap = false;
39386 }
39387
39388 var level = this.hierarchical.levels[node.id];
39389
39390 if (level !== undefined) {
39391 var index = this.hierarchical.distributionIndex[node.id];
39392 var position = this.direction.getPosition(node);
39393 var ordering = this.hierarchical.distributionOrdering[level];
39394 var minSpace = 1e9;
39395 var maxSpace = 1e9;
39396
39397 if (index !== 0) {
39398 var prevNode = ordering[index - 1];
39399
39400 if (useMap === true && map[prevNode.id] === undefined || useMap === false) {
39401 var prevPos = this.direction.getPosition(prevNode);
39402 minSpace = position - prevPos;
39403 }
39404 }
39405
39406 if (index != ordering.length - 1) {
39407 var nextNode = ordering[index + 1];
39408
39409 if (useMap === true && map[nextNode.id] === undefined || useMap === false) {
39410 var nextPos = this.direction.getPosition(nextNode);
39411 maxSpace = Math.min(maxSpace, nextPos - position);
39412 }
39413 }
39414
39415 return [minSpace, maxSpace];
39416 } else {
39417 return [0, 0];
39418 }
39419 }
39420 /**
39421 * We use this method to center a parent node and check if it does not cross other nodes when it does.
39422 *
39423 * @param {Node} node
39424 * @private
39425 */
39426
39427 }, {
39428 key: "_centerParent",
39429 value: function _centerParent(node) {
39430 if (this.hierarchical.parentReference[node.id]) {
39431 var parents = this.hierarchical.parentReference[node.id];
39432
39433 for (var i = 0; i < parents.length; i++) {
39434 var parentId = parents[i];
39435 var parentNode = this.body.nodes[parentId];
39436 var children = this.hierarchical.childrenReference[parentId];
39437
39438 if (children !== undefined) {
39439 // get the range of the children
39440 var newPosition = this._getCenterPosition(children);
39441
39442 var position = this.direction.getPosition(parentNode);
39443
39444 var _this$_getSpaceAround = this._getSpaceAroundNode(parentNode),
39445 _this$_getSpaceAround2 = _slicedToArray(_this$_getSpaceAround, 2),
39446 minSpace = _this$_getSpaceAround2[0],
39447 maxSpace = _this$_getSpaceAround2[1];
39448
39449 var diff = position - newPosition;
39450
39451 if (diff < 0 && Math.abs(diff) < maxSpace - this.options.hierarchical.nodeSpacing || diff > 0 && Math.abs(diff) < minSpace - this.options.hierarchical.nodeSpacing) {
39452 this.direction.setPosition(parentNode, newPosition);
39453 }
39454 }
39455 }
39456 }
39457 }
39458 /**
39459 * This function places the nodes on the canvas based on the hierarchial distribution.
39460 *
39461 * @param {object} distribution | obtained by the function this._getDistribution()
39462 * @private
39463 */
39464
39465 }, {
39466 key: "_placeNodesByHierarchy",
39467 value: function _placeNodesByHierarchy(distribution) {
39468 this.positionedNodes = {}; // start placing all the level 0 nodes first. Then recursively position their branches.
39469
39470 for (var level in distribution) {
39471 if (Object.prototype.hasOwnProperty.call(distribution, level)) {
39472 var _context;
39473
39474 // sort nodes in level by position:
39475 var nodeArray = keys$4(distribution[level]);
39476
39477 nodeArray = this._indexArrayToNodes(nodeArray);
39478
39479 sort(_context = this.direction).call(_context, nodeArray);
39480
39481 var handledNodeCount = 0;
39482
39483 for (var i = 0; i < nodeArray.length; i++) {
39484 var node = nodeArray[i];
39485
39486 if (this.positionedNodes[node.id] === undefined) {
39487 var spacing = this.options.hierarchical.nodeSpacing;
39488 var pos = spacing * handledNodeCount; // We get the X or Y values we need and store them in pos and previousPos.
39489 // The get and set make sure we get X or Y
39490
39491 if (handledNodeCount > 0) {
39492 pos = this.direction.getPosition(nodeArray[i - 1]) + spacing;
39493 }
39494
39495 this.direction.setPosition(node, pos, level);
39496
39497 this._validatePositionAndContinue(node, level, pos);
39498
39499 handledNodeCount++;
39500 }
39501 }
39502 }
39503 }
39504 }
39505 /**
39506 * This is a recursively called function to enumerate the branches from the largest hubs and place the nodes
39507 * on a X position that ensures there will be no overlap.
39508 *
39509 * @param {Node.id} parentId
39510 * @param {number} parentLevel
39511 * @private
39512 */
39513
39514 }, {
39515 key: "_placeBranchNodes",
39516 value: function _placeBranchNodes(parentId, parentLevel) {
39517 var _context2;
39518
39519 var childRef = this.hierarchical.childrenReference[parentId]; // if this is not a parent, cancel the placing. This can happen with multiple parents to one child.
39520
39521 if (childRef === undefined) {
39522 return;
39523 } // get a list of childNodes
39524
39525
39526 var childNodes = [];
39527
39528 for (var i = 0; i < childRef.length; i++) {
39529 childNodes.push(this.body.nodes[childRef[i]]);
39530 } // use the positions to order the nodes.
39531
39532
39533 sort(_context2 = this.direction).call(_context2, childNodes); // position the childNodes
39534
39535
39536 for (var _i5 = 0; _i5 < childNodes.length; _i5++) {
39537 var childNode = childNodes[_i5];
39538 var childNodeLevel = this.hierarchical.levels[childNode.id]; // check if the child node is below the parent node and if it has already been positioned.
39539
39540 if (childNodeLevel > parentLevel && this.positionedNodes[childNode.id] === undefined) {
39541 // get the amount of space required for this node. If parent the width is based on the amount of children.
39542 var spacing = this.options.hierarchical.nodeSpacing;
39543 var pos = void 0; // we get the X or Y values we need and store them in pos and previousPos.
39544 // The get and set make sure we get X or Y
39545
39546 if (_i5 === 0) {
39547 pos = this.direction.getPosition(this.body.nodes[parentId]);
39548 } else {
39549 pos = this.direction.getPosition(childNodes[_i5 - 1]) + spacing;
39550 }
39551
39552 this.direction.setPosition(childNode, pos, childNodeLevel);
39553
39554 this._validatePositionAndContinue(childNode, childNodeLevel, pos);
39555 } else {
39556 return;
39557 }
39558 } // center the parent nodes.
39559
39560
39561 var center = this._getCenterPosition(childNodes);
39562
39563 this.direction.setPosition(this.body.nodes[parentId], center, parentLevel);
39564 }
39565 /**
39566 * This method checks for overlap and if required shifts the branch. It also keeps records of positioned nodes.
39567 * Finally it will call _placeBranchNodes to place the branch nodes.
39568 *
39569 * @param {Node} node
39570 * @param {number} level
39571 * @param {number} pos
39572 * @private
39573 */
39574
39575 }, {
39576 key: "_validatePositionAndContinue",
39577 value: function _validatePositionAndContinue(node, level, pos) {
39578 // This method only works for formal trees and formal forests
39579 // Early exit if this is not the case
39580 if (!this.hierarchical.isTree) return; // if overlap has been detected, we shift the branch
39581
39582 if (this.lastNodeOnLevel[level] !== undefined) {
39583 var previousPos = this.direction.getPosition(this.body.nodes[this.lastNodeOnLevel[level]]);
39584
39585 if (pos - previousPos < this.options.hierarchical.nodeSpacing) {
39586 var diff = previousPos + this.options.hierarchical.nodeSpacing - pos;
39587
39588 var sharedParent = this._findCommonParent(this.lastNodeOnLevel[level], node.id);
39589
39590 this._shiftBlock(sharedParent.withChild, diff);
39591 }
39592 }
39593
39594 this.lastNodeOnLevel[level] = node.id; // store change in position.
39595
39596 this.positionedNodes[node.id] = true;
39597
39598 this._placeBranchNodes(node.id, level);
39599 }
39600 /**
39601 * Receives an array with node indices and returns an array with the actual node references.
39602 * Used for sorting based on node properties.
39603 *
39604 * @param {Array.<Node.id>} idArray
39605 * @returns {Array.<Node>}
39606 */
39607
39608 }, {
39609 key: "_indexArrayToNodes",
39610 value: function _indexArrayToNodes(idArray) {
39611 var array = [];
39612
39613 for (var i = 0; i < idArray.length; i++) {
39614 array.push(this.body.nodes[idArray[i]]);
39615 }
39616
39617 return array;
39618 }
39619 /**
39620 * This function get the distribution of levels based on hubsize
39621 *
39622 * @returns {object}
39623 * @private
39624 */
39625
39626 }, {
39627 key: "_getDistribution",
39628 value: function _getDistribution() {
39629 var distribution = {};
39630 var nodeId, node; // we fix Y because the hierarchy is vertical,
39631 // we fix X so we do not give a node an x position for a second time.
39632 // the fix of X is removed after the x value has been set.
39633
39634 for (nodeId in this.body.nodes) {
39635 if (Object.prototype.hasOwnProperty.call(this.body.nodes, nodeId)) {
39636 node = this.body.nodes[nodeId];
39637 var level = this.hierarchical.levels[nodeId] === undefined ? 0 : this.hierarchical.levels[nodeId];
39638 this.direction.fix(node, level);
39639
39640 if (distribution[level] === undefined) {
39641 distribution[level] = {};
39642 }
39643
39644 distribution[level][nodeId] = node;
39645 }
39646 }
39647
39648 return distribution;
39649 }
39650 /**
39651 * Return the active (i.e. visible) edges for this node
39652 *
39653 * @param {Node} node
39654 * @returns {Array.<vis.Edge>} Array of edge instances
39655 * @private
39656 */
39657
39658 }, {
39659 key: "_getActiveEdges",
39660 value: function _getActiveEdges(node) {
39661 var _this4 = this;
39662
39663 var result = [];
39664 forEach$1(node.edges, function (edge) {
39665 var _context3;
39666
39667 if (indexOf(_context3 = _this4.body.edgeIndices).call(_context3, edge.id) !== -1) {
39668 result.push(edge);
39669 }
39670 });
39671 return result;
39672 }
39673 /**
39674 * Get the hubsizes for all active nodes.
39675 *
39676 * @returns {number}
39677 * @private
39678 */
39679
39680 }, {
39681 key: "_getHubSizes",
39682 value: function _getHubSizes() {
39683 var _this5 = this;
39684
39685 var hubSizes = {};
39686 var nodeIds = this.body.nodeIndices;
39687 forEach$1(nodeIds, function (nodeId) {
39688 var node = _this5.body.nodes[nodeId];
39689
39690 var hubSize = _this5._getActiveEdges(node).length;
39691
39692 hubSizes[hubSize] = true;
39693 }); // Make an array of the size sorted descending
39694
39695 var result = [];
39696 forEach$1(hubSizes, function (size) {
39697 result.push(Number(size));
39698 });
39699
39700 sort(timsort).call(timsort, result, function (a, b) {
39701 return b - a;
39702 });
39703
39704 return result;
39705 }
39706 /**
39707 * this function allocates nodes in levels based on the recursive branching from the largest hubs.
39708 *
39709 * @private
39710 */
39711
39712 }, {
39713 key: "_determineLevelsByHubsize",
39714 value: function _determineLevelsByHubsize() {
39715 var _this6 = this;
39716
39717 var levelDownstream = function levelDownstream(nodeA, nodeB) {
39718 _this6.hierarchical.levelDownstream(nodeA, nodeB);
39719 };
39720
39721 var hubSizes = this._getHubSizes();
39722
39723 var _loop = function _loop(i) {
39724 var hubSize = hubSizes[i];
39725 if (hubSize === 0) return "break";
39726 forEach$1(_this6.body.nodeIndices, function (nodeId) {
39727 var node = _this6.body.nodes[nodeId];
39728
39729 if (hubSize === _this6._getActiveEdges(node).length) {
39730 _this6._crawlNetwork(levelDownstream, nodeId);
39731 }
39732 });
39733 };
39734
39735 for (var i = 0; i < hubSizes.length; ++i) {
39736 var _ret = _loop(i);
39737
39738 if (_ret === "break") break;
39739 }
39740 }
39741 /**
39742 * TODO: release feature
39743 * TODO: Determine if this feature is needed at all
39744 *
39745 * @private
39746 */
39747
39748 }, {
39749 key: "_determineLevelsCustomCallback",
39750 value: function _determineLevelsCustomCallback() {
39751 var _this7 = this;
39752
39753 var minLevel = 100000; // TODO: this should come from options.
39754 // eslint-disable-next-line no-unused-vars -- This should eventually be implemented with these parameters used.
39755
39756 var customCallback = function customCallback(nodeA, nodeB, edge) {}; // TODO: perhaps move to HierarchicalStatus.
39757 // But I currently don't see the point, this method is not used.
39758
39759
39760 var levelByDirection = function levelByDirection(nodeA, nodeB, edge) {
39761 var levelA = _this7.hierarchical.levels[nodeA.id]; // set initial level
39762
39763 if (levelA === undefined) {
39764 levelA = _this7.hierarchical.levels[nodeA.id] = minLevel;
39765 }
39766
39767 var diff = customCallback(NetworkUtil.cloneOptions(nodeA, "node"), NetworkUtil.cloneOptions(nodeB, "node"), NetworkUtil.cloneOptions(edge, "edge"));
39768 _this7.hierarchical.levels[nodeB.id] = levelA + diff;
39769 };
39770
39771 this._crawlNetwork(levelByDirection);
39772
39773 this.hierarchical.setMinLevelToZero(this.body.nodes);
39774 }
39775 /**
39776 * Allocate nodes in levels based on the direction of the edges.
39777 *
39778 * @private
39779 */
39780
39781 }, {
39782 key: "_determineLevelsDirected",
39783 value: function _determineLevelsDirected() {
39784 var _context4,
39785 _this8 = this;
39786
39787 var nodes = reduce(_context4 = this.body.nodeIndices).call(_context4, function (acc, id) {
39788 acc.set(id, _this8.body.nodes[id]);
39789 return acc;
39790 }, new map());
39791
39792 if (this.options.hierarchical.shakeTowards === "roots") {
39793 this.hierarchical.levels = fillLevelsByDirectionRoots(nodes);
39794 } else {
39795 this.hierarchical.levels = fillLevelsByDirectionLeaves(nodes);
39796 }
39797
39798 this.hierarchical.setMinLevelToZero(this.body.nodes);
39799 }
39800 /**
39801 * Update the bookkeeping of parent and child.
39802 *
39803 * @private
39804 */
39805
39806 }, {
39807 key: "_generateMap",
39808 value: function _generateMap() {
39809 var _this9 = this;
39810
39811 var fillInRelations = function fillInRelations(parentNode, childNode) {
39812 if (_this9.hierarchical.levels[childNode.id] > _this9.hierarchical.levels[parentNode.id]) {
39813 _this9.hierarchical.addRelation(parentNode.id, childNode.id);
39814 }
39815 };
39816
39817 this._crawlNetwork(fillInRelations);
39818
39819 this.hierarchical.checkIfTree();
39820 }
39821 /**
39822 * Crawl over the entire network and use a callback on each node couple that is connected to each other.
39823 *
39824 * @param {Function} [callback=function(){}] | will receive nodeA, nodeB and the connecting edge. A and B are distinct.
39825 * @param {Node.id} startingNodeId
39826 * @private
39827 */
39828
39829 }, {
39830 key: "_crawlNetwork",
39831 value: function _crawlNetwork() {
39832 var _this10 = this;
39833
39834 var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
39835 var startingNodeId = arguments.length > 1 ? arguments[1] : undefined;
39836 var progress = {};
39837
39838 var crawler = function crawler(node, tree) {
39839 if (progress[node.id] === undefined) {
39840 _this10.hierarchical.setTreeIndex(node, tree);
39841
39842 progress[node.id] = true;
39843 var childNode;
39844
39845 var edges = _this10._getActiveEdges(node);
39846
39847 for (var i = 0; i < edges.length; i++) {
39848 var edge = edges[i];
39849
39850 if (edge.connected === true) {
39851 if (edge.toId == node.id) {
39852 // Not '===' because id's can be string and numeric
39853 childNode = edge.from;
39854 } else {
39855 childNode = edge.to;
39856 }
39857
39858 if (node.id != childNode.id) {
39859 // Not '!==' because id's can be string and numeric
39860 callback(node, childNode, edge);
39861 crawler(childNode, tree);
39862 }
39863 }
39864 }
39865 }
39866 };
39867
39868 if (startingNodeId === undefined) {
39869 // Crawl over all nodes
39870 var treeIndex = 0; // Serves to pass a unique id for the current distinct tree
39871
39872 for (var i = 0; i < this.body.nodeIndices.length; i++) {
39873 var nodeId = this.body.nodeIndices[i];
39874
39875 if (progress[nodeId] === undefined) {
39876 var node = this.body.nodes[nodeId];
39877 crawler(node, treeIndex);
39878 treeIndex += 1;
39879 }
39880 }
39881 } else {
39882 // Crawl from the given starting node
39883 var _node2 = this.body.nodes[startingNodeId];
39884
39885 if (_node2 === undefined) {
39886 console.error("Node not found:", startingNodeId);
39887 return;
39888 }
39889
39890 crawler(_node2);
39891 }
39892 }
39893 /**
39894 * Shift a branch a certain distance
39895 *
39896 * @param {Node.id} parentId
39897 * @param {number} diff
39898 * @private
39899 */
39900
39901 }, {
39902 key: "_shiftBlock",
39903 value: function _shiftBlock(parentId, diff) {
39904 var _this11 = this;
39905
39906 var progress = {};
39907
39908 var shifter = function shifter(parentId) {
39909 if (progress[parentId]) {
39910 return;
39911 }
39912
39913 progress[parentId] = true;
39914
39915 _this11.direction.shift(parentId, diff);
39916
39917 var childRef = _this11.hierarchical.childrenReference[parentId];
39918
39919 if (childRef !== undefined) {
39920 for (var i = 0; i < childRef.length; i++) {
39921 shifter(childRef[i]);
39922 }
39923 }
39924 };
39925
39926 shifter(parentId);
39927 }
39928 /**
39929 * Find a common parent between branches.
39930 *
39931 * @param {Node.id} childA
39932 * @param {Node.id} childB
39933 * @returns {{foundParent, withChild}}
39934 * @private
39935 */
39936
39937 }, {
39938 key: "_findCommonParent",
39939 value: function _findCommonParent(childA, childB) {
39940 var _this12 = this;
39941
39942 var parents = {};
39943
39944 var iterateParents = function iterateParents(parents, child) {
39945 var parentRef = _this12.hierarchical.parentReference[child];
39946
39947 if (parentRef !== undefined) {
39948 for (var i = 0; i < parentRef.length; i++) {
39949 var parent = parentRef[i];
39950 parents[parent] = true;
39951 iterateParents(parents, parent);
39952 }
39953 }
39954 };
39955
39956 var findParent = function findParent(parents, child) {
39957 var parentRef = _this12.hierarchical.parentReference[child];
39958
39959 if (parentRef !== undefined) {
39960 for (var i = 0; i < parentRef.length; i++) {
39961 var parent = parentRef[i];
39962
39963 if (parents[parent] !== undefined) {
39964 return {
39965 foundParent: parent,
39966 withChild: child
39967 };
39968 }
39969
39970 var branch = findParent(parents, parent);
39971
39972 if (branch.foundParent !== null) {
39973 return branch;
39974 }
39975 }
39976 }
39977
39978 return {
39979 foundParent: null,
39980 withChild: child
39981 };
39982 };
39983
39984 iterateParents(parents, childA);
39985 return findParent(parents, childB);
39986 }
39987 /**
39988 * Set the strategy pattern for handling the coordinates given the current direction.
39989 *
39990 * The individual instances contain all the operations and data specific to a layout direction.
39991 *
39992 * @param {Node} node
39993 * @param {{x: number, y: number}} position
39994 * @param {number} level
39995 * @param {boolean} [doNotUpdate=false]
39996 * @private
39997 */
39998
39999 }, {
40000 key: "setDirectionStrategy",
40001 value: function setDirectionStrategy() {
40002 var isVertical = this.options.hierarchical.direction === "UD" || this.options.hierarchical.direction === "DU";
40003
40004 if (isVertical) {
40005 this.direction = new VerticalStrategy(this);
40006 } else {
40007 this.direction = new HorizontalStrategy(this);
40008 }
40009 }
40010 /**
40011 * Determine the center position of a branch from the passed list of child nodes
40012 *
40013 * This takes into account the positions of all the child nodes.
40014 *
40015 * @param {Array.<Node|vis.Node.id>} childNodes Array of either child nodes or node id's
40016 * @returns {number}
40017 * @private
40018 */
40019
40020 }, {
40021 key: "_getCenterPosition",
40022 value: function _getCenterPosition(childNodes) {
40023 var minPos = 1e9;
40024 var maxPos = -1e9;
40025
40026 for (var i = 0; i < childNodes.length; i++) {
40027 var childNode = void 0;
40028
40029 if (childNodes[i].id !== undefined) {
40030 childNode = childNodes[i];
40031 } else {
40032 var childNodeId = childNodes[i];
40033 childNode = this.body.nodes[childNodeId];
40034 }
40035
40036 var position = this.direction.getPosition(childNode);
40037 minPos = Math.min(minPos, position);
40038 maxPos = Math.max(maxPos, position);
40039 }
40040
40041 return 0.5 * (minPos + maxPos);
40042 }
40043 }]);
40044
40045 return LayoutEngine;
40046}();
40047
40048var css_248z = "div.vis-network div.vis-manipulation {\n box-sizing: content-box;\n\n border-width: 0;\n border-bottom: 1px;\n border-style: solid;\n border-color: #d6d9d8;\n background: #ffffff; /* Old browsers */\n background: -moz-linear-gradient(\n top,\n #ffffff 0%,\n #fcfcfc 48%,\n #fafafa 50%,\n #fcfcfc 100%\n ); /* FF3.6+ */\n background: -webkit-gradient(\n linear,\n left top,\n left bottom,\n color-stop(0%, #ffffff),\n color-stop(48%, #fcfcfc),\n color-stop(50%, #fafafa),\n color-stop(100%, #fcfcfc)\n ); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(\n top,\n #ffffff 0%,\n #fcfcfc 48%,\n #fafafa 50%,\n #fcfcfc 100%\n ); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(\n top,\n #ffffff 0%,\n #fcfcfc 48%,\n #fafafa 50%,\n #fcfcfc 100%\n ); /* Opera 11.10+ */\n background: -ms-linear-gradient(\n top,\n #ffffff 0%,\n #fcfcfc 48%,\n #fafafa 50%,\n #fcfcfc 100%\n ); /* IE10+ */\n background: linear-gradient(\n to bottom,\n #ffffff 0%,\n #fcfcfc 48%,\n #fafafa 50%,\n #fcfcfc 100%\n ); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */\n\n padding-top: 4px;\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 28px;\n}\n\ndiv.vis-network div.vis-edit-mode,\ndiv.vis-network button.vis-edit-mode {\n position: absolute;\n left: 0;\n top: 5px;\n height: 30px;\n}\n\n/* FIXME: shouldn't the vis-close button be a child of the vis-manipulation div? */\n\ndiv.vis-network button.vis-close {\n position: absolute;\n right: 0;\n top: 0;\n width: 30px;\n height: 30px;\n\n background-color: transparent;\n background-position: 20px 3px;\n background-repeat: no-repeat;\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAADvGaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTQtMDItMTRUMTE6NTU6MzUrMDE6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDE0LTAyLTE0VDEyOjA1OjE3KzAxOjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNC0wMi0xNFQxMjowNToxNyswMTowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6NjU0YmM5YmQtMWI2Yi1jYjRhLTllOWQtNWY2MzgxNDVjZjk0PC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjk4MmM2MGIwLWUzZjMtMDk0MC04MjU0LTFiZTliNWE0ZTE4MzwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjk4MmM2MGIwLWUzZjMtMDk0MC04MjU0LTFiZTliNWE0ZTE4MzwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo5ODJjNjBiMC1lM2YzLTA5NDAtODI1NC0xYmU5YjVhNGUxODM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDItMTRUMTE6NTU6MzUrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjIxODYxNmM2LTM1MWMtNDI0OS04YWFkLWJkZDQ2ZTczNWE0NDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNC0wMi0xNFQxMTo1NTozNSswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NjU0YmM5YmQtMWI2Yi1jYjRhLTllOWQtNWY2MzgxNDVjZjk0PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE0LTAyLTE0VDEyOjA1OjE3KzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjc8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NzwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+cZUZMwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAA2ElEQVR42gDLADT/AS0tLUQFBQUVFxcXtPHx8fPl5eUNCAgITCkpKesEHx8fGgYGBjH+/v4a+Pj4qgQEBFU6OjodMTExzwQUFBSvEBAQEfX19SD19fVqNDQ0CElJSd/9/f2vAwEBAfrn5+fkBwcHLRYWFgsXFxfz29vbo9LS0uwDDQ0NDfPz81orKysXIyMj+ODg4Avh4eEa/f391gMkJCRYPz8/KUhISOMCAgKh8fHxHRsbGx4UFBQQBDk5OeY7Ozv7CAgItPb29vMEBASaJSUlTQ0NDesDAEwpT0Ko8Ri2AAAAAElFTkSuQmCC');\n border: none;\n cursor: pointer;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\ndiv.vis-network button.vis-close:hover {\n opacity: 0.6;\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button,\ndiv.vis-network div.vis-edit-mode button.vis-button {\n float: left;\n font-family: verdana;\n font-size: 12px;\n border: none;\n box-sizing: content-box;\n -moz-border-radius: 15px;\n border-radius: 15px;\n background-color: transparent;\n background-position: 0px 0px;\n background-repeat: no-repeat;\n height: 24px;\n margin-left: 10px;\n cursor: pointer;\n padding: 0px 8px 0px 8px;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button:hover {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.2);\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button:active {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.5);\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button.vis-back {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAEEOaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNC0wMi0wNFQxNTowMTowOSswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTQtMDItMDRUMTU6MDE6MDkrMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOmI2YjQwMjVkLTAxNjQtMzU0OC1hOTdlLTQ4ZmYxMWM3NTYzMzwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6RUE2MEEyNEUxOTg0RTMxMUFEQUZFRkU2RUMzMzNFMDM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDEtMjNUMTk6MTg6MDcrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDpmOWQ3OGY4ZC1lNzY0LTc1NDgtODZiNy1iNmQ1OGMzZDg2OTc8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDItMDRUMTU6MDE6MDkrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmI2YjQwMjVkLTAxNjQtMzU0OC1hOTdlLTQ4ZmYxMWM3NTYzMzwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNC0wMi0wNFQxNTowMTowOSswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06RGVyaXZlZEZyb20gcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICA8c3RSZWY6aW5zdGFuY2VJRD54bXAuaWlkOmY5ZDc4ZjhkLWU3NjQtNzU0OC04NmI3LWI2ZDU4YzNkODY5Nzwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDA5MC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDkwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4jq1U/AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAVTSURBVHjanFVfTFNnFP+d77ve8qeVFbBrpcVgRrCRFikFByLxwSAaE32oRCHD6JMxxhhn8G2RxxH3MsOTbyYsmCAxPMmMMYtkIUYmK60OO0qAK23BFlNob0uh3x7WS5jLZPpLbm6+k/P9zrm5v9855PF4UFhYCABgjIExBgAgIqRSqRIi6gDQRkQ1RGTB3wgR0e8AHgH4Sa/XR/EBiAiJRAJ04cIF5Ofng4g2n0gkUkxENwF0c843LzHGQEQQQkCLExEA9ALotVgsUQAQQmgNQhJCbF5kjCEUCl0moj4t5na7fTU1NUpVVVXUYrEkASAcDhe8efOmxOfzWScmJqoBdBNR99LS0hWz2dynNSSEAF28eBGFhYVgjCEcDn9HRD1EhIMHD3o9Hs9kWVlZAh9BKBQqGB4edr58+dKZ+6JbJpOpBwBWV1fB6+rqIMsyIpHIFcZYL2MMra2tY5cuXRrfuXNnBtvAYDBk3G63oqpqZm5uzgrgSDKZjBoMhueZTAbc5XIhFouVEtFTxhiOHTs2dv78eS8+Efv374+oqpqZnZ21cs5PJJPJPlmWkyynnBuMMTQ0NHi7uro+mVyDx+Pxulwu71ZOlkqlSonoJhGhvb39s8k1nDx50ss5hyRJN9PpdKlERB2aWjSVaEilUvzBgwcORVEs5eXloXPnzk1sV8BkMiUdDofP7/dXZ7PZDilnIhw4cGBeS1pbW2P37t1zBwKBikQiUUREWFhYsHHO0d7evm0Ru90+/+rVq2rO+XGJiJxEhMrKyhgAjI6OWoeHh5tWVla+4JzDZrO9bW5unhwcHGzz+/32np4e+xaDbfoHAMxmc6ijo2O0oqIiJkkSNjY2HBIRmRljMJvNyWfPnln7+/tPMMZQXl6+0NbW9qK2tjYcj8floaEhqKpq+HCkbD3PzMwYBgYG0NXV9UuusFna2kEgELAQEQ4dOvSis7PzN41Ar9dnrl27NqCNkv/C3bt3zy4tLVmICJxzEBFJRBQmorLFxcWCqqqq0Pj4eO3Y2JhbUZTdra2tL2pra8OJRGLHnTt3zkqS9K+huHU4EhHMZnMoGo0W5OIh7nK5jjLGKq1W69vDhw8rRqMxMjc3t2t5eXnX5ORklc/nM+fl5SWnpqa+0uv1K/n5+Ws6nW5NluXNd15e3ppOp1uz2WyzZ86cGQ0Gg6ZAIFCZzWZ/lYjokRDiuN/vt7W0tMw3NTUpbrd78P79++5gMFgRiUTKHj58WMYYQ3V19etTp05tq6Lp6Wkb5xxCiEfc7XZPM8a6FxcXTfX19a/1en2Gcy5qamreNjY2/qGq6joRZe12+9Tp06e3JY/FYgWPHz8+mhvr3/CWlpbk+vp6PmOseWVlBS6XS9GSJUkSdrs93NDQ8Oe+ffvC/8fJIyMjddFo9Esi6pVleVjT2m0A8Hq9zqGhIefnjoknT544A4GAM/eDbxMReFNTE0pKSpKqqsaI6Pj8/LxVVdWM3W6PfCr5xMTE1zllXS0uLn6aSqXAGxsbodPpoNfrn6uqCs75EUVRrJFIZMfevXsXdTrdxseIE4mEPDIyUu/3++tynd8yGo29RIR0Og26fv06ioqKwBgD5xzv3r27zBjrIyJIkgSHwzFZWVmp7NmzJ1ZaWpoAgGg0WqgoSvHMzIw1GAw6tvjhitFo7NPW5fv370Hd3d0oKCgA53zTQMvLy+VCiKuSJH0rSdLmztZytIWv5RPRD0T0Y3Fx8dzWfby6ugopHo//w4mcc8iyPMc5v5FOp7/PZrOdQohWInIC2C2EgBBigYi8Qoifs9lsv06nWyIiaFxagXg8jr8GAGxuIe7LBeWhAAAAAElFTkSuQmCC');\n}\n\ndiv.vis-network div.vis-manipulation div.vis-none:hover {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0);\n cursor: default;\n}\ndiv.vis-network div.vis-manipulation div.vis-none:active {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0);\n}\ndiv.vis-network div.vis-manipulation div.vis-none {\n padding: 0px;\n line-height: 23px;\n}\ndiv.vis-network div.vis-manipulation div.notification {\n margin: 2px;\n font-weight: bold;\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button.vis-add {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAEEOaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNC0wMi0wNFQxNDo0MDoyOSswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTQtMDItMDRUMTQ6NDA6MjkrMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOjVkNWIwNmQwLTVmMjAtOGE0NC1hMzIwLWZmMTEzMzQwNDc0YjwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6RUE2MEEyNEUxOTg0RTMxMUFEQUZFRkU2RUMzMzNFMDM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDEtMjNUMTk6MTg6MDcrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo2OWVmYWE1NS01ZTI5LTIzNGUtYTUzMy0xNDkxYjM1NDNmYmE8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDItMDRUMTQ6NDA6MjkrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjVkNWIwNmQwLTVmMjAtOGE0NC1hMzIwLWZmMTEzMzQwNDc0Yjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNC0wMi0wNFQxNDo0MDoyOSswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06RGVyaXZlZEZyb20gcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICA8c3RSZWY6aW5zdGFuY2VJRD54bXAuaWlkOjY5ZWZhYTU1LTVlMjktMjM0ZS1hNTMzLTE0OTFiMzU0M2ZiYTwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDA5MC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDkwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz5WKqp9AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAYXSURBVHjafFZtUFTXGX7e9z27sveuMCwYV8ElrA7YSFYHtJUPkaaI0aRqG8wP00zUzljDINNSA/2ROtpO24SxnahlxjYd7SSjmUkymcxYlDhQPzHGisEVp8HwYWCVVVgEsrsuLnL74+5uqTF9Z+7cO/d8PO95zvO851BlZSV0XQcAMDOYGQBARDhX3JRmMDYZwLPMWAzGHACYIgwS46oBNBNwtOL8CwE8EkSEUCgE2rJlC2w2G4go8Zwo/bMDgnoG6gxLfAAAYvPDMCCszKTAMIAGAhrWnf15AAAMwwARIRKJgDZv3gy73Q4iAjPjxIr9VVOMRhbAYKB8zvrO0llrfEsdKwLZek6YAPSFvtSu3GtLawu0ZJ6625SHGBQB1T88t6MxvopgMAjaunUrdF0HM+P4yv27DMYeJmB1RqW3Jnf3tQX2p0L4P9EXuqEd7PmDp+XuMU9sRbvXnnt1TxxACgoKYLVacbzsQDUJGkSATe6qi28uPtzusM6Kxie6NHLGUX3lxVUNX9StPHnn4wy3njuUYcu6n2pNi66avcEXnByP/nv8aiaIyrqz2gO5A9+9FI1GIfn5+WhZdTAdjFMkwMvZOy7uWnTAOz3L4Yk71m3t69fdfTDoUGTBeHTUfiHQ6lo7Z2OXJvpDAChKe+aOCdKRKWxZ2+1qb3yyd3GYmRkQ7GQBVs99wfv6on3eR2k4PdTkDEbH7IuS8/svld/561PJS/pDk1/bzwx94pze7xc5v/H+YPY6r5BAkdrJzODTK46lE6PeYEJt7u+8j+OZwCBiEAgAoNgKJoEQf6PvNvdrXgtZoNhSf7q0KZ3B2AQmVMze0Jmt54S/DcDCVig2NcvEUGxJAE4Pl+YOr0iv6BRSIPAmBeBZAmHlE2sH4p1uhrq1s0MnnEQMBsf8wRASAICQQCCITN1X7/sOuc0kgOVp3/fPs2WHv+coG7gQOJUnLGsUCTxEjPzUohEA+NfIWUdtx0+efzA1kSSkIGyBAQNCKgHAEBAJ3u79U7kiAcWoem/gb5Fd33nrH3kp+SMWtuAB+GllMJxMjCx9QRgA3uiqL5kwHiTlpxb3smlfMDGYGPP1hcMAkJvs8ScpfdJspdj+MK6Pf+5+u29vyb4lR4+BGEziVESAkEpw6Av1OhUpHCz4qOXbzFWz4Ncdj/v/o08Lt92ODDgZDCEFJYoUGH4mzugP92puPTf0pD3H7wvfdFZdqSxnMtWjoGAAmG9fOLxjwesdjT2/XzIQ7ks3sycYMSEwGHNtWf5bkX5NkYCJBxUBXiGV0XHvosOt54Zey33j/K+8P33++vjnbiGJbbLE+J9SANAb6nJ2B79wcUwETAwQQ7fMjPzMvfP8ja87HUIKMOiaAqMZhrGmLdAy78eZrwwsTS0eObTs+IdtgVanxBUExqGbb5VzrIISGIoUXsmqbgEhJldCQWqRf27SvPAn/o8XmgLhZsUkR4ll37mhk3n94Z4OlzY/7NLcYZfm7o1z2zT4vsvUNSXqprBCkmiTFbPX90/fh8GIT2sf+zTPdDMf4dVnNg4z+E0ixsGeBs9jd5ViSgLHjCb/peaR+MD3d4/ZJg2llyuG2Vwy7QWAs8PNnn1f7vkGSGxAzE6mk+kxkx/p/4unffSCR0hAoL1EBCYiPNdWNcwkNQTCR7feWX6g+7f/A7I8rcw/U6UEe0Ndrhc/W7mtL9ztmqlSgstSS/zTJ28dalpOpkRryrwbhwBACgsLMWPGDOT4ll3qyeqAkJTdCF7P/CrUY/GkLL1rE+2hTbSH8+0Lb/WEuhzhyaA905blf9Vd/895WnZwLHrPevir/cvOB1oLYpTtLrm6oYGIMDExAaqtrUVKSgqYGSKCk0WHq5ikkWEWtNL0imv5qUW+RclLRjJsrhBAuH1/QL8R7HR4xy5nescuP23E6hOA6mLv+sb4uTw6Ogqqq6uDpmkQkcStorX4XRcM1FjZ+kvFFjCJKU1WpkNJJUqIMtX1RyLeX3JtQ0JRhmGYZ/L27duRnJycuFGISOJ9pqh5lrB6iYgqGOxRrOaa54DcZmKvkJxk8JHC9rKh+KVhOsD4+Dj+MwADIf8n5m4xGwAAAABJRU5ErkJggg==');\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button.vis-edit,\ndiv.vis-network div.vis-edit-mode button.vis-button.vis-edit {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAEEOaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNC0wMi0wNVQxNDoxMjoyNSswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTQtMDItMDVUMTQ6MTI6MjUrMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOjY5OTM3ZGZjLTJjNzQtYTU0YS05OTIzLTQyMmZhNDNkMjljNDwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6RUE2MEEyNEUxOTg0RTMxMUFEQUZFRkU2RUMzMzNFMDM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDEtMjNUMTk6MTg6MDcrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDozOWNhNzE5ZC03YzNlLTUyNGEtYmY1NS03NGVmMmM1MzE0YTc8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDItMDVUMTQ6MTI6MjUrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjY5OTM3ZGZjLTJjNzQtYTU0YS05OTIzLTQyMmZhNDNkMjljNDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNC0wMi0wNVQxNDoxMjoyNSswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06RGVyaXZlZEZyb20gcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICA8c3RSZWY6aW5zdGFuY2VJRD54bXAuaWlkOjM5Y2E3MTlkLTdjM2UtNTI0YS1iZjU1LTc0ZWYyYzUzMTRhNzwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDA5MC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDkwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4ykninAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAYpSURBVHjafFZtTFvnFX7Oea+NudiY2Hwam4CBlgQwXdKREDKUoYg0jbRJ29RJ2VZ1mjRFUxSpA3VTfkzJfkQbS7spU6rtx5Z2UtppScjaHxvLuiatWi2jLEoMIUDCh23g2gbj7+tPuPvhOurawPl1dc99n+c55z33fV46ceIEZFkGADAziAgAQERoe/9ZK4GPM/AcgbsIXAcABCgMvkfAqAa89eDoJyF8LogIqqqChoaGYDAYHr8kItS8uc8iIH6iAa9IkAo5EAQX8pqmgUVBCBggYFgDhv0/GAsBgKZpICJkMhnQ4OAgZFkGEYGZUXmp+0cS+CKBwWA0DVRPOg5Zl2q6zaHyJlnVAMQXVTkwHrUqH0Xsvn+tdQAAMQDgpPLS2MViFY8rkGUZzIzaS/t/xqCzGggtz9e697zsnKhoLUtim4jOq/LE6x7X0nsh16dEZ5a/O3a2SCAOHjwInU6Hujd6ThJ4mCDQ+b2G232v7v6vwarPbQn8MGlMr+X0kpE3Wr5Zt5hL5HPhqYSdQIfKJ+yhxDPKWC6Xg+jt7UXD5b5KBt1kCHS85Ljd8/On3NupfnhFaZj4rWff1B98B1R/hnUmKd36bdtCNl4g0en4edNE/cXwLq8qMTMIPAQwmo/WuHvObA8+9c58k/dKtD0TyZWXN5YGA7ej7epKxspM//7SoNOdWc/Jyq2wiwhDzPxT8cP0jys3VMM7OmL0/77zn4Ydui3b8uiK0jD7RrA77c9Wd57cefPpF+2T6bWsFPWkaiPTCWvTsZpHFU+XrS+8G3AR08F6X+1FJvBxQQzHQOWk2SmrW4FPX/U2LVwPuDZj+fJKl2khPpeyAqA9rzR/YqwuiWXX8taN/CabGkrVuq9YJlkQQDjOAJ5jAhz9Vt9W4N5/rNp8I+vtMV/aZm4zLnUNNt0urdYnF68HWoJj4Wo1mLGUNRr8LEgDgNqeCh8xQIKOsgC7iAjVe83rT9zQa8uNM28u70kspessu8q8zq/V3NcZpVzb9+0zmVhOvvvrhaMVzrJg0zeq7xMVCCwdpnWSGBqjUyJwLTFgbvxie3w31uoWR1Y74r60rdxZqrR8q85t2W2MGCp12bm/KC3hyaSTiMhxuGrKcahqpbjOaDOoEhOEoFqJQCCJvqA85I6bfTdDjQlf2lbxVNlS6wt19yy7jRHZZlDnrinNj/6sHMhnNw2Ogco7O79e5fm/xQywRBBCEAuwn4gQ96bkYj4Vyuq9N1Z3Bj4Od5bs0MXt/dZZ21ctiqFan174q985P+Lfp+U1g7XDON/1ctP458WlVjLyJhOISZE0wM0S1QfuRC3lTjkJAKKEtNC9eIOhSh9xHLZOJRZTFuXDsEoStLkR/768ummsaJG9Pb9oe+9J+xaeSVokiQDSJphAo5uaBuWjiKP4QTqS1cUWU7ayesN66wu22frD1vmVW6GW6T8u9eVjGyZzs+w78Nqu0a2mbvVu1KEJQAgeZRL0liQYyx+GOmKeQpu0rMYsAJPNEFGD2dLodLIy6c9Ys7G8yeSUl3tf2/X3rcBVJSOv34l3sCBogi7z1LH/rBHjl4IJ93/ncQFAnjeImJD0Z8zuCwu9q3djDXqTlAKID5xv+9t2R8n8VcUFBljQ8Gyfe40BYBM4DwDLt8Kue79ZcFkbzfEdbUbv+oN4c9KTtsfm1MbYQqqh+2zrVZYKs/7Ef+byimt1POYiJhDhPBFBIiIEXhxfs7/dfYoIF+auBfYTE/pebx/V8hqBP2ODvD34yvuh/WCAmU75Bx6sIgaI/v5+6PV6JLqUsYr7dpDAoehs0h73pHTWrvKgThYbRSt9UmSjef3MpaUvBz4O72UmADgTOPJguGiZor+/HyUlJWBmJFz+D8xTtlUiOpbwpmrmrweeSXrT+g11k4SBN3RGKUcAVCVdFhyP1nreDbY//NPyEXUlU/Pp4XYycGT6V0Ux2WwWdO7cOZSWlkII8diX7SPPNgDaKdbxoNAxwATBAEkEEgSWCEQAqPAMwqvMdCEwMO0tVqZpWsGTT58+DaPR+PhGIYQAAAgh0P7B3ioW/B0iGiCGiwXbCuOHFSJys6AbYFye2T+xWhT3WYJEIoH/DQBMw3kes8OJPgAAAABJRU5ErkJggg==');\n}\n\ndiv.vis-network div.vis-edit-mode button.vis-button.vis-edit.vis-edit-mode {\n background-color: #fcfcfc;\n border: 1px solid #cccccc;\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button.vis-connect {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAEEOaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNC0wMi0wNFQxNDozODo1NyswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTQtMDItMDRUMTQ6Mzg6NTcrMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOjlmYjUwMDU0LWE3ODEtMWQ0OC05ZTllLTU2ZWQ5YzhlYjdjNjwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6RUE2MEEyNEUxOTg0RTMxMUFEQUZFRkU2RUMzMzNFMDM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDEtMjNUMTk6MTg6MDcrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo3ZWRhMjI0MC0yYTQxLTNlNDQtYWM2My1iNzNiYTE5OWI3Y2E8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDItMDRUMTQ6Mzg6NTcrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjlmYjUwMDU0LWE3ODEtMWQ0OC05ZTllLTU2ZWQ5YzhlYjdjNjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNC0wMi0wNFQxNDozODo1NyswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06RGVyaXZlZEZyb20gcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICA8c3RSZWY6aW5zdGFuY2VJRD54bXAuaWlkOjdlZGEyMjQwLTJhNDEtM2U0NC1hYzYzLWI3M2JhMTk5YjdjYTwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDA5MC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDkwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4ubxs+AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAUtSURBVHjajJZ/bNT1Gcdfz/P53PV6B4W7VltLqdAaplIOiMOoyxxJCSs/Gv/yB4gzJroAosmmDklwkYWR0bQsdmkykoojTpcsWYLxD/lRZdMQkTHRtkLZRqG0tIVe7662vTu43n32x/VKZ/jh89cn38/zvN7P5/l88zwf2blzJz6fDwARQUSm1n8s31CM0/VAnbNmsUPuAsDpgEO+Bg4C7//iyv5hvmMiQiqVQpqamvB6vVNwEeG1JZtCBrYi/MrkAwDNgjhwAlbzICBLA0rDb0+/839C6XQaaWxspLCw8Dp86cbNmqVFJQddE6KzdjZ9D89g+B6fSyCOcyn1nxil+O9xKg5HqWFSHGXLjrP7W/ICqVQK2bNnDz6fDxFh65KNvxbHDhF4rJj2bXPo+IGfcW5h5xL4f99P+FCEMIAob75x9t0dAMlkElNXV4e1lteXbNqiQoMaeOFOjrdU868SD2luYyEP6dUh+sYmSHeOU6GO5Z8VLx5+NNZxIpPJ5AS2L3upROCoCvz8Lo7vnkf77cAHhpiz/zIL9vWz8L8p/NvupmM0Q7pjnAoLqz8tDrc8MnQqYVUVhVdF4LEg7b+rvDn8wDDlH0WoPpukLJImSBaMwjcJqmwWts2jPZLG/8kwYVFeVdXXZcFf4yVDc2cNKfBFmD9X+0ncCP58F48eG+Feo2CAUkvs4dl0V/uJvdXLiiV+ut++n7YLSfxPfMMG54ChzB3WIesVWB2i82bw1AR6fJR7C4VsfYiv6u/k3A9nEgP4zXke8DiYHyAOMK+QxPIgnZ9GqSHr1itQJ8DK2fTerDQ+S/bHRXQJaHSCwNIZ2Xh+7+S3VAmwNMBA/tuPZtErgKquUmdMWIFlRURvdamRNEXGwIWrlP47pTMzLiunxghGMwTLvcTWlHAp77s4QNSrYMQtss6ZMgWqCm5cHoDHO1nbk6K8zEN8+3zatv2Hn1b59EqJZdxmYUERg9P9KwpIiAOTdWUWBXuLzB/vZG3P1Un4PNp2d1MbmyD45TWCxuCsQm0x56bHGHFYEZwxok7toAA9Sfw3hCcoL/NOwi9QO5wmWO1j4JEgZxTkodmcWRGkf3pcX0r8xoAaBixKu4U5/xwndM+0tpAvS6mP+PZK2nb1UBvPEKwKMLDvPj4ESGc55lGy303sdJKQdZB2rkMdctAB/4gzN+/Q2ENNd4LyUi/xN+bTtquX2thk5nk4wI3gAF+OMNcA1nFQDfK+BY5GqbkwWabTY5QZhXWlnNx1ntrY1Rz87fuvw29m/Sn8J+PUGAFj5T19baA1IspuBZp7cx1x4SwG1cEf+lgRSROs8jGwb+Ht4QB/GSSsAhYano39LWIBxNEIbP14hPDuiyS2VtJuHXQlKKvxM/jiXDq/D/xPlwifGMkJZB2NIoKpr69nxeiZxLHicFSFVWfGqBidIP3LSjrWltD94CyufF/4kQgPuVz2Lz93+dDRa9eu5QQ8Hg8/iXee+Dy4CKMs7xqn4nwKz9IirhQqmVuB42m8ey+x7LMoD6iAON782eChhqmRuXfvXgKBAKqKqtI0/8nNKrQI4BVYXkzHgzPpC88gWuHL/caXrhLoGiN0apSKr0ZZRBZM7q2w5ZnLR1oAnHOMjY0hra2tFBQUYIyZmstvVT1Z6eDlAuEVq7merxmwueNPDXy9PvybjKP5mctHLk4/XTKZRJqbm/H7/VNw1VyEMYbW4FN3WNWnnchKoy5sHeVGBRX6VWi3ymFx7r11Ix8MTX/y5C2RSPC/AQB61erowbpqSwAAAABJRU5ErkJggg==');\n}\n\ndiv.vis-network div.vis-manipulation button.vis-button.vis-delete {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAEEOaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNC0wMi0wNFQxNDo0MTowNCswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTQtMDItMDRUMTQ6NDE6MDQrMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOjc3NDkzYmUxLTEyZGItOTg0NC1iNDYyLTg2NGVmNGIzMzM3MTwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE0LTAxLTIyVDE5OjI0OjUxKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6RUE2MEEyNEUxOTg0RTMxMUFEQUZFRkU2RUMzMzNFMDM8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDEtMjNUMTk6MTg6MDcrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowNmE3NWYwMy04MDdhLWUzNGYtYjk1Zi1jZGU2MjM0Mzg4OGY8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTQtMDItMDRUMTQ6NDE6MDQrMDE6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjc3NDkzYmUxLTEyZGItOTg0NC1iNDYyLTg2NGVmNGIzMzM3MTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNC0wMi0wNFQxNDo0MTowNCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06RGVyaXZlZEZyb20gcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICA8c3RSZWY6aW5zdGFuY2VJRD54bXAuaWlkOjA2YTc1ZjAzLTgwN2EtZTM0Zi1iOTVmLWNkZTYyMzQzODg4Zjwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpFQTc2MkY5Njc0ODNFMzExOTQ4QkQxM0UyQkU3OTlBMTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjczQjYyQUFEOTE4M0UzMTE5NDhCRDEzRTJCRTc5OUExPC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDA5MC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDkwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4aYJzYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAYGSURBVHjalJZ7UJTnFcZ/73m/72PdJY1RbhoQp6lkXRAvmIYxdCUadLVOozPNtGObap1JsKipjiShbdoRbeKEiQHpQK3xj0xa03aamTbaTGyAYV1QGeqFi+JyiZFLAlmESBkWRmS3fyzslGkmnZ5/v/M873Oe75zzvqqoqAibzQaAiKCUAkApRdHIK/NFsx2NR91nOSILADDoJyzNaM4xxbtvPHh0iC+JiYkJ1OHDh4mJiUEpFSXPv/ziPC28TIiXDCOSrAClQDSEpsCwJPIhrEBRQpiSytXlQwDhcBilFPfu3UMVFxdjt9ujFTzfcLBADCoEEAFr1ZbrrNjch2vtEImPBgHob7fTcWE+bVXJNJ/NiFQlEGLvieXHKmYqGB8fRx05cgSbzYaIsPvywV8pKFaA7fGtLTzz61YWpo/xVTHQbufsq5lcez9zWuWhk5mvFwMEg0H0+vXrMU2Tn1wp3CtCiQ5DjGd3A/m/v8IDCZP8r4iNmyRrWx/j/5qktykZpXKzAjVDVxPzGqemptDr1q1jX3NRnIJarcDKK2hgR2ULXRfncv7UYv7xpovhnhiW5Mz+kefeSKO6LJ1A1xzEuk/Ojm4mRibpuZaMZW3OCtRUND60NmiICCIUShisx7a2sLMiQn4s77uEQgIabnqdfHIlgT1/qQeg8vs5dHhdCNB1wYn3RIiC995j26stjAbsNH+YiZJCESnS1Y/XxIXu8r4YIPv/VkVs3CTnTy2ms34xro1+sp9po6sxlTu34ultmsPVvy6is86FCHgO+DDs49zpjufBpCG+seYOC9OHaTidieicb9ouVAhKtouAseI710ma7pLuqwmgYfHqAFt+6WdLoQ/LBl11Lm7VudAa8vb72PCin9TlAWIsGGhLACD+kSAZnusYBii1XQAPYWDllt6ov2lrBkDBR2+6Ofuak2//3M+G/T4wAAPW7fPhKfRTVeqk9qQbFKRmDUTxS3N7QYGYmwzCkqklBGlPDEcTNv+sg9tNCbTXuvBWujE0bHrZj9JE1B/wU1Pm5PwJN6YBS9a2kVvQEcWnrh5GTFD3lxkYkqRMgYQlwVldUvDnen73LHTUuqitdKM0eAr9AFQfd1J/yo2aJn+2sn4Wdn5qEFODJskgBIjx5T0uCrQA08pnIjS9PERDjPnfOKXAMEBECUoGEIHBj+2zkt76UQ6dXheGAev3+cg74Kf6uJPqcicbfuond7cPy4SOiy7+tD9nFvZurx00KOk3CNEC+mE+vjSPBc7IWqgqTaPT60IMcO/xsXGa3HfKjRgRdbl7/KDg0jtubje6aHj7c7J3dgLQ2zoPwwQ91SooOQdAW1VKVMHty0kA5Bb48BycJn/LjWFGbLv4thvvb53kFvjJ+XEdWkPfjQVR/CcNKYgGMc8JWt5Fa2j+MIPPuyI2pa4IoHSkt6vLIuRaQ9q32khzt4GCxtNu6k46GeiIR2lIfDQQsafPzq1LGRGL9Gk9d+vrwewvfHPQOoexQVjxdB/auk/zmaUMdsfz6bVUtIalT7bxveP1ZHh6GPDPYeSzeD69kcpIfxymFWLNrka+ljhBTWkWwz2JiJT84YHnz2iPx0P20PkmRF5i6HYiwZFJsn/YzdezbzE3cQibY5xV266z6RfXohakb+xB9CjanCD9qTbW7Grk4WV38VZm0l6dhQiEw9taHSuDqrS0FIfDwXM3X9mHMsvRAk/sauDpQy38P+GtzOTGB9mEpkD0C2dS8n8zOjqK9ng8WJZFU+JTjasGvaCNXPpvJBPoMlm0OoDNMfWVxONfWNSUPUZ7TUQ56tCZlPwSgMnJSVRpaSmxsbFE1raw82ZxAZZRQUiBYUKGp5UlOX2krBzmoUVjiIKhHge9rfPo+Wcy3ZeXIYASgL1/X5RfMXMvj46OosrLy7HZbGitUUohIuzoem0RofALaOsghgWGjky0MiJTL8b0lOvI8hN1DKXKP0jd3TNTWDgcJhgMoo4ePYrD4Yi+KmaeLlprnrtXFo9h/AAlG1AqE8yFmBrC+jO0bgH9EVpO/1F2Dc5g//OAsbEx/j0Af+USsQynL1UAAAAASUVORK5CYII=');\n}\n/* top right bottom left */\ndiv.vis-network div.vis-manipulation div.vis-label,\ndiv.vis-network div.vis-edit-mode div.vis-label {\n margin: 0 0 0 23px;\n line-height: 25px;\n}\ndiv.vis-network div.vis-manipulation div.vis-separator-line {\n float: left;\n display: inline-block;\n width: 1px;\n height: 21px;\n background-color: #bdbdbd;\n margin: 0px 7px 0 15px; /*top right bottom left*/\n}\n\n/* TODO: is this redundant?\ndiv.network-navigation_wrapper {\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n}\n*/\n";
40049styleInject(css_248z);
40050
40051function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof symbol !== "undefined" && getIteratorMethod$2(o) || o["@@iterator"]; if (!it) { if (isArray$2(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
40052
40053function _unsupportedIterableToArray(o, minLen) { var _context32; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = slice$1(_context32 = Object.prototype.toString.call(o)).call(_context32, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return from$2(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
40054
40055function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
40056/**
40057 * Clears the toolbar div element of children
40058 *
40059 * @private
40060 */
40061
40062var ManipulationSystem = /*#__PURE__*/function () {
40063 /**
40064 * @param {object} body
40065 * @param {Canvas} canvas
40066 * @param {SelectionHandler} selectionHandler
40067 * @param {InteractionHandler} interactionHandler
40068 */
40069 function ManipulationSystem(body, canvas, selectionHandler, interactionHandler) {
40070 var _this = this,
40071 _context,
40072 _context2;
40073
40074 _classCallCheck(this, ManipulationSystem);
40075
40076 this.body = body;
40077 this.canvas = canvas;
40078 this.selectionHandler = selectionHandler;
40079 this.interactionHandler = interactionHandler;
40080 this.editMode = false;
40081 this.manipulationDiv = undefined;
40082 this.editModeDiv = undefined;
40083 this.closeDiv = undefined;
40084 this._domEventListenerCleanupQueue = [];
40085 this.temporaryUIFunctions = {};
40086 this.temporaryEventFunctions = [];
40087 this.touchTime = 0;
40088 this.temporaryIds = {
40089 nodes: [],
40090 edges: []
40091 };
40092 this.guiEnabled = false;
40093 this.inMode = false;
40094 this.selectedControlNode = undefined;
40095 this.options = {};
40096 this.defaultOptions = {
40097 enabled: false,
40098 initiallyActive: false,
40099 addNode: true,
40100 addEdge: true,
40101 editNode: undefined,
40102 editEdge: true,
40103 deleteNode: true,
40104 deleteEdge: true,
40105 controlNodeStyle: {
40106 shape: "dot",
40107 size: 6,
40108 color: {
40109 background: "#ff0000",
40110 border: "#3c3c3c",
40111 highlight: {
40112 background: "#07f968",
40113 border: "#3c3c3c"
40114 }
40115 },
40116 borderWidth: 2,
40117 borderWidthSelected: 2
40118 }
40119 };
40120
40121 assign$2(this.options, this.defaultOptions);
40122
40123 this.body.emitter.on("destroy", function () {
40124 _this._clean();
40125 });
40126 this.body.emitter.on("_dataChanged", bind$6(_context = this._restore).call(_context, this));
40127 this.body.emitter.on("_resetData", bind$6(_context2 = this._restore).call(_context2, this));
40128 }
40129 /**
40130 * If something changes in the data during editing, switch back to the initial datamanipulation state and close all edit modes.
40131 *
40132 * @private
40133 */
40134
40135
40136 _createClass(ManipulationSystem, [{
40137 key: "_restore",
40138 value: function _restore() {
40139 if (this.inMode !== false) {
40140 if (this.options.initiallyActive === true) {
40141 this.enableEditMode();
40142 } else {
40143 this.disableEditMode();
40144 }
40145 }
40146 }
40147 /**
40148 * Set the Options
40149 *
40150 * @param {object} options
40151 * @param {object} allOptions
40152 * @param {object} globalOptions
40153 */
40154
40155 }, {
40156 key: "setOptions",
40157 value: function setOptions(options, allOptions, globalOptions) {
40158 if (allOptions !== undefined) {
40159 if (allOptions.locale !== undefined) {
40160 this.options.locale = allOptions.locale;
40161 } else {
40162 this.options.locale = globalOptions.locale;
40163 }
40164
40165 if (allOptions.locales !== undefined) {
40166 this.options.locales = allOptions.locales;
40167 } else {
40168 this.options.locales = globalOptions.locales;
40169 }
40170 }
40171
40172 if (options !== undefined) {
40173 if (typeof options === "boolean") {
40174 this.options.enabled = options;
40175 } else {
40176 this.options.enabled = true;
40177 deepExtend(this.options, options);
40178 }
40179
40180 if (this.options.initiallyActive === true) {
40181 this.editMode = true;
40182 }
40183
40184 this._setup();
40185 }
40186 }
40187 /**
40188 * Enable or disable edit-mode. Draws the DOM required and cleans up after itself.
40189 *
40190 * @private
40191 */
40192
40193 }, {
40194 key: "toggleEditMode",
40195 value: function toggleEditMode() {
40196 if (this.editMode === true) {
40197 this.disableEditMode();
40198 } else {
40199 this.enableEditMode();
40200 }
40201 }
40202 /**
40203 * Enables Edit Mode
40204 */
40205
40206 }, {
40207 key: "enableEditMode",
40208 value: function enableEditMode() {
40209 this.editMode = true;
40210
40211 this._clean();
40212
40213 if (this.guiEnabled === true) {
40214 this.manipulationDiv.style.display = "block";
40215 this.closeDiv.style.display = "block";
40216 this.editModeDiv.style.display = "none";
40217 this.showManipulatorToolbar();
40218 }
40219 }
40220 /**
40221 * Disables Edit Mode
40222 */
40223
40224 }, {
40225 key: "disableEditMode",
40226 value: function disableEditMode() {
40227 this.editMode = false;
40228
40229 this._clean();
40230
40231 if (this.guiEnabled === true) {
40232 this.manipulationDiv.style.display = "none";
40233 this.closeDiv.style.display = "none";
40234 this.editModeDiv.style.display = "block";
40235
40236 this._createEditButton();
40237 }
40238 }
40239 /**
40240 * Creates the main toolbar. Removes functions bound to the select event. Binds all the buttons of the toolbar.
40241 *
40242 * @private
40243 */
40244
40245 }, {
40246 key: "showManipulatorToolbar",
40247 value: function showManipulatorToolbar() {
40248 // restore the state of any bound functions or events, remove control nodes, restore physics
40249 this._clean(); // reset global variables
40250
40251
40252 this.manipulationDOM = {}; // if the gui is enabled, draw all elements.
40253
40254 if (this.guiEnabled === true) {
40255 var _context3, _context4;
40256
40257 // a _restore will hide these menus
40258 this.editMode = true;
40259 this.manipulationDiv.style.display = "block";
40260 this.closeDiv.style.display = "block";
40261 var selectedNodeCount = this.selectionHandler.getSelectedNodeCount();
40262 var selectedEdgeCount = this.selectionHandler.getSelectedEdgeCount();
40263 var selectedTotalCount = selectedNodeCount + selectedEdgeCount;
40264 var locale = this.options.locales[this.options.locale];
40265 var needSeperator = false;
40266
40267 if (this.options.addNode !== false) {
40268 this._createAddNodeButton(locale);
40269
40270 needSeperator = true;
40271 }
40272
40273 if (this.options.addEdge !== false) {
40274 if (needSeperator === true) {
40275 this._createSeperator(1);
40276 } else {
40277 needSeperator = true;
40278 }
40279
40280 this._createAddEdgeButton(locale);
40281 }
40282
40283 if (selectedNodeCount === 1 && typeof this.options.editNode === "function") {
40284 if (needSeperator === true) {
40285 this._createSeperator(2);
40286 } else {
40287 needSeperator = true;
40288 }
40289
40290 this._createEditNodeButton(locale);
40291 } else if (selectedEdgeCount === 1 && selectedNodeCount === 0 && this.options.editEdge !== false) {
40292 if (needSeperator === true) {
40293 this._createSeperator(3);
40294 } else {
40295 needSeperator = true;
40296 }
40297
40298 this._createEditEdgeButton(locale);
40299 } // remove buttons
40300
40301
40302 if (selectedTotalCount !== 0) {
40303 if (selectedNodeCount > 0 && this.options.deleteNode !== false) {
40304 if (needSeperator === true) {
40305 this._createSeperator(4);
40306 }
40307
40308 this._createDeleteButton(locale);
40309 } else if (selectedNodeCount === 0 && this.options.deleteEdge !== false) {
40310 if (needSeperator === true) {
40311 this._createSeperator(4);
40312 }
40313
40314 this._createDeleteButton(locale);
40315 }
40316 } // bind the close button
40317
40318
40319 this._bindElementEvents(this.closeDiv, bind$6(_context3 = this.toggleEditMode).call(_context3, this)); // refresh this bar based on what has been selected
40320
40321
40322 this._temporaryBindEvent("select", bind$6(_context4 = this.showManipulatorToolbar).call(_context4, this));
40323 } // redraw to show any possible changes
40324
40325
40326 this.body.emitter.emit("_redraw");
40327 }
40328 /**
40329 * Create the toolbar for adding Nodes
40330 */
40331
40332 }, {
40333 key: "addNodeMode",
40334 value: function addNodeMode() {
40335 var _context6;
40336
40337 // when using the gui, enable edit mode if it wasnt already.
40338 if (this.editMode !== true) {
40339 this.enableEditMode();
40340 } // restore the state of any bound functions or events, remove control nodes, restore physics
40341
40342
40343 this._clean();
40344
40345 this.inMode = "addNode";
40346
40347 if (this.guiEnabled === true) {
40348 var _context5;
40349
40350 var locale = this.options.locales[this.options.locale];
40351 this.manipulationDOM = {};
40352
40353 this._createBackButton(locale);
40354
40355 this._createSeperator();
40356
40357 this._createDescription(locale["addDescription"] || this.options.locales["en"]["addDescription"]); // bind the close button
40358
40359
40360 this._bindElementEvents(this.closeDiv, bind$6(_context5 = this.toggleEditMode).call(_context5, this));
40361 }
40362
40363 this._temporaryBindEvent("click", bind$6(_context6 = this._performAddNode).call(_context6, this));
40364 }
40365 /**
40366 * call the bound function to handle the editing of the node. The node has to be selected.
40367 */
40368
40369 }, {
40370 key: "editNode",
40371 value: function editNode() {
40372 var _this2 = this;
40373
40374 // when using the gui, enable edit mode if it wasnt already.
40375 if (this.editMode !== true) {
40376 this.enableEditMode();
40377 } // restore the state of any bound functions or events, remove control nodes, restore physics
40378
40379
40380 this._clean();
40381
40382 var node = this.selectionHandler.getSelectedNodes()[0];
40383
40384 if (node !== undefined) {
40385 this.inMode = "editNode";
40386
40387 if (typeof this.options.editNode === "function") {
40388 if (node.isCluster !== true) {
40389 var data = deepExtend({}, node.options, false);
40390 data.x = node.x;
40391 data.y = node.y;
40392
40393 if (this.options.editNode.length === 2) {
40394 this.options.editNode(data, function (finalizedData) {
40395 if (finalizedData !== null && finalizedData !== undefined && _this2.inMode === "editNode") {
40396 // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
40397 _this2.body.data.nodes.getDataSet().update(finalizedData);
40398 }
40399
40400 _this2.showManipulatorToolbar();
40401 });
40402 } else {
40403 throw new Error("The function for edit does not support two arguments (data, callback)");
40404 }
40405 } else {
40406 alert(this.options.locales[this.options.locale]["editClusterError"] || this.options.locales["en"]["editClusterError"]);
40407 }
40408 } else {
40409 throw new Error("No function has been configured to handle the editing of nodes.");
40410 }
40411 } else {
40412 this.showManipulatorToolbar();
40413 }
40414 }
40415 /**
40416 * create the toolbar to connect nodes
40417 */
40418
40419 }, {
40420 key: "addEdgeMode",
40421 value: function addEdgeMode() {
40422 var _context8, _context9, _context10, _context11, _context12;
40423
40424 // when using the gui, enable edit mode if it wasnt already.
40425 if (this.editMode !== true) {
40426 this.enableEditMode();
40427 } // restore the state of any bound functions or events, remove control nodes, restore physics
40428
40429
40430 this._clean();
40431
40432 this.inMode = "addEdge";
40433
40434 if (this.guiEnabled === true) {
40435 var _context7;
40436
40437 var locale = this.options.locales[this.options.locale];
40438 this.manipulationDOM = {};
40439
40440 this._createBackButton(locale);
40441
40442 this._createSeperator();
40443
40444 this._createDescription(locale["edgeDescription"] || this.options.locales["en"]["edgeDescription"]); // bind the close button
40445
40446
40447 this._bindElementEvents(this.closeDiv, bind$6(_context7 = this.toggleEditMode).call(_context7, this));
40448 } // temporarily overload functions
40449
40450
40451 this._temporaryBindUI("onTouch", bind$6(_context8 = this._handleConnect).call(_context8, this));
40452
40453 this._temporaryBindUI("onDragEnd", bind$6(_context9 = this._finishConnect).call(_context9, this));
40454
40455 this._temporaryBindUI("onDrag", bind$6(_context10 = this._dragControlNode).call(_context10, this));
40456
40457 this._temporaryBindUI("onRelease", bind$6(_context11 = this._finishConnect).call(_context11, this));
40458
40459 this._temporaryBindUI("onDragStart", bind$6(_context12 = this._dragStartEdge).call(_context12, this));
40460
40461 this._temporaryBindUI("onHold", function () {});
40462 }
40463 /**
40464 * create the toolbar to edit edges
40465 */
40466
40467 }, {
40468 key: "editEdgeMode",
40469 value: function editEdgeMode() {
40470 // when using the gui, enable edit mode if it wasn't already.
40471 if (this.editMode !== true) {
40472 this.enableEditMode();
40473 } // restore the state of any bound functions or events, remove control nodes, restore physics
40474
40475
40476 this._clean();
40477
40478 this.inMode = "editEdge";
40479
40480 if (_typeof(this.options.editEdge) === "object" && typeof this.options.editEdge.editWithoutDrag === "function") {
40481 this.edgeBeingEditedId = this.selectionHandler.getSelectedEdgeIds()[0];
40482
40483 if (this.edgeBeingEditedId !== undefined) {
40484 var edge = this.body.edges[this.edgeBeingEditedId];
40485
40486 this._performEditEdge(edge.from.id, edge.to.id);
40487
40488 return;
40489 }
40490 }
40491
40492 if (this.guiEnabled === true) {
40493 var _context13;
40494
40495 var locale = this.options.locales[this.options.locale];
40496 this.manipulationDOM = {};
40497
40498 this._createBackButton(locale);
40499
40500 this._createSeperator();
40501
40502 this._createDescription(locale["editEdgeDescription"] || this.options.locales["en"]["editEdgeDescription"]); // bind the close button
40503
40504
40505 this._bindElementEvents(this.closeDiv, bind$6(_context13 = this.toggleEditMode).call(_context13, this));
40506 }
40507
40508 this.edgeBeingEditedId = this.selectionHandler.getSelectedEdgeIds()[0];
40509
40510 if (this.edgeBeingEditedId !== undefined) {
40511 var _context14, _context15, _context16, _context17;
40512
40513 var _edge = this.body.edges[this.edgeBeingEditedId]; // create control nodes
40514
40515 var controlNodeFrom = this._getNewTargetNode(_edge.from.x, _edge.from.y);
40516
40517 var controlNodeTo = this._getNewTargetNode(_edge.to.x, _edge.to.y);
40518
40519 this.temporaryIds.nodes.push(controlNodeFrom.id);
40520 this.temporaryIds.nodes.push(controlNodeTo.id);
40521 this.body.nodes[controlNodeFrom.id] = controlNodeFrom;
40522 this.body.nodeIndices.push(controlNodeFrom.id);
40523 this.body.nodes[controlNodeTo.id] = controlNodeTo;
40524 this.body.nodeIndices.push(controlNodeTo.id); // temporarily overload UI functions, cleaned up automatically because of _temporaryBindUI
40525
40526 this._temporaryBindUI("onTouch", bind$6(_context14 = this._controlNodeTouch).call(_context14, this)); // used to get the position
40527
40528
40529 this._temporaryBindUI("onTap", function () {}); // disabled
40530
40531
40532 this._temporaryBindUI("onHold", function () {}); // disabled
40533
40534
40535 this._temporaryBindUI("onDragStart", bind$6(_context15 = this._controlNodeDragStart).call(_context15, this)); // used to select control node
40536
40537
40538 this._temporaryBindUI("onDrag", bind$6(_context16 = this._controlNodeDrag).call(_context16, this)); // used to drag control node
40539
40540
40541 this._temporaryBindUI("onDragEnd", bind$6(_context17 = this._controlNodeDragEnd).call(_context17, this)); // used to connect or revert control nodes
40542
40543
40544 this._temporaryBindUI("onMouseMove", function () {}); // disabled
40545 // create function to position control nodes correctly on movement
40546 // automatically cleaned up because we use the temporary bind
40547
40548
40549 this._temporaryBindEvent("beforeDrawing", function (ctx) {
40550 var positions = _edge.edgeType.findBorderPositions(ctx);
40551
40552 if (controlNodeFrom.selected === false) {
40553 controlNodeFrom.x = positions.from.x;
40554 controlNodeFrom.y = positions.from.y;
40555 }
40556
40557 if (controlNodeTo.selected === false) {
40558 controlNodeTo.x = positions.to.x;
40559 controlNodeTo.y = positions.to.y;
40560 }
40561 });
40562
40563 this.body.emitter.emit("_redraw");
40564 } else {
40565 this.showManipulatorToolbar();
40566 }
40567 }
40568 /**
40569 * delete everything in the selection
40570 */
40571
40572 }, {
40573 key: "deleteSelected",
40574 value: function deleteSelected() {
40575 var _this3 = this;
40576
40577 // when using the gui, enable edit mode if it wasnt already.
40578 if (this.editMode !== true) {
40579 this.enableEditMode();
40580 } // restore the state of any bound functions or events, remove control nodes, restore physics
40581
40582
40583 this._clean();
40584
40585 this.inMode = "delete";
40586 var selectedNodes = this.selectionHandler.getSelectedNodeIds();
40587 var selectedEdges = this.selectionHandler.getSelectedEdgeIds();
40588 var deleteFunction = undefined;
40589
40590 if (selectedNodes.length > 0) {
40591 for (var i = 0; i < selectedNodes.length; i++) {
40592 if (this.body.nodes[selectedNodes[i]].isCluster === true) {
40593 alert(this.options.locales[this.options.locale]["deleteClusterError"] || this.options.locales["en"]["deleteClusterError"]);
40594 return;
40595 }
40596 }
40597
40598 if (typeof this.options.deleteNode === "function") {
40599 deleteFunction = this.options.deleteNode;
40600 }
40601 } else if (selectedEdges.length > 0) {
40602 if (typeof this.options.deleteEdge === "function") {
40603 deleteFunction = this.options.deleteEdge;
40604 }
40605 }
40606
40607 if (typeof deleteFunction === "function") {
40608 var data = {
40609 nodes: selectedNodes,
40610 edges: selectedEdges
40611 };
40612
40613 if (deleteFunction.length === 2) {
40614 deleteFunction(data, function (finalizedData) {
40615 if (finalizedData !== null && finalizedData !== undefined && _this3.inMode === "delete") {
40616 // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
40617 _this3.body.data.edges.getDataSet().remove(finalizedData.edges);
40618
40619 _this3.body.data.nodes.getDataSet().remove(finalizedData.nodes);
40620
40621 _this3.body.emitter.emit("startSimulation");
40622
40623 _this3.showManipulatorToolbar();
40624 } else {
40625 _this3.body.emitter.emit("startSimulation");
40626
40627 _this3.showManipulatorToolbar();
40628 }
40629 });
40630 } else {
40631 throw new Error("The function for delete does not support two arguments (data, callback)");
40632 }
40633 } else {
40634 this.body.data.edges.getDataSet().remove(selectedEdges);
40635 this.body.data.nodes.getDataSet().remove(selectedNodes);
40636 this.body.emitter.emit("startSimulation");
40637 this.showManipulatorToolbar();
40638 }
40639 } //********************************************** PRIVATE ***************************************//
40640
40641 /**
40642 * draw or remove the DOM
40643 *
40644 * @private
40645 */
40646
40647 }, {
40648 key: "_setup",
40649 value: function _setup() {
40650 if (this.options.enabled === true) {
40651 // Enable the GUI
40652 this.guiEnabled = true;
40653
40654 this._createWrappers();
40655
40656 if (this.editMode === false) {
40657 this._createEditButton();
40658 } else {
40659 this.showManipulatorToolbar();
40660 }
40661 } else {
40662 this._removeManipulationDOM(); // disable the gui
40663
40664
40665 this.guiEnabled = false;
40666 }
40667 }
40668 /**
40669 * create the div overlays that contain the DOM
40670 *
40671 * @private
40672 */
40673
40674 }, {
40675 key: "_createWrappers",
40676 value: function _createWrappers() {
40677 // load the manipulator HTML elements. All styling done in css.
40678 if (this.manipulationDiv === undefined) {
40679 this.manipulationDiv = document.createElement("div");
40680 this.manipulationDiv.className = "vis-manipulation";
40681
40682 if (this.editMode === true) {
40683 this.manipulationDiv.style.display = "block";
40684 } else {
40685 this.manipulationDiv.style.display = "none";
40686 }
40687
40688 this.canvas.frame.appendChild(this.manipulationDiv);
40689 } // container for the edit button.
40690
40691
40692 if (this.editModeDiv === undefined) {
40693 this.editModeDiv = document.createElement("div");
40694 this.editModeDiv.className = "vis-edit-mode";
40695
40696 if (this.editMode === true) {
40697 this.editModeDiv.style.display = "none";
40698 } else {
40699 this.editModeDiv.style.display = "block";
40700 }
40701
40702 this.canvas.frame.appendChild(this.editModeDiv);
40703 } // container for the close div button
40704
40705
40706 if (this.closeDiv === undefined) {
40707 var _this$options$locales, _this$options$locales2;
40708
40709 this.closeDiv = document.createElement("button");
40710 this.closeDiv.className = "vis-close";
40711 this.closeDiv.setAttribute("aria-label", (_this$options$locales = (_this$options$locales2 = this.options.locales[this.options.locale]) === null || _this$options$locales2 === void 0 ? void 0 : _this$options$locales2["close"]) !== null && _this$options$locales !== void 0 ? _this$options$locales : this.options.locales["en"]["close"]);
40712 this.closeDiv.style.display = this.manipulationDiv.style.display;
40713 this.canvas.frame.appendChild(this.closeDiv);
40714 }
40715 }
40716 /**
40717 * generate a new target node. Used for creating new edges and editing edges
40718 *
40719 * @param {number} x
40720 * @param {number} y
40721 * @returns {Node}
40722 * @private
40723 */
40724
40725 }, {
40726 key: "_getNewTargetNode",
40727 value: function _getNewTargetNode(x, y) {
40728 var controlNodeStyle = deepExtend({}, this.options.controlNodeStyle);
40729 controlNodeStyle.id = "targetNode" + v4();
40730 controlNodeStyle.hidden = false;
40731 controlNodeStyle.physics = false;
40732 controlNodeStyle.x = x;
40733 controlNodeStyle.y = y; // we have to define the bounding box in order for the nodes to be drawn immediately
40734
40735 var node = this.body.functions.createNode(controlNodeStyle);
40736 node.shape.boundingBox = {
40737 left: x,
40738 right: x,
40739 top: y,
40740 bottom: y
40741 };
40742 return node;
40743 }
40744 /**
40745 * Create the edit button
40746 */
40747
40748 }, {
40749 key: "_createEditButton",
40750 value: function _createEditButton() {
40751 var _context18;
40752
40753 // restore everything to it's original state (if applicable)
40754 this._clean(); // reset the manipulationDOM
40755
40756
40757 this.manipulationDOM = {}; // empty the editModeDiv
40758
40759 recursiveDOMDelete(this.editModeDiv); // create the contents for the editMode button
40760
40761 var locale = this.options.locales[this.options.locale];
40762
40763 var button = this._createButton("editMode", "vis-edit vis-edit-mode", locale["edit"] || this.options.locales["en"]["edit"]);
40764
40765 this.editModeDiv.appendChild(button); // bind a hammer listener to the button, calling the function toggleEditMode.
40766
40767 this._bindElementEvents(button, bind$6(_context18 = this.toggleEditMode).call(_context18, this));
40768 }
40769 /**
40770 * this function cleans up after everything this module does. Temporary elements, functions and events are removed, physics restored, hammers removed.
40771 *
40772 * @private
40773 */
40774
40775 }, {
40776 key: "_clean",
40777 value: function _clean() {
40778 // not in mode
40779 this.inMode = false; // _clean the divs
40780
40781 if (this.guiEnabled === true) {
40782 recursiveDOMDelete(this.editModeDiv);
40783 recursiveDOMDelete(this.manipulationDiv); // removes all the bindings and overloads
40784
40785 this._cleanupDOMEventListeners();
40786 } // remove temporary nodes and edges
40787
40788
40789 this._cleanupTemporaryNodesAndEdges(); // restore overloaded UI functions
40790
40791
40792 this._unbindTemporaryUIs(); // remove the temporaryEventFunctions
40793
40794
40795 this._unbindTemporaryEvents(); // restore the physics if required
40796
40797
40798 this.body.emitter.emit("restorePhysics");
40799 }
40800 /**
40801 * Each dom element has it's own hammer. They are stored in this.manipulationHammers. This cleans them up.
40802 *
40803 * @private
40804 */
40805
40806 }, {
40807 key: "_cleanupDOMEventListeners",
40808 value: function _cleanupDOMEventListeners() {
40809 var _context19;
40810
40811 // _clean DOM event listener bindings
40812 var _iterator = _createForOfIteratorHelper(splice(_context19 = this._domEventListenerCleanupQueue).call(_context19, 0)),
40813 _step;
40814
40815 try {
40816 for (_iterator.s(); !(_step = _iterator.n()).done;) {
40817 var callback = _step.value;
40818 callback();
40819 }
40820 } catch (err) {
40821 _iterator.e(err);
40822 } finally {
40823 _iterator.f();
40824 }
40825 }
40826 /**
40827 * Remove all DOM elements created by this module.
40828 *
40829 * @private
40830 */
40831
40832 }, {
40833 key: "_removeManipulationDOM",
40834 value: function _removeManipulationDOM() {
40835 // removes all the bindings and overloads
40836 this._clean(); // empty the manipulation divs
40837
40838
40839 recursiveDOMDelete(this.manipulationDiv);
40840 recursiveDOMDelete(this.editModeDiv);
40841 recursiveDOMDelete(this.closeDiv); // remove the manipulation divs
40842
40843 if (this.manipulationDiv) {
40844 this.canvas.frame.removeChild(this.manipulationDiv);
40845 }
40846
40847 if (this.editModeDiv) {
40848 this.canvas.frame.removeChild(this.editModeDiv);
40849 }
40850
40851 if (this.closeDiv) {
40852 this.canvas.frame.removeChild(this.closeDiv);
40853 } // set the references to undefined
40854
40855
40856 this.manipulationDiv = undefined;
40857 this.editModeDiv = undefined;
40858 this.closeDiv = undefined;
40859 }
40860 /**
40861 * create a seperator line. the index is to differentiate in the manipulation dom
40862 *
40863 * @param {number} [index=1]
40864 * @private
40865 */
40866
40867 }, {
40868 key: "_createSeperator",
40869 value: function _createSeperator() {
40870 var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
40871 this.manipulationDOM["seperatorLineDiv" + index] = document.createElement("div");
40872 this.manipulationDOM["seperatorLineDiv" + index].className = "vis-separator-line";
40873 this.manipulationDiv.appendChild(this.manipulationDOM["seperatorLineDiv" + index]);
40874 } // ---------------------- DOM functions for buttons --------------------------//
40875
40876 /**
40877 *
40878 * @param {Locale} locale
40879 * @private
40880 */
40881
40882 }, {
40883 key: "_createAddNodeButton",
40884 value: function _createAddNodeButton(locale) {
40885 var _context20;
40886
40887 var button = this._createButton("addNode", "vis-add", locale["addNode"] || this.options.locales["en"]["addNode"]);
40888
40889 this.manipulationDiv.appendChild(button);
40890
40891 this._bindElementEvents(button, bind$6(_context20 = this.addNodeMode).call(_context20, this));
40892 }
40893 /**
40894 *
40895 * @param {Locale} locale
40896 * @private
40897 */
40898
40899 }, {
40900 key: "_createAddEdgeButton",
40901 value: function _createAddEdgeButton(locale) {
40902 var _context21;
40903
40904 var button = this._createButton("addEdge", "vis-connect", locale["addEdge"] || this.options.locales["en"]["addEdge"]);
40905
40906 this.manipulationDiv.appendChild(button);
40907
40908 this._bindElementEvents(button, bind$6(_context21 = this.addEdgeMode).call(_context21, this));
40909 }
40910 /**
40911 *
40912 * @param {Locale} locale
40913 * @private
40914 */
40915
40916 }, {
40917 key: "_createEditNodeButton",
40918 value: function _createEditNodeButton(locale) {
40919 var _context22;
40920
40921 var button = this._createButton("editNode", "vis-edit", locale["editNode"] || this.options.locales["en"]["editNode"]);
40922
40923 this.manipulationDiv.appendChild(button);
40924
40925 this._bindElementEvents(button, bind$6(_context22 = this.editNode).call(_context22, this));
40926 }
40927 /**
40928 *
40929 * @param {Locale} locale
40930 * @private
40931 */
40932
40933 }, {
40934 key: "_createEditEdgeButton",
40935 value: function _createEditEdgeButton(locale) {
40936 var _context23;
40937
40938 var button = this._createButton("editEdge", "vis-edit", locale["editEdge"] || this.options.locales["en"]["editEdge"]);
40939
40940 this.manipulationDiv.appendChild(button);
40941
40942 this._bindElementEvents(button, bind$6(_context23 = this.editEdgeMode).call(_context23, this));
40943 }
40944 /**
40945 *
40946 * @param {Locale} locale
40947 * @private
40948 */
40949
40950 }, {
40951 key: "_createDeleteButton",
40952 value: function _createDeleteButton(locale) {
40953 var _context24;
40954
40955 var deleteBtnClass;
40956
40957 if (this.options.rtl) {
40958 deleteBtnClass = "vis-delete-rtl";
40959 } else {
40960 deleteBtnClass = "vis-delete";
40961 }
40962
40963 var button = this._createButton("delete", deleteBtnClass, locale["del"] || this.options.locales["en"]["del"]);
40964
40965 this.manipulationDiv.appendChild(button);
40966
40967 this._bindElementEvents(button, bind$6(_context24 = this.deleteSelected).call(_context24, this));
40968 }
40969 /**
40970 *
40971 * @param {Locale} locale
40972 * @private
40973 */
40974
40975 }, {
40976 key: "_createBackButton",
40977 value: function _createBackButton(locale) {
40978 var _context25;
40979
40980 var button = this._createButton("back", "vis-back", locale["back"] || this.options.locales["en"]["back"]);
40981
40982 this.manipulationDiv.appendChild(button);
40983
40984 this._bindElementEvents(button, bind$6(_context25 = this.showManipulatorToolbar).call(_context25, this));
40985 }
40986 /**
40987 *
40988 * @param {number|string} id
40989 * @param {string} className
40990 * @param {label} label
40991 * @param {string} labelClassName
40992 * @returns {HTMLElement}
40993 * @private
40994 */
40995
40996 }, {
40997 key: "_createButton",
40998 value: function _createButton(id, className, label) {
40999 var labelClassName = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "vis-label";
41000 this.manipulationDOM[id + "Div"] = document.createElement("button");
41001 this.manipulationDOM[id + "Div"].className = "vis-button " + className;
41002 this.manipulationDOM[id + "Label"] = document.createElement("div");
41003 this.manipulationDOM[id + "Label"].className = labelClassName;
41004 this.manipulationDOM[id + "Label"].innerText = label;
41005 this.manipulationDOM[id + "Div"].appendChild(this.manipulationDOM[id + "Label"]);
41006 return this.manipulationDOM[id + "Div"];
41007 }
41008 /**
41009 *
41010 * @param {Label} label
41011 * @private
41012 */
41013
41014 }, {
41015 key: "_createDescription",
41016 value: function _createDescription(label) {
41017 this.manipulationDOM["descriptionLabel"] = document.createElement("div");
41018 this.manipulationDOM["descriptionLabel"].className = "vis-none";
41019 this.manipulationDOM["descriptionLabel"].innerText = label;
41020 this.manipulationDiv.appendChild(this.manipulationDOM["descriptionLabel"]);
41021 } // -------------------------- End of DOM functions for buttons ------------------------------//
41022
41023 /**
41024 * this binds an event until cleanup by the clean functions.
41025 *
41026 * @param {Event} event The event
41027 * @param {Function} newFunction
41028 * @private
41029 */
41030
41031 }, {
41032 key: "_temporaryBindEvent",
41033 value: function _temporaryBindEvent(event, newFunction) {
41034 this.temporaryEventFunctions.push({
41035 event: event,
41036 boundFunction: newFunction
41037 });
41038 this.body.emitter.on(event, newFunction);
41039 }
41040 /**
41041 * this overrides an UI function until cleanup by the clean function
41042 *
41043 * @param {string} UIfunctionName
41044 * @param {Function} newFunction
41045 * @private
41046 */
41047
41048 }, {
41049 key: "_temporaryBindUI",
41050 value: function _temporaryBindUI(UIfunctionName, newFunction) {
41051 if (this.body.eventListeners[UIfunctionName] !== undefined) {
41052 this.temporaryUIFunctions[UIfunctionName] = this.body.eventListeners[UIfunctionName];
41053 this.body.eventListeners[UIfunctionName] = newFunction;
41054 } else {
41055 throw new Error("This UI function does not exist. Typo? You tried: " + UIfunctionName + " possible are: " + stringify$1(keys$4(this.body.eventListeners)));
41056 }
41057 }
41058 /**
41059 * Restore the overridden UI functions to their original state.
41060 *
41061 * @private
41062 */
41063
41064 }, {
41065 key: "_unbindTemporaryUIs",
41066 value: function _unbindTemporaryUIs() {
41067 for (var functionName in this.temporaryUIFunctions) {
41068 if (Object.prototype.hasOwnProperty.call(this.temporaryUIFunctions, functionName)) {
41069 this.body.eventListeners[functionName] = this.temporaryUIFunctions[functionName];
41070 delete this.temporaryUIFunctions[functionName];
41071 }
41072 }
41073
41074 this.temporaryUIFunctions = {};
41075 }
41076 /**
41077 * Unbind the events created by _temporaryBindEvent
41078 *
41079 * @private
41080 */
41081
41082 }, {
41083 key: "_unbindTemporaryEvents",
41084 value: function _unbindTemporaryEvents() {
41085 for (var i = 0; i < this.temporaryEventFunctions.length; i++) {
41086 var eventName = this.temporaryEventFunctions[i].event;
41087 var boundFunction = this.temporaryEventFunctions[i].boundFunction;
41088 this.body.emitter.off(eventName, boundFunction);
41089 }
41090
41091 this.temporaryEventFunctions = [];
41092 }
41093 /**
41094 * Bind an hammer instance to a DOM element.
41095 *
41096 * @param {Element} domElement
41097 * @param {Function} boundFunction
41098 */
41099
41100 }, {
41101 key: "_bindElementEvents",
41102 value: function _bindElementEvents(domElement, boundFunction) {
41103 // Bind touch events.
41104 var hammer = new Hammer$1(domElement, {});
41105 onTouch(hammer, boundFunction);
41106
41107 this._domEventListenerCleanupQueue.push(function () {
41108 hammer.destroy();
41109 }); // Bind keyboard events.
41110
41111
41112 var keyupListener = function keyupListener(_ref) {
41113 var keyCode = _ref.keyCode,
41114 key = _ref.key;
41115
41116 if (key === "Enter" || key === " " || keyCode === 13 || keyCode === 32) {
41117 boundFunction();
41118 }
41119 };
41120
41121 domElement.addEventListener("keyup", keyupListener, false);
41122
41123 this._domEventListenerCleanupQueue.push(function () {
41124 domElement.removeEventListener("keyup", keyupListener, false);
41125 });
41126 }
41127 /**
41128 * Neatly clean up temporary edges and nodes
41129 *
41130 * @private
41131 */
41132
41133 }, {
41134 key: "_cleanupTemporaryNodesAndEdges",
41135 value: function _cleanupTemporaryNodesAndEdges() {
41136 // _clean temporary edges
41137 for (var i = 0; i < this.temporaryIds.edges.length; i++) {
41138 var _context26;
41139
41140 this.body.edges[this.temporaryIds.edges[i]].disconnect();
41141 delete this.body.edges[this.temporaryIds.edges[i]];
41142
41143 var indexTempEdge = indexOf(_context26 = this.body.edgeIndices).call(_context26, this.temporaryIds.edges[i]);
41144
41145 if (indexTempEdge !== -1) {
41146 var _context27;
41147
41148 splice(_context27 = this.body.edgeIndices).call(_context27, indexTempEdge, 1);
41149 }
41150 } // _clean temporary nodes
41151
41152
41153 for (var _i = 0; _i < this.temporaryIds.nodes.length; _i++) {
41154 var _context28;
41155
41156 delete this.body.nodes[this.temporaryIds.nodes[_i]];
41157
41158 var indexTempNode = indexOf(_context28 = this.body.nodeIndices).call(_context28, this.temporaryIds.nodes[_i]);
41159
41160 if (indexTempNode !== -1) {
41161 var _context29;
41162
41163 splice(_context29 = this.body.nodeIndices).call(_context29, indexTempNode, 1);
41164 }
41165 }
41166
41167 this.temporaryIds = {
41168 nodes: [],
41169 edges: []
41170 };
41171 } // ------------------------------------------ EDIT EDGE FUNCTIONS -----------------------------------------//
41172
41173 /**
41174 * the touch is used to get the position of the initial click
41175 *
41176 * @param {Event} event The event
41177 * @private
41178 */
41179
41180 }, {
41181 key: "_controlNodeTouch",
41182 value: function _controlNodeTouch(event) {
41183 this.selectionHandler.unselectAll();
41184 this.lastTouch = this.body.functions.getPointer(event.center);
41185 this.lastTouch.translation = assign$2({}, this.body.view.translation); // copy the object
41186 }
41187 /**
41188 * the drag start is used to mark one of the control nodes as selected.
41189 *
41190 * @private
41191 */
41192
41193 }, {
41194 key: "_controlNodeDragStart",
41195 value: function _controlNodeDragStart() {
41196 var pointer = this.lastTouch;
41197
41198 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer);
41199
41200 var from = this.body.nodes[this.temporaryIds.nodes[0]];
41201 var to = this.body.nodes[this.temporaryIds.nodes[1]];
41202 var edge = this.body.edges[this.edgeBeingEditedId];
41203 this.selectedControlNode = undefined;
41204 var fromSelect = from.isOverlappingWith(pointerObj);
41205 var toSelect = to.isOverlappingWith(pointerObj);
41206
41207 if (fromSelect === true) {
41208 this.selectedControlNode = from;
41209 edge.edgeType.from = from;
41210 } else if (toSelect === true) {
41211 this.selectedControlNode = to;
41212 edge.edgeType.to = to;
41213 } // we use the selection to find the node that is being dragged. We explicitly select it here.
41214
41215
41216 if (this.selectedControlNode !== undefined) {
41217 this.selectionHandler.selectObject(this.selectedControlNode);
41218 }
41219
41220 this.body.emitter.emit("_redraw");
41221 }
41222 /**
41223 * dragging the control nodes or the canvas
41224 *
41225 * @param {Event} event The event
41226 * @private
41227 */
41228
41229 }, {
41230 key: "_controlNodeDrag",
41231 value: function _controlNodeDrag(event) {
41232 this.body.emitter.emit("disablePhysics");
41233 var pointer = this.body.functions.getPointer(event.center);
41234 var pos = this.canvas.DOMtoCanvas(pointer);
41235
41236 if (this.selectedControlNode !== undefined) {
41237 this.selectedControlNode.x = pos.x;
41238 this.selectedControlNode.y = pos.y;
41239 } else {
41240 this.interactionHandler.onDrag(event);
41241 }
41242
41243 this.body.emitter.emit("_redraw");
41244 }
41245 /**
41246 * connecting or restoring the control nodes.
41247 *
41248 * @param {Event} event The event
41249 * @private
41250 */
41251
41252 }, {
41253 key: "_controlNodeDragEnd",
41254 value: function _controlNodeDragEnd(event) {
41255 var pointer = this.body.functions.getPointer(event.center);
41256
41257 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer);
41258
41259 var edge = this.body.edges[this.edgeBeingEditedId]; // if the node that was dragged is not a control node, return
41260
41261 if (this.selectedControlNode === undefined) {
41262 return;
41263 } // we use the selection to find the node that is being dragged. We explicitly DEselect the control node here.
41264
41265
41266 this.selectionHandler.unselectAll();
41267
41268 var overlappingNodeIds = this.selectionHandler._getAllNodesOverlappingWith(pointerObj);
41269
41270 var node = undefined;
41271
41272 for (var i = overlappingNodeIds.length - 1; i >= 0; i--) {
41273 if (overlappingNodeIds[i] !== this.selectedControlNode.id) {
41274 node = this.body.nodes[overlappingNodeIds[i]];
41275 break;
41276 }
41277 } // perform the connection
41278
41279
41280 if (node !== undefined && this.selectedControlNode !== undefined) {
41281 if (node.isCluster === true) {
41282 alert(this.options.locales[this.options.locale]["createEdgeError"] || this.options.locales["en"]["createEdgeError"]);
41283 } else {
41284 var from = this.body.nodes[this.temporaryIds.nodes[0]];
41285
41286 if (this.selectedControlNode.id === from.id) {
41287 this._performEditEdge(node.id, edge.to.id);
41288 } else {
41289 this._performEditEdge(edge.from.id, node.id);
41290 }
41291 }
41292 } else {
41293 edge.updateEdgeType();
41294 this.body.emitter.emit("restorePhysics");
41295 }
41296
41297 this.body.emitter.emit("_redraw");
41298 } // ------------------------------------ END OF EDIT EDGE FUNCTIONS -----------------------------------------//
41299 // ------------------------------------------- ADD EDGE FUNCTIONS -----------------------------------------//
41300
41301 /**
41302 * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
41303 * to walk the user through the process.
41304 *
41305 * @param {Event} event
41306 * @private
41307 */
41308
41309 }, {
41310 key: "_handleConnect",
41311 value: function _handleConnect(event) {
41312 // check to avoid double fireing of this function.
41313 if (new Date().valueOf() - this.touchTime > 100) {
41314 this.lastTouch = this.body.functions.getPointer(event.center);
41315 this.lastTouch.translation = assign$2({}, this.body.view.translation); // copy the object
41316
41317 this.interactionHandler.drag.pointer = this.lastTouch; // Drag pointer is not updated when adding edges
41318
41319 this.interactionHandler.drag.translation = this.lastTouch.translation;
41320 var pointer = this.lastTouch;
41321 var node = this.selectionHandler.getNodeAt(pointer);
41322
41323 if (node !== undefined) {
41324 if (node.isCluster === true) {
41325 alert(this.options.locales[this.options.locale]["createEdgeError"] || this.options.locales["en"]["createEdgeError"]);
41326 } else {
41327 // create a node the temporary line can look at
41328 var targetNode = this._getNewTargetNode(node.x, node.y);
41329
41330 this.body.nodes[targetNode.id] = targetNode;
41331 this.body.nodeIndices.push(targetNode.id); // create a temporary edge
41332
41333 var connectionEdge = this.body.functions.createEdge({
41334 id: "connectionEdge" + v4(),
41335 from: node.id,
41336 to: targetNode.id,
41337 physics: false,
41338 smooth: {
41339 enabled: true,
41340 type: "continuous",
41341 roundness: 0.5
41342 }
41343 });
41344 this.body.edges[connectionEdge.id] = connectionEdge;
41345 this.body.edgeIndices.push(connectionEdge.id);
41346 this.temporaryIds.nodes.push(targetNode.id);
41347 this.temporaryIds.edges.push(connectionEdge.id);
41348 }
41349 }
41350
41351 this.touchTime = new Date().valueOf();
41352 }
41353 }
41354 /**
41355 *
41356 * @param {Event} event
41357 * @private
41358 */
41359
41360 }, {
41361 key: "_dragControlNode",
41362 value: function _dragControlNode(event) {
41363 var pointer = this.body.functions.getPointer(event.center);
41364
41365 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer); // remember the edge id
41366
41367
41368 var connectFromId = undefined;
41369
41370 if (this.temporaryIds.edges[0] !== undefined) {
41371 connectFromId = this.body.edges[this.temporaryIds.edges[0]].fromId;
41372 } // get the overlapping node but NOT the temporary node;
41373
41374
41375 var overlappingNodeIds = this.selectionHandler._getAllNodesOverlappingWith(pointerObj);
41376
41377 var node = undefined;
41378
41379 for (var i = overlappingNodeIds.length - 1; i >= 0; i--) {
41380 var _context30;
41381
41382 // if the node id is NOT a temporary node, accept the node.
41383 if (indexOf(_context30 = this.temporaryIds.nodes).call(_context30, overlappingNodeIds[i]) === -1) {
41384 node = this.body.nodes[overlappingNodeIds[i]];
41385 break;
41386 }
41387 }
41388
41389 event.controlEdge = {
41390 from: connectFromId,
41391 to: node ? node.id : undefined
41392 };
41393 this.selectionHandler.generateClickEvent("controlNodeDragging", event, pointer);
41394
41395 if (this.temporaryIds.nodes[0] !== undefined) {
41396 var targetNode = this.body.nodes[this.temporaryIds.nodes[0]]; // there is only one temp node in the add edge mode.
41397
41398 targetNode.x = this.canvas._XconvertDOMtoCanvas(pointer.x);
41399 targetNode.y = this.canvas._YconvertDOMtoCanvas(pointer.y);
41400 this.body.emitter.emit("_redraw");
41401 } else {
41402 this.interactionHandler.onDrag(event);
41403 }
41404 }
41405 /**
41406 * Connect the new edge to the target if one exists, otherwise remove temp line
41407 *
41408 * @param {Event} event The event
41409 * @private
41410 */
41411
41412 }, {
41413 key: "_finishConnect",
41414 value: function _finishConnect(event) {
41415 var pointer = this.body.functions.getPointer(event.center);
41416
41417 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer); // remember the edge id
41418
41419
41420 var connectFromId = undefined;
41421
41422 if (this.temporaryIds.edges[0] !== undefined) {
41423 connectFromId = this.body.edges[this.temporaryIds.edges[0]].fromId;
41424 } // get the overlapping node but NOT the temporary node;
41425
41426
41427 var overlappingNodeIds = this.selectionHandler._getAllNodesOverlappingWith(pointerObj);
41428
41429 var node = undefined;
41430
41431 for (var i = overlappingNodeIds.length - 1; i >= 0; i--) {
41432 var _context31;
41433
41434 // if the node id is NOT a temporary node, accept the node.
41435 if (indexOf(_context31 = this.temporaryIds.nodes).call(_context31, overlappingNodeIds[i]) === -1) {
41436 node = this.body.nodes[overlappingNodeIds[i]];
41437 break;
41438 }
41439 } // clean temporary nodes and edges.
41440
41441
41442 this._cleanupTemporaryNodesAndEdges(); // perform the connection
41443
41444
41445 if (node !== undefined) {
41446 if (node.isCluster === true) {
41447 alert(this.options.locales[this.options.locale]["createEdgeError"] || this.options.locales["en"]["createEdgeError"]);
41448 } else {
41449 if (this.body.nodes[connectFromId] !== undefined && this.body.nodes[node.id] !== undefined) {
41450 this._performAddEdge(connectFromId, node.id);
41451 }
41452 }
41453 }
41454
41455 event.controlEdge = {
41456 from: connectFromId,
41457 to: node ? node.id : undefined
41458 };
41459 this.selectionHandler.generateClickEvent("controlNodeDragEnd", event, pointer); // No need to do _generateclickevent('dragEnd') here, the regular dragEnd event fires.
41460
41461 this.body.emitter.emit("_redraw");
41462 }
41463 /**
41464 *
41465 * @param {Event} event
41466 * @private
41467 */
41468
41469 }, {
41470 key: "_dragStartEdge",
41471 value: function _dragStartEdge(event) {
41472 var pointer = this.lastTouch;
41473 this.selectionHandler.generateClickEvent("dragStart", event, pointer, undefined, true);
41474 } // --------------------------------------- END OF ADD EDGE FUNCTIONS -------------------------------------//
41475 // ------------------------------ Performing all the actual data manipulation ------------------------//
41476
41477 /**
41478 * Adds a node on the specified location
41479 *
41480 * @param {object} clickData
41481 * @private
41482 */
41483
41484 }, {
41485 key: "_performAddNode",
41486 value: function _performAddNode(clickData) {
41487 var _this4 = this;
41488
41489 var defaultData = {
41490 id: v4(),
41491 x: clickData.pointer.canvas.x,
41492 y: clickData.pointer.canvas.y,
41493 label: "new"
41494 };
41495
41496 if (typeof this.options.addNode === "function") {
41497 if (this.options.addNode.length === 2) {
41498 this.options.addNode(defaultData, function (finalizedData) {
41499 if (finalizedData !== null && finalizedData !== undefined && _this4.inMode === "addNode") {
41500 // if for whatever reason the mode has changes (due to dataset change) disregard the callback
41501 _this4.body.data.nodes.getDataSet().add(finalizedData);
41502 }
41503
41504 _this4.showManipulatorToolbar();
41505 });
41506 } else {
41507 this.showManipulatorToolbar();
41508 throw new Error("The function for add does not support two arguments (data,callback)");
41509 }
41510 } else {
41511 this.body.data.nodes.getDataSet().add(defaultData);
41512 this.showManipulatorToolbar();
41513 }
41514 }
41515 /**
41516 * connect two nodes with a new edge.
41517 *
41518 * @param {Node.id} sourceNodeId
41519 * @param {Node.id} targetNodeId
41520 * @private
41521 */
41522
41523 }, {
41524 key: "_performAddEdge",
41525 value: function _performAddEdge(sourceNodeId, targetNodeId) {
41526 var _this5 = this;
41527
41528 var defaultData = {
41529 from: sourceNodeId,
41530 to: targetNodeId
41531 };
41532
41533 if (typeof this.options.addEdge === "function") {
41534 if (this.options.addEdge.length === 2) {
41535 this.options.addEdge(defaultData, function (finalizedData) {
41536 if (finalizedData !== null && finalizedData !== undefined && _this5.inMode === "addEdge") {
41537 // if for whatever reason the mode has changes (due to dataset change) disregard the callback
41538 _this5.body.data.edges.getDataSet().add(finalizedData);
41539
41540 _this5.selectionHandler.unselectAll();
41541
41542 _this5.showManipulatorToolbar();
41543 }
41544 });
41545 } else {
41546 throw new Error("The function for connect does not support two arguments (data,callback)");
41547 }
41548 } else {
41549 this.body.data.edges.getDataSet().add(defaultData);
41550 this.selectionHandler.unselectAll();
41551 this.showManipulatorToolbar();
41552 }
41553 }
41554 /**
41555 * connect two nodes with a new edge.
41556 *
41557 * @param {Node.id} sourceNodeId
41558 * @param {Node.id} targetNodeId
41559 * @private
41560 */
41561
41562 }, {
41563 key: "_performEditEdge",
41564 value: function _performEditEdge(sourceNodeId, targetNodeId) {
41565 var _this6 = this;
41566
41567 var defaultData = {
41568 id: this.edgeBeingEditedId,
41569 from: sourceNodeId,
41570 to: targetNodeId,
41571 label: this.body.data.edges.get(this.edgeBeingEditedId).label
41572 };
41573 var eeFunct = this.options.editEdge;
41574
41575 if (_typeof(eeFunct) === "object") {
41576 eeFunct = eeFunct.editWithoutDrag;
41577 }
41578
41579 if (typeof eeFunct === "function") {
41580 if (eeFunct.length === 2) {
41581 eeFunct(defaultData, function (finalizedData) {
41582 if (finalizedData === null || finalizedData === undefined || _this6.inMode !== "editEdge") {
41583 // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
41584 _this6.body.edges[defaultData.id].updateEdgeType();
41585
41586 _this6.body.emitter.emit("_redraw");
41587
41588 _this6.showManipulatorToolbar();
41589 } else {
41590 _this6.body.data.edges.getDataSet().update(finalizedData);
41591
41592 _this6.selectionHandler.unselectAll();
41593
41594 _this6.showManipulatorToolbar();
41595 }
41596 });
41597 } else {
41598 throw new Error("The function for edit does not support two arguments (data, callback)");
41599 }
41600 } else {
41601 this.body.data.edges.getDataSet().update(defaultData);
41602 this.selectionHandler.unselectAll();
41603 this.showManipulatorToolbar();
41604 }
41605 }
41606 }]);
41607
41608 return ManipulationSystem;
41609}();
41610
41611/**
41612 * This object contains all possible options. It will check if the types are correct, if required if the option is one
41613 * of the allowed values.
41614 *
41615 * __any__ means that the name of the property does not matter.
41616 * __type__ is a required field for all objects and contains the allowed types of all objects
41617 */
41618var string = "string";
41619var bool = "boolean";
41620var number = "number";
41621var array = "array";
41622var object = "object"; // should only be in a __type__ property
41623
41624var dom = "dom";
41625var any = "any"; // List of endpoints
41626
41627var endPoints = ["arrow", "bar", "box", "circle", "crow", "curve", "diamond", "image", "inv_curve", "inv_triangle", "triangle", "vee"];
41628/* eslint-disable @typescript-eslint/naming-convention -- The __*__ format is used to prevent collisions with actual option names. */
41629
41630var nodeOptions = {
41631 borderWidth: {
41632 number: number
41633 },
41634 borderWidthSelected: {
41635 number: number,
41636 undefined: "undefined"
41637 },
41638 brokenImage: {
41639 string: string,
41640 undefined: "undefined"
41641 },
41642 chosen: {
41643 label: {
41644 boolean: bool,
41645 function: "function"
41646 },
41647 node: {
41648 boolean: bool,
41649 function: "function"
41650 },
41651 __type__: {
41652 object: object,
41653 boolean: bool
41654 }
41655 },
41656 color: {
41657 border: {
41658 string: string
41659 },
41660 background: {
41661 string: string
41662 },
41663 highlight: {
41664 border: {
41665 string: string
41666 },
41667 background: {
41668 string: string
41669 },
41670 __type__: {
41671 object: object,
41672 string: string
41673 }
41674 },
41675 hover: {
41676 border: {
41677 string: string
41678 },
41679 background: {
41680 string: string
41681 },
41682 __type__: {
41683 object: object,
41684 string: string
41685 }
41686 },
41687 __type__: {
41688 object: object,
41689 string: string
41690 }
41691 },
41692 opacity: {
41693 number: number,
41694 undefined: "undefined"
41695 },
41696 fixed: {
41697 x: {
41698 boolean: bool
41699 },
41700 y: {
41701 boolean: bool
41702 },
41703 __type__: {
41704 object: object,
41705 boolean: bool
41706 }
41707 },
41708 font: {
41709 align: {
41710 string: string
41711 },
41712 color: {
41713 string: string
41714 },
41715 size: {
41716 number: number
41717 },
41718 face: {
41719 string: string
41720 },
41721 background: {
41722 string: string
41723 },
41724 strokeWidth: {
41725 number: number
41726 },
41727 strokeColor: {
41728 string: string
41729 },
41730 vadjust: {
41731 number: number
41732 },
41733 multi: {
41734 boolean: bool,
41735 string: string
41736 },
41737 bold: {
41738 color: {
41739 string: string
41740 },
41741 size: {
41742 number: number
41743 },
41744 face: {
41745 string: string
41746 },
41747 mod: {
41748 string: string
41749 },
41750 vadjust: {
41751 number: number
41752 },
41753 __type__: {
41754 object: object,
41755 string: string
41756 }
41757 },
41758 boldital: {
41759 color: {
41760 string: string
41761 },
41762 size: {
41763 number: number
41764 },
41765 face: {
41766 string: string
41767 },
41768 mod: {
41769 string: string
41770 },
41771 vadjust: {
41772 number: number
41773 },
41774 __type__: {
41775 object: object,
41776 string: string
41777 }
41778 },
41779 ital: {
41780 color: {
41781 string: string
41782 },
41783 size: {
41784 number: number
41785 },
41786 face: {
41787 string: string
41788 },
41789 mod: {
41790 string: string
41791 },
41792 vadjust: {
41793 number: number
41794 },
41795 __type__: {
41796 object: object,
41797 string: string
41798 }
41799 },
41800 mono: {
41801 color: {
41802 string: string
41803 },
41804 size: {
41805 number: number
41806 },
41807 face: {
41808 string: string
41809 },
41810 mod: {
41811 string: string
41812 },
41813 vadjust: {
41814 number: number
41815 },
41816 __type__: {
41817 object: object,
41818 string: string
41819 }
41820 },
41821 __type__: {
41822 object: object,
41823 string: string
41824 }
41825 },
41826 group: {
41827 string: string,
41828 number: number,
41829 undefined: "undefined"
41830 },
41831 heightConstraint: {
41832 minimum: {
41833 number: number
41834 },
41835 valign: {
41836 string: string
41837 },
41838 __type__: {
41839 object: object,
41840 boolean: bool,
41841 number: number
41842 }
41843 },
41844 hidden: {
41845 boolean: bool
41846 },
41847 icon: {
41848 face: {
41849 string: string
41850 },
41851 code: {
41852 string: string
41853 },
41854 size: {
41855 number: number
41856 },
41857 color: {
41858 string: string
41859 },
41860 weight: {
41861 string: string,
41862 number: number
41863 },
41864 __type__: {
41865 object: object
41866 }
41867 },
41868 id: {
41869 string: string,
41870 number: number
41871 },
41872 image: {
41873 selected: {
41874 string: string,
41875 undefined: "undefined"
41876 },
41877 unselected: {
41878 string: string,
41879 undefined: "undefined"
41880 },
41881 __type__: {
41882 object: object,
41883 string: string
41884 }
41885 },
41886 imagePadding: {
41887 top: {
41888 number: number
41889 },
41890 right: {
41891 number: number
41892 },
41893 bottom: {
41894 number: number
41895 },
41896 left: {
41897 number: number
41898 },
41899 __type__: {
41900 object: object,
41901 number: number
41902 }
41903 },
41904 label: {
41905 string: string,
41906 undefined: "undefined"
41907 },
41908 labelHighlightBold: {
41909 boolean: bool
41910 },
41911 level: {
41912 number: number,
41913 undefined: "undefined"
41914 },
41915 margin: {
41916 top: {
41917 number: number
41918 },
41919 right: {
41920 number: number
41921 },
41922 bottom: {
41923 number: number
41924 },
41925 left: {
41926 number: number
41927 },
41928 __type__: {
41929 object: object,
41930 number: number
41931 }
41932 },
41933 mass: {
41934 number: number
41935 },
41936 physics: {
41937 boolean: bool
41938 },
41939 scaling: {
41940 min: {
41941 number: number
41942 },
41943 max: {
41944 number: number
41945 },
41946 label: {
41947 enabled: {
41948 boolean: bool
41949 },
41950 min: {
41951 number: number
41952 },
41953 max: {
41954 number: number
41955 },
41956 maxVisible: {
41957 number: number
41958 },
41959 drawThreshold: {
41960 number: number
41961 },
41962 __type__: {
41963 object: object,
41964 boolean: bool
41965 }
41966 },
41967 customScalingFunction: {
41968 function: "function"
41969 },
41970 __type__: {
41971 object: object
41972 }
41973 },
41974 shadow: {
41975 enabled: {
41976 boolean: bool
41977 },
41978 color: {
41979 string: string
41980 },
41981 size: {
41982 number: number
41983 },
41984 x: {
41985 number: number
41986 },
41987 y: {
41988 number: number
41989 },
41990 __type__: {
41991 object: object,
41992 boolean: bool
41993 }
41994 },
41995 shape: {
41996 string: ["custom", "ellipse", "circle", "database", "box", "text", "image", "circularImage", "diamond", "dot", "star", "triangle", "triangleDown", "square", "icon", "hexagon"]
41997 },
41998 ctxRenderer: {
41999 function: "function"
42000 },
42001 shapeProperties: {
42002 borderDashes: {
42003 boolean: bool,
42004 array: array
42005 },
42006 borderRadius: {
42007 number: number
42008 },
42009 interpolation: {
42010 boolean: bool
42011 },
42012 useImageSize: {
42013 boolean: bool
42014 },
42015 useBorderWithImage: {
42016 boolean: bool
42017 },
42018 coordinateOrigin: {
42019 string: ["center", "top-left"]
42020 },
42021 __type__: {
42022 object: object
42023 }
42024 },
42025 size: {
42026 number: number
42027 },
42028 title: {
42029 string: string,
42030 dom: dom,
42031 undefined: "undefined"
42032 },
42033 value: {
42034 number: number,
42035 undefined: "undefined"
42036 },
42037 widthConstraint: {
42038 minimum: {
42039 number: number
42040 },
42041 maximum: {
42042 number: number
42043 },
42044 __type__: {
42045 object: object,
42046 boolean: bool,
42047 number: number
42048 }
42049 },
42050 x: {
42051 number: number
42052 },
42053 y: {
42054 number: number
42055 },
42056 __type__: {
42057 object: object
42058 }
42059};
42060var allOptions = {
42061 configure: {
42062 enabled: {
42063 boolean: bool
42064 },
42065 filter: {
42066 boolean: bool,
42067 string: string,
42068 array: array,
42069 function: "function"
42070 },
42071 container: {
42072 dom: dom
42073 },
42074 showButton: {
42075 boolean: bool
42076 },
42077 __type__: {
42078 object: object,
42079 boolean: bool,
42080 string: string,
42081 array: array,
42082 function: "function"
42083 }
42084 },
42085 edges: {
42086 arrows: {
42087 to: {
42088 enabled: {
42089 boolean: bool
42090 },
42091 scaleFactor: {
42092 number: number
42093 },
42094 type: {
42095 string: endPoints
42096 },
42097 imageHeight: {
42098 number: number
42099 },
42100 imageWidth: {
42101 number: number
42102 },
42103 src: {
42104 string: string
42105 },
42106 __type__: {
42107 object: object,
42108 boolean: bool
42109 }
42110 },
42111 middle: {
42112 enabled: {
42113 boolean: bool
42114 },
42115 scaleFactor: {
42116 number: number
42117 },
42118 type: {
42119 string: endPoints
42120 },
42121 imageWidth: {
42122 number: number
42123 },
42124 imageHeight: {
42125 number: number
42126 },
42127 src: {
42128 string: string
42129 },
42130 __type__: {
42131 object: object,
42132 boolean: bool
42133 }
42134 },
42135 from: {
42136 enabled: {
42137 boolean: bool
42138 },
42139 scaleFactor: {
42140 number: number
42141 },
42142 type: {
42143 string: endPoints
42144 },
42145 imageWidth: {
42146 number: number
42147 },
42148 imageHeight: {
42149 number: number
42150 },
42151 src: {
42152 string: string
42153 },
42154 __type__: {
42155 object: object,
42156 boolean: bool
42157 }
42158 },
42159 __type__: {
42160 string: ["from", "to", "middle"],
42161 object: object
42162 }
42163 },
42164 endPointOffset: {
42165 from: {
42166 number: number
42167 },
42168 to: {
42169 number: number
42170 },
42171 __type__: {
42172 object: object,
42173 number: number
42174 }
42175 },
42176 arrowStrikethrough: {
42177 boolean: bool
42178 },
42179 background: {
42180 enabled: {
42181 boolean: bool
42182 },
42183 color: {
42184 string: string
42185 },
42186 size: {
42187 number: number
42188 },
42189 dashes: {
42190 boolean: bool,
42191 array: array
42192 },
42193 __type__: {
42194 object: object,
42195 boolean: bool
42196 }
42197 },
42198 chosen: {
42199 label: {
42200 boolean: bool,
42201 function: "function"
42202 },
42203 edge: {
42204 boolean: bool,
42205 function: "function"
42206 },
42207 __type__: {
42208 object: object,
42209 boolean: bool
42210 }
42211 },
42212 color: {
42213 color: {
42214 string: string
42215 },
42216 highlight: {
42217 string: string
42218 },
42219 hover: {
42220 string: string
42221 },
42222 inherit: {
42223 string: ["from", "to", "both"],
42224 boolean: bool
42225 },
42226 opacity: {
42227 number: number
42228 },
42229 __type__: {
42230 object: object,
42231 string: string
42232 }
42233 },
42234 dashes: {
42235 boolean: bool,
42236 array: array
42237 },
42238 font: {
42239 color: {
42240 string: string
42241 },
42242 size: {
42243 number: number
42244 },
42245 face: {
42246 string: string
42247 },
42248 background: {
42249 string: string
42250 },
42251 strokeWidth: {
42252 number: number
42253 },
42254 strokeColor: {
42255 string: string
42256 },
42257 align: {
42258 string: ["horizontal", "top", "middle", "bottom"]
42259 },
42260 vadjust: {
42261 number: number
42262 },
42263 multi: {
42264 boolean: bool,
42265 string: string
42266 },
42267 bold: {
42268 color: {
42269 string: string
42270 },
42271 size: {
42272 number: number
42273 },
42274 face: {
42275 string: string
42276 },
42277 mod: {
42278 string: string
42279 },
42280 vadjust: {
42281 number: number
42282 },
42283 __type__: {
42284 object: object,
42285 string: string
42286 }
42287 },
42288 boldital: {
42289 color: {
42290 string: string
42291 },
42292 size: {
42293 number: number
42294 },
42295 face: {
42296 string: string
42297 },
42298 mod: {
42299 string: string
42300 },
42301 vadjust: {
42302 number: number
42303 },
42304 __type__: {
42305 object: object,
42306 string: string
42307 }
42308 },
42309 ital: {
42310 color: {
42311 string: string
42312 },
42313 size: {
42314 number: number
42315 },
42316 face: {
42317 string: string
42318 },
42319 mod: {
42320 string: string
42321 },
42322 vadjust: {
42323 number: number
42324 },
42325 __type__: {
42326 object: object,
42327 string: string
42328 }
42329 },
42330 mono: {
42331 color: {
42332 string: string
42333 },
42334 size: {
42335 number: number
42336 },
42337 face: {
42338 string: string
42339 },
42340 mod: {
42341 string: string
42342 },
42343 vadjust: {
42344 number: number
42345 },
42346 __type__: {
42347 object: object,
42348 string: string
42349 }
42350 },
42351 __type__: {
42352 object: object,
42353 string: string
42354 }
42355 },
42356 hidden: {
42357 boolean: bool
42358 },
42359 hoverWidth: {
42360 function: "function",
42361 number: number
42362 },
42363 label: {
42364 string: string,
42365 undefined: "undefined"
42366 },
42367 labelHighlightBold: {
42368 boolean: bool
42369 },
42370 length: {
42371 number: number,
42372 undefined: "undefined"
42373 },
42374 physics: {
42375 boolean: bool
42376 },
42377 scaling: {
42378 min: {
42379 number: number
42380 },
42381 max: {
42382 number: number
42383 },
42384 label: {
42385 enabled: {
42386 boolean: bool
42387 },
42388 min: {
42389 number: number
42390 },
42391 max: {
42392 number: number
42393 },
42394 maxVisible: {
42395 number: number
42396 },
42397 drawThreshold: {
42398 number: number
42399 },
42400 __type__: {
42401 object: object,
42402 boolean: bool
42403 }
42404 },
42405 customScalingFunction: {
42406 function: "function"
42407 },
42408 __type__: {
42409 object: object
42410 }
42411 },
42412 selectionWidth: {
42413 function: "function",
42414 number: number
42415 },
42416 selfReferenceSize: {
42417 number: number
42418 },
42419 selfReference: {
42420 size: {
42421 number: number
42422 },
42423 angle: {
42424 number: number
42425 },
42426 renderBehindTheNode: {
42427 boolean: bool
42428 },
42429 __type__: {
42430 object: object
42431 }
42432 },
42433 shadow: {
42434 enabled: {
42435 boolean: bool
42436 },
42437 color: {
42438 string: string
42439 },
42440 size: {
42441 number: number
42442 },
42443 x: {
42444 number: number
42445 },
42446 y: {
42447 number: number
42448 },
42449 __type__: {
42450 object: object,
42451 boolean: bool
42452 }
42453 },
42454 smooth: {
42455 enabled: {
42456 boolean: bool
42457 },
42458 type: {
42459 string: ["dynamic", "continuous", "discrete", "diagonalCross", "straightCross", "horizontal", "vertical", "curvedCW", "curvedCCW", "cubicBezier"]
42460 },
42461 roundness: {
42462 number: number
42463 },
42464 forceDirection: {
42465 string: ["horizontal", "vertical", "none"],
42466 boolean: bool
42467 },
42468 __type__: {
42469 object: object,
42470 boolean: bool
42471 }
42472 },
42473 title: {
42474 string: string,
42475 undefined: "undefined"
42476 },
42477 width: {
42478 number: number
42479 },
42480 widthConstraint: {
42481 maximum: {
42482 number: number
42483 },
42484 __type__: {
42485 object: object,
42486 boolean: bool,
42487 number: number
42488 }
42489 },
42490 value: {
42491 number: number,
42492 undefined: "undefined"
42493 },
42494 __type__: {
42495 object: object
42496 }
42497 },
42498 groups: {
42499 useDefaultGroups: {
42500 boolean: bool
42501 },
42502 __any__: nodeOptions,
42503 __type__: {
42504 object: object
42505 }
42506 },
42507 interaction: {
42508 dragNodes: {
42509 boolean: bool
42510 },
42511 dragView: {
42512 boolean: bool
42513 },
42514 hideEdgesOnDrag: {
42515 boolean: bool
42516 },
42517 hideEdgesOnZoom: {
42518 boolean: bool
42519 },
42520 hideNodesOnDrag: {
42521 boolean: bool
42522 },
42523 hover: {
42524 boolean: bool
42525 },
42526 keyboard: {
42527 enabled: {
42528 boolean: bool
42529 },
42530 speed: {
42531 x: {
42532 number: number
42533 },
42534 y: {
42535 number: number
42536 },
42537 zoom: {
42538 number: number
42539 },
42540 __type__: {
42541 object: object
42542 }
42543 },
42544 bindToWindow: {
42545 boolean: bool
42546 },
42547 autoFocus: {
42548 boolean: bool
42549 },
42550 __type__: {
42551 object: object,
42552 boolean: bool
42553 }
42554 },
42555 multiselect: {
42556 boolean: bool
42557 },
42558 navigationButtons: {
42559 boolean: bool
42560 },
42561 selectable: {
42562 boolean: bool
42563 },
42564 selectConnectedEdges: {
42565 boolean: bool
42566 },
42567 hoverConnectedEdges: {
42568 boolean: bool
42569 },
42570 tooltipDelay: {
42571 number: number
42572 },
42573 zoomView: {
42574 boolean: bool
42575 },
42576 zoomSpeed: {
42577 number: number
42578 },
42579 __type__: {
42580 object: object
42581 }
42582 },
42583 layout: {
42584 randomSeed: {
42585 undefined: "undefined",
42586 number: number,
42587 string: string
42588 },
42589 improvedLayout: {
42590 boolean: bool
42591 },
42592 clusterThreshold: {
42593 number: number
42594 },
42595 hierarchical: {
42596 enabled: {
42597 boolean: bool
42598 },
42599 levelSeparation: {
42600 number: number
42601 },
42602 nodeSpacing: {
42603 number: number
42604 },
42605 treeSpacing: {
42606 number: number
42607 },
42608 blockShifting: {
42609 boolean: bool
42610 },
42611 edgeMinimization: {
42612 boolean: bool
42613 },
42614 parentCentralization: {
42615 boolean: bool
42616 },
42617 direction: {
42618 string: ["UD", "DU", "LR", "RL"]
42619 },
42620 sortMethod: {
42621 string: ["hubsize", "directed"]
42622 },
42623 shakeTowards: {
42624 string: ["leaves", "roots"]
42625 },
42626 __type__: {
42627 object: object,
42628 boolean: bool
42629 }
42630 },
42631 __type__: {
42632 object: object
42633 }
42634 },
42635 manipulation: {
42636 enabled: {
42637 boolean: bool
42638 },
42639 initiallyActive: {
42640 boolean: bool
42641 },
42642 addNode: {
42643 boolean: bool,
42644 function: "function"
42645 },
42646 addEdge: {
42647 boolean: bool,
42648 function: "function"
42649 },
42650 editNode: {
42651 function: "function"
42652 },
42653 editEdge: {
42654 editWithoutDrag: {
42655 function: "function"
42656 },
42657 __type__: {
42658 object: object,
42659 boolean: bool,
42660 function: "function"
42661 }
42662 },
42663 deleteNode: {
42664 boolean: bool,
42665 function: "function"
42666 },
42667 deleteEdge: {
42668 boolean: bool,
42669 function: "function"
42670 },
42671 controlNodeStyle: nodeOptions,
42672 __type__: {
42673 object: object,
42674 boolean: bool
42675 }
42676 },
42677 nodes: nodeOptions,
42678 physics: {
42679 enabled: {
42680 boolean: bool
42681 },
42682 barnesHut: {
42683 theta: {
42684 number: number
42685 },
42686 gravitationalConstant: {
42687 number: number
42688 },
42689 centralGravity: {
42690 number: number
42691 },
42692 springLength: {
42693 number: number
42694 },
42695 springConstant: {
42696 number: number
42697 },
42698 damping: {
42699 number: number
42700 },
42701 avoidOverlap: {
42702 number: number
42703 },
42704 __type__: {
42705 object: object
42706 }
42707 },
42708 forceAtlas2Based: {
42709 theta: {
42710 number: number
42711 },
42712 gravitationalConstant: {
42713 number: number
42714 },
42715 centralGravity: {
42716 number: number
42717 },
42718 springLength: {
42719 number: number
42720 },
42721 springConstant: {
42722 number: number
42723 },
42724 damping: {
42725 number: number
42726 },
42727 avoidOverlap: {
42728 number: number
42729 },
42730 __type__: {
42731 object: object
42732 }
42733 },
42734 repulsion: {
42735 centralGravity: {
42736 number: number
42737 },
42738 springLength: {
42739 number: number
42740 },
42741 springConstant: {
42742 number: number
42743 },
42744 nodeDistance: {
42745 number: number
42746 },
42747 damping: {
42748 number: number
42749 },
42750 __type__: {
42751 object: object
42752 }
42753 },
42754 hierarchicalRepulsion: {
42755 centralGravity: {
42756 number: number
42757 },
42758 springLength: {
42759 number: number
42760 },
42761 springConstant: {
42762 number: number
42763 },
42764 nodeDistance: {
42765 number: number
42766 },
42767 damping: {
42768 number: number
42769 },
42770 avoidOverlap: {
42771 number: number
42772 },
42773 __type__: {
42774 object: object
42775 }
42776 },
42777 maxVelocity: {
42778 number: number
42779 },
42780 minVelocity: {
42781 number: number
42782 },
42783 solver: {
42784 string: ["barnesHut", "repulsion", "hierarchicalRepulsion", "forceAtlas2Based"]
42785 },
42786 stabilization: {
42787 enabled: {
42788 boolean: bool
42789 },
42790 iterations: {
42791 number: number
42792 },
42793 updateInterval: {
42794 number: number
42795 },
42796 onlyDynamicEdges: {
42797 boolean: bool
42798 },
42799 fit: {
42800 boolean: bool
42801 },
42802 __type__: {
42803 object: object,
42804 boolean: bool
42805 }
42806 },
42807 timestep: {
42808 number: number
42809 },
42810 adaptiveTimestep: {
42811 boolean: bool
42812 },
42813 wind: {
42814 x: {
42815 number: number
42816 },
42817 y: {
42818 number: number
42819 },
42820 __type__: {
42821 object: object
42822 }
42823 },
42824 __type__: {
42825 object: object,
42826 boolean: bool
42827 }
42828 },
42829 //globals :
42830 autoResize: {
42831 boolean: bool
42832 },
42833 clickToUse: {
42834 boolean: bool
42835 },
42836 locale: {
42837 string: string
42838 },
42839 locales: {
42840 __any__: {
42841 any: any
42842 },
42843 __type__: {
42844 object: object
42845 }
42846 },
42847 height: {
42848 string: string
42849 },
42850 width: {
42851 string: string
42852 },
42853 __type__: {
42854 object: object
42855 }
42856};
42857/* eslint-enable @typescript-eslint/naming-convention */
42858
42859/**
42860 * This provides ranges, initial values, steps and dropdown menu choices for the
42861 * configuration.
42862 *
42863 * @remarks
42864 * Checkbox: `boolean`
42865 * The value supllied will be used as the initial value.
42866 *
42867 * Text field: `string`
42868 * The passed text will be used as the initial value. Any text will be
42869 * accepted afterwards.
42870 *
42871 * Number range: `[number, number, number, number]`
42872 * The meanings are `[initial value, min, max, step]`.
42873 *
42874 * Dropdown: `[Exclude<string, "color">, ...(string | number | boolean)[]]`
42875 * Translations for people with poor understanding of TypeScript: the first
42876 * value always has to be a string but never `"color"`, the rest can be any
42877 * combination of strings, numbers and booleans.
42878 *
42879 * Color picker: `["color", string]`
42880 * The first value says this will be a color picker not a dropdown menu. The
42881 * next value is the initial color.
42882 */
42883
42884var configureOptions = {
42885 nodes: {
42886 borderWidth: [1, 0, 10, 1],
42887 borderWidthSelected: [2, 0, 10, 1],
42888 color: {
42889 border: ["color", "#2B7CE9"],
42890 background: ["color", "#97C2FC"],
42891 highlight: {
42892 border: ["color", "#2B7CE9"],
42893 background: ["color", "#D2E5FF"]
42894 },
42895 hover: {
42896 border: ["color", "#2B7CE9"],
42897 background: ["color", "#D2E5FF"]
42898 }
42899 },
42900 opacity: [0, 0, 1, 0.1],
42901 fixed: {
42902 x: false,
42903 y: false
42904 },
42905 font: {
42906 color: ["color", "#343434"],
42907 size: [14, 0, 100, 1],
42908 face: ["arial", "verdana", "tahoma"],
42909 background: ["color", "none"],
42910 strokeWidth: [0, 0, 50, 1],
42911 strokeColor: ["color", "#ffffff"]
42912 },
42913 //group: 'string',
42914 hidden: false,
42915 labelHighlightBold: true,
42916 //icon: {
42917 // face: 'string', //'FontAwesome',
42918 // code: 'string', //'\uf007',
42919 // size: [50, 0, 200, 1], //50,
42920 // color: ['color','#2B7CE9'] //'#aa00ff'
42921 //},
42922 //image: 'string', // --> URL
42923 physics: true,
42924 scaling: {
42925 min: [10, 0, 200, 1],
42926 max: [30, 0, 200, 1],
42927 label: {
42928 enabled: false,
42929 min: [14, 0, 200, 1],
42930 max: [30, 0, 200, 1],
42931 maxVisible: [30, 0, 200, 1],
42932 drawThreshold: [5, 0, 20, 1]
42933 }
42934 },
42935 shadow: {
42936 enabled: false,
42937 color: "rgba(0,0,0,0.5)",
42938 size: [10, 0, 20, 1],
42939 x: [5, -30, 30, 1],
42940 y: [5, -30, 30, 1]
42941 },
42942 shape: ["ellipse", "box", "circle", "database", "diamond", "dot", "square", "star", "text", "triangle", "triangleDown", "hexagon"],
42943 shapeProperties: {
42944 borderDashes: false,
42945 borderRadius: [6, 0, 20, 1],
42946 interpolation: true,
42947 useImageSize: false
42948 },
42949 size: [25, 0, 200, 1]
42950 },
42951 edges: {
42952 arrows: {
42953 to: {
42954 enabled: false,
42955 scaleFactor: [1, 0, 3, 0.05],
42956 type: "arrow"
42957 },
42958 middle: {
42959 enabled: false,
42960 scaleFactor: [1, 0, 3, 0.05],
42961 type: "arrow"
42962 },
42963 from: {
42964 enabled: false,
42965 scaleFactor: [1, 0, 3, 0.05],
42966 type: "arrow"
42967 }
42968 },
42969 endPointOffset: {
42970 from: [0, -10, 10, 1],
42971 to: [0, -10, 10, 1]
42972 },
42973 arrowStrikethrough: true,
42974 color: {
42975 color: ["color", "#848484"],
42976 highlight: ["color", "#848484"],
42977 hover: ["color", "#848484"],
42978 inherit: ["from", "to", "both", true, false],
42979 opacity: [1, 0, 1, 0.05]
42980 },
42981 dashes: false,
42982 font: {
42983 color: ["color", "#343434"],
42984 size: [14, 0, 100, 1],
42985 face: ["arial", "verdana", "tahoma"],
42986 background: ["color", "none"],
42987 strokeWidth: [2, 0, 50, 1],
42988 strokeColor: ["color", "#ffffff"],
42989 align: ["horizontal", "top", "middle", "bottom"]
42990 },
42991 hidden: false,
42992 hoverWidth: [1.5, 0, 5, 0.1],
42993 labelHighlightBold: true,
42994 physics: true,
42995 scaling: {
42996 min: [1, 0, 100, 1],
42997 max: [15, 0, 100, 1],
42998 label: {
42999 enabled: true,
43000 min: [14, 0, 200, 1],
43001 max: [30, 0, 200, 1],
43002 maxVisible: [30, 0, 200, 1],
43003 drawThreshold: [5, 0, 20, 1]
43004 }
43005 },
43006 selectionWidth: [1.5, 0, 5, 0.1],
43007 selfReferenceSize: [20, 0, 200, 1],
43008 selfReference: {
43009 size: [20, 0, 200, 1],
43010 angle: [Math.PI / 2, -6 * Math.PI, 6 * Math.PI, Math.PI / 8],
43011 renderBehindTheNode: true
43012 },
43013 shadow: {
43014 enabled: false,
43015 color: "rgba(0,0,0,0.5)",
43016 size: [10, 0, 20, 1],
43017 x: [5, -30, 30, 1],
43018 y: [5, -30, 30, 1]
43019 },
43020 smooth: {
43021 enabled: true,
43022 type: ["dynamic", "continuous", "discrete", "diagonalCross", "straightCross", "horizontal", "vertical", "curvedCW", "curvedCCW", "cubicBezier"],
43023 forceDirection: ["horizontal", "vertical", "none"],
43024 roundness: [0.5, 0, 1, 0.05]
43025 },
43026 width: [1, 0, 30, 1]
43027 },
43028 layout: {
43029 //randomSeed: [0, 0, 500, 1],
43030 //improvedLayout: true,
43031 hierarchical: {
43032 enabled: false,
43033 levelSeparation: [150, 20, 500, 5],
43034 nodeSpacing: [100, 20, 500, 5],
43035 treeSpacing: [200, 20, 500, 5],
43036 blockShifting: true,
43037 edgeMinimization: true,
43038 parentCentralization: true,
43039 direction: ["UD", "DU", "LR", "RL"],
43040 sortMethod: ["hubsize", "directed"],
43041 shakeTowards: ["leaves", "roots"] // leaves, roots
43042
43043 }
43044 },
43045 interaction: {
43046 dragNodes: true,
43047 dragView: true,
43048 hideEdgesOnDrag: false,
43049 hideEdgesOnZoom: false,
43050 hideNodesOnDrag: false,
43051 hover: false,
43052 keyboard: {
43053 enabled: false,
43054 speed: {
43055 x: [10, 0, 40, 1],
43056 y: [10, 0, 40, 1],
43057 zoom: [0.02, 0, 0.1, 0.005]
43058 },
43059 bindToWindow: true,
43060 autoFocus: true
43061 },
43062 multiselect: false,
43063 navigationButtons: false,
43064 selectable: true,
43065 selectConnectedEdges: true,
43066 hoverConnectedEdges: true,
43067 tooltipDelay: [300, 0, 1000, 25],
43068 zoomView: true,
43069 zoomSpeed: [1, 0.1, 2, 0.1]
43070 },
43071 manipulation: {
43072 enabled: false,
43073 initiallyActive: false
43074 },
43075 physics: {
43076 enabled: true,
43077 barnesHut: {
43078 theta: [0.5, 0.1, 1, 0.05],
43079 gravitationalConstant: [-2000, -30000, 0, 50],
43080 centralGravity: [0.3, 0, 10, 0.05],
43081 springLength: [95, 0, 500, 5],
43082 springConstant: [0.04, 0, 1.2, 0.005],
43083 damping: [0.09, 0, 1, 0.01],
43084 avoidOverlap: [0, 0, 1, 0.01]
43085 },
43086 forceAtlas2Based: {
43087 theta: [0.5, 0.1, 1, 0.05],
43088 gravitationalConstant: [-50, -500, 0, 1],
43089 centralGravity: [0.01, 0, 1, 0.005],
43090 springLength: [95, 0, 500, 5],
43091 springConstant: [0.08, 0, 1.2, 0.005],
43092 damping: [0.4, 0, 1, 0.01],
43093 avoidOverlap: [0, 0, 1, 0.01]
43094 },
43095 repulsion: {
43096 centralGravity: [0.2, 0, 10, 0.05],
43097 springLength: [200, 0, 500, 5],
43098 springConstant: [0.05, 0, 1.2, 0.005],
43099 nodeDistance: [100, 0, 500, 5],
43100 damping: [0.09, 0, 1, 0.01]
43101 },
43102 hierarchicalRepulsion: {
43103 centralGravity: [0.2, 0, 10, 0.05],
43104 springLength: [100, 0, 500, 5],
43105 springConstant: [0.01, 0, 1.2, 0.005],
43106 nodeDistance: [120, 0, 500, 5],
43107 damping: [0.09, 0, 1, 0.01],
43108 avoidOverlap: [0, 0, 1, 0.01]
43109 },
43110 maxVelocity: [50, 0, 150, 1],
43111 minVelocity: [0.1, 0.01, 0.5, 0.01],
43112 solver: ["barnesHut", "forceAtlas2Based", "repulsion", "hierarchicalRepulsion"],
43113 timestep: [0.5, 0.01, 1, 0.01],
43114 wind: {
43115 x: [0, -10, 10, 0.1],
43116 y: [0, -10, 10, 0.1]
43117 } //adaptiveTimestep: true
43118
43119 }
43120};
43121var configuratorHideOption = function configuratorHideOption(parentPath, optionName, options) {
43122 var _context;
43123
43124 if (includes(parentPath).call(parentPath, "physics") && includes(_context = configureOptions.physics.solver).call(_context, optionName) && options.physics.solver !== optionName && optionName !== "wind") {
43125 return true;
43126 }
43127
43128 return false;
43129};
43130
43131var options = /*#__PURE__*/Object.freeze({
43132 __proto__: null,
43133 configuratorHideOption: configuratorHideOption,
43134 allOptions: allOptions,
43135 configureOptions: configureOptions
43136});
43137
43138/**
43139 * The Floyd–Warshall algorithm is an algorithm for finding shortest paths in
43140 * a weighted graph with positive or negative edge weights (but with no negative
43141 * cycles). - https://en.wikipedia.org/wiki/Floyd–Warshall_algorithm
43142 */
43143var FloydWarshall = /*#__PURE__*/function () {
43144 /**
43145 * @ignore
43146 */
43147 function FloydWarshall() {
43148 _classCallCheck(this, FloydWarshall);
43149 }
43150 /**
43151 *
43152 * @param {object} body
43153 * @param {Array.<Node>} nodesArray
43154 * @param {Array.<Edge>} edgesArray
43155 * @returns {{}}
43156 */
43157
43158
43159 _createClass(FloydWarshall, [{
43160 key: "getDistances",
43161 value: function getDistances(body, nodesArray, edgesArray) {
43162 var D_matrix = {};
43163 var edges = body.edges; // prepare matrix with large numbers
43164
43165 for (var i = 0; i < nodesArray.length; i++) {
43166 var node = nodesArray[i];
43167 var cell = {};
43168 D_matrix[node] = cell;
43169
43170 for (var j = 0; j < nodesArray.length; j++) {
43171 cell[nodesArray[j]] = i == j ? 0 : 1e9;
43172 }
43173 } // put the weights for the edges in. This assumes unidirectionality.
43174
43175
43176 for (var _i = 0; _i < edgesArray.length; _i++) {
43177 var edge = edges[edgesArray[_i]]; // edge has to be connected if it counts to the distances. If it is connected to inner clusters it will crash so we also check if it is in the D_matrix
43178
43179 if (edge.connected === true && D_matrix[edge.fromId] !== undefined && D_matrix[edge.toId] !== undefined) {
43180 D_matrix[edge.fromId][edge.toId] = 1;
43181 D_matrix[edge.toId][edge.fromId] = 1;
43182 }
43183 }
43184
43185 var nodeCount = nodesArray.length; // Adapted FloydWarshall based on unidirectionality to greatly reduce complexity.
43186
43187 for (var k = 0; k < nodeCount; k++) {
43188 var knode = nodesArray[k];
43189 var kcolm = D_matrix[knode];
43190
43191 for (var _i2 = 0; _i2 < nodeCount - 1; _i2++) {
43192 var inode = nodesArray[_i2];
43193 var icolm = D_matrix[inode];
43194
43195 for (var _j = _i2 + 1; _j < nodeCount; _j++) {
43196 var jnode = nodesArray[_j];
43197 var jcolm = D_matrix[jnode];
43198 var val = Math.min(icolm[jnode], icolm[knode] + kcolm[jnode]);
43199 icolm[jnode] = val;
43200 jcolm[inode] = val;
43201 }
43202 }
43203 }
43204
43205 return D_matrix;
43206 }
43207 }]);
43208
43209 return FloydWarshall;
43210}();
43211
43212/**
43213 * KamadaKawai positions the nodes initially based on
43214 *
43215 * "AN ALGORITHM FOR DRAWING GENERAL UNDIRECTED GRAPHS"
43216 * -- Tomihisa KAMADA and Satoru KAWAI in 1989
43217 *
43218 * Possible optimizations in the distance calculation can be implemented.
43219 */
43220
43221var KamadaKawai = /*#__PURE__*/function () {
43222 /**
43223 * @param {object} body
43224 * @param {number} edgeLength
43225 * @param {number} edgeStrength
43226 */
43227 function KamadaKawai(body, edgeLength, edgeStrength) {
43228 _classCallCheck(this, KamadaKawai);
43229
43230 this.body = body;
43231 this.springLength = edgeLength;
43232 this.springConstant = edgeStrength;
43233 this.distanceSolver = new FloydWarshall();
43234 }
43235 /**
43236 * Not sure if needed but can be used to update the spring length and spring constant
43237 *
43238 * @param {object} options
43239 */
43240
43241
43242 _createClass(KamadaKawai, [{
43243 key: "setOptions",
43244 value: function setOptions(options) {
43245 if (options) {
43246 if (options.springLength) {
43247 this.springLength = options.springLength;
43248 }
43249
43250 if (options.springConstant) {
43251 this.springConstant = options.springConstant;
43252 }
43253 }
43254 }
43255 /**
43256 * Position the system
43257 *
43258 * @param {Array.<Node>} nodesArray
43259 * @param {Array.<vis.Edge>} edgesArray
43260 * @param {boolean} [ignoreClusters=false]
43261 */
43262
43263 }, {
43264 key: "solve",
43265 value: function solve(nodesArray, edgesArray) {
43266 var ignoreClusters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
43267 // get distance matrix
43268 var D_matrix = this.distanceSolver.getDistances(this.body, nodesArray, edgesArray); // distance matrix
43269 // get the L Matrix
43270
43271 this._createL_matrix(D_matrix); // get the K Matrix
43272
43273
43274 this._createK_matrix(D_matrix); // initial E Matrix
43275
43276
43277 this._createE_matrix(); // calculate positions
43278
43279
43280 var threshold = 0.01;
43281 var innerThreshold = 1;
43282 var iterations = 0;
43283 var maxIterations = Math.max(1000, Math.min(10 * this.body.nodeIndices.length, 6000));
43284 var maxInnerIterations = 5;
43285 var maxEnergy = 1e9;
43286 var highE_nodeId = 0,
43287 dE_dx = 0,
43288 dE_dy = 0,
43289 delta_m = 0,
43290 subIterations = 0;
43291
43292 while (maxEnergy > threshold && iterations < maxIterations) {
43293 iterations += 1;
43294
43295 var _this$_getHighestEner = this._getHighestEnergyNode(ignoreClusters);
43296
43297 var _this$_getHighestEner2 = _slicedToArray(_this$_getHighestEner, 4);
43298
43299 highE_nodeId = _this$_getHighestEner2[0];
43300 maxEnergy = _this$_getHighestEner2[1];
43301 dE_dx = _this$_getHighestEner2[2];
43302 dE_dy = _this$_getHighestEner2[3];
43303 delta_m = maxEnergy;
43304 subIterations = 0;
43305
43306 while (delta_m > innerThreshold && subIterations < maxInnerIterations) {
43307 subIterations += 1;
43308
43309 this._moveNode(highE_nodeId, dE_dx, dE_dy);
43310
43311 var _this$_getEnergy = this._getEnergy(highE_nodeId);
43312
43313 var _this$_getEnergy2 = _slicedToArray(_this$_getEnergy, 3);
43314
43315 delta_m = _this$_getEnergy2[0];
43316 dE_dx = _this$_getEnergy2[1];
43317 dE_dy = _this$_getEnergy2[2];
43318 }
43319 }
43320 }
43321 /**
43322 * get the node with the highest energy
43323 *
43324 * @param {boolean} ignoreClusters
43325 * @returns {number[]}
43326 * @private
43327 */
43328
43329 }, {
43330 key: "_getHighestEnergyNode",
43331 value: function _getHighestEnergyNode(ignoreClusters) {
43332 var nodesArray = this.body.nodeIndices;
43333 var nodes = this.body.nodes;
43334 var maxEnergy = 0;
43335 var maxEnergyNodeId = nodesArray[0];
43336 var dE_dx_max = 0,
43337 dE_dy_max = 0;
43338
43339 for (var nodeIdx = 0; nodeIdx < nodesArray.length; nodeIdx++) {
43340 var m = nodesArray[nodeIdx]; // by not evaluating nodes with predefined positions we should only move nodes that have no positions.
43341
43342 if (nodes[m].predefinedPosition !== true || nodes[m].isCluster === true && ignoreClusters === true || nodes[m].options.fixed.x !== true || nodes[m].options.fixed.y !== true) {
43343 var _this$_getEnergy3 = this._getEnergy(m),
43344 _this$_getEnergy4 = _slicedToArray(_this$_getEnergy3, 3),
43345 delta_m = _this$_getEnergy4[0],
43346 dE_dx = _this$_getEnergy4[1],
43347 dE_dy = _this$_getEnergy4[2];
43348
43349 if (maxEnergy < delta_m) {
43350 maxEnergy = delta_m;
43351 maxEnergyNodeId = m;
43352 dE_dx_max = dE_dx;
43353 dE_dy_max = dE_dy;
43354 }
43355 }
43356 }
43357
43358 return [maxEnergyNodeId, maxEnergy, dE_dx_max, dE_dy_max];
43359 }
43360 /**
43361 * calculate the energy of a single node
43362 *
43363 * @param {Node.id} m
43364 * @returns {number[]}
43365 * @private
43366 */
43367
43368 }, {
43369 key: "_getEnergy",
43370 value: function _getEnergy(m) {
43371 var _this$E_sums$m = _slicedToArray(this.E_sums[m], 2),
43372 dE_dx = _this$E_sums$m[0],
43373 dE_dy = _this$E_sums$m[1];
43374
43375 var delta_m = Math.sqrt(Math.pow(dE_dx, 2) + Math.pow(dE_dy, 2));
43376 return [delta_m, dE_dx, dE_dy];
43377 }
43378 /**
43379 * move the node based on it's energy
43380 * the dx and dy are calculated from the linear system proposed by Kamada and Kawai
43381 *
43382 * @param {number} m
43383 * @param {number} dE_dx
43384 * @param {number} dE_dy
43385 * @private
43386 */
43387
43388 }, {
43389 key: "_moveNode",
43390 value: function _moveNode(m, dE_dx, dE_dy) {
43391 var nodesArray = this.body.nodeIndices;
43392 var nodes = this.body.nodes;
43393 var d2E_dx2 = 0;
43394 var d2E_dxdy = 0;
43395 var d2E_dy2 = 0;
43396 var x_m = nodes[m].x;
43397 var y_m = nodes[m].y;
43398 var km = this.K_matrix[m];
43399 var lm = this.L_matrix[m];
43400
43401 for (var iIdx = 0; iIdx < nodesArray.length; iIdx++) {
43402 var i = nodesArray[iIdx];
43403
43404 if (i !== m) {
43405 var x_i = nodes[i].x;
43406 var y_i = nodes[i].y;
43407 var kmat = km[i];
43408 var lmat = lm[i];
43409 var denominator = 1.0 / Math.pow(Math.pow(x_m - x_i, 2) + Math.pow(y_m - y_i, 2), 1.5);
43410 d2E_dx2 += kmat * (1 - lmat * Math.pow(y_m - y_i, 2) * denominator);
43411 d2E_dxdy += kmat * (lmat * (x_m - x_i) * (y_m - y_i) * denominator);
43412 d2E_dy2 += kmat * (1 - lmat * Math.pow(x_m - x_i, 2) * denominator);
43413 }
43414 } // make the variable names easier to make the solving of the linear system easier to read
43415
43416
43417 var A = d2E_dx2,
43418 B = d2E_dxdy,
43419 C = dE_dx,
43420 D = d2E_dy2,
43421 E = dE_dy; // solve the linear system for dx and dy
43422
43423 var dy = (C / A + E / B) / (B / A - D / B);
43424 var dx = -(B * dy + C) / A; // move the node
43425
43426 nodes[m].x += dx;
43427 nodes[m].y += dy; // Recalculate E_matrix (should be incremental)
43428
43429 this._updateE_matrix(m);
43430 }
43431 /**
43432 * Create the L matrix: edge length times shortest path
43433 *
43434 * @param {object} D_matrix
43435 * @private
43436 */
43437
43438 }, {
43439 key: "_createL_matrix",
43440 value: function _createL_matrix(D_matrix) {
43441 var nodesArray = this.body.nodeIndices;
43442 var edgeLength = this.springLength;
43443 this.L_matrix = [];
43444
43445 for (var i = 0; i < nodesArray.length; i++) {
43446 this.L_matrix[nodesArray[i]] = {};
43447
43448 for (var j = 0; j < nodesArray.length; j++) {
43449 this.L_matrix[nodesArray[i]][nodesArray[j]] = edgeLength * D_matrix[nodesArray[i]][nodesArray[j]];
43450 }
43451 }
43452 }
43453 /**
43454 * Create the K matrix: spring constants times shortest path
43455 *
43456 * @param {object} D_matrix
43457 * @private
43458 */
43459
43460 }, {
43461 key: "_createK_matrix",
43462 value: function _createK_matrix(D_matrix) {
43463 var nodesArray = this.body.nodeIndices;
43464 var edgeStrength = this.springConstant;
43465 this.K_matrix = [];
43466
43467 for (var i = 0; i < nodesArray.length; i++) {
43468 this.K_matrix[nodesArray[i]] = {};
43469
43470 for (var j = 0; j < nodesArray.length; j++) {
43471 this.K_matrix[nodesArray[i]][nodesArray[j]] = edgeStrength * Math.pow(D_matrix[nodesArray[i]][nodesArray[j]], -2);
43472 }
43473 }
43474 }
43475 /**
43476 * Create matrix with all energies between nodes
43477 *
43478 * @private
43479 */
43480
43481 }, {
43482 key: "_createE_matrix",
43483 value: function _createE_matrix() {
43484 var nodesArray = this.body.nodeIndices;
43485 var nodes = this.body.nodes;
43486 this.E_matrix = {};
43487 this.E_sums = {};
43488
43489 for (var mIdx = 0; mIdx < nodesArray.length; mIdx++) {
43490 this.E_matrix[nodesArray[mIdx]] = [];
43491 }
43492
43493 for (var _mIdx = 0; _mIdx < nodesArray.length; _mIdx++) {
43494 var m = nodesArray[_mIdx];
43495 var x_m = nodes[m].x;
43496 var y_m = nodes[m].y;
43497 var dE_dx = 0;
43498 var dE_dy = 0;
43499
43500 for (var iIdx = _mIdx; iIdx < nodesArray.length; iIdx++) {
43501 var i = nodesArray[iIdx];
43502
43503 if (i !== m) {
43504 var x_i = nodes[i].x;
43505 var y_i = nodes[i].y;
43506 var denominator = 1.0 / Math.sqrt(Math.pow(x_m - x_i, 2) + Math.pow(y_m - y_i, 2));
43507 this.E_matrix[m][iIdx] = [this.K_matrix[m][i] * (x_m - x_i - this.L_matrix[m][i] * (x_m - x_i) * denominator), this.K_matrix[m][i] * (y_m - y_i - this.L_matrix[m][i] * (y_m - y_i) * denominator)];
43508 this.E_matrix[i][_mIdx] = this.E_matrix[m][iIdx];
43509 dE_dx += this.E_matrix[m][iIdx][0];
43510 dE_dy += this.E_matrix[m][iIdx][1];
43511 }
43512 } //Store sum
43513
43514
43515 this.E_sums[m] = [dE_dx, dE_dy];
43516 }
43517 }
43518 /**
43519 * Update method, just doing single column (rows are auto-updated) (update all sums)
43520 *
43521 * @param {number} m
43522 * @private
43523 */
43524
43525 }, {
43526 key: "_updateE_matrix",
43527 value: function _updateE_matrix(m) {
43528 var nodesArray = this.body.nodeIndices;
43529 var nodes = this.body.nodes;
43530 var colm = this.E_matrix[m];
43531 var kcolm = this.K_matrix[m];
43532 var lcolm = this.L_matrix[m];
43533 var x_m = nodes[m].x;
43534 var y_m = nodes[m].y;
43535 var dE_dx = 0;
43536 var dE_dy = 0;
43537
43538 for (var iIdx = 0; iIdx < nodesArray.length; iIdx++) {
43539 var i = nodesArray[iIdx];
43540
43541 if (i !== m) {
43542 //Keep old energy value for sum modification below
43543 var cell = colm[iIdx];
43544 var oldDx = cell[0];
43545 var oldDy = cell[1]; //Calc new energy:
43546
43547 var x_i = nodes[i].x;
43548 var y_i = nodes[i].y;
43549 var denominator = 1.0 / Math.sqrt(Math.pow(x_m - x_i, 2) + Math.pow(y_m - y_i, 2));
43550 var dx = kcolm[i] * (x_m - x_i - lcolm[i] * (x_m - x_i) * denominator);
43551 var dy = kcolm[i] * (y_m - y_i - lcolm[i] * (y_m - y_i) * denominator);
43552 colm[iIdx] = [dx, dy];
43553 dE_dx += dx;
43554 dE_dy += dy; //add new energy to sum of each column
43555
43556 var sum = this.E_sums[i];
43557 sum[0] += dx - oldDx;
43558 sum[1] += dy - oldDy;
43559 }
43560 } //Store sum at -1 index
43561
43562
43563 this.E_sums[m] = [dE_dx, dE_dy];
43564 }
43565 }]);
43566
43567 return KamadaKawai;
43568}();
43569
43570/**
43571 * Create a network visualization, displaying nodes and edges.
43572 *
43573 * @param {Element} container The DOM element in which the Network will
43574 * be created. Normally a div element.
43575 * @param {object} data An object containing parameters
43576 * {Array} nodes
43577 * {Array} edges
43578 * @param {object} options Options
43579 * @class Network
43580 */
43581
43582function Network(container, data, options) {
43583 var _context,
43584 _context2,
43585 _context3,
43586 _context4,
43587 _this = this;
43588
43589 if (!(this instanceof Network)) {
43590 throw new SyntaxError("Constructor must be called with the new operator");
43591 } // set constant values
43592
43593
43594 this.options = {};
43595 this.defaultOptions = {
43596 locale: "en",
43597 locales: locales,
43598 clickToUse: false
43599 };
43600
43601 assign$2(this.options, this.defaultOptions);
43602 /**
43603 * Containers for nodes and edges.
43604 *
43605 * 'edges' and 'nodes' contain the full definitions of all the network elements.
43606 * 'nodeIndices' and 'edgeIndices' contain the id's of the active elements.
43607 *
43608 * The distinction is important, because a defined node need not be active, i.e.
43609 * visible on the canvas. This happens in particular when clusters are defined, in
43610 * that case there will be nodes and edges not displayed.
43611 * The bottom line is that all code with actions related to visibility, *must* use
43612 * 'nodeIndices' and 'edgeIndices', not 'nodes' and 'edges' directly.
43613 */
43614
43615
43616 this.body = {
43617 container: container,
43618 // See comment above for following fields
43619 nodes: {},
43620 nodeIndices: [],
43621 edges: {},
43622 edgeIndices: [],
43623 emitter: {
43624 on: bind$6(_context = this.on).call(_context, this),
43625 off: bind$6(_context2 = this.off).call(_context2, this),
43626 emit: bind$6(_context3 = this.emit).call(_context3, this),
43627 once: bind$6(_context4 = this.once).call(_context4, this)
43628 },
43629 eventListeners: {
43630 onTap: function onTap() {},
43631 onTouch: function onTouch() {},
43632 onDoubleTap: function onDoubleTap() {},
43633 onHold: function onHold() {},
43634 onDragStart: function onDragStart() {},
43635 onDrag: function onDrag() {},
43636 onDragEnd: function onDragEnd() {},
43637 onMouseWheel: function onMouseWheel() {},
43638 onPinch: function onPinch() {},
43639 onMouseMove: function onMouseMove() {},
43640 onRelease: function onRelease() {},
43641 onContext: function onContext() {}
43642 },
43643 data: {
43644 nodes: null,
43645 // A DataSet or DataView
43646 edges: null // A DataSet or DataView
43647
43648 },
43649 functions: {
43650 createNode: function createNode() {},
43651 createEdge: function createEdge() {},
43652 getPointer: function getPointer() {}
43653 },
43654 modules: {},
43655 view: {
43656 scale: 1,
43657 translation: {
43658 x: 0,
43659 y: 0
43660 }
43661 },
43662 selectionBox: {
43663 show: false,
43664 position: {
43665 start: {
43666 x: 0,
43667 y: 0
43668 },
43669 end: {
43670 x: 0,
43671 y: 0
43672 }
43673 }
43674 }
43675 }; // bind the event listeners
43676
43677 this.bindEventListeners(); // setting up all modules
43678
43679 this.images = new Images(function () {
43680 return _this.body.emitter.emit("_requestRedraw");
43681 }); // object with images
43682
43683 this.groups = new Groups(); // object with groups
43684
43685 this.canvas = new Canvas(this.body); // DOM handler
43686
43687 this.selectionHandler = new SelectionHandler(this.body, this.canvas); // Selection handler
43688
43689 this.interactionHandler = new InteractionHandler(this.body, this.canvas, this.selectionHandler); // Interaction handler handles all the hammer bindings (that are bound by canvas), key
43690
43691 this.view = new View(this.body, this.canvas); // camera handler, does animations and zooms
43692
43693 this.renderer = new CanvasRenderer(this.body, this.canvas); // renderer, starts renderloop, has events that modules can hook into
43694
43695 this.physics = new PhysicsEngine(this.body); // physics engine, does all the simulations
43696
43697 this.layoutEngine = new LayoutEngine(this.body); // layout engine for inital layout and hierarchical layout
43698
43699 this.clustering = new ClusterEngine(this.body); // clustering api
43700
43701 this.manipulation = new ManipulationSystem(this.body, this.canvas, this.selectionHandler, this.interactionHandler); // data manipulation system
43702
43703 this.nodesHandler = new NodesHandler(this.body, this.images, this.groups, this.layoutEngine); // Handle adding, deleting and updating of nodes as well as global options
43704
43705 this.edgesHandler = new EdgesHandler(this.body, this.images, this.groups); // Handle adding, deleting and updating of edges as well as global options
43706
43707 this.body.modules["kamadaKawai"] = new KamadaKawai(this.body, 150, 0.05); // Layouting algorithm.
43708
43709 this.body.modules["clustering"] = this.clustering; // create the DOM elements
43710
43711 this.canvas._create(); // apply options
43712
43713
43714 this.setOptions(options); // load data (the disable start variable will be the same as the enabled clustering)
43715
43716 this.setData(data);
43717} // Extend Network with an Emitter mixin
43718
43719Emitter(Network.prototype);
43720/**
43721 * Set options
43722 *
43723 * @param {object} options
43724 */
43725
43726Network.prototype.setOptions = function (options) {
43727 var _this2 = this;
43728
43729 if (options === null) {
43730 options = undefined; // This ensures that options handling doesn't crash in the handling
43731 }
43732
43733 if (options !== undefined) {
43734 var errorFound = Validator$1.validate(options, allOptions);
43735
43736 if (errorFound === true) {
43737 console.error("%cErrors have been found in the supplied options object.", VALIDATOR_PRINT_STYLE$1);
43738 } // copy the global fields over
43739
43740
43741 var fields = ["locale", "locales", "clickToUse"];
43742 selectiveDeepExtend(fields, this.options, options); // normalize the locale or use English
43743
43744 if (options.locale !== undefined) {
43745 options.locale = normalizeLanguageCode(options.locales || this.options.locales, options.locale);
43746 } // the hierarchical system can adapt the edges and the physics to it's own options because not all combinations work with the hierarichical system.
43747
43748
43749 options = this.layoutEngine.setOptions(options.layout, options);
43750 this.canvas.setOptions(options); // options for canvas are in globals
43751 // pass the options to the modules
43752
43753 this.groups.setOptions(options.groups);
43754 this.nodesHandler.setOptions(options.nodes);
43755 this.edgesHandler.setOptions(options.edges);
43756 this.physics.setOptions(options.physics);
43757 this.manipulation.setOptions(options.manipulation, options, this.options); // manipulation uses the locales in the globals
43758
43759 this.interactionHandler.setOptions(options.interaction);
43760 this.renderer.setOptions(options.interaction); // options for rendering are in interaction
43761
43762 this.selectionHandler.setOptions(options.interaction); // options for selection are in interaction
43763 // reload the settings of the nodes to apply changes in groups that are not referenced by pointer.
43764
43765 if (options.groups !== undefined) {
43766 this.body.emitter.emit("refreshNodes");
43767 } // these two do not have options at the moment, here for completeness
43768 //this.view.setOptions(options.view);
43769 //this.clustering.setOptions(options.clustering);
43770
43771
43772 if ("configure" in options) {
43773 if (!this.configurator) {
43774 this.configurator = new Configurator$1(this, this.body.container, configureOptions, this.canvas.pixelRatio, configuratorHideOption);
43775 }
43776
43777 this.configurator.setOptions(options.configure);
43778 } // if the configuration system is enabled, copy all options and put them into the config system
43779
43780
43781 if (this.configurator && this.configurator.options.enabled === true) {
43782 var networkOptions = {
43783 nodes: {},
43784 edges: {},
43785 layout: {},
43786 interaction: {},
43787 manipulation: {},
43788 physics: {},
43789 global: {}
43790 };
43791 deepExtend(networkOptions.nodes, this.nodesHandler.options);
43792 deepExtend(networkOptions.edges, this.edgesHandler.options);
43793 deepExtend(networkOptions.layout, this.layoutEngine.options); // load the selectionHandler and render default options in to the interaction group
43794
43795 deepExtend(networkOptions.interaction, this.selectionHandler.options);
43796 deepExtend(networkOptions.interaction, this.renderer.options);
43797 deepExtend(networkOptions.interaction, this.interactionHandler.options);
43798 deepExtend(networkOptions.manipulation, this.manipulation.options);
43799 deepExtend(networkOptions.physics, this.physics.options); // load globals into the global object
43800
43801 deepExtend(networkOptions.global, this.canvas.options);
43802 deepExtend(networkOptions.global, this.options);
43803 this.configurator.setModuleOptions(networkOptions);
43804 } // handle network global options
43805
43806
43807 if (options.clickToUse !== undefined) {
43808 if (options.clickToUse === true) {
43809 if (this.activator === undefined) {
43810 this.activator = new Activator$1(this.canvas.frame);
43811 this.activator.on("change", function () {
43812 _this2.body.emitter.emit("activate");
43813 });
43814 }
43815 } else {
43816 if (this.activator !== undefined) {
43817 this.activator.destroy();
43818 delete this.activator;
43819 }
43820
43821 this.body.emitter.emit("activate");
43822 }
43823 } else {
43824 this.body.emitter.emit("activate");
43825 }
43826
43827 this.canvas.setSize(); // start the physics simulation. Can be safely called multiple times.
43828
43829 this.body.emitter.emit("startSimulation");
43830 }
43831};
43832/**
43833 * Update the visible nodes and edges list with the most recent node state.
43834 *
43835 * Visible nodes are stored in this.body.nodeIndices.
43836 * Visible edges are stored in this.body.edgeIndices.
43837 * A node or edges is visible if it is not hidden or clustered.
43838 *
43839 * @private
43840 */
43841
43842
43843Network.prototype._updateVisibleIndices = function () {
43844 var nodes = this.body.nodes;
43845 var edges = this.body.edges;
43846 this.body.nodeIndices = [];
43847 this.body.edgeIndices = [];
43848
43849 for (var nodeId in nodes) {
43850 if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) {
43851 if (!this.clustering._isClusteredNode(nodeId) && nodes[nodeId].options.hidden === false) {
43852 this.body.nodeIndices.push(nodes[nodeId].id);
43853 }
43854 }
43855 }
43856
43857 for (var edgeId in edges) {
43858 if (Object.prototype.hasOwnProperty.call(edges, edgeId)) {
43859 var edge = edges[edgeId]; // It can happen that this is executed *after* a node edge has been removed,
43860 // but *before* the edge itself has been removed. Taking this into account.
43861
43862 var fromNode = nodes[edge.fromId];
43863 var toNode = nodes[edge.toId];
43864 var edgeNodesPresent = fromNode !== undefined && toNode !== undefined;
43865 var isVisible = !this.clustering._isClusteredEdge(edgeId) && edge.options.hidden === false && edgeNodesPresent && fromNode.options.hidden === false && // Also hidden if any of its connecting nodes are hidden
43866 toNode.options.hidden === false; // idem
43867
43868 if (isVisible) {
43869 this.body.edgeIndices.push(edge.id);
43870 }
43871 }
43872 }
43873};
43874/**
43875 * Bind all events
43876 */
43877
43878
43879Network.prototype.bindEventListeners = function () {
43880 var _this3 = this;
43881
43882 // This event will trigger a rebuilding of the cache everything.
43883 // Used when nodes or edges have been added or removed.
43884 this.body.emitter.on("_dataChanged", function () {
43885 _this3.edgesHandler._updateState();
43886
43887 _this3.body.emitter.emit("_dataUpdated");
43888 }); // this is called when options of EXISTING nodes or edges have changed.
43889
43890 this.body.emitter.on("_dataUpdated", function () {
43891 // Order important in following block
43892 _this3.clustering._updateState();
43893
43894 _this3._updateVisibleIndices();
43895
43896 _this3._updateValueRange(_this3.body.nodes);
43897
43898 _this3._updateValueRange(_this3.body.edges); // start simulation (can be called safely, even if already running)
43899
43900
43901 _this3.body.emitter.emit("startSimulation");
43902
43903 _this3.body.emitter.emit("_requestRedraw");
43904 });
43905};
43906/**
43907 * Set nodes and edges, and optionally options as well.
43908 *
43909 * @param {object} data Object containing parameters:
43910 * {Array | DataSet | DataView} [nodes] Array with nodes
43911 * {Array | DataSet | DataView} [edges] Array with edges
43912 * {String} [dot] String containing data in DOT format
43913 * {String} [gephi] String containing data in gephi JSON format
43914 * {Options} [options] Object with options
43915 */
43916
43917
43918Network.prototype.setData = function (data) {
43919 // reset the physics engine.
43920 this.body.emitter.emit("resetPhysics");
43921 this.body.emitter.emit("_resetData"); // unselect all to ensure no selections from old data are carried over.
43922
43923 this.selectionHandler.unselectAll();
43924
43925 if (data && data.dot && (data.nodes || data.edges)) {
43926 throw new SyntaxError('Data must contain either parameter "dot" or ' + ' parameter pair "nodes" and "edges", but not both.');
43927 } // set options
43928
43929
43930 this.setOptions(data && data.options); // set all data
43931
43932 if (data && data.dot) {
43933 console.warn("The dot property has been deprecated. Please use the static convertDot method to convert DOT into vis.network format and use the normal data format with nodes and edges. This converter is used like this: var data = vis.network.convertDot(dotString);"); // parse DOT file
43934
43935 var dotData = DOTToGraph(data.dot);
43936 this.setData(dotData);
43937 return;
43938 } else if (data && data.gephi) {
43939 // parse DOT file
43940 console.warn("The gephi property has been deprecated. Please use the static convertGephi method to convert gephi into vis.network format and use the normal data format with nodes and edges. This converter is used like this: var data = vis.network.convertGephi(gephiJson);");
43941 var gephiData = parseGephi(data.gephi);
43942 this.setData(gephiData);
43943 return;
43944 } else {
43945 this.nodesHandler.setData(data && data.nodes, true);
43946 this.edgesHandler.setData(data && data.edges, true);
43947 } // emit change in data
43948
43949
43950 this.body.emitter.emit("_dataChanged"); // emit data loaded
43951
43952 this.body.emitter.emit("_dataLoaded"); // find a stable position or start animating to a stable position
43953
43954 this.body.emitter.emit("initPhysics");
43955};
43956/**
43957 * Cleans up all bindings of the network, removing it fully from the memory IF the variable is set to null after calling this function.
43958 * var network = new vis.Network(..);
43959 * network.destroy();
43960 * network = null;
43961 */
43962
43963
43964Network.prototype.destroy = function () {
43965 this.body.emitter.emit("destroy"); // clear events
43966
43967 this.body.emitter.off();
43968 this.off(); // delete modules
43969
43970 delete this.groups;
43971 delete this.canvas;
43972 delete this.selectionHandler;
43973 delete this.interactionHandler;
43974 delete this.view;
43975 delete this.renderer;
43976 delete this.physics;
43977 delete this.layoutEngine;
43978 delete this.clustering;
43979 delete this.manipulation;
43980 delete this.nodesHandler;
43981 delete this.edgesHandler;
43982 delete this.configurator;
43983 delete this.images;
43984
43985 for (var nodeId in this.body.nodes) {
43986 if (!Object.prototype.hasOwnProperty.call(this.body.nodes, nodeId)) continue;
43987 delete this.body.nodes[nodeId];
43988 }
43989
43990 for (var edgeId in this.body.edges) {
43991 if (!Object.prototype.hasOwnProperty.call(this.body.edges, edgeId)) continue;
43992 delete this.body.edges[edgeId];
43993 } // remove the container and everything inside it recursively
43994
43995
43996 recursiveDOMDelete(this.body.container);
43997};
43998/**
43999 * Update the values of all object in the given array according to the current
44000 * value range of the objects in the array.
44001 *
44002 * @param {object} obj An object containing a set of Edges or Nodes
44003 * The objects must have a method getValue() and
44004 * setValueRange(min, max).
44005 * @private
44006 */
44007
44008
44009Network.prototype._updateValueRange = function (obj) {
44010 var id; // determine the range of the objects
44011
44012 var valueMin = undefined;
44013 var valueMax = undefined;
44014 var valueTotal = 0;
44015
44016 for (id in obj) {
44017 if (Object.prototype.hasOwnProperty.call(obj, id)) {
44018 var value = obj[id].getValue();
44019
44020 if (value !== undefined) {
44021 valueMin = valueMin === undefined ? value : Math.min(value, valueMin);
44022 valueMax = valueMax === undefined ? value : Math.max(value, valueMax);
44023 valueTotal += value;
44024 }
44025 }
44026 } // adjust the range of all objects
44027
44028
44029 if (valueMin !== undefined && valueMax !== undefined) {
44030 for (id in obj) {
44031 if (Object.prototype.hasOwnProperty.call(obj, id)) {
44032 obj[id].setValueRange(valueMin, valueMax, valueTotal);
44033 }
44034 }
44035 }
44036};
44037/**
44038 * Returns true when the Network is active.
44039 *
44040 * @returns {boolean}
44041 */
44042
44043
44044Network.prototype.isActive = function () {
44045 return !this.activator || this.activator.active;
44046};
44047
44048Network.prototype.setSize = function () {
44049 return this.canvas.setSize.apply(this.canvas, arguments);
44050};
44051
44052Network.prototype.canvasToDOM = function () {
44053 return this.canvas.canvasToDOM.apply(this.canvas, arguments);
44054};
44055
44056Network.prototype.DOMtoCanvas = function () {
44057 return this.canvas.DOMtoCanvas.apply(this.canvas, arguments);
44058};
44059/**
44060 * Nodes can be in clusters. Clusters can also be in clusters. This function returns and array of
44061 * nodeIds showing where the node is.
44062 *
44063 * If any nodeId in the chain, especially the first passed in as a parameter, is not present in
44064 * the current nodes list, an empty array is returned.
44065 *
44066 * Example:
44067 * cluster 'A' contains cluster 'B',
44068 * cluster 'B' contains cluster 'C',
44069 * cluster 'C' contains node 'fred'.
44070 * `jsnetwork.clustering.findNode('fred')` will return `['A','B','C','fred']`.
44071 *
44072 * @param {string|number} nodeId
44073 * @returns {Array}
44074 */
44075
44076
44077Network.prototype.findNode = function () {
44078 return this.clustering.findNode.apply(this.clustering, arguments);
44079};
44080
44081Network.prototype.isCluster = function () {
44082 return this.clustering.isCluster.apply(this.clustering, arguments);
44083};
44084
44085Network.prototype.openCluster = function () {
44086 return this.clustering.openCluster.apply(this.clustering, arguments);
44087};
44088
44089Network.prototype.cluster = function () {
44090 return this.clustering.cluster.apply(this.clustering, arguments);
44091};
44092
44093Network.prototype.getNodesInCluster = function () {
44094 return this.clustering.getNodesInCluster.apply(this.clustering, arguments);
44095};
44096
44097Network.prototype.clusterByConnection = function () {
44098 return this.clustering.clusterByConnection.apply(this.clustering, arguments);
44099};
44100
44101Network.prototype.clusterByHubsize = function () {
44102 return this.clustering.clusterByHubsize.apply(this.clustering, arguments);
44103};
44104
44105Network.prototype.updateClusteredNode = function () {
44106 return this.clustering.updateClusteredNode.apply(this.clustering, arguments);
44107};
44108
44109Network.prototype.getClusteredEdges = function () {
44110 return this.clustering.getClusteredEdges.apply(this.clustering, arguments);
44111};
44112
44113Network.prototype.getBaseEdge = function () {
44114 return this.clustering.getBaseEdge.apply(this.clustering, arguments);
44115};
44116
44117Network.prototype.getBaseEdges = function () {
44118 return this.clustering.getBaseEdges.apply(this.clustering, arguments);
44119};
44120
44121Network.prototype.updateEdge = function () {
44122 return this.clustering.updateEdge.apply(this.clustering, arguments);
44123};
44124/**
44125 * This method will cluster all nodes with 1 edge with their respective connected node.
44126 * The options object is explained in full <a data-scroll="" data-options="{ &quot;easing&quot;: &quot;easeInCubic&quot; }" href="#optionsObject">below</a>.
44127 *
44128 * @param {object} [options]
44129 * @returns {undefined}
44130 */
44131
44132
44133Network.prototype.clusterOutliers = function () {
44134 return this.clustering.clusterOutliers.apply(this.clustering, arguments);
44135};
44136
44137Network.prototype.getSeed = function () {
44138 return this.layoutEngine.getSeed.apply(this.layoutEngine, arguments);
44139};
44140
44141Network.prototype.enableEditMode = function () {
44142 return this.manipulation.enableEditMode.apply(this.manipulation, arguments);
44143};
44144
44145Network.prototype.disableEditMode = function () {
44146 return this.manipulation.disableEditMode.apply(this.manipulation, arguments);
44147};
44148
44149Network.prototype.addNodeMode = function () {
44150 return this.manipulation.addNodeMode.apply(this.manipulation, arguments);
44151};
44152
44153Network.prototype.editNode = function () {
44154 return this.manipulation.editNode.apply(this.manipulation, arguments);
44155};
44156
44157Network.prototype.editNodeMode = function () {
44158 console.warn("Deprecated: Please use editNode instead of editNodeMode.");
44159 return this.manipulation.editNode.apply(this.manipulation, arguments);
44160};
44161
44162Network.prototype.addEdgeMode = function () {
44163 return this.manipulation.addEdgeMode.apply(this.manipulation, arguments);
44164};
44165
44166Network.prototype.editEdgeMode = function () {
44167 return this.manipulation.editEdgeMode.apply(this.manipulation, arguments);
44168};
44169
44170Network.prototype.deleteSelected = function () {
44171 return this.manipulation.deleteSelected.apply(this.manipulation, arguments);
44172};
44173
44174Network.prototype.getPositions = function () {
44175 return this.nodesHandler.getPositions.apply(this.nodesHandler, arguments);
44176};
44177
44178Network.prototype.getPosition = function () {
44179 return this.nodesHandler.getPosition.apply(this.nodesHandler, arguments);
44180};
44181
44182Network.prototype.storePositions = function () {
44183 return this.nodesHandler.storePositions.apply(this.nodesHandler, arguments);
44184};
44185
44186Network.prototype.moveNode = function () {
44187 return this.nodesHandler.moveNode.apply(this.nodesHandler, arguments);
44188};
44189
44190Network.prototype.getBoundingBox = function () {
44191 return this.nodesHandler.getBoundingBox.apply(this.nodesHandler, arguments);
44192};
44193
44194Network.prototype.getConnectedNodes = function (objectId) {
44195 if (this.body.nodes[objectId] !== undefined) {
44196 return this.nodesHandler.getConnectedNodes.apply(this.nodesHandler, arguments);
44197 } else {
44198 return this.edgesHandler.getConnectedNodes.apply(this.edgesHandler, arguments);
44199 }
44200};
44201
44202Network.prototype.getConnectedEdges = function () {
44203 return this.nodesHandler.getConnectedEdges.apply(this.nodesHandler, arguments);
44204};
44205
44206Network.prototype.startSimulation = function () {
44207 return this.physics.startSimulation.apply(this.physics, arguments);
44208};
44209
44210Network.prototype.stopSimulation = function () {
44211 return this.physics.stopSimulation.apply(this.physics, arguments);
44212};
44213
44214Network.prototype.stabilize = function () {
44215 return this.physics.stabilize.apply(this.physics, arguments);
44216};
44217
44218Network.prototype.getSelection = function () {
44219 return this.selectionHandler.getSelection.apply(this.selectionHandler, arguments);
44220};
44221
44222Network.prototype.setSelection = function () {
44223 return this.selectionHandler.setSelection.apply(this.selectionHandler, arguments);
44224};
44225
44226Network.prototype.getSelectedNodes = function () {
44227 return this.selectionHandler.getSelectedNodeIds.apply(this.selectionHandler, arguments);
44228};
44229
44230Network.prototype.getSelectedEdges = function () {
44231 return this.selectionHandler.getSelectedEdgeIds.apply(this.selectionHandler, arguments);
44232};
44233
44234Network.prototype.getNodeAt = function () {
44235 var node = this.selectionHandler.getNodeAt.apply(this.selectionHandler, arguments);
44236
44237 if (node !== undefined && node.id !== undefined) {
44238 return node.id;
44239 }
44240
44241 return node;
44242};
44243
44244Network.prototype.getEdgeAt = function () {
44245 var edge = this.selectionHandler.getEdgeAt.apply(this.selectionHandler, arguments);
44246
44247 if (edge !== undefined && edge.id !== undefined) {
44248 return edge.id;
44249 }
44250
44251 return edge;
44252};
44253
44254Network.prototype.selectNodes = function () {
44255 return this.selectionHandler.selectNodes.apply(this.selectionHandler, arguments);
44256};
44257
44258Network.prototype.selectEdges = function () {
44259 return this.selectionHandler.selectEdges.apply(this.selectionHandler, arguments);
44260};
44261
44262Network.prototype.unselectAll = function () {
44263 this.selectionHandler.unselectAll.apply(this.selectionHandler, arguments);
44264 this.selectionHandler.commitWithoutEmitting.apply(this.selectionHandler);
44265 this.redraw();
44266};
44267
44268Network.prototype.redraw = function () {
44269 return this.renderer.redraw.apply(this.renderer, arguments);
44270};
44271
44272Network.prototype.getScale = function () {
44273 return this.view.getScale.apply(this.view, arguments);
44274};
44275
44276Network.prototype.getViewPosition = function () {
44277 return this.view.getViewPosition.apply(this.view, arguments);
44278};
44279
44280Network.prototype.fit = function () {
44281 return this.view.fit.apply(this.view, arguments);
44282};
44283
44284Network.prototype.moveTo = function () {
44285 return this.view.moveTo.apply(this.view, arguments);
44286};
44287
44288Network.prototype.focus = function () {
44289 return this.view.focus.apply(this.view, arguments);
44290};
44291
44292Network.prototype.releaseNode = function () {
44293 return this.view.releaseNode.apply(this.view, arguments);
44294};
44295
44296Network.prototype.getOptionsFromConfigurator = function () {
44297 var options = {};
44298
44299 if (this.configurator) {
44300 options = this.configurator.getOptions.apply(this.configurator);
44301 }
44302
44303 return options;
44304};
44305
44306var parseDOTNetwork = DOTToGraph;
44307// overflow in UMD builds. They all export vis namespace therefore reexporting
44308// leads to loading vis to load vis to load vis…
44309
44310export { DataSet, DataView, Network, Images as NetworkImages, Queue, index as data, dotparser as networkDOTParser, gephiParser as networkGephiParser, options as networkOptions, parseDOTNetwork, parseGephi as parseGephiNetwork };
44311//# sourceMappingURL=vis-network.js.map