UNPKG

1.95 MBJavaScriptView Raw
1/**
2 * vis-network - network
3 * http://visjs.org/
4 *
5 * A dynamic, browser-based visualization library.
6 *
7 * @version 6.3.2
8 * @date 2019-11-08T19:05:41Z
9 *
10 * @copyright (c) 2011-2017 Almende B.V, http://almende.com
11 * @copyright (c) 2018-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(function (global, factory) {
27 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
28 typeof define === 'function' && define.amd ? define(['exports'], factory) :
29 (global = global || self, factory(global.vis = global.vis || {}));
30}(this, (function (exports) { 'use strict';
31
32 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
33
34 function unwrapExports (x) {
35 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
36 }
37
38 function createCommonjsModule(fn, module) {
39 return module = { exports: {} }, fn(module, module.exports), module.exports;
40 }
41
42 function getCjsExportFromNamespace (n) {
43 return n && n['default'] || n;
44 }
45
46 var check = function (it) {
47 return it && it.Math == Math && it;
48 };
49
50 // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
51 var global_1 =
52 // eslint-disable-next-line no-undef
53 check(typeof globalThis == 'object' && globalThis) ||
54 check(typeof window == 'object' && window) ||
55 check(typeof self == 'object' && self) ||
56 check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
57 // eslint-disable-next-line no-new-func
58 Function('return this')();
59
60 var fails = function (exec) {
61 try {
62 return !!exec();
63 } catch (error) {
64 return true;
65 }
66 };
67
68 // Thank's IE8 for his funny defineProperty
69 var descriptors = !fails(function () {
70 return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
71 });
72
73 var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
74 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
75
76 // Nashorn ~ JDK8 bug
77 var NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
78
79 // `Object.prototype.propertyIsEnumerable` method implementation
80 // https://tc39.github.io/ecma262/#sec-object.prototype.propertyisenumerable
81 var f = NASHORN_BUG ? function propertyIsEnumerable(V) {
82 var descriptor = getOwnPropertyDescriptor(this, V);
83 return !!descriptor && descriptor.enumerable;
84 } : nativePropertyIsEnumerable;
85
86 var objectPropertyIsEnumerable = {
87 f: f
88 };
89
90 var createPropertyDescriptor = function (bitmap, value) {
91 return {
92 enumerable: !(bitmap & 1),
93 configurable: !(bitmap & 2),
94 writable: !(bitmap & 4),
95 value: value
96 };
97 };
98
99 var toString = {}.toString;
100
101 var classofRaw = function (it) {
102 return toString.call(it).slice(8, -1);
103 };
104
105 var split = ''.split;
106
107 // fallback for non-array-like ES3 and non-enumerable old V8 strings
108 var indexedObject = fails(function () {
109 // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
110 // eslint-disable-next-line no-prototype-builtins
111 return !Object('z').propertyIsEnumerable(0);
112 }) ? function (it) {
113 return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
114 } : Object;
115
116 // `RequireObjectCoercible` abstract operation
117 // https://tc39.github.io/ecma262/#sec-requireobjectcoercible
118 var requireObjectCoercible = function (it) {
119 if (it == undefined) throw TypeError("Can't call method on " + it);
120 return it;
121 };
122
123 // toObject with fallback for non-array-like ES3 strings
124
125
126
127 var toIndexedObject = function (it) {
128 return indexedObject(requireObjectCoercible(it));
129 };
130
131 var isObject = function (it) {
132 return typeof it === 'object' ? it !== null : typeof it === 'function';
133 };
134
135 // `ToPrimitive` abstract operation
136 // https://tc39.github.io/ecma262/#sec-toprimitive
137 // instead of the ES6 spec version, we didn't implement @@toPrimitive case
138 // and the second argument - flag - preferred type is a string
139 var toPrimitive = function (input, PREFERRED_STRING) {
140 if (!isObject(input)) return input;
141 var fn, val;
142 if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
143 if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
144 if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
145 throw TypeError("Can't convert object to primitive value");
146 };
147
148 var hasOwnProperty = {}.hasOwnProperty;
149
150 var has = function (it, key) {
151 return hasOwnProperty.call(it, key);
152 };
153
154 var document$1 = global_1.document;
155 // typeof document.createElement is 'object' in old IE
156 var EXISTS = isObject(document$1) && isObject(document$1.createElement);
157
158 var documentCreateElement = function (it) {
159 return EXISTS ? document$1.createElement(it) : {};
160 };
161
162 // Thank's IE8 for his funny defineProperty
163 var ie8DomDefine = !descriptors && !fails(function () {
164 return Object.defineProperty(documentCreateElement('div'), 'a', {
165 get: function () { return 7; }
166 }).a != 7;
167 });
168
169 var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
170
171 // `Object.getOwnPropertyDescriptor` method
172 // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor
173 var f$1 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
174 O = toIndexedObject(O);
175 P = toPrimitive(P, true);
176 if (ie8DomDefine) try {
177 return nativeGetOwnPropertyDescriptor(O, P);
178 } catch (error) { /* empty */ }
179 if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
180 };
181
182 var objectGetOwnPropertyDescriptor = {
183 f: f$1
184 };
185
186 var anObject = function (it) {
187 if (!isObject(it)) {
188 throw TypeError(String(it) + ' is not an object');
189 } return it;
190 };
191
192 var nativeDefineProperty = Object.defineProperty;
193
194 // `Object.defineProperty` method
195 // https://tc39.github.io/ecma262/#sec-object.defineproperty
196 var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
197 anObject(O);
198 P = toPrimitive(P, true);
199 anObject(Attributes);
200 if (ie8DomDefine) try {
201 return nativeDefineProperty(O, P, Attributes);
202 } catch (error) { /* empty */ }
203 if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
204 if ('value' in Attributes) O[P] = Attributes.value;
205 return O;
206 };
207
208 var objectDefineProperty = {
209 f: f$2
210 };
211
212 var createNonEnumerableProperty = descriptors ? function (object, key, value) {
213 return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
214 } : function (object, key, value) {
215 object[key] = value;
216 return object;
217 };
218
219 var isPure = false;
220
221 var setGlobal = function (key, value) {
222 try {
223 createNonEnumerableProperty(global_1, key, value);
224 } catch (error) {
225 global_1[key] = value;
226 } return value;
227 };
228
229 var SHARED = '__core-js_shared__';
230 var store = global_1[SHARED] || setGlobal(SHARED, {});
231
232 var sharedStore = store;
233
234 var shared = createCommonjsModule(function (module) {
235 (module.exports = function (key, value) {
236 return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
237 })('versions', []).push({
238 version: '3.3.4',
239 mode: 'global',
240 copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
241 });
242 });
243
244 var functionToString = shared('native-function-to-string', Function.toString);
245
246 var WeakMap = global_1.WeakMap;
247
248 var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(functionToString.call(WeakMap));
249
250 var id = 0;
251 var postfix = Math.random();
252
253 var uid = function (key) {
254 return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
255 };
256
257 var keys = shared('keys');
258
259 var sharedKey = function (key) {
260 return keys[key] || (keys[key] = uid(key));
261 };
262
263 var hiddenKeys = {};
264
265 var WeakMap$1 = global_1.WeakMap;
266 var set, get, has$1;
267
268 var enforce = function (it) {
269 return has$1(it) ? get(it) : set(it, {});
270 };
271
272 var getterFor = function (TYPE) {
273 return function (it) {
274 var state;
275 if (!isObject(it) || (state = get(it)).type !== TYPE) {
276 throw TypeError('Incompatible receiver, ' + TYPE + ' required');
277 } return state;
278 };
279 };
280
281 if (nativeWeakMap) {
282 var store$1 = new WeakMap$1();
283 var wmget = store$1.get;
284 var wmhas = store$1.has;
285 var wmset = store$1.set;
286 set = function (it, metadata) {
287 wmset.call(store$1, it, metadata);
288 return metadata;
289 };
290 get = function (it) {
291 return wmget.call(store$1, it) || {};
292 };
293 has$1 = function (it) {
294 return wmhas.call(store$1, it);
295 };
296 } else {
297 var STATE = sharedKey('state');
298 hiddenKeys[STATE] = true;
299 set = function (it, metadata) {
300 createNonEnumerableProperty(it, STATE, metadata);
301 return metadata;
302 };
303 get = function (it) {
304 return has(it, STATE) ? it[STATE] : {};
305 };
306 has$1 = function (it) {
307 return has(it, STATE);
308 };
309 }
310
311 var internalState = {
312 set: set,
313 get: get,
314 has: has$1,
315 enforce: enforce,
316 getterFor: getterFor
317 };
318
319 var redefine = createCommonjsModule(function (module) {
320 var getInternalState = internalState.get;
321 var enforceInternalState = internalState.enforce;
322 var TEMPLATE = String(functionToString).split('toString');
323
324 shared('inspectSource', function (it) {
325 return functionToString.call(it);
326 });
327
328 (module.exports = function (O, key, value, options) {
329 var unsafe = options ? !!options.unsafe : false;
330 var simple = options ? !!options.enumerable : false;
331 var noTargetGet = options ? !!options.noTargetGet : false;
332 if (typeof value == 'function') {
333 if (typeof key == 'string' && !has(value, 'name')) createNonEnumerableProperty(value, 'name', key);
334 enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
335 }
336 if (O === global_1) {
337 if (simple) O[key] = value;
338 else setGlobal(key, value);
339 return;
340 } else if (!unsafe) {
341 delete O[key];
342 } else if (!noTargetGet && O[key]) {
343 simple = true;
344 }
345 if (simple) O[key] = value;
346 else createNonEnumerableProperty(O, key, value);
347 // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
348 })(Function.prototype, 'toString', function toString() {
349 return typeof this == 'function' && getInternalState(this).source || functionToString.call(this);
350 });
351 });
352
353 var path = global_1;
354
355 var aFunction = function (variable) {
356 return typeof variable == 'function' ? variable : undefined;
357 };
358
359 var getBuiltIn = function (namespace, method) {
360 return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
361 : path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
362 };
363
364 var ceil = Math.ceil;
365 var floor = Math.floor;
366
367 // `ToInteger` abstract operation
368 // https://tc39.github.io/ecma262/#sec-tointeger
369 var toInteger = function (argument) {
370 return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
371 };
372
373 var min = Math.min;
374
375 // `ToLength` abstract operation
376 // https://tc39.github.io/ecma262/#sec-tolength
377 var toLength = function (argument) {
378 return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
379 };
380
381 var max = Math.max;
382 var min$1 = Math.min;
383
384 // Helper for a popular repeating case of the spec:
385 // Let integer be ? ToInteger(index).
386 // If integer < 0, let result be max((length + integer), 0); else let result be min(length, length).
387 var toAbsoluteIndex = function (index, length) {
388 var integer = toInteger(index);
389 return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
390 };
391
392 // `Array.prototype.{ indexOf, includes }` methods implementation
393 var createMethod = function (IS_INCLUDES) {
394 return function ($this, el, fromIndex) {
395 var O = toIndexedObject($this);
396 var length = toLength(O.length);
397 var index = toAbsoluteIndex(fromIndex, length);
398 var value;
399 // Array#includes uses SameValueZero equality algorithm
400 // eslint-disable-next-line no-self-compare
401 if (IS_INCLUDES && el != el) while (length > index) {
402 value = O[index++];
403 // eslint-disable-next-line no-self-compare
404 if (value != value) return true;
405 // Array#indexOf ignores holes, Array#includes - not
406 } else for (;length > index; index++) {
407 if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
408 } return !IS_INCLUDES && -1;
409 };
410 };
411
412 var arrayIncludes = {
413 // `Array.prototype.includes` method
414 // https://tc39.github.io/ecma262/#sec-array.prototype.includes
415 includes: createMethod(true),
416 // `Array.prototype.indexOf` method
417 // https://tc39.github.io/ecma262/#sec-array.prototype.indexof
418 indexOf: createMethod(false)
419 };
420
421 var indexOf = arrayIncludes.indexOf;
422
423
424 var objectKeysInternal = function (object, names) {
425 var O = toIndexedObject(object);
426 var i = 0;
427 var result = [];
428 var key;
429 for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
430 // Don't enum bug & hidden keys
431 while (names.length > i) if (has(O, key = names[i++])) {
432 ~indexOf(result, key) || result.push(key);
433 }
434 return result;
435 };
436
437 // IE8- don't enum bug keys
438 var enumBugKeys = [
439 'constructor',
440 'hasOwnProperty',
441 'isPrototypeOf',
442 'propertyIsEnumerable',
443 'toLocaleString',
444 'toString',
445 'valueOf'
446 ];
447
448 var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype');
449
450 // `Object.getOwnPropertyNames` method
451 // https://tc39.github.io/ecma262/#sec-object.getownpropertynames
452 var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
453 return objectKeysInternal(O, hiddenKeys$1);
454 };
455
456 var objectGetOwnPropertyNames = {
457 f: f$3
458 };
459
460 var f$4 = Object.getOwnPropertySymbols;
461
462 var objectGetOwnPropertySymbols = {
463 f: f$4
464 };
465
466 // all object keys, includes non-enumerable and symbols
467 var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
468 var keys = objectGetOwnPropertyNames.f(anObject(it));
469 var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
470 return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
471 };
472
473 var copyConstructorProperties = function (target, source) {
474 var keys = ownKeys(source);
475 var defineProperty = objectDefineProperty.f;
476 var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
477 for (var i = 0; i < keys.length; i++) {
478 var key = keys[i];
479 if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
480 }
481 };
482
483 var replacement = /#|\.prototype\./;
484
485 var isForced = function (feature, detection) {
486 var value = data[normalize(feature)];
487 return value == POLYFILL ? true
488 : value == NATIVE ? false
489 : typeof detection == 'function' ? fails(detection)
490 : !!detection;
491 };
492
493 var normalize = isForced.normalize = function (string) {
494 return String(string).replace(replacement, '.').toLowerCase();
495 };
496
497 var data = isForced.data = {};
498 var NATIVE = isForced.NATIVE = 'N';
499 var POLYFILL = isForced.POLYFILL = 'P';
500
501 var isForced_1 = isForced;
502
503 var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
504
505
506
507
508
509
510 /*
511 options.target - name of the target object
512 options.global - target is the global object
513 options.stat - export as static methods of target
514 options.proto - export as prototype methods of target
515 options.real - real prototype method for the `pure` version
516 options.forced - export even if the native feature is available
517 options.bind - bind methods to the target, required for the `pure` version
518 options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
519 options.unsafe - use the simple assignment of property instead of delete + defineProperty
520 options.sham - add a flag to not completely full polyfills
521 options.enumerable - export as enumerable property
522 options.noTargetGet - prevent calling a getter on target
523 */
524 var _export = function (options, source) {
525 var TARGET = options.target;
526 var GLOBAL = options.global;
527 var STATIC = options.stat;
528 var FORCED, target, key, targetProperty, sourceProperty, descriptor;
529 if (GLOBAL) {
530 target = global_1;
531 } else if (STATIC) {
532 target = global_1[TARGET] || setGlobal(TARGET, {});
533 } else {
534 target = (global_1[TARGET] || {}).prototype;
535 }
536 if (target) for (key in source) {
537 sourceProperty = source[key];
538 if (options.noTargetGet) {
539 descriptor = getOwnPropertyDescriptor$1(target, key);
540 targetProperty = descriptor && descriptor.value;
541 } else targetProperty = target[key];
542 FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
543 // contained in target
544 if (!FORCED && targetProperty !== undefined) {
545 if (typeof sourceProperty === typeof targetProperty) continue;
546 copyConstructorProperties(sourceProperty, targetProperty);
547 }
548 // add a flag to not completely full polyfills
549 if (options.sham || (targetProperty && targetProperty.sham)) {
550 createNonEnumerableProperty(sourceProperty, 'sham', true);
551 }
552 // extend global
553 redefine(target, key, sourceProperty, options);
554 }
555 };
556
557 var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
558 // Chrome 38 Symbol has incorrect toString conversion
559 // eslint-disable-next-line no-undef
560 return !String(Symbol());
561 });
562
563 var Symbol$1 = global_1.Symbol;
564 var store$2 = shared('wks');
565
566 var wellKnownSymbol = function (name) {
567 return store$2[name] || (store$2[name] = nativeSymbol && Symbol$1[name]
568 || (nativeSymbol ? Symbol$1 : uid)('Symbol.' + name));
569 };
570
571 var TO_STRING_TAG = wellKnownSymbol('toStringTag');
572 // ES3 wrong here
573 var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
574
575 // fallback for IE11 Script Access Denied error
576 var tryGet = function (it, key) {
577 try {
578 return it[key];
579 } catch (error) { /* empty */ }
580 };
581
582 // getting tag from ES6+ `Object.prototype.toString`
583 var classof = function (it) {
584 var O, tag, result;
585 return it === undefined ? 'Undefined' : it === null ? 'Null'
586 // @@toStringTag case
587 : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG)) == 'string' ? tag
588 // builtinTag case
589 : CORRECT_ARGUMENTS ? classofRaw(O)
590 // ES3 arguments fallback
591 : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
592 };
593
594 // `ToObject` abstract operation
595 // https://tc39.github.io/ecma262/#sec-toobject
596 var toObject = function (argument) {
597 return Object(requireObjectCoercible(argument));
598 };
599
600 var correctPrototypeGetter = !fails(function () {
601 function F() { /* empty */ }
602 F.prototype.constructor = null;
603 return Object.getPrototypeOf(new F()) !== F.prototype;
604 });
605
606 var IE_PROTO = sharedKey('IE_PROTO');
607 var ObjectPrototype = Object.prototype;
608
609 // `Object.getPrototypeOf` method
610 // https://tc39.github.io/ecma262/#sec-object.getprototypeof
611 var objectGetPrototypeOf = correctPrototypeGetter ? Object.getPrototypeOf : function (O) {
612 O = toObject(O);
613 if (has(O, IE_PROTO)) return O[IE_PROTO];
614 if (typeof O.constructor == 'function' && O instanceof O.constructor) {
615 return O.constructor.prototype;
616 } return O instanceof Object ? ObjectPrototype : null;
617 };
618
619 var aPossiblePrototype = function (it) {
620 if (!isObject(it) && it !== null) {
621 throw TypeError("Can't set " + String(it) + ' as a prototype');
622 } return it;
623 };
624
625 // `Object.setPrototypeOf` method
626 // https://tc39.github.io/ecma262/#sec-object.setprototypeof
627 // Works with __proto__ only. Old v8 can't work with null proto objects.
628 /* eslint-disable no-proto */
629 var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
630 var CORRECT_SETTER = false;
631 var test = {};
632 var setter;
633 try {
634 setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
635 setter.call(test, []);
636 CORRECT_SETTER = test instanceof Array;
637 } catch (error) { /* empty */ }
638 return function setPrototypeOf(O, proto) {
639 anObject(O);
640 aPossiblePrototype(proto);
641 if (CORRECT_SETTER) setter.call(O, proto);
642 else O.__proto__ = proto;
643 return O;
644 };
645 }() : undefined);
646
647 var defineProperty = objectDefineProperty.f;
648
649
650
651
652
653 var DataView = global_1.DataView;
654 var DataViewPrototype = DataView && DataView.prototype;
655 var Int8Array$1 = global_1.Int8Array;
656 var Int8ArrayPrototype = Int8Array$1 && Int8Array$1.prototype;
657 var Uint8ClampedArray = global_1.Uint8ClampedArray;
658 var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype;
659 var TypedArray = Int8Array$1 && objectGetPrototypeOf(Int8Array$1);
660 var TypedArrayPrototype = Int8ArrayPrototype && objectGetPrototypeOf(Int8ArrayPrototype);
661 var ObjectPrototype$1 = Object.prototype;
662 var isPrototypeOf = ObjectPrototype$1.isPrototypeOf;
663
664 var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
665 var TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG');
666 var NATIVE_ARRAY_BUFFER = !!(global_1.ArrayBuffer && DataView);
667 // Fixing native typed arrays in Opera Presto crashes the browser, see #595
668 var NATIVE_ARRAY_BUFFER_VIEWS = NATIVE_ARRAY_BUFFER && !!objectSetPrototypeOf && classof(global_1.opera) !== 'Opera';
669 var TYPED_ARRAY_TAG_REQIRED = false;
670 var NAME;
671
672 var TypedArrayConstructorsList = {
673 Int8Array: 1,
674 Uint8Array: 1,
675 Uint8ClampedArray: 1,
676 Int16Array: 2,
677 Uint16Array: 2,
678 Int32Array: 4,
679 Uint32Array: 4,
680 Float32Array: 4,
681 Float64Array: 8
682 };
683
684 var isView = function isView(it) {
685 var klass = classof(it);
686 return klass === 'DataView' || has(TypedArrayConstructorsList, klass);
687 };
688
689 var isTypedArray = function (it) {
690 return isObject(it) && has(TypedArrayConstructorsList, classof(it));
691 };
692
693 var aTypedArray = function (it) {
694 if (isTypedArray(it)) return it;
695 throw TypeError('Target is not a typed array');
696 };
697
698 var aTypedArrayConstructor = function (C) {
699 if (objectSetPrototypeOf) {
700 if (isPrototypeOf.call(TypedArray, C)) return C;
701 } else for (var ARRAY in TypedArrayConstructorsList) if (has(TypedArrayConstructorsList, NAME)) {
702 var TypedArrayConstructor = global_1[ARRAY];
703 if (TypedArrayConstructor && (C === TypedArrayConstructor || isPrototypeOf.call(TypedArrayConstructor, C))) {
704 return C;
705 }
706 } throw TypeError('Target is not a typed array constructor');
707 };
708
709 var exportProto = function (KEY, property, forced) {
710 if (!descriptors) return;
711 if (forced) for (var ARRAY in TypedArrayConstructorsList) {
712 var TypedArrayConstructor = global_1[ARRAY];
713 if (TypedArrayConstructor && has(TypedArrayConstructor.prototype, KEY)) {
714 delete TypedArrayConstructor.prototype[KEY];
715 }
716 }
717 if (!TypedArrayPrototype[KEY] || forced) {
718 redefine(TypedArrayPrototype, KEY, forced ? property
719 : NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property);
720 }
721 };
722
723 var exportStatic = function (KEY, property, forced) {
724 var ARRAY, TypedArrayConstructor;
725 if (!descriptors) return;
726 if (objectSetPrototypeOf) {
727 if (forced) for (ARRAY in TypedArrayConstructorsList) {
728 TypedArrayConstructor = global_1[ARRAY];
729 if (TypedArrayConstructor && has(TypedArrayConstructor, KEY)) {
730 delete TypedArrayConstructor[KEY];
731 }
732 }
733 if (!TypedArray[KEY] || forced) {
734 // V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable
735 try {
736 return redefine(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && Int8Array$1[KEY] || property);
737 } catch (error) { /* empty */ }
738 } else return;
739 }
740 for (ARRAY in TypedArrayConstructorsList) {
741 TypedArrayConstructor = global_1[ARRAY];
742 if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) {
743 redefine(TypedArrayConstructor, KEY, property);
744 }
745 }
746 };
747
748 for (NAME in TypedArrayConstructorsList) {
749 if (!global_1[NAME]) NATIVE_ARRAY_BUFFER_VIEWS = false;
750 }
751
752 // WebKit bug - typed arrays constructors prototype is Object.prototype
753 if (!NATIVE_ARRAY_BUFFER_VIEWS || typeof TypedArray != 'function' || TypedArray === Function.prototype) {
754 // eslint-disable-next-line no-shadow
755 TypedArray = function TypedArray() {
756 throw TypeError('Incorrect invocation');
757 };
758 if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
759 if (global_1[NAME]) objectSetPrototypeOf(global_1[NAME], TypedArray);
760 }
761 }
762
763 if (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype$1) {
764 TypedArrayPrototype = TypedArray.prototype;
765 if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
766 if (global_1[NAME]) objectSetPrototypeOf(global_1[NAME].prototype, TypedArrayPrototype);
767 }
768 }
769
770 // WebKit bug - one more object in Uint8ClampedArray prototype chain
771 if (NATIVE_ARRAY_BUFFER_VIEWS && objectGetPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) {
772 objectSetPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype);
773 }
774
775 if (descriptors && !has(TypedArrayPrototype, TO_STRING_TAG$1)) {
776 TYPED_ARRAY_TAG_REQIRED = true;
777 defineProperty(TypedArrayPrototype, TO_STRING_TAG$1, { get: function () {
778 return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined;
779 } });
780 for (NAME in TypedArrayConstructorsList) if (global_1[NAME]) {
781 createNonEnumerableProperty(global_1[NAME], TYPED_ARRAY_TAG, NAME);
782 }
783 }
784
785 // WebKit bug - the same parent prototype for typed arrays and data view
786 if (NATIVE_ARRAY_BUFFER && objectSetPrototypeOf && objectGetPrototypeOf(DataViewPrototype) !== ObjectPrototype$1) {
787 objectSetPrototypeOf(DataViewPrototype, ObjectPrototype$1);
788 }
789
790 var arrayBufferViewCore = {
791 NATIVE_ARRAY_BUFFER: NATIVE_ARRAY_BUFFER,
792 NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS,
793 TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQIRED && TYPED_ARRAY_TAG,
794 aTypedArray: aTypedArray,
795 aTypedArrayConstructor: aTypedArrayConstructor,
796 exportProto: exportProto,
797 exportStatic: exportStatic,
798 isView: isView,
799 isTypedArray: isTypedArray,
800 TypedArray: TypedArray,
801 TypedArrayPrototype: TypedArrayPrototype
802 };
803
804 var redefineAll = function (target, src, options) {
805 for (var key in src) redefine(target, key, src[key], options);
806 return target;
807 };
808
809 var anInstance = function (it, Constructor, name) {
810 if (!(it instanceof Constructor)) {
811 throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
812 } return it;
813 };
814
815 // `ToIndex` abstract operation
816 // https://tc39.github.io/ecma262/#sec-toindex
817 var toIndex = function (it) {
818 if (it === undefined) return 0;
819 var number = toInteger(it);
820 var length = toLength(number);
821 if (number !== length) throw RangeError('Wrong length or index');
822 return length;
823 };
824
825 // `Array.prototype.fill` method implementation
826 // https://tc39.github.io/ecma262/#sec-array.prototype.fill
827 var arrayFill = function fill(value /* , start = 0, end = @length */) {
828 var O = toObject(this);
829 var length = toLength(O.length);
830 var argumentsLength = arguments.length;
831 var index = toAbsoluteIndex(argumentsLength > 1 ? arguments[1] : undefined, length);
832 var end = argumentsLength > 2 ? arguments[2] : undefined;
833 var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
834 while (endPos > index) O[index++] = value;
835 return O;
836 };
837
838 var defineProperty$1 = objectDefineProperty.f;
839
840
841
842 var TO_STRING_TAG$2 = wellKnownSymbol('toStringTag');
843
844 var setToStringTag = function (it, TAG, STATIC) {
845 if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG$2)) {
846 defineProperty$1(it, TO_STRING_TAG$2, { configurable: true, value: TAG });
847 }
848 };
849
850 var NATIVE_ARRAY_BUFFER$1 = arrayBufferViewCore.NATIVE_ARRAY_BUFFER;
851
852
853
854
855
856
857
858 var getOwnPropertyNames = objectGetOwnPropertyNames.f;
859 var defineProperty$2 = objectDefineProperty.f;
860
861
862
863
864 var getInternalState = internalState.get;
865 var setInternalState = internalState.set;
866 var ARRAY_BUFFER = 'ArrayBuffer';
867 var DATA_VIEW = 'DataView';
868 var PROTOTYPE = 'prototype';
869 var WRONG_LENGTH = 'Wrong length';
870 var WRONG_INDEX = 'Wrong index';
871 var NativeArrayBuffer = global_1[ARRAY_BUFFER];
872 var $ArrayBuffer = NativeArrayBuffer;
873 var $DataView = global_1[DATA_VIEW];
874 var Math$1 = global_1.Math;
875 var RangeError$1 = global_1.RangeError;
876 // eslint-disable-next-line no-shadow-restricted-names
877 var Infinity$1 = 1 / 0;
878 var abs = Math$1.abs;
879 var pow = Math$1.pow;
880 var floor$1 = Math$1.floor;
881 var log = Math$1.log;
882 var LN2 = Math$1.LN2;
883
884 // IEEE754 conversions based on https://github.com/feross/ieee754
885 var packIEEE754 = function (number, mantissaLength, bytes) {
886 var buffer = new Array(bytes);
887 var exponentLength = bytes * 8 - mantissaLength - 1;
888 var eMax = (1 << exponentLength) - 1;
889 var eBias = eMax >> 1;
890 var rt = mantissaLength === 23 ? pow(2, -24) - pow(2, -77) : 0;
891 var sign = number < 0 || number === 0 && 1 / number < 0 ? 1 : 0;
892 var index = 0;
893 var exponent, mantissa, c;
894 number = abs(number);
895 // eslint-disable-next-line no-self-compare
896 if (number != number || number === Infinity$1) {
897 // eslint-disable-next-line no-self-compare
898 mantissa = number != number ? 1 : 0;
899 exponent = eMax;
900 } else {
901 exponent = floor$1(log(number) / LN2);
902 if (number * (c = pow(2, -exponent)) < 1) {
903 exponent--;
904 c *= 2;
905 }
906 if (exponent + eBias >= 1) {
907 number += rt / c;
908 } else {
909 number += rt * pow(2, 1 - eBias);
910 }
911 if (number * c >= 2) {
912 exponent++;
913 c /= 2;
914 }
915 if (exponent + eBias >= eMax) {
916 mantissa = 0;
917 exponent = eMax;
918 } else if (exponent + eBias >= 1) {
919 mantissa = (number * c - 1) * pow(2, mantissaLength);
920 exponent = exponent + eBias;
921 } else {
922 mantissa = number * pow(2, eBias - 1) * pow(2, mantissaLength);
923 exponent = 0;
924 }
925 }
926 for (; mantissaLength >= 8; buffer[index++] = mantissa & 255, mantissa /= 256, mantissaLength -= 8);
927 exponent = exponent << mantissaLength | mantissa;
928 exponentLength += mantissaLength;
929 for (; exponentLength > 0; buffer[index++] = exponent & 255, exponent /= 256, exponentLength -= 8);
930 buffer[--index] |= sign * 128;
931 return buffer;
932 };
933
934 var unpackIEEE754 = function (buffer, mantissaLength) {
935 var bytes = buffer.length;
936 var exponentLength = bytes * 8 - mantissaLength - 1;
937 var eMax = (1 << exponentLength) - 1;
938 var eBias = eMax >> 1;
939 var nBits = exponentLength - 7;
940 var index = bytes - 1;
941 var sign = buffer[index--];
942 var exponent = sign & 127;
943 var mantissa;
944 sign >>= 7;
945 for (; nBits > 0; exponent = exponent * 256 + buffer[index], index--, nBits -= 8);
946 mantissa = exponent & (1 << -nBits) - 1;
947 exponent >>= -nBits;
948 nBits += mantissaLength;
949 for (; nBits > 0; mantissa = mantissa * 256 + buffer[index], index--, nBits -= 8);
950 if (exponent === 0) {
951 exponent = 1 - eBias;
952 } else if (exponent === eMax) {
953 return mantissa ? NaN : sign ? -Infinity$1 : Infinity$1;
954 } else {
955 mantissa = mantissa + pow(2, mantissaLength);
956 exponent = exponent - eBias;
957 } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);
958 };
959
960 var unpackInt32 = function (buffer) {
961 return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
962 };
963
964 var packInt8 = function (number) {
965 return [number & 0xFF];
966 };
967
968 var packInt16 = function (number) {
969 return [number & 0xFF, number >> 8 & 0xFF];
970 };
971
972 var packInt32 = function (number) {
973 return [number & 0xFF, number >> 8 & 0xFF, number >> 16 & 0xFF, number >> 24 & 0xFF];
974 };
975
976 var packFloat32 = function (number) {
977 return packIEEE754(number, 23, 4);
978 };
979
980 var packFloat64 = function (number) {
981 return packIEEE754(number, 52, 8);
982 };
983
984 var addGetter = function (Constructor, key) {
985 defineProperty$2(Constructor[PROTOTYPE], key, { get: function () { return getInternalState(this)[key]; } });
986 };
987
988 var get$1 = function (view, count, index, isLittleEndian) {
989 var numIndex = +index;
990 var intIndex = toIndex(numIndex);
991 var store = getInternalState(view);
992 if (intIndex + count > store.byteLength) throw RangeError$1(WRONG_INDEX);
993 var bytes = getInternalState(store.buffer).bytes;
994 var start = intIndex + store.byteOffset;
995 var pack = bytes.slice(start, start + count);
996 return isLittleEndian ? pack : pack.reverse();
997 };
998
999 var set$1 = function (view, count, index, conversion, value, isLittleEndian) {
1000 var numIndex = +index;
1001 var intIndex = toIndex(numIndex);
1002 var store = getInternalState(view);
1003 if (intIndex + count > store.byteLength) throw RangeError$1(WRONG_INDEX);
1004 var bytes = getInternalState(store.buffer).bytes;
1005 var start = intIndex + store.byteOffset;
1006 var pack = conversion(+value);
1007 for (var i = 0; i < count; i++) bytes[start + i] = pack[isLittleEndian ? i : count - i - 1];
1008 };
1009
1010 if (!NATIVE_ARRAY_BUFFER$1) {
1011 $ArrayBuffer = function ArrayBuffer(length) {
1012 anInstance(this, $ArrayBuffer, ARRAY_BUFFER);
1013 var byteLength = toIndex(length);
1014 setInternalState(this, {
1015 bytes: arrayFill.call(new Array(byteLength), 0),
1016 byteLength: byteLength
1017 });
1018 if (!descriptors) this.byteLength = byteLength;
1019 };
1020
1021 $DataView = function DataView(buffer, byteOffset, byteLength) {
1022 anInstance(this, $DataView, DATA_VIEW);
1023 anInstance(buffer, $ArrayBuffer, DATA_VIEW);
1024 var bufferLength = getInternalState(buffer).byteLength;
1025 var offset = toInteger(byteOffset);
1026 if (offset < 0 || offset > bufferLength) throw RangeError$1('Wrong offset');
1027 byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
1028 if (offset + byteLength > bufferLength) throw RangeError$1(WRONG_LENGTH);
1029 setInternalState(this, {
1030 buffer: buffer,
1031 byteLength: byteLength,
1032 byteOffset: offset
1033 });
1034 if (!descriptors) {
1035 this.buffer = buffer;
1036 this.byteLength = byteLength;
1037 this.byteOffset = offset;
1038 }
1039 };
1040
1041 if (descriptors) {
1042 addGetter($ArrayBuffer, 'byteLength');
1043 addGetter($DataView, 'buffer');
1044 addGetter($DataView, 'byteLength');
1045 addGetter($DataView, 'byteOffset');
1046 }
1047
1048 redefineAll($DataView[PROTOTYPE], {
1049 getInt8: function getInt8(byteOffset) {
1050 return get$1(this, 1, byteOffset)[0] << 24 >> 24;
1051 },
1052 getUint8: function getUint8(byteOffset) {
1053 return get$1(this, 1, byteOffset)[0];
1054 },
1055 getInt16: function getInt16(byteOffset /* , littleEndian */) {
1056 var bytes = get$1(this, 2, byteOffset, arguments.length > 1 ? arguments[1] : undefined);
1057 return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
1058 },
1059 getUint16: function getUint16(byteOffset /* , littleEndian */) {
1060 var bytes = get$1(this, 2, byteOffset, arguments.length > 1 ? arguments[1] : undefined);
1061 return bytes[1] << 8 | bytes[0];
1062 },
1063 getInt32: function getInt32(byteOffset /* , littleEndian */) {
1064 return unpackInt32(get$1(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined));
1065 },
1066 getUint32: function getUint32(byteOffset /* , littleEndian */) {
1067 return unpackInt32(get$1(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined)) >>> 0;
1068 },
1069 getFloat32: function getFloat32(byteOffset /* , littleEndian */) {
1070 return unpackIEEE754(get$1(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined), 23);
1071 },
1072 getFloat64: function getFloat64(byteOffset /* , littleEndian */) {
1073 return unpackIEEE754(get$1(this, 8, byteOffset, arguments.length > 1 ? arguments[1] : undefined), 52);
1074 },
1075 setInt8: function setInt8(byteOffset, value) {
1076 set$1(this, 1, byteOffset, packInt8, value);
1077 },
1078 setUint8: function setUint8(byteOffset, value) {
1079 set$1(this, 1, byteOffset, packInt8, value);
1080 },
1081 setInt16: function setInt16(byteOffset, value /* , littleEndian */) {
1082 set$1(this, 2, byteOffset, packInt16, value, arguments.length > 2 ? arguments[2] : undefined);
1083 },
1084 setUint16: function setUint16(byteOffset, value /* , littleEndian */) {
1085 set$1(this, 2, byteOffset, packInt16, value, arguments.length > 2 ? arguments[2] : undefined);
1086 },
1087 setInt32: function setInt32(byteOffset, value /* , littleEndian */) {
1088 set$1(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : undefined);
1089 },
1090 setUint32: function setUint32(byteOffset, value /* , littleEndian */) {
1091 set$1(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : undefined);
1092 },
1093 setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {
1094 set$1(this, 4, byteOffset, packFloat32, value, arguments.length > 2 ? arguments[2] : undefined);
1095 },
1096 setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {
1097 set$1(this, 8, byteOffset, packFloat64, value, arguments.length > 2 ? arguments[2] : undefined);
1098 }
1099 });
1100 } else {
1101 if (!fails(function () {
1102 NativeArrayBuffer(1);
1103 }) || !fails(function () {
1104 new NativeArrayBuffer(-1); // eslint-disable-line no-new
1105 }) || fails(function () {
1106 new NativeArrayBuffer(); // eslint-disable-line no-new
1107 new NativeArrayBuffer(1.5); // eslint-disable-line no-new
1108 new NativeArrayBuffer(NaN); // eslint-disable-line no-new
1109 return NativeArrayBuffer.name != ARRAY_BUFFER;
1110 })) {
1111 $ArrayBuffer = function ArrayBuffer(length) {
1112 anInstance(this, $ArrayBuffer);
1113 return new NativeArrayBuffer(toIndex(length));
1114 };
1115 var ArrayBufferPrototype = $ArrayBuffer[PROTOTYPE] = NativeArrayBuffer[PROTOTYPE];
1116 for (var keys$1 = getOwnPropertyNames(NativeArrayBuffer), j = 0, key; keys$1.length > j;) {
1117 if (!((key = keys$1[j++]) in $ArrayBuffer)) {
1118 createNonEnumerableProperty($ArrayBuffer, key, NativeArrayBuffer[key]);
1119 }
1120 }
1121 ArrayBufferPrototype.constructor = $ArrayBuffer;
1122 }
1123 // iOS Safari 7.x bug
1124 var testView = new $DataView(new $ArrayBuffer(2));
1125 var nativeSetInt8 = $DataView[PROTOTYPE].setInt8;
1126 testView.setInt8(0, 2147483648);
1127 testView.setInt8(1, 2147483649);
1128 if (testView.getInt8(0) || !testView.getInt8(1)) redefineAll($DataView[PROTOTYPE], {
1129 setInt8: function setInt8(byteOffset, value) {
1130 nativeSetInt8.call(this, byteOffset, value << 24 >> 24);
1131 },
1132 setUint8: function setUint8(byteOffset, value) {
1133 nativeSetInt8.call(this, byteOffset, value << 24 >> 24);
1134 }
1135 }, { unsafe: true });
1136 }
1137
1138 setToStringTag($ArrayBuffer, ARRAY_BUFFER);
1139 setToStringTag($DataView, DATA_VIEW);
1140
1141 var arrayBuffer = {
1142 ArrayBuffer: $ArrayBuffer,
1143 DataView: $DataView
1144 };
1145
1146 var aFunction$1 = function (it) {
1147 if (typeof it != 'function') {
1148 throw TypeError(String(it) + ' is not a function');
1149 } return it;
1150 };
1151
1152 var SPECIES = wellKnownSymbol('species');
1153
1154 // `SpeciesConstructor` abstract operation
1155 // https://tc39.github.io/ecma262/#sec-speciesconstructor
1156 var speciesConstructor = function (O, defaultConstructor) {
1157 var C = anObject(O).constructor;
1158 var S;
1159 return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? defaultConstructor : aFunction$1(S);
1160 };
1161
1162 var ArrayBuffer = arrayBuffer.ArrayBuffer;
1163 var DataView$1 = arrayBuffer.DataView;
1164 var nativeArrayBufferSlice = ArrayBuffer.prototype.slice;
1165
1166 var INCORRECT_SLICE = fails(function () {
1167 return !new ArrayBuffer(2).slice(1, undefined).byteLength;
1168 });
1169
1170 // `ArrayBuffer.prototype.slice` method
1171 // https://tc39.github.io/ecma262/#sec-arraybuffer.prototype.slice
1172 _export({ target: 'ArrayBuffer', proto: true, unsafe: true, forced: INCORRECT_SLICE }, {
1173 slice: function slice(start, end) {
1174 if (nativeArrayBufferSlice !== undefined && end === undefined) {
1175 return nativeArrayBufferSlice.call(anObject(this), start); // FF fix
1176 }
1177 var length = anObject(this).byteLength;
1178 var first = toAbsoluteIndex(start, length);
1179 var fin = toAbsoluteIndex(end === undefined ? length : end, length);
1180 var result = new (speciesConstructor(this, ArrayBuffer))(toLength(fin - first));
1181 var viewSource = new DataView$1(this);
1182 var viewTarget = new DataView$1(result);
1183 var index = 0;
1184 while (first < fin) {
1185 viewTarget.setUint8(index++, viewSource.getUint8(first++));
1186 } return result;
1187 }
1188 });
1189
1190 var NATIVE_ARRAY_BUFFER$2 = arrayBufferViewCore.NATIVE_ARRAY_BUFFER;
1191
1192 // `DataView` constructor
1193 // https://tc39.github.io/ecma262/#sec-dataview-constructor
1194 _export({ global: true, forced: !NATIVE_ARRAY_BUFFER$2 }, {
1195 DataView: arrayBuffer.DataView
1196 });
1197
1198 var TO_STRING_TAG$3 = wellKnownSymbol('toStringTag');
1199 var test = {};
1200
1201 test[TO_STRING_TAG$3] = 'z';
1202
1203 // `Object.prototype.toString` method implementation
1204 // https://tc39.github.io/ecma262/#sec-object.prototype.tostring
1205 var objectToString = String(test) !== '[object z]' ? function toString() {
1206 return '[object ' + classof(this) + ']';
1207 } : test.toString;
1208
1209 var ObjectPrototype$2 = Object.prototype;
1210
1211 // `Object.prototype.toString` method
1212 // https://tc39.github.io/ecma262/#sec-object.prototype.tostring
1213 if (objectToString !== ObjectPrototype$2.toString) {
1214 redefine(ObjectPrototype$2, 'toString', objectToString, { unsafe: true });
1215 }
1216
1217 /*
1218 * Canvas shapes used by Network
1219 */
1220
1221 if (typeof CanvasRenderingContext2D !== "undefined") {
1222 CanvasRenderingContext2D.prototype.circle = function (x, y, r) {
1223 this.beginPath();
1224 this.arc(x, y, r, 0, 2 * Math.PI, false);
1225 this.closePath();
1226 };
1227
1228 CanvasRenderingContext2D.prototype.square = function (x, y, r) {
1229 this.beginPath();
1230 this.rect(x - r, y - r, r * 2, r * 2);
1231 this.closePath();
1232 };
1233
1234 CanvasRenderingContext2D.prototype.triangle = function (x, y, r) {
1235 this.beginPath(); // the change in radius and the offset is here to center the shape
1236
1237 r *= 1.15;
1238 y += 0.275 * r;
1239 var s = r * 2;
1240 var s2 = s / 2;
1241 var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
1242
1243 var h = Math.sqrt(s * s - s2 * s2); // height
1244
1245 this.moveTo(x, y - (h - ir));
1246 this.lineTo(x + s2, y + ir);
1247 this.lineTo(x - s2, y + ir);
1248 this.lineTo(x, y - (h - ir));
1249 this.closePath();
1250 };
1251
1252 CanvasRenderingContext2D.prototype.triangleDown = function (x, y, r) {
1253 this.beginPath(); // the change in radius and the offset is here to center the shape
1254
1255 r *= 1.15;
1256 y -= 0.275 * r;
1257 var s = r * 2;
1258 var s2 = s / 2;
1259 var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
1260
1261 var h = Math.sqrt(s * s - s2 * s2); // height
1262
1263 this.moveTo(x, y + (h - ir));
1264 this.lineTo(x + s2, y - ir);
1265 this.lineTo(x - s2, y - ir);
1266 this.lineTo(x, y + (h - ir));
1267 this.closePath();
1268 };
1269
1270 CanvasRenderingContext2D.prototype.star = function (x, y, r) {
1271 // http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
1272 this.beginPath(); // the change in radius and the offset is here to center the shape
1273
1274 r *= 0.82;
1275 y += 0.1 * r;
1276
1277 for (var n = 0; n < 10; n++) {
1278 var radius = n % 2 === 0 ? r * 1.3 : r * 0.5;
1279 this.lineTo(x + radius * Math.sin(n * 2 * Math.PI / 10), y - radius * Math.cos(n * 2 * Math.PI / 10));
1280 }
1281
1282 this.closePath();
1283 };
1284
1285 CanvasRenderingContext2D.prototype.diamond = function (x, y, r) {
1286 this.beginPath();
1287 this.lineTo(x, y + r);
1288 this.lineTo(x + r, y);
1289 this.lineTo(x, y - r);
1290 this.lineTo(x - r, y);
1291 this.closePath();
1292 };
1293
1294 CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
1295 var r2d = Math.PI / 180;
1296
1297 if (w - 2 * r < 0) {
1298 r = w / 2;
1299 } //ensure that the radius isn't too large for x
1300
1301
1302 if (h - 2 * r < 0) {
1303 r = h / 2;
1304 } //ensure that the radius isn't too large for y
1305
1306
1307 this.beginPath();
1308 this.moveTo(x + r, y);
1309 this.lineTo(x + w - r, y);
1310 this.arc(x + w - r, y + r, r, r2d * 270, r2d * 360, false);
1311 this.lineTo(x + w, y + h - r);
1312 this.arc(x + w - r, y + h - r, r, 0, r2d * 90, false);
1313 this.lineTo(x + r, y + h);
1314 this.arc(x + r, y + h - r, r, r2d * 90, r2d * 180, false);
1315 this.lineTo(x, y + r);
1316 this.arc(x + r, y + r, r, r2d * 180, r2d * 270, false);
1317 this.closePath();
1318 };
1319
1320 CanvasRenderingContext2D.prototype.ellipse_vis = function (x, y, w, h) {
1321 var kappa = 0.5522848,
1322 ox = w / 2 * kappa,
1323 // control point offset horizontal
1324 oy = h / 2 * kappa,
1325 // control point offset vertical
1326 xe = x + w,
1327 // x-end
1328 ye = y + h,
1329 // y-end
1330 xm = x + w / 2,
1331 // x-middle
1332 ym = y + h / 2; // y-middle
1333
1334 this.beginPath();
1335 this.moveTo(x, ym);
1336 this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
1337 this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
1338 this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
1339 this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
1340 this.closePath();
1341 };
1342
1343 CanvasRenderingContext2D.prototype.database = function (x, y, w, h) {
1344 var f = 1 / 3;
1345 var wEllipse = w;
1346 var hEllipse = h * f;
1347 var kappa = 0.5522848,
1348 ox = wEllipse / 2 * kappa,
1349 // control point offset horizontal
1350 oy = hEllipse / 2 * kappa,
1351 // control point offset vertical
1352 xe = x + wEllipse,
1353 // x-end
1354 ye = y + hEllipse,
1355 // y-end
1356 xm = x + wEllipse / 2,
1357 // x-middle
1358 ym = y + hEllipse / 2,
1359 // y-middle
1360 ymb = y + (h - hEllipse / 2),
1361 // y-midlle, bottom ellipse
1362 yeb = y + h; // y-end, bottom ellipse
1363
1364 this.beginPath();
1365 this.moveTo(xe, ym);
1366 this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
1367 this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
1368 this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
1369 this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
1370 this.lineTo(xe, ymb);
1371 this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb);
1372 this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb);
1373 this.lineTo(x, ym);
1374 };
1375
1376 CanvasRenderingContext2D.prototype.dashedLine = function (x, y, x2, y2, pattern) {
1377 this.beginPath();
1378 this.moveTo(x, y);
1379 var patternLength = pattern.length;
1380 var dx = x2 - x;
1381 var dy = y2 - y;
1382 var slope = dy / dx;
1383 var distRemaining = Math.sqrt(dx * dx + dy * dy);
1384 var patternIndex = 0;
1385 var draw = true;
1386 var xStep = 0;
1387 var dashLength = +pattern[0];
1388
1389 while (distRemaining >= 0.1) {
1390 dashLength = +pattern[patternIndex++ % patternLength];
1391
1392 if (dashLength > distRemaining) {
1393 dashLength = distRemaining;
1394 }
1395
1396 xStep = Math.sqrt(dashLength * dashLength / (1 + slope * slope));
1397 xStep = dx < 0 ? -xStep : xStep;
1398 x += xStep;
1399 y += slope * xStep;
1400
1401 if (draw === true) {
1402 this.lineTo(x, y);
1403 } else {
1404 this.moveTo(x, y);
1405 }
1406
1407 distRemaining -= dashLength;
1408 draw = !draw;
1409 }
1410 };
1411
1412 CanvasRenderingContext2D.prototype.hexagon = function (x, y, r) {
1413 this.beginPath();
1414 var sides = 6;
1415 var a = Math.PI * 2 / sides;
1416 this.moveTo(x + r, y);
1417
1418 for (var i = 1; i < sides; i++) {
1419 this.lineTo(x + r * Math.cos(a * i), y + r * Math.sin(a * i));
1420 }
1421
1422 this.closePath();
1423 };
1424 }
1425
1426 // `IsArray` abstract operation
1427 // https://tc39.github.io/ecma262/#sec-isarray
1428 var isArray = Array.isArray || function isArray(arg) {
1429 return classofRaw(arg) == 'Array';
1430 };
1431
1432 var createProperty = function (object, key, value) {
1433 var propertyKey = toPrimitive(key);
1434 if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
1435 else object[propertyKey] = value;
1436 };
1437
1438 var userAgent = getBuiltIn('navigator', 'userAgent') || '';
1439
1440 var process = global_1.process;
1441 var versions = process && process.versions;
1442 var v8 = versions && versions.v8;
1443 var match, version;
1444
1445 if (v8) {
1446 match = v8.split('.');
1447 version = match[0] + match[1];
1448 } else if (userAgent) {
1449 match = userAgent.match(/Chrome\/(\d+)/);
1450 if (match) version = match[1];
1451 }
1452
1453 var v8Version = version && +version;
1454
1455 var SPECIES$1 = wellKnownSymbol('species');
1456
1457 var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
1458 // We can't use this feature detection in V8 since it causes
1459 // deoptimization and serious performance degradation
1460 // https://github.com/zloirock/core-js/issues/677
1461 return v8Version >= 51 || !fails(function () {
1462 var array = [];
1463 var constructor = array.constructor = {};
1464 constructor[SPECIES$1] = function () {
1465 return { foo: 1 };
1466 };
1467 return array[METHOD_NAME](Boolean).foo !== 1;
1468 });
1469 };
1470
1471 var SPECIES$2 = wellKnownSymbol('species');
1472 var nativeSlice = [].slice;
1473 var max$1 = Math.max;
1474
1475 // `Array.prototype.slice` method
1476 // https://tc39.github.io/ecma262/#sec-array.prototype.slice
1477 // fallback for not array-like ES3 strings and DOM objects
1478 _export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('slice') }, {
1479 slice: function slice(start, end) {
1480 var O = toIndexedObject(this);
1481 var length = toLength(O.length);
1482 var k = toAbsoluteIndex(start, length);
1483 var fin = toAbsoluteIndex(end === undefined ? length : end, length);
1484 // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
1485 var Constructor, result, n;
1486 if (isArray(O)) {
1487 Constructor = O.constructor;
1488 // cross-realm fallback
1489 if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
1490 Constructor = undefined;
1491 } else if (isObject(Constructor)) {
1492 Constructor = Constructor[SPECIES$2];
1493 if (Constructor === null) Constructor = undefined;
1494 }
1495 if (Constructor === Array || Constructor === undefined) {
1496 return nativeSlice.call(O, k, fin);
1497 }
1498 }
1499 result = new (Constructor === undefined ? Array : Constructor)(max$1(fin - k, 0));
1500 for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
1501 result.length = n;
1502 return result;
1503 }
1504 });
1505
1506 var SPECIES$3 = wellKnownSymbol('species');
1507
1508 // `ArraySpeciesCreate` abstract operation
1509 // https://tc39.github.io/ecma262/#sec-arrayspeciescreate
1510 var arraySpeciesCreate = function (originalArray, length) {
1511 var C;
1512 if (isArray(originalArray)) {
1513 C = originalArray.constructor;
1514 // cross-realm fallback
1515 if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
1516 else if (isObject(C)) {
1517 C = C[SPECIES$3];
1518 if (C === null) C = undefined;
1519 }
1520 } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
1521 };
1522
1523 var max$2 = Math.max;
1524 var min$2 = Math.min;
1525 var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
1526 var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
1527
1528 // `Array.prototype.splice` method
1529 // https://tc39.github.io/ecma262/#sec-array.prototype.splice
1530 // with adding support of @@species
1531 _export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('splice') }, {
1532 splice: function splice(start, deleteCount /* , ...items */) {
1533 var O = toObject(this);
1534 var len = toLength(O.length);
1535 var actualStart = toAbsoluteIndex(start, len);
1536 var argumentsLength = arguments.length;
1537 var insertCount, actualDeleteCount, A, k, from, to;
1538 if (argumentsLength === 0) {
1539 insertCount = actualDeleteCount = 0;
1540 } else if (argumentsLength === 1) {
1541 insertCount = 0;
1542 actualDeleteCount = len - actualStart;
1543 } else {
1544 insertCount = argumentsLength - 2;
1545 actualDeleteCount = min$2(max$2(toInteger(deleteCount), 0), len - actualStart);
1546 }
1547 if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
1548 throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
1549 }
1550 A = arraySpeciesCreate(O, actualDeleteCount);
1551 for (k = 0; k < actualDeleteCount; k++) {
1552 from = actualStart + k;
1553 if (from in O) createProperty(A, k, O[from]);
1554 }
1555 A.length = actualDeleteCount;
1556 if (insertCount < actualDeleteCount) {
1557 for (k = actualStart; k < len - actualDeleteCount; k++) {
1558 from = k + actualDeleteCount;
1559 to = k + insertCount;
1560 if (from in O) O[to] = O[from];
1561 else delete O[to];
1562 }
1563 for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
1564 } else if (insertCount > actualDeleteCount) {
1565 for (k = len - actualDeleteCount; k > actualStart; k--) {
1566 from = k + actualDeleteCount - 1;
1567 to = k + insertCount - 1;
1568 if (from in O) O[to] = O[from];
1569 else delete O[to];
1570 }
1571 }
1572 for (k = 0; k < insertCount; k++) {
1573 O[k + actualStart] = arguments[k + 2];
1574 }
1575 O.length = len - actualDeleteCount + insertCount;
1576 return A;
1577 }
1578 });
1579
1580 var componentEmitter = createCommonjsModule(function (module) {
1581 /**
1582 * Expose `Emitter`.
1583 */
1584 {
1585 module.exports = Emitter;
1586 }
1587 /**
1588 * Initialize a new `Emitter`.
1589 *
1590 * @api public
1591 */
1592
1593
1594 function Emitter(obj) {
1595 if (obj) return mixin(obj);
1596 }
1597 /**
1598 * Mixin the emitter properties.
1599 *
1600 * @param {Object} obj
1601 * @return {Object}
1602 * @api private
1603 */
1604
1605 function mixin(obj) {
1606 for (var key in Emitter.prototype) {
1607 obj[key] = Emitter.prototype[key];
1608 }
1609
1610 return obj;
1611 }
1612 /**
1613 * Listen on the given `event` with `fn`.
1614 *
1615 * @param {String} event
1616 * @param {Function} fn
1617 * @return {Emitter}
1618 * @api public
1619 */
1620
1621
1622 Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
1623 this._callbacks = this._callbacks || {};
1624 (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);
1625 return this;
1626 };
1627 /**
1628 * Adds an `event` listener that will be invoked a single
1629 * time then automatically removed.
1630 *
1631 * @param {String} event
1632 * @param {Function} fn
1633 * @return {Emitter}
1634 * @api public
1635 */
1636
1637
1638 Emitter.prototype.once = function (event, fn) {
1639 function on() {
1640 this.off(event, on);
1641 fn.apply(this, arguments);
1642 }
1643
1644 on.fn = fn;
1645 this.on(event, on);
1646 return this;
1647 };
1648 /**
1649 * Remove the given callback for `event` or all
1650 * registered callbacks.
1651 *
1652 * @param {String} event
1653 * @param {Function} fn
1654 * @return {Emitter}
1655 * @api public
1656 */
1657
1658
1659 Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
1660 this._callbacks = this._callbacks || {}; // all
1661
1662 if (0 == arguments.length) {
1663 this._callbacks = {};
1664 return this;
1665 } // specific event
1666
1667
1668 var callbacks = this._callbacks['$' + event];
1669 if (!callbacks) return this; // remove all handlers
1670
1671 if (1 == arguments.length) {
1672 delete this._callbacks['$' + event];
1673 return this;
1674 } // remove specific handler
1675
1676
1677 var cb;
1678
1679 for (var i = 0; i < callbacks.length; i++) {
1680 cb = callbacks[i];
1681
1682 if (cb === fn || cb.fn === fn) {
1683 callbacks.splice(i, 1);
1684 break;
1685 }
1686 } // Remove event specific arrays for event types that no
1687 // one is subscribed for to avoid memory leak.
1688
1689
1690 if (callbacks.length === 0) {
1691 delete this._callbacks['$' + event];
1692 }
1693
1694 return this;
1695 };
1696 /**
1697 * Emit `event` with the given args.
1698 *
1699 * @param {String} event
1700 * @param {Mixed} ...
1701 * @return {Emitter}
1702 */
1703
1704
1705 Emitter.prototype.emit = function (event) {
1706 this._callbacks = this._callbacks || {};
1707 var args = new Array(arguments.length - 1),
1708 callbacks = this._callbacks['$' + event];
1709
1710 for (var i = 1; i < arguments.length; i++) {
1711 args[i - 1] = arguments[i];
1712 }
1713
1714 if (callbacks) {
1715 callbacks = callbacks.slice(0);
1716
1717 for (var i = 0, len = callbacks.length; i < len; ++i) {
1718 callbacks[i].apply(this, args);
1719 }
1720 }
1721
1722 return this;
1723 };
1724 /**
1725 * Return array of callbacks for `event`.
1726 *
1727 * @param {String} event
1728 * @return {Array}
1729 * @api public
1730 */
1731
1732
1733 Emitter.prototype.listeners = function (event) {
1734 this._callbacks = this._callbacks || {};
1735 return this._callbacks['$' + event] || [];
1736 };
1737 /**
1738 * Check if this emitter has `event` handlers.
1739 *
1740 * @param {String} event
1741 * @return {Boolean}
1742 * @api public
1743 */
1744
1745
1746 Emitter.prototype.hasListeners = function (event) {
1747 return !!this.listeners(event).length;
1748 };
1749 });
1750
1751 // `Object.keys` method
1752 // https://tc39.github.io/ecma262/#sec-object.keys
1753 var objectKeys = Object.keys || function keys(O) {
1754 return objectKeysInternal(O, enumBugKeys);
1755 };
1756
1757 // `Object.defineProperties` method
1758 // https://tc39.github.io/ecma262/#sec-object.defineproperties
1759 var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
1760 anObject(O);
1761 var keys = objectKeys(Properties);
1762 var length = keys.length;
1763 var index = 0;
1764 var key;
1765 while (length > index) objectDefineProperty.f(O, key = keys[index++], Properties[key]);
1766 return O;
1767 };
1768
1769 var html = getBuiltIn('document', 'documentElement');
1770
1771 var IE_PROTO$1 = sharedKey('IE_PROTO');
1772
1773 var PROTOTYPE$1 = 'prototype';
1774 var Empty = function () { /* empty */ };
1775
1776 // Create object with fake `null` prototype: use iframe Object with cleared prototype
1777 var createDict = function () {
1778 // Thrash, waste and sodomy: IE GC bug
1779 var iframe = documentCreateElement('iframe');
1780 var length = enumBugKeys.length;
1781 var lt = '<';
1782 var script = 'script';
1783 var gt = '>';
1784 var js = 'java' + script + ':';
1785 var iframeDocument;
1786 iframe.style.display = 'none';
1787 html.appendChild(iframe);
1788 iframe.src = String(js);
1789 iframeDocument = iframe.contentWindow.document;
1790 iframeDocument.open();
1791 iframeDocument.write(lt + script + gt + 'document.F=Object' + lt + '/' + script + gt);
1792 iframeDocument.close();
1793 createDict = iframeDocument.F;
1794 while (length--) delete createDict[PROTOTYPE$1][enumBugKeys[length]];
1795 return createDict();
1796 };
1797
1798 // `Object.create` method
1799 // https://tc39.github.io/ecma262/#sec-object.create
1800 var objectCreate = Object.create || function create(O, Properties) {
1801 var result;
1802 if (O !== null) {
1803 Empty[PROTOTYPE$1] = anObject(O);
1804 result = new Empty();
1805 Empty[PROTOTYPE$1] = null;
1806 // add "__proto__" for Object.getPrototypeOf polyfill
1807 result[IE_PROTO$1] = O;
1808 } else result = createDict();
1809 return Properties === undefined ? result : objectDefineProperties(result, Properties);
1810 };
1811
1812 hiddenKeys[IE_PROTO$1] = true;
1813
1814 var nativeGetOwnPropertyNames = objectGetOwnPropertyNames.f;
1815
1816 var toString$1 = {}.toString;
1817
1818 var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
1819 ? Object.getOwnPropertyNames(window) : [];
1820
1821 var getWindowNames = function (it) {
1822 try {
1823 return nativeGetOwnPropertyNames(it);
1824 } catch (error) {
1825 return windowNames.slice();
1826 }
1827 };
1828
1829 // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
1830 var f$5 = function getOwnPropertyNames(it) {
1831 return windowNames && toString$1.call(it) == '[object Window]'
1832 ? getWindowNames(it)
1833 : nativeGetOwnPropertyNames(toIndexedObject(it));
1834 };
1835
1836 var objectGetOwnPropertyNamesExternal = {
1837 f: f$5
1838 };
1839
1840 var f$6 = wellKnownSymbol;
1841
1842 var wrappedWellKnownSymbol = {
1843 f: f$6
1844 };
1845
1846 var defineProperty$3 = objectDefineProperty.f;
1847
1848 var defineWellKnownSymbol = function (NAME) {
1849 var Symbol = path.Symbol || (path.Symbol = {});
1850 if (!has(Symbol, NAME)) defineProperty$3(Symbol, NAME, {
1851 value: wrappedWellKnownSymbol.f(NAME)
1852 });
1853 };
1854
1855 // optional / simple context binding
1856 var bindContext = function (fn, that, length) {
1857 aFunction$1(fn);
1858 if (that === undefined) return fn;
1859 switch (length) {
1860 case 0: return function () {
1861 return fn.call(that);
1862 };
1863 case 1: return function (a) {
1864 return fn.call(that, a);
1865 };
1866 case 2: return function (a, b) {
1867 return fn.call(that, a, b);
1868 };
1869 case 3: return function (a, b, c) {
1870 return fn.call(that, a, b, c);
1871 };
1872 }
1873 return function (/* ...args */) {
1874 return fn.apply(that, arguments);
1875 };
1876 };
1877
1878 var push = [].push;
1879
1880 // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex }` methods implementation
1881 var createMethod$1 = function (TYPE) {
1882 var IS_MAP = TYPE == 1;
1883 var IS_FILTER = TYPE == 2;
1884 var IS_SOME = TYPE == 3;
1885 var IS_EVERY = TYPE == 4;
1886 var IS_FIND_INDEX = TYPE == 6;
1887 var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
1888 return function ($this, callbackfn, that, specificCreate) {
1889 var O = toObject($this);
1890 var self = indexedObject(O);
1891 var boundFunction = bindContext(callbackfn, that, 3);
1892 var length = toLength(self.length);
1893 var index = 0;
1894 var create = specificCreate || arraySpeciesCreate;
1895 var target = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
1896 var value, result;
1897 for (;length > index; index++) if (NO_HOLES || index in self) {
1898 value = self[index];
1899 result = boundFunction(value, index, O);
1900 if (TYPE) {
1901 if (IS_MAP) target[index] = result; // map
1902 else if (result) switch (TYPE) {
1903 case 3: return true; // some
1904 case 5: return value; // find
1905 case 6: return index; // findIndex
1906 case 2: push.call(target, value); // filter
1907 } else if (IS_EVERY) return false; // every
1908 }
1909 }
1910 return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
1911 };
1912 };
1913
1914 var arrayIteration = {
1915 // `Array.prototype.forEach` method
1916 // https://tc39.github.io/ecma262/#sec-array.prototype.foreach
1917 forEach: createMethod$1(0),
1918 // `Array.prototype.map` method
1919 // https://tc39.github.io/ecma262/#sec-array.prototype.map
1920 map: createMethod$1(1),
1921 // `Array.prototype.filter` method
1922 // https://tc39.github.io/ecma262/#sec-array.prototype.filter
1923 filter: createMethod$1(2),
1924 // `Array.prototype.some` method
1925 // https://tc39.github.io/ecma262/#sec-array.prototype.some
1926 some: createMethod$1(3),
1927 // `Array.prototype.every` method
1928 // https://tc39.github.io/ecma262/#sec-array.prototype.every
1929 every: createMethod$1(4),
1930 // `Array.prototype.find` method
1931 // https://tc39.github.io/ecma262/#sec-array.prototype.find
1932 find: createMethod$1(5),
1933 // `Array.prototype.findIndex` method
1934 // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
1935 findIndex: createMethod$1(6)
1936 };
1937
1938 var $forEach = arrayIteration.forEach;
1939
1940 var HIDDEN = sharedKey('hidden');
1941 var SYMBOL = 'Symbol';
1942 var PROTOTYPE$2 = 'prototype';
1943 var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
1944 var setInternalState$1 = internalState.set;
1945 var getInternalState$1 = internalState.getterFor(SYMBOL);
1946 var ObjectPrototype$3 = Object[PROTOTYPE$2];
1947 var $Symbol = global_1.Symbol;
1948 var JSON$1 = global_1.JSON;
1949 var nativeJSONStringify = JSON$1 && JSON$1.stringify;
1950 var nativeGetOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
1951 var nativeDefineProperty$1 = objectDefineProperty.f;
1952 var nativeGetOwnPropertyNames$1 = objectGetOwnPropertyNamesExternal.f;
1953 var nativePropertyIsEnumerable$1 = objectPropertyIsEnumerable.f;
1954 var AllSymbols = shared('symbols');
1955 var ObjectPrototypeSymbols = shared('op-symbols');
1956 var StringToSymbolRegistry = shared('string-to-symbol-registry');
1957 var SymbolToStringRegistry = shared('symbol-to-string-registry');
1958 var WellKnownSymbolsStore = shared('wks');
1959 var QObject = global_1.QObject;
1960 // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
1961 var USE_SETTER = !QObject || !QObject[PROTOTYPE$2] || !QObject[PROTOTYPE$2].findChild;
1962
1963 // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
1964 var setSymbolDescriptor = descriptors && fails(function () {
1965 return objectCreate(nativeDefineProperty$1({}, 'a', {
1966 get: function () { return nativeDefineProperty$1(this, 'a', { value: 7 }).a; }
1967 })).a != 7;
1968 }) ? function (O, P, Attributes) {
1969 var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor$1(ObjectPrototype$3, P);
1970 if (ObjectPrototypeDescriptor) delete ObjectPrototype$3[P];
1971 nativeDefineProperty$1(O, P, Attributes);
1972 if (ObjectPrototypeDescriptor && O !== ObjectPrototype$3) {
1973 nativeDefineProperty$1(ObjectPrototype$3, P, ObjectPrototypeDescriptor);
1974 }
1975 } : nativeDefineProperty$1;
1976
1977 var wrap = function (tag, description) {
1978 var symbol = AllSymbols[tag] = objectCreate($Symbol[PROTOTYPE$2]);
1979 setInternalState$1(symbol, {
1980 type: SYMBOL,
1981 tag: tag,
1982 description: description
1983 });
1984 if (!descriptors) symbol.description = description;
1985 return symbol;
1986 };
1987
1988 var isSymbol = nativeSymbol && typeof $Symbol.iterator == 'symbol' ? function (it) {
1989 return typeof it == 'symbol';
1990 } : function (it) {
1991 return Object(it) instanceof $Symbol;
1992 };
1993
1994 var $defineProperty = function defineProperty(O, P, Attributes) {
1995 if (O === ObjectPrototype$3) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
1996 anObject(O);
1997 var key = toPrimitive(P, true);
1998 anObject(Attributes);
1999 if (has(AllSymbols, key)) {
2000 if (!Attributes.enumerable) {
2001 if (!has(O, HIDDEN)) nativeDefineProperty$1(O, HIDDEN, createPropertyDescriptor(1, {}));
2002 O[HIDDEN][key] = true;
2003 } else {
2004 if (has(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
2005 Attributes = objectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });
2006 } return setSymbolDescriptor(O, key, Attributes);
2007 } return nativeDefineProperty$1(O, key, Attributes);
2008 };
2009
2010 var $defineProperties = function defineProperties(O, Properties) {
2011 anObject(O);
2012 var properties = toIndexedObject(Properties);
2013 var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));
2014 $forEach(keys, function (key) {
2015 if (!descriptors || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]);
2016 });
2017 return O;
2018 };
2019
2020 var $create = function create(O, Properties) {
2021 return Properties === undefined ? objectCreate(O) : $defineProperties(objectCreate(O), Properties);
2022 };
2023
2024 var $propertyIsEnumerable = function propertyIsEnumerable(V) {
2025 var P = toPrimitive(V, true);
2026 var enumerable = nativePropertyIsEnumerable$1.call(this, P);
2027 if (this === ObjectPrototype$3 && has(AllSymbols, P) && !has(ObjectPrototypeSymbols, P)) return false;
2028 return enumerable || !has(this, P) || !has(AllSymbols, P) || has(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true;
2029 };
2030
2031 var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
2032 var it = toIndexedObject(O);
2033 var key = toPrimitive(P, true);
2034 if (it === ObjectPrototype$3 && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return;
2035 var descriptor = nativeGetOwnPropertyDescriptor$1(it, key);
2036 if (descriptor && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) {
2037 descriptor.enumerable = true;
2038 }
2039 return descriptor;
2040 };
2041
2042 var $getOwnPropertyNames = function getOwnPropertyNames(O) {
2043 var names = nativeGetOwnPropertyNames$1(toIndexedObject(O));
2044 var result = [];
2045 $forEach(names, function (key) {
2046 if (!has(AllSymbols, key) && !has(hiddenKeys, key)) result.push(key);
2047 });
2048 return result;
2049 };
2050
2051 var $getOwnPropertySymbols = function getOwnPropertySymbols(O) {
2052 var IS_OBJECT_PROTOTYPE = O === ObjectPrototype$3;
2053 var names = nativeGetOwnPropertyNames$1(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
2054 var result = [];
2055 $forEach(names, function (key) {
2056 if (has(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has(ObjectPrototype$3, key))) {
2057 result.push(AllSymbols[key]);
2058 }
2059 });
2060 return result;
2061 };
2062
2063 // `Symbol` constructor
2064 // https://tc39.github.io/ecma262/#sec-symbol-constructor
2065 if (!nativeSymbol) {
2066 $Symbol = function Symbol() {
2067 if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
2068 var description = !arguments.length || arguments[0] === undefined ? undefined : String(arguments[0]);
2069 var tag = uid(description);
2070 var setter = function (value) {
2071 if (this === ObjectPrototype$3) setter.call(ObjectPrototypeSymbols, value);
2072 if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
2073 setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
2074 };
2075 if (descriptors && USE_SETTER) setSymbolDescriptor(ObjectPrototype$3, tag, { configurable: true, set: setter });
2076 return wrap(tag, description);
2077 };
2078
2079 redefine($Symbol[PROTOTYPE$2], 'toString', function toString() {
2080 return getInternalState$1(this).tag;
2081 });
2082
2083 objectPropertyIsEnumerable.f = $propertyIsEnumerable;
2084 objectDefineProperty.f = $defineProperty;
2085 objectGetOwnPropertyDescriptor.f = $getOwnPropertyDescriptor;
2086 objectGetOwnPropertyNames.f = objectGetOwnPropertyNamesExternal.f = $getOwnPropertyNames;
2087 objectGetOwnPropertySymbols.f = $getOwnPropertySymbols;
2088
2089 if (descriptors) {
2090 // https://github.com/tc39/proposal-Symbol-description
2091 nativeDefineProperty$1($Symbol[PROTOTYPE$2], 'description', {
2092 configurable: true,
2093 get: function description() {
2094 return getInternalState$1(this).description;
2095 }
2096 });
2097 {
2098 redefine(ObjectPrototype$3, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });
2099 }
2100 }
2101
2102 wrappedWellKnownSymbol.f = function (name) {
2103 return wrap(wellKnownSymbol(name), name);
2104 };
2105 }
2106
2107 _export({ global: true, wrap: true, forced: !nativeSymbol, sham: !nativeSymbol }, {
2108 Symbol: $Symbol
2109 });
2110
2111 $forEach(objectKeys(WellKnownSymbolsStore), function (name) {
2112 defineWellKnownSymbol(name);
2113 });
2114
2115 _export({ target: SYMBOL, stat: true, forced: !nativeSymbol }, {
2116 // `Symbol.for` method
2117 // https://tc39.github.io/ecma262/#sec-symbol.for
2118 'for': function (key) {
2119 var string = String(key);
2120 if (has(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
2121 var symbol = $Symbol(string);
2122 StringToSymbolRegistry[string] = symbol;
2123 SymbolToStringRegistry[symbol] = string;
2124 return symbol;
2125 },
2126 // `Symbol.keyFor` method
2127 // https://tc39.github.io/ecma262/#sec-symbol.keyfor
2128 keyFor: function keyFor(sym) {
2129 if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
2130 if (has(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
2131 },
2132 useSetter: function () { USE_SETTER = true; },
2133 useSimple: function () { USE_SETTER = false; }
2134 });
2135
2136 _export({ target: 'Object', stat: true, forced: !nativeSymbol, sham: !descriptors }, {
2137 // `Object.create` method
2138 // https://tc39.github.io/ecma262/#sec-object.create
2139 create: $create,
2140 // `Object.defineProperty` method
2141 // https://tc39.github.io/ecma262/#sec-object.defineproperty
2142 defineProperty: $defineProperty,
2143 // `Object.defineProperties` method
2144 // https://tc39.github.io/ecma262/#sec-object.defineproperties
2145 defineProperties: $defineProperties,
2146 // `Object.getOwnPropertyDescriptor` method
2147 // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
2148 getOwnPropertyDescriptor: $getOwnPropertyDescriptor
2149 });
2150
2151 _export({ target: 'Object', stat: true, forced: !nativeSymbol }, {
2152 // `Object.getOwnPropertyNames` method
2153 // https://tc39.github.io/ecma262/#sec-object.getownpropertynames
2154 getOwnPropertyNames: $getOwnPropertyNames,
2155 // `Object.getOwnPropertySymbols` method
2156 // https://tc39.github.io/ecma262/#sec-object.getownpropertysymbols
2157 getOwnPropertySymbols: $getOwnPropertySymbols
2158 });
2159
2160 // Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
2161 // https://bugs.chromium.org/p/v8/issues/detail?id=3443
2162 _export({ target: 'Object', stat: true, forced: fails(function () { objectGetOwnPropertySymbols.f(1); }) }, {
2163 getOwnPropertySymbols: function getOwnPropertySymbols(it) {
2164 return objectGetOwnPropertySymbols.f(toObject(it));
2165 }
2166 });
2167
2168 // `JSON.stringify` method behavior with symbols
2169 // https://tc39.github.io/ecma262/#sec-json.stringify
2170 JSON$1 && _export({ target: 'JSON', stat: true, forced: !nativeSymbol || fails(function () {
2171 var symbol = $Symbol();
2172 // MS Edge converts symbol values to JSON as {}
2173 return nativeJSONStringify([symbol]) != '[null]'
2174 // WebKit converts symbol values to JSON as null
2175 || nativeJSONStringify({ a: symbol }) != '{}'
2176 // V8 throws on boxed symbols
2177 || nativeJSONStringify(Object(symbol)) != '{}';
2178 }) }, {
2179 stringify: function stringify(it) {
2180 var args = [it];
2181 var index = 1;
2182 var replacer, $replacer;
2183 while (arguments.length > index) args.push(arguments[index++]);
2184 $replacer = replacer = args[1];
2185 if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
2186 if (!isArray(replacer)) replacer = function (key, value) {
2187 if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
2188 if (!isSymbol(value)) return value;
2189 };
2190 args[1] = replacer;
2191 return nativeJSONStringify.apply(JSON$1, args);
2192 }
2193 });
2194
2195 // `Symbol.prototype[@@toPrimitive]` method
2196 // https://tc39.github.io/ecma262/#sec-symbol.prototype-@@toprimitive
2197 if (!$Symbol[PROTOTYPE$2][TO_PRIMITIVE]) {
2198 createNonEnumerableProperty($Symbol[PROTOTYPE$2], TO_PRIMITIVE, $Symbol[PROTOTYPE$2].valueOf);
2199 }
2200 // `Symbol.prototype[@@toStringTag]` property
2201 // https://tc39.github.io/ecma262/#sec-symbol.prototype-@@tostringtag
2202 setToStringTag($Symbol, SYMBOL);
2203
2204 hiddenKeys[HIDDEN] = true;
2205
2206 var defineProperty$4 = objectDefineProperty.f;
2207
2208
2209 var NativeSymbol = global_1.Symbol;
2210
2211 if (descriptors && typeof NativeSymbol == 'function' && (!('description' in NativeSymbol.prototype) ||
2212 // Safari 12 bug
2213 NativeSymbol().description !== undefined
2214 )) {
2215 var EmptyStringDescriptionStore = {};
2216 // wrap Symbol constructor for correct work with undefined description
2217 var SymbolWrapper = function Symbol() {
2218 var description = arguments.length < 1 || arguments[0] === undefined ? undefined : String(arguments[0]);
2219 var result = this instanceof SymbolWrapper
2220 ? new NativeSymbol(description)
2221 // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)'
2222 : description === undefined ? NativeSymbol() : NativeSymbol(description);
2223 if (description === '') EmptyStringDescriptionStore[result] = true;
2224 return result;
2225 };
2226 copyConstructorProperties(SymbolWrapper, NativeSymbol);
2227 var symbolPrototype = SymbolWrapper.prototype = NativeSymbol.prototype;
2228 symbolPrototype.constructor = SymbolWrapper;
2229
2230 var symbolToString = symbolPrototype.toString;
2231 var native = String(NativeSymbol('test')) == 'Symbol(test)';
2232 var regexp = /^Symbol\((.*)\)[^)]+$/;
2233 defineProperty$4(symbolPrototype, 'description', {
2234 configurable: true,
2235 get: function description() {
2236 var symbol = isObject(this) ? this.valueOf() : this;
2237 var string = symbolToString.call(symbol);
2238 if (has(EmptyStringDescriptionStore, symbol)) return '';
2239 var desc = native ? string.slice(7, -1) : string.replace(regexp, '$1');
2240 return desc === '' ? undefined : desc;
2241 }
2242 });
2243
2244 _export({ global: true, forced: true }, {
2245 Symbol: SymbolWrapper
2246 });
2247 }
2248
2249 // `Symbol.iterator` well-known symbol
2250 // https://tc39.github.io/ecma262/#sec-symbol.iterator
2251 defineWellKnownSymbol('iterator');
2252
2253 var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
2254 var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
2255 var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
2256
2257 var IS_CONCAT_SPREADABLE_SUPPORT = !fails(function () {
2258 var array = [];
2259 array[IS_CONCAT_SPREADABLE] = false;
2260 return array.concat()[0] !== array;
2261 });
2262
2263 var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
2264
2265 var isConcatSpreadable = function (O) {
2266 if (!isObject(O)) return false;
2267 var spreadable = O[IS_CONCAT_SPREADABLE];
2268 return spreadable !== undefined ? !!spreadable : isArray(O);
2269 };
2270
2271 var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
2272
2273 // `Array.prototype.concat` method
2274 // https://tc39.github.io/ecma262/#sec-array.prototype.concat
2275 // with adding support of @@isConcatSpreadable and @@species
2276 _export({ target: 'Array', proto: true, forced: FORCED }, {
2277 concat: function concat(arg) { // eslint-disable-line no-unused-vars
2278 var O = toObject(this);
2279 var A = arraySpeciesCreate(O, 0);
2280 var n = 0;
2281 var i, k, length, len, E;
2282 for (i = -1, length = arguments.length; i < length; i++) {
2283 E = i === -1 ? O : arguments[i];
2284 if (isConcatSpreadable(E)) {
2285 len = toLength(E.length);
2286 if (n + len > MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
2287 for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
2288 } else {
2289 if (n >= MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
2290 createProperty(A, n++, E);
2291 }
2292 }
2293 A.length = n;
2294 return A;
2295 }
2296 });
2297
2298 var $filter = arrayIteration.filter;
2299
2300
2301 // `Array.prototype.filter` method
2302 // https://tc39.github.io/ecma262/#sec-array.prototype.filter
2303 // with adding support of @@species
2304 _export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('filter') }, {
2305 filter: function filter(callbackfn /* , thisArg */) {
2306 return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
2307 }
2308 });
2309
2310 var sloppyArrayMethod = function (METHOD_NAME, argument) {
2311 var method = [][METHOD_NAME];
2312 return !method || !fails(function () {
2313 // eslint-disable-next-line no-useless-call,no-throw-literal
2314 method.call(null, argument || function () { throw 1; }, 1);
2315 });
2316 };
2317
2318 var $forEach$1 = arrayIteration.forEach;
2319
2320
2321 // `Array.prototype.forEach` method implementation
2322 // https://tc39.github.io/ecma262/#sec-array.prototype.foreach
2323 var arrayForEach = sloppyArrayMethod('forEach') ? function forEach(callbackfn /* , thisArg */) {
2324 return $forEach$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
2325 } : [].forEach;
2326
2327 // `Array.prototype.forEach` method
2328 // https://tc39.github.io/ecma262/#sec-array.prototype.foreach
2329 _export({ target: 'Array', proto: true, forced: [].forEach != arrayForEach }, {
2330 forEach: arrayForEach
2331 });
2332
2333 // call something on iterator step with safe closing on error
2334 var callWithSafeIterationClosing = function (iterator, fn, value, ENTRIES) {
2335 try {
2336 return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);
2337 // 7.4.6 IteratorClose(iterator, completion)
2338 } catch (error) {
2339 var returnMethod = iterator['return'];
2340 if (returnMethod !== undefined) anObject(returnMethod.call(iterator));
2341 throw error;
2342 }
2343 };
2344
2345 var iterators = {};
2346
2347 var ITERATOR = wellKnownSymbol('iterator');
2348 var ArrayPrototype = Array.prototype;
2349
2350 // check on default Array iterator
2351 var isArrayIteratorMethod = function (it) {
2352 return it !== undefined && (iterators.Array === it || ArrayPrototype[ITERATOR] === it);
2353 };
2354
2355 var ITERATOR$1 = wellKnownSymbol('iterator');
2356
2357 var getIteratorMethod = function (it) {
2358 if (it != undefined) return it[ITERATOR$1]
2359 || it['@@iterator']
2360 || iterators[classof(it)];
2361 };
2362
2363 // `Array.from` method implementation
2364 // https://tc39.github.io/ecma262/#sec-array.from
2365 var arrayFrom = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
2366 var O = toObject(arrayLike);
2367 var C = typeof this == 'function' ? this : Array;
2368 var argumentsLength = arguments.length;
2369 var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
2370 var mapping = mapfn !== undefined;
2371 var index = 0;
2372 var iteratorMethod = getIteratorMethod(O);
2373 var length, result, step, iterator, next;
2374 if (mapping) mapfn = bindContext(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2);
2375 // if the target is not iterable or it's an array with the default iterator - use a simple case
2376 if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) {
2377 iterator = iteratorMethod.call(O);
2378 next = iterator.next;
2379 result = new C();
2380 for (;!(step = next.call(iterator)).done; index++) {
2381 createProperty(result, index, mapping
2382 ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true)
2383 : step.value
2384 );
2385 }
2386 } else {
2387 length = toLength(O.length);
2388 result = new C(length);
2389 for (;length > index; index++) {
2390 createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
2391 }
2392 }
2393 result.length = index;
2394 return result;
2395 };
2396
2397 var ITERATOR$2 = wellKnownSymbol('iterator');
2398 var SAFE_CLOSING = false;
2399
2400 try {
2401 var called = 0;
2402 var iteratorWithReturn = {
2403 next: function () {
2404 return { done: !!called++ };
2405 },
2406 'return': function () {
2407 SAFE_CLOSING = true;
2408 }
2409 };
2410 iteratorWithReturn[ITERATOR$2] = function () {
2411 return this;
2412 };
2413 // eslint-disable-next-line no-throw-literal
2414 Array.from(iteratorWithReturn, function () { throw 2; });
2415 } catch (error) { /* empty */ }
2416
2417 var checkCorrectnessOfIteration = function (exec, SKIP_CLOSING) {
2418 if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
2419 var ITERATION_SUPPORT = false;
2420 try {
2421 var object = {};
2422 object[ITERATOR$2] = function () {
2423 return {
2424 next: function () {
2425 return { done: ITERATION_SUPPORT = true };
2426 }
2427 };
2428 };
2429 exec(object);
2430 } catch (error) { /* empty */ }
2431 return ITERATION_SUPPORT;
2432 };
2433
2434 var INCORRECT_ITERATION = !checkCorrectnessOfIteration(function (iterable) {
2435 Array.from(iterable);
2436 });
2437
2438 // `Array.from` method
2439 // https://tc39.github.io/ecma262/#sec-array.from
2440 _export({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, {
2441 from: arrayFrom
2442 });
2443
2444 var $indexOf = arrayIncludes.indexOf;
2445
2446
2447 var nativeIndexOf = [].indexOf;
2448
2449 var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
2450 var SLOPPY_METHOD = sloppyArrayMethod('indexOf');
2451
2452 // `Array.prototype.indexOf` method
2453 // https://tc39.github.io/ecma262/#sec-array.prototype.indexof
2454 _export({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || SLOPPY_METHOD }, {
2455 indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
2456 return NEGATIVE_ZERO
2457 // convert -0 to +0
2458 ? nativeIndexOf.apply(this, arguments) || 0
2459 : $indexOf(this, searchElement, arguments.length > 1 ? arguments[1] : undefined);
2460 }
2461 });
2462
2463 var UNSCOPABLES = wellKnownSymbol('unscopables');
2464 var ArrayPrototype$1 = Array.prototype;
2465
2466 // Array.prototype[@@unscopables]
2467 // https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
2468 if (ArrayPrototype$1[UNSCOPABLES] == undefined) {
2469 createNonEnumerableProperty(ArrayPrototype$1, UNSCOPABLES, objectCreate(null));
2470 }
2471
2472 // add a key to Array.prototype[@@unscopables]
2473 var addToUnscopables = function (key) {
2474 ArrayPrototype$1[UNSCOPABLES][key] = true;
2475 };
2476
2477 var ITERATOR$3 = wellKnownSymbol('iterator');
2478 var BUGGY_SAFARI_ITERATORS = false;
2479
2480 var returnThis = function () { return this; };
2481
2482 // `%IteratorPrototype%` object
2483 // https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object
2484 var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;
2485
2486 if ([].keys) {
2487 arrayIterator = [].keys();
2488 // Safari 8 has buggy iterators w/o `next`
2489 if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
2490 else {
2491 PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator));
2492 if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
2493 }
2494 }
2495
2496 if (IteratorPrototype == undefined) IteratorPrototype = {};
2497
2498 // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
2499 if ( !has(IteratorPrototype, ITERATOR$3)) {
2500 createNonEnumerableProperty(IteratorPrototype, ITERATOR$3, returnThis);
2501 }
2502
2503 var iteratorsCore = {
2504 IteratorPrototype: IteratorPrototype,
2505 BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
2506 };
2507
2508 var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
2509
2510
2511
2512
2513
2514 var returnThis$1 = function () { return this; };
2515
2516 var createIteratorConstructor = function (IteratorConstructor, NAME, next) {
2517 var TO_STRING_TAG = NAME + ' Iterator';
2518 IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, { next: createPropertyDescriptor(1, next) });
2519 setToStringTag(IteratorConstructor, TO_STRING_TAG, false);
2520 iterators[TO_STRING_TAG] = returnThis$1;
2521 return IteratorConstructor;
2522 };
2523
2524 var IteratorPrototype$2 = iteratorsCore.IteratorPrototype;
2525 var BUGGY_SAFARI_ITERATORS$1 = iteratorsCore.BUGGY_SAFARI_ITERATORS;
2526 var ITERATOR$4 = wellKnownSymbol('iterator');
2527 var KEYS = 'keys';
2528 var VALUES = 'values';
2529 var ENTRIES = 'entries';
2530
2531 var returnThis$2 = function () { return this; };
2532
2533 var defineIterator = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
2534 createIteratorConstructor(IteratorConstructor, NAME, next);
2535
2536 var getIterationMethod = function (KIND) {
2537 if (KIND === DEFAULT && defaultIterator) return defaultIterator;
2538 if (!BUGGY_SAFARI_ITERATORS$1 && KIND in IterablePrototype) return IterablePrototype[KIND];
2539 switch (KIND) {
2540 case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
2541 case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
2542 case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
2543 } return function () { return new IteratorConstructor(this); };
2544 };
2545
2546 var TO_STRING_TAG = NAME + ' Iterator';
2547 var INCORRECT_VALUES_NAME = false;
2548 var IterablePrototype = Iterable.prototype;
2549 var nativeIterator = IterablePrototype[ITERATOR$4]
2550 || IterablePrototype['@@iterator']
2551 || DEFAULT && IterablePrototype[DEFAULT];
2552 var defaultIterator = !BUGGY_SAFARI_ITERATORS$1 && nativeIterator || getIterationMethod(DEFAULT);
2553 var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
2554 var CurrentIteratorPrototype, methods, KEY;
2555
2556 // fix native
2557 if (anyNativeIterator) {
2558 CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable()));
2559 if (IteratorPrototype$2 !== Object.prototype && CurrentIteratorPrototype.next) {
2560 if ( objectGetPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype$2) {
2561 if (objectSetPrototypeOf) {
2562 objectSetPrototypeOf(CurrentIteratorPrototype, IteratorPrototype$2);
2563 } else if (typeof CurrentIteratorPrototype[ITERATOR$4] != 'function') {
2564 createNonEnumerableProperty(CurrentIteratorPrototype, ITERATOR$4, returnThis$2);
2565 }
2566 }
2567 // Set @@toStringTag to native iterators
2568 setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true);
2569 }
2570 }
2571
2572 // fix Array#{values, @@iterator}.name in V8 / FF
2573 if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
2574 INCORRECT_VALUES_NAME = true;
2575 defaultIterator = function values() { return nativeIterator.call(this); };
2576 }
2577
2578 // define iterator
2579 if ( IterablePrototype[ITERATOR$4] !== defaultIterator) {
2580 createNonEnumerableProperty(IterablePrototype, ITERATOR$4, defaultIterator);
2581 }
2582 iterators[NAME] = defaultIterator;
2583
2584 // export additional methods
2585 if (DEFAULT) {
2586 methods = {
2587 values: getIterationMethod(VALUES),
2588 keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
2589 entries: getIterationMethod(ENTRIES)
2590 };
2591 if (FORCED) for (KEY in methods) {
2592 if (BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
2593 redefine(IterablePrototype, KEY, methods[KEY]);
2594 }
2595 } else _export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME }, methods);
2596 }
2597
2598 return methods;
2599 };
2600
2601 var ARRAY_ITERATOR = 'Array Iterator';
2602 var setInternalState$2 = internalState.set;
2603 var getInternalState$2 = internalState.getterFor(ARRAY_ITERATOR);
2604
2605 // `Array.prototype.entries` method
2606 // https://tc39.github.io/ecma262/#sec-array.prototype.entries
2607 // `Array.prototype.keys` method
2608 // https://tc39.github.io/ecma262/#sec-array.prototype.keys
2609 // `Array.prototype.values` method
2610 // https://tc39.github.io/ecma262/#sec-array.prototype.values
2611 // `Array.prototype[@@iterator]` method
2612 // https://tc39.github.io/ecma262/#sec-array.prototype-@@iterator
2613 // `CreateArrayIterator` internal method
2614 // https://tc39.github.io/ecma262/#sec-createarrayiterator
2615 var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind) {
2616 setInternalState$2(this, {
2617 type: ARRAY_ITERATOR,
2618 target: toIndexedObject(iterated), // target
2619 index: 0, // next index
2620 kind: kind // kind
2621 });
2622 // `%ArrayIteratorPrototype%.next` method
2623 // https://tc39.github.io/ecma262/#sec-%arrayiteratorprototype%.next
2624 }, function () {
2625 var state = getInternalState$2(this);
2626 var target = state.target;
2627 var kind = state.kind;
2628 var index = state.index++;
2629 if (!target || index >= target.length) {
2630 state.target = undefined;
2631 return { value: undefined, done: true };
2632 }
2633 if (kind == 'keys') return { value: index, done: false };
2634 if (kind == 'values') return { value: target[index], done: false };
2635 return { value: [index, target[index]], done: false };
2636 }, 'values');
2637
2638 // argumentsList[@@iterator] is %ArrayProto_values%
2639 // https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
2640 // https://tc39.github.io/ecma262/#sec-createmappedargumentsobject
2641 iterators.Arguments = iterators.Array;
2642
2643 // https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
2644 addToUnscopables('keys');
2645 addToUnscopables('values');
2646 addToUnscopables('entries');
2647
2648 var nativeJoin = [].join;
2649
2650 var ES3_STRINGS = indexedObject != Object;
2651 var SLOPPY_METHOD$1 = sloppyArrayMethod('join', ',');
2652
2653 // `Array.prototype.join` method
2654 // https://tc39.github.io/ecma262/#sec-array.prototype.join
2655 _export({ target: 'Array', proto: true, forced: ES3_STRINGS || SLOPPY_METHOD$1 }, {
2656 join: function join(separator) {
2657 return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
2658 }
2659 });
2660
2661 var $map = arrayIteration.map;
2662
2663
2664 // `Array.prototype.map` method
2665 // https://tc39.github.io/ecma262/#sec-array.prototype.map
2666 // with adding support of @@species
2667 _export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('map') }, {
2668 map: function map(callbackfn /* , thisArg */) {
2669 return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
2670 }
2671 });
2672
2673 var $some = arrayIteration.some;
2674
2675
2676 // `Array.prototype.some` method
2677 // https://tc39.github.io/ecma262/#sec-array.prototype.some
2678 _export({ target: 'Array', proto: true, forced: sloppyArrayMethod('some') }, {
2679 some: function some(callbackfn /* , thisArg */) {
2680 return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
2681 }
2682 });
2683
2684 var nativeSort = [].sort;
2685 var test$1 = [1, 2, 3];
2686
2687 // IE8-
2688 var FAILS_ON_UNDEFINED = fails(function () {
2689 test$1.sort(undefined);
2690 });
2691 // V8 bug
2692 var FAILS_ON_NULL = fails(function () {
2693 test$1.sort(null);
2694 });
2695 // Old WebKit
2696 var SLOPPY_METHOD$2 = sloppyArrayMethod('sort');
2697
2698 var FORCED$1 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || SLOPPY_METHOD$2;
2699
2700 // `Array.prototype.sort` method
2701 // https://tc39.github.io/ecma262/#sec-array.prototype.sort
2702 _export({ target: 'Array', proto: true, forced: FORCED$1 }, {
2703 sort: function sort(comparefn) {
2704 return comparefn === undefined
2705 ? nativeSort.call(toObject(this))
2706 : nativeSort.call(toObject(this), aFunction$1(comparefn));
2707 }
2708 });
2709
2710 // `String.prototype.repeat` method implementation
2711 // https://tc39.github.io/ecma262/#sec-string.prototype.repeat
2712 var stringRepeat = ''.repeat || function repeat(count) {
2713 var str = String(requireObjectCoercible(this));
2714 var result = '';
2715 var n = toInteger(count);
2716 if (n < 0 || n == Infinity) throw RangeError('Wrong number of repetitions');
2717 for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str;
2718 return result;
2719 };
2720
2721 // https://github.com/tc39/proposal-string-pad-start-end
2722
2723
2724
2725
2726 var ceil$1 = Math.ceil;
2727
2728 // `String.prototype.{ padStart, padEnd }` methods implementation
2729 var createMethod$2 = function (IS_END) {
2730 return function ($this, maxLength, fillString) {
2731 var S = String(requireObjectCoercible($this));
2732 var stringLength = S.length;
2733 var fillStr = fillString === undefined ? ' ' : String(fillString);
2734 var intMaxLength = toLength(maxLength);
2735 var fillLen, stringFiller;
2736 if (intMaxLength <= stringLength || fillStr == '') return S;
2737 fillLen = intMaxLength - stringLength;
2738 stringFiller = stringRepeat.call(fillStr, ceil$1(fillLen / fillStr.length));
2739 if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);
2740 return IS_END ? S + stringFiller : stringFiller + S;
2741 };
2742 };
2743
2744 var stringPad = {
2745 // `String.prototype.padStart` method
2746 // https://tc39.github.io/ecma262/#sec-string.prototype.padstart
2747 start: createMethod$2(false),
2748 // `String.prototype.padEnd` method
2749 // https://tc39.github.io/ecma262/#sec-string.prototype.padend
2750 end: createMethod$2(true)
2751 };
2752
2753 var padStart = stringPad.start;
2754
2755 var abs$1 = Math.abs;
2756 var DatePrototype = Date.prototype;
2757 var getTime = DatePrototype.getTime;
2758 var nativeDateToISOString = DatePrototype.toISOString;
2759
2760 // `Date.prototype.toISOString` method implementation
2761 // https://tc39.github.io/ecma262/#sec-date.prototype.toisostring
2762 // PhantomJS / old WebKit fails here:
2763 var dateToIsoString = (fails(function () {
2764 return nativeDateToISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z';
2765 }) || !fails(function () {
2766 nativeDateToISOString.call(new Date(NaN));
2767 })) ? function toISOString() {
2768 if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value');
2769 var date = this;
2770 var year = date.getUTCFullYear();
2771 var milliseconds = date.getUTCMilliseconds();
2772 var sign = year < 0 ? '-' : year > 9999 ? '+' : '';
2773 return sign + padStart(abs$1(year), sign ? 6 : 4, 0) +
2774 '-' + padStart(date.getUTCMonth() + 1, 2, 0) +
2775 '-' + padStart(date.getUTCDate(), 2, 0) +
2776 'T' + padStart(date.getUTCHours(), 2, 0) +
2777 ':' + padStart(date.getUTCMinutes(), 2, 0) +
2778 ':' + padStart(date.getUTCSeconds(), 2, 0) +
2779 '.' + padStart(milliseconds, 3, 0) +
2780 'Z';
2781 } : nativeDateToISOString;
2782
2783 // `Date.prototype.toISOString` method
2784 // https://tc39.github.io/ecma262/#sec-date.prototype.toisostring
2785 // PhantomJS / old WebKit has a broken implementations
2786 _export({ target: 'Date', proto: true, forced: Date.prototype.toISOString !== dateToIsoString }, {
2787 toISOString: dateToIsoString
2788 });
2789
2790 var FORCED$2 = fails(function () {
2791 return new Date(NaN).toJSON() !== null
2792 || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1;
2793 });
2794
2795 // `Date.prototype.toJSON` method
2796 // https://tc39.github.io/ecma262/#sec-date.prototype.tojson
2797 _export({ target: 'Date', proto: true, forced: FORCED$2 }, {
2798 // eslint-disable-next-line no-unused-vars
2799 toJSON: function toJSON(key) {
2800 var O = toObject(this);
2801 var pv = toPrimitive(O);
2802 return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
2803 }
2804 });
2805
2806 var DatePrototype$1 = Date.prototype;
2807 var INVALID_DATE = 'Invalid Date';
2808 var TO_STRING = 'toString';
2809 var nativeDateToString = DatePrototype$1[TO_STRING];
2810 var getTime$1 = DatePrototype$1.getTime;
2811
2812 // `Date.prototype.toString` method
2813 // https://tc39.github.io/ecma262/#sec-date.prototype.tostring
2814 if (new Date(NaN) + '' != INVALID_DATE) {
2815 redefine(DatePrototype$1, TO_STRING, function toString() {
2816 var value = getTime$1.call(this);
2817 // eslint-disable-next-line no-self-compare
2818 return value === value ? nativeDateToString.call(this) : INVALID_DATE;
2819 });
2820 }
2821
2822 var defineProperty$5 = objectDefineProperty.f;
2823
2824 var FunctionPrototype = Function.prototype;
2825 var FunctionPrototypeToString = FunctionPrototype.toString;
2826 var nameRE = /^\s*function ([^ (]*)/;
2827 var NAME$1 = 'name';
2828
2829 // Function instances `.name` property
2830 // https://tc39.github.io/ecma262/#sec-function-instances-name
2831 if (descriptors && !(NAME$1 in FunctionPrototype)) {
2832 defineProperty$5(FunctionPrototype, NAME$1, {
2833 configurable: true,
2834 get: function () {
2835 try {
2836 return FunctionPrototypeToString.call(this).match(nameRE)[1];
2837 } catch (error) {
2838 return '';
2839 }
2840 }
2841 });
2842 }
2843
2844 // makes subclassing work correct for wrapped built-ins
2845 var inheritIfRequired = function ($this, dummy, Wrapper) {
2846 var NewTarget, NewTargetPrototype;
2847 if (
2848 // it can work only with native `setPrototypeOf`
2849 objectSetPrototypeOf &&
2850 // we haven't completely correct pre-ES6 way for getting `new.target`, so use this
2851 typeof (NewTarget = dummy.constructor) == 'function' &&
2852 NewTarget !== Wrapper &&
2853 isObject(NewTargetPrototype = NewTarget.prototype) &&
2854 NewTargetPrototype !== Wrapper.prototype
2855 ) objectSetPrototypeOf($this, NewTargetPrototype);
2856 return $this;
2857 };
2858
2859 // a string of all valid unicode whitespaces
2860 // eslint-disable-next-line max-len
2861 var whitespaces = '\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';
2862
2863 var whitespace = '[' + whitespaces + ']';
2864 var ltrim = RegExp('^' + whitespace + whitespace + '*');
2865 var rtrim = RegExp(whitespace + whitespace + '*$');
2866
2867 // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
2868 var createMethod$3 = function (TYPE) {
2869 return function ($this) {
2870 var string = String(requireObjectCoercible($this));
2871 if (TYPE & 1) string = string.replace(ltrim, '');
2872 if (TYPE & 2) string = string.replace(rtrim, '');
2873 return string;
2874 };
2875 };
2876
2877 var stringTrim = {
2878 // `String.prototype.{ trimLeft, trimStart }` methods
2879 // https://tc39.github.io/ecma262/#sec-string.prototype.trimstart
2880 start: createMethod$3(1),
2881 // `String.prototype.{ trimRight, trimEnd }` methods
2882 // https://tc39.github.io/ecma262/#sec-string.prototype.trimend
2883 end: createMethod$3(2),
2884 // `String.prototype.trim` method
2885 // https://tc39.github.io/ecma262/#sec-string.prototype.trim
2886 trim: createMethod$3(3)
2887 };
2888
2889 var getOwnPropertyNames$1 = objectGetOwnPropertyNames.f;
2890 var getOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f;
2891 var defineProperty$6 = objectDefineProperty.f;
2892 var trim = stringTrim.trim;
2893
2894 var NUMBER = 'Number';
2895 var NativeNumber = global_1[NUMBER];
2896 var NumberPrototype = NativeNumber.prototype;
2897
2898 // Opera ~12 has broken Object#toString
2899 var BROKEN_CLASSOF = classofRaw(objectCreate(NumberPrototype)) == NUMBER;
2900
2901 // `ToNumber` abstract operation
2902 // https://tc39.github.io/ecma262/#sec-tonumber
2903 var toNumber = function (argument) {
2904 var it = toPrimitive(argument, false);
2905 var first, third, radix, maxCode, digits, length, index, code;
2906 if (typeof it == 'string' && it.length > 2) {
2907 it = trim(it);
2908 first = it.charCodeAt(0);
2909 if (first === 43 || first === 45) {
2910 third = it.charCodeAt(2);
2911 if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
2912 } else if (first === 48) {
2913 switch (it.charCodeAt(1)) {
2914 case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i
2915 case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i
2916 default: return +it;
2917 }
2918 digits = it.slice(2);
2919 length = digits.length;
2920 for (index = 0; index < length; index++) {
2921 code = digits.charCodeAt(index);
2922 // parseInt parses a string to a first unavailable symbol
2923 // but ToNumber should return NaN if a string contains unavailable symbols
2924 if (code < 48 || code > maxCode) return NaN;
2925 } return parseInt(digits, radix);
2926 }
2927 } return +it;
2928 };
2929
2930 // `Number` constructor
2931 // https://tc39.github.io/ecma262/#sec-number-constructor
2932 if (isForced_1(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {
2933 var NumberWrapper = function Number(value) {
2934 var it = arguments.length < 1 ? 0 : value;
2935 var dummy = this;
2936 return dummy instanceof NumberWrapper
2937 // check on 1..constructor(foo) case
2938 && (BROKEN_CLASSOF ? fails(function () { NumberPrototype.valueOf.call(dummy); }) : classofRaw(dummy) != NUMBER)
2939 ? inheritIfRequired(new NativeNumber(toNumber(it)), dummy, NumberWrapper) : toNumber(it);
2940 };
2941 for (var keys$2 = descriptors ? getOwnPropertyNames$1(NativeNumber) : (
2942 // ES3:
2943 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
2944 // ES2015 (in case, if modules with ES2015 Number statics required before):
2945 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
2946 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
2947 ).split(','), j$1 = 0, key$1; keys$2.length > j$1; j$1++) {
2948 if (has(NativeNumber, key$1 = keys$2[j$1]) && !has(NumberWrapper, key$1)) {
2949 defineProperty$6(NumberWrapper, key$1, getOwnPropertyDescriptor$2(NativeNumber, key$1));
2950 }
2951 }
2952 NumberWrapper.prototype = NumberPrototype;
2953 NumberPrototype.constructor = NumberWrapper;
2954 redefine(global_1, NUMBER, NumberWrapper);
2955 }
2956
2957 // `thisNumberValue` abstract operation
2958 // https://tc39.github.io/ecma262/#sec-thisnumbervalue
2959 var thisNumberValue = function (value) {
2960 if (typeof value != 'number' && classofRaw(value) != 'Number') {
2961 throw TypeError('Incorrect invocation');
2962 }
2963 return +value;
2964 };
2965
2966 var nativeToFixed = 1.0.toFixed;
2967 var floor$2 = Math.floor;
2968
2969 var pow$1 = function (x, n, acc) {
2970 return n === 0 ? acc : n % 2 === 1 ? pow$1(x, n - 1, acc * x) : pow$1(x * x, n / 2, acc);
2971 };
2972
2973 var log$1 = function (x) {
2974 var n = 0;
2975 var x2 = x;
2976 while (x2 >= 4096) {
2977 n += 12;
2978 x2 /= 4096;
2979 }
2980 while (x2 >= 2) {
2981 n += 1;
2982 x2 /= 2;
2983 } return n;
2984 };
2985
2986 var FORCED$3 = nativeToFixed && (
2987 0.00008.toFixed(3) !== '0.000' ||
2988 0.9.toFixed(0) !== '1' ||
2989 1.255.toFixed(2) !== '1.25' ||
2990 1000000000000000128.0.toFixed(0) !== '1000000000000000128'
2991 ) || !fails(function () {
2992 // V8 ~ Android 4.3-
2993 nativeToFixed.call({});
2994 });
2995
2996 // `Number.prototype.toFixed` method
2997 // https://tc39.github.io/ecma262/#sec-number.prototype.tofixed
2998 _export({ target: 'Number', proto: true, forced: FORCED$3 }, {
2999 // eslint-disable-next-line max-statements
3000 toFixed: function toFixed(fractionDigits) {
3001 var number = thisNumberValue(this);
3002 var fractDigits = toInteger(fractionDigits);
3003 var data = [0, 0, 0, 0, 0, 0];
3004 var sign = '';
3005 var result = '0';
3006 var e, z, j, k;
3007
3008 var multiply = function (n, c) {
3009 var index = -1;
3010 var c2 = c;
3011 while (++index < 6) {
3012 c2 += n * data[index];
3013 data[index] = c2 % 1e7;
3014 c2 = floor$2(c2 / 1e7);
3015 }
3016 };
3017
3018 var divide = function (n) {
3019 var index = 6;
3020 var c = 0;
3021 while (--index >= 0) {
3022 c += data[index];
3023 data[index] = floor$2(c / n);
3024 c = (c % n) * 1e7;
3025 }
3026 };
3027
3028 var dataToString = function () {
3029 var index = 6;
3030 var s = '';
3031 while (--index >= 0) {
3032 if (s !== '' || index === 0 || data[index] !== 0) {
3033 var t = String(data[index]);
3034 s = s === '' ? t : s + stringRepeat.call('0', 7 - t.length) + t;
3035 }
3036 } return s;
3037 };
3038
3039 if (fractDigits < 0 || fractDigits > 20) throw RangeError('Incorrect fraction digits');
3040 // eslint-disable-next-line no-self-compare
3041 if (number != number) return 'NaN';
3042 if (number <= -1e21 || number >= 1e21) return String(number);
3043 if (number < 0) {
3044 sign = '-';
3045 number = -number;
3046 }
3047 if (number > 1e-21) {
3048 e = log$1(number * pow$1(2, 69, 1)) - 69;
3049 z = e < 0 ? number * pow$1(2, -e, 1) : number / pow$1(2, e, 1);
3050 z *= 0x10000000000000;
3051 e = 52 - e;
3052 if (e > 0) {
3053 multiply(0, z);
3054 j = fractDigits;
3055 while (j >= 7) {
3056 multiply(1e7, 0);
3057 j -= 7;
3058 }
3059 multiply(pow$1(10, j, 1), 0);
3060 j = e - 1;
3061 while (j >= 23) {
3062 divide(1 << 23);
3063 j -= 23;
3064 }
3065 divide(1 << j);
3066 multiply(1, 1);
3067 divide(2);
3068 result = dataToString();
3069 } else {
3070 multiply(0, z);
3071 multiply(1 << -e, 0);
3072 result = dataToString() + stringRepeat.call('0', fractDigits);
3073 }
3074 }
3075 if (fractDigits > 0) {
3076 k = result.length;
3077 result = sign + (k <= fractDigits
3078 ? '0.' + stringRepeat.call('0', fractDigits - k) + result
3079 : result.slice(0, k - fractDigits) + '.' + result.slice(k - fractDigits));
3080 } else {
3081 result = sign + result;
3082 } return result;
3083 }
3084 });
3085
3086 var nativeAssign = Object.assign;
3087
3088 // `Object.assign` method
3089 // https://tc39.github.io/ecma262/#sec-object.assign
3090 // should work with symbols and should have deterministic property order (V8 bug)
3091 var objectAssign = !nativeAssign || fails(function () {
3092 var A = {};
3093 var B = {};
3094 // eslint-disable-next-line no-undef
3095 var symbol = Symbol();
3096 var alphabet = 'abcdefghijklmnopqrst';
3097 A[symbol] = 7;
3098 alphabet.split('').forEach(function (chr) { B[chr] = chr; });
3099 return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
3100 }) ? function assign(target, source) { // eslint-disable-line no-unused-vars
3101 var T = toObject(target);
3102 var argumentsLength = arguments.length;
3103 var index = 1;
3104 var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
3105 var propertyIsEnumerable = objectPropertyIsEnumerable.f;
3106 while (argumentsLength > index) {
3107 var S = indexedObject(arguments[index++]);
3108 var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
3109 var length = keys.length;
3110 var j = 0;
3111 var key;
3112 while (length > j) {
3113 key = keys[j++];
3114 if (!descriptors || propertyIsEnumerable.call(S, key)) T[key] = S[key];
3115 }
3116 } return T;
3117 } : nativeAssign;
3118
3119 // `Object.assign` method
3120 // https://tc39.github.io/ecma262/#sec-object.assign
3121 _export({ target: 'Object', stat: true, forced: Object.assign !== objectAssign }, {
3122 assign: objectAssign
3123 });
3124
3125 // `Object.defineProperties` method
3126 // https://tc39.github.io/ecma262/#sec-object.defineproperties
3127 _export({ target: 'Object', stat: true, forced: !descriptors, sham: !descriptors }, {
3128 defineProperties: objectDefineProperties
3129 });
3130
3131 // `Object.defineProperty` method
3132 // https://tc39.github.io/ecma262/#sec-object.defineproperty
3133 _export({ target: 'Object', stat: true, forced: !descriptors, sham: !descriptors }, {
3134 defineProperty: objectDefineProperty.f
3135 });
3136
3137 var freezing = !fails(function () {
3138 return Object.isExtensible(Object.preventExtensions({}));
3139 });
3140
3141 var internalMetadata = createCommonjsModule(function (module) {
3142 var defineProperty = objectDefineProperty.f;
3143
3144
3145
3146 var METADATA = uid('meta');
3147 var id = 0;
3148
3149 var isExtensible = Object.isExtensible || function () {
3150 return true;
3151 };
3152
3153 var setMetadata = function (it) {
3154 defineProperty(it, METADATA, { value: {
3155 objectID: 'O' + ++id, // object ID
3156 weakData: {} // weak collections IDs
3157 } });
3158 };
3159
3160 var fastKey = function (it, create) {
3161 // return a primitive with prefix
3162 if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
3163 if (!has(it, METADATA)) {
3164 // can't set metadata to uncaught frozen object
3165 if (!isExtensible(it)) return 'F';
3166 // not necessary to add metadata
3167 if (!create) return 'E';
3168 // add missing metadata
3169 setMetadata(it);
3170 // return object ID
3171 } return it[METADATA].objectID;
3172 };
3173
3174 var getWeakData = function (it, create) {
3175 if (!has(it, METADATA)) {
3176 // can't set metadata to uncaught frozen object
3177 if (!isExtensible(it)) return true;
3178 // not necessary to add metadata
3179 if (!create) return false;
3180 // add missing metadata
3181 setMetadata(it);
3182 // return the store of weak collections IDs
3183 } return it[METADATA].weakData;
3184 };
3185
3186 // add metadata on freeze-family methods calling
3187 var onFreeze = function (it) {
3188 if (freezing && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);
3189 return it;
3190 };
3191
3192 var meta = module.exports = {
3193 REQUIRED: false,
3194 fastKey: fastKey,
3195 getWeakData: getWeakData,
3196 onFreeze: onFreeze
3197 };
3198
3199 hiddenKeys[METADATA] = true;
3200 });
3201 var internalMetadata_1 = internalMetadata.REQUIRED;
3202 var internalMetadata_2 = internalMetadata.fastKey;
3203 var internalMetadata_3 = internalMetadata.getWeakData;
3204 var internalMetadata_4 = internalMetadata.onFreeze;
3205
3206 var onFreeze = internalMetadata.onFreeze;
3207
3208 var nativeFreeze = Object.freeze;
3209 var FAILS_ON_PRIMITIVES = fails(function () { nativeFreeze(1); });
3210
3211 // `Object.freeze` method
3212 // https://tc39.github.io/ecma262/#sec-object.freeze
3213 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES, sham: !freezing }, {
3214 freeze: function freeze(it) {
3215 return nativeFreeze && isObject(it) ? nativeFreeze(onFreeze(it)) : it;
3216 }
3217 });
3218
3219 var nativeGetOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f;
3220
3221
3222 var FAILS_ON_PRIMITIVES$1 = fails(function () { nativeGetOwnPropertyDescriptor$2(1); });
3223 var FORCED$4 = !descriptors || FAILS_ON_PRIMITIVES$1;
3224
3225 // `Object.getOwnPropertyDescriptor` method
3226 // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor
3227 _export({ target: 'Object', stat: true, forced: FORCED$4, sham: !descriptors }, {
3228 getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {
3229 return nativeGetOwnPropertyDescriptor$2(toIndexedObject(it), key);
3230 }
3231 });
3232
3233 // `Object.getOwnPropertyDescriptors` method
3234 // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
3235 _export({ target: 'Object', stat: true, sham: !descriptors }, {
3236 getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {
3237 var O = toIndexedObject(object);
3238 var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
3239 var keys = ownKeys(O);
3240 var result = {};
3241 var index = 0;
3242 var key, descriptor;
3243 while (keys.length > index) {
3244 descriptor = getOwnPropertyDescriptor(O, key = keys[index++]);
3245 if (descriptor !== undefined) createProperty(result, key, descriptor);
3246 }
3247 return result;
3248 }
3249 });
3250
3251 var nativeGetOwnPropertyNames$2 = objectGetOwnPropertyNamesExternal.f;
3252
3253 var FAILS_ON_PRIMITIVES$2 = fails(function () { return !Object.getOwnPropertyNames(1); });
3254
3255 // `Object.getOwnPropertyNames` method
3256 // https://tc39.github.io/ecma262/#sec-object.getownpropertynames
3257 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$2 }, {
3258 getOwnPropertyNames: nativeGetOwnPropertyNames$2
3259 });
3260
3261 var FAILS_ON_PRIMITIVES$3 = fails(function () { objectGetPrototypeOf(1); });
3262
3263 // `Object.getPrototypeOf` method
3264 // https://tc39.github.io/ecma262/#sec-object.getprototypeof
3265 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$3, sham: !correctPrototypeGetter }, {
3266 getPrototypeOf: function getPrototypeOf(it) {
3267 return objectGetPrototypeOf(toObject(it));
3268 }
3269 });
3270
3271 var nativeIsExtensible = Object.isExtensible;
3272 var FAILS_ON_PRIMITIVES$4 = fails(function () { nativeIsExtensible(1); });
3273
3274 // `Object.isExtensible` method
3275 // https://tc39.github.io/ecma262/#sec-object.isextensible
3276 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$4 }, {
3277 isExtensible: function isExtensible(it) {
3278 return isObject(it) ? nativeIsExtensible ? nativeIsExtensible(it) : true : false;
3279 }
3280 });
3281
3282 var nativeIsFrozen = Object.isFrozen;
3283 var FAILS_ON_PRIMITIVES$5 = fails(function () { nativeIsFrozen(1); });
3284
3285 // `Object.isFrozen` method
3286 // https://tc39.github.io/ecma262/#sec-object.isfrozen
3287 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$5 }, {
3288 isFrozen: function isFrozen(it) {
3289 return isObject(it) ? nativeIsFrozen ? nativeIsFrozen(it) : false : true;
3290 }
3291 });
3292
3293 var FAILS_ON_PRIMITIVES$6 = fails(function () { objectKeys(1); });
3294
3295 // `Object.keys` method
3296 // https://tc39.github.io/ecma262/#sec-object.keys
3297 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$6 }, {
3298 keys: function keys(it) {
3299 return objectKeys(toObject(it));
3300 }
3301 });
3302
3303 var onFreeze$1 = internalMetadata.onFreeze;
3304
3305
3306
3307 var nativePreventExtensions = Object.preventExtensions;
3308 var FAILS_ON_PRIMITIVES$7 = fails(function () { nativePreventExtensions(1); });
3309
3310 // `Object.preventExtensions` method
3311 // https://tc39.github.io/ecma262/#sec-object.preventextensions
3312 _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$7, sham: !freezing }, {
3313 preventExtensions: function preventExtensions(it) {
3314 return nativePreventExtensions && isObject(it) ? nativePreventExtensions(onFreeze$1(it)) : it;
3315 }
3316 });
3317
3318 // `Object.setPrototypeOf` method
3319 // https://tc39.github.io/ecma262/#sec-object.setprototypeof
3320 _export({ target: 'Object', stat: true }, {
3321 setPrototypeOf: objectSetPrototypeOf
3322 });
3323
3324 var propertyIsEnumerable = objectPropertyIsEnumerable.f;
3325
3326 // `Object.{ entries, values }` methods implementation
3327 var createMethod$4 = function (TO_ENTRIES) {
3328 return function (it) {
3329 var O = toIndexedObject(it);
3330 var keys = objectKeys(O);
3331 var length = keys.length;
3332 var i = 0;
3333 var result = [];
3334 var key;
3335 while (length > i) {
3336 key = keys[i++];
3337 if (!descriptors || propertyIsEnumerable.call(O, key)) {
3338 result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
3339 }
3340 }
3341 return result;
3342 };
3343 };
3344
3345 var objectToArray = {
3346 // `Object.entries` method
3347 // https://tc39.github.io/ecma262/#sec-object.entries
3348 entries: createMethod$4(true),
3349 // `Object.values` method
3350 // https://tc39.github.io/ecma262/#sec-object.values
3351 values: createMethod$4(false)
3352 };
3353
3354 var $values = objectToArray.values;
3355
3356 // `Object.values` method
3357 // https://tc39.github.io/ecma262/#sec-object.values
3358 _export({ target: 'Object', stat: true }, {
3359 values: function values(O) {
3360 return $values(O);
3361 }
3362 });
3363
3364 var trim$1 = stringTrim.trim;
3365
3366
3367 var nativeParseFloat = global_1.parseFloat;
3368 var FORCED$5 = 1 / nativeParseFloat(whitespaces + '-0') !== -Infinity;
3369
3370 // `parseFloat` method
3371 // https://tc39.github.io/ecma262/#sec-parsefloat-string
3372 var _parseFloat = FORCED$5 ? function parseFloat(string) {
3373 var trimmedString = trim$1(String(string));
3374 var result = nativeParseFloat(trimmedString);
3375 return result === 0 && trimmedString.charAt(0) == '-' ? -0 : result;
3376 } : nativeParseFloat;
3377
3378 // `parseFloat` method
3379 // https://tc39.github.io/ecma262/#sec-parsefloat-string
3380 _export({ global: true, forced: parseFloat != _parseFloat }, {
3381 parseFloat: _parseFloat
3382 });
3383
3384 var trim$2 = stringTrim.trim;
3385
3386
3387 var nativeParseInt = global_1.parseInt;
3388 var hex = /^[+-]?0[Xx]/;
3389 var FORCED$6 = nativeParseInt(whitespaces + '08') !== 8 || nativeParseInt(whitespaces + '0x16') !== 22;
3390
3391 // `parseInt` method
3392 // https://tc39.github.io/ecma262/#sec-parseint-string-radix
3393 var _parseInt = FORCED$6 ? function parseInt(string, radix) {
3394 var S = trim$2(String(string));
3395 return nativeParseInt(S, (radix >>> 0) || (hex.test(S) ? 16 : 10));
3396 } : nativeParseInt;
3397
3398 // `parseInt` method
3399 // https://tc39.github.io/ecma262/#sec-parseint-string-radix
3400 _export({ global: true, forced: parseInt != _parseInt }, {
3401 parseInt: _parseInt
3402 });
3403
3404 var MATCH = wellKnownSymbol('match');
3405
3406 // `IsRegExp` abstract operation
3407 // https://tc39.github.io/ecma262/#sec-isregexp
3408 var isRegexp = function (it) {
3409 var isRegExp;
3410 return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp');
3411 };
3412
3413 // `RegExp.prototype.flags` getter implementation
3414 // https://tc39.github.io/ecma262/#sec-get-regexp.prototype.flags
3415 var regexpFlags = function () {
3416 var that = anObject(this);
3417 var result = '';
3418 if (that.global) result += 'g';
3419 if (that.ignoreCase) result += 'i';
3420 if (that.multiline) result += 'm';
3421 if (that.dotAll) result += 's';
3422 if (that.unicode) result += 'u';
3423 if (that.sticky) result += 'y';
3424 return result;
3425 };
3426
3427 var SPECIES$4 = wellKnownSymbol('species');
3428
3429 var setSpecies = function (CONSTRUCTOR_NAME) {
3430 var Constructor = getBuiltIn(CONSTRUCTOR_NAME);
3431 var defineProperty = objectDefineProperty.f;
3432
3433 if (descriptors && Constructor && !Constructor[SPECIES$4]) {
3434 defineProperty(Constructor, SPECIES$4, {
3435 configurable: true,
3436 get: function () { return this; }
3437 });
3438 }
3439 };
3440
3441 var defineProperty$7 = objectDefineProperty.f;
3442 var getOwnPropertyNames$2 = objectGetOwnPropertyNames.f;
3443
3444
3445
3446
3447
3448
3449
3450 var MATCH$1 = wellKnownSymbol('match');
3451 var NativeRegExp = global_1.RegExp;
3452 var RegExpPrototype = NativeRegExp.prototype;
3453 var re1 = /a/g;
3454 var re2 = /a/g;
3455
3456 // "new" should create a new object, old webkit bug
3457 var CORRECT_NEW = new NativeRegExp(re1) !== re1;
3458
3459 var FORCED$7 = descriptors && isForced_1('RegExp', (!CORRECT_NEW || fails(function () {
3460 re2[MATCH$1] = false;
3461 // RegExp constructor can alter flags and IsRegExp works correct with @@match
3462 return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';
3463 })));
3464
3465 // `RegExp` constructor
3466 // https://tc39.github.io/ecma262/#sec-regexp-constructor
3467 if (FORCED$7) {
3468 var RegExpWrapper = function RegExp(pattern, flags) {
3469 var thisIsRegExp = this instanceof RegExpWrapper;
3470 var patternIsRegExp = isRegexp(pattern);
3471 var flagsAreUndefined = flags === undefined;
3472 return !thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined ? pattern
3473 : inheritIfRequired(CORRECT_NEW
3474 ? new NativeRegExp(patternIsRegExp && !flagsAreUndefined ? pattern.source : pattern, flags)
3475 : NativeRegExp((patternIsRegExp = pattern instanceof RegExpWrapper)
3476 ? pattern.source
3477 : pattern, patternIsRegExp && flagsAreUndefined ? regexpFlags.call(pattern) : flags)
3478 , thisIsRegExp ? this : RegExpPrototype, RegExpWrapper);
3479 };
3480 var proxy = function (key) {
3481 key in RegExpWrapper || defineProperty$7(RegExpWrapper, key, {
3482 configurable: true,
3483 get: function () { return NativeRegExp[key]; },
3484 set: function (it) { NativeRegExp[key] = it; }
3485 });
3486 };
3487 var keys$3 = getOwnPropertyNames$2(NativeRegExp);
3488 var index = 0;
3489 while (keys$3.length > index) proxy(keys$3[index++]);
3490 RegExpPrototype.constructor = RegExpWrapper;
3491 RegExpWrapper.prototype = RegExpPrototype;
3492 redefine(global_1, 'RegExp', RegExpWrapper);
3493 }
3494
3495 // https://tc39.github.io/ecma262/#sec-get-regexp-@@species
3496 setSpecies('RegExp');
3497
3498 var nativeExec = RegExp.prototype.exec;
3499 // This always refers to the native implementation, because the
3500 // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
3501 // which loads this file before patching the method.
3502 var nativeReplace = String.prototype.replace;
3503
3504 var patchedExec = nativeExec;
3505
3506 var UPDATES_LAST_INDEX_WRONG = (function () {
3507 var re1 = /a/;
3508 var re2 = /b*/g;
3509 nativeExec.call(re1, 'a');
3510 nativeExec.call(re2, 'a');
3511 return re1.lastIndex !== 0 || re2.lastIndex !== 0;
3512 })();
3513
3514 // nonparticipating capturing group, copied from es5-shim's String#split patch.
3515 var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
3516
3517 var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
3518
3519 if (PATCH) {
3520 patchedExec = function exec(str) {
3521 var re = this;
3522 var lastIndex, reCopy, match, i;
3523
3524 if (NPCG_INCLUDED) {
3525 reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re));
3526 }
3527 if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
3528
3529 match = nativeExec.call(re, str);
3530
3531 if (UPDATES_LAST_INDEX_WRONG && match) {
3532 re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
3533 }
3534 if (NPCG_INCLUDED && match && match.length > 1) {
3535 // Fix browsers whose `exec` methods don't consistently return `undefined`
3536 // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
3537 nativeReplace.call(match[0], reCopy, function () {
3538 for (i = 1; i < arguments.length - 2; i++) {
3539 if (arguments[i] === undefined) match[i] = undefined;
3540 }
3541 });
3542 }
3543
3544 return match;
3545 };
3546 }
3547
3548 var regexpExec = patchedExec;
3549
3550 _export({ target: 'RegExp', proto: true, forced: /./.exec !== regexpExec }, {
3551 exec: regexpExec
3552 });
3553
3554 // `RegExp.prototype.flags` getter
3555 // https://tc39.github.io/ecma262/#sec-get-regexp.prototype.flags
3556 if (descriptors && /./g.flags != 'g') {
3557 objectDefineProperty.f(RegExp.prototype, 'flags', {
3558 configurable: true,
3559 get: regexpFlags
3560 });
3561 }
3562
3563 var TO_STRING$1 = 'toString';
3564 var RegExpPrototype$1 = RegExp.prototype;
3565 var nativeToString = RegExpPrototype$1[TO_STRING$1];
3566
3567 var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
3568 // FF44- RegExp#toString has a wrong name
3569 var INCORRECT_NAME = nativeToString.name != TO_STRING$1;
3570
3571 // `RegExp.prototype.toString` method
3572 // https://tc39.github.io/ecma262/#sec-regexp.prototype.tostring
3573 if (NOT_GENERIC || INCORRECT_NAME) {
3574 redefine(RegExp.prototype, TO_STRING$1, function toString() {
3575 var R = anObject(this);
3576 var p = String(R.source);
3577 var rf = R.flags;
3578 var f = String(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype$1) ? regexpFlags.call(R) : rf);
3579 return '/' + p + '/' + f;
3580 }, { unsafe: true });
3581 }
3582
3583 // `String.prototype.{ codePointAt, at }` methods implementation
3584 var createMethod$5 = function (CONVERT_TO_STRING) {
3585 return function ($this, pos) {
3586 var S = String(requireObjectCoercible($this));
3587 var position = toInteger(pos);
3588 var size = S.length;
3589 var first, second;
3590 if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
3591 first = S.charCodeAt(position);
3592 return first < 0xD800 || first > 0xDBFF || position + 1 === size
3593 || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
3594 ? CONVERT_TO_STRING ? S.charAt(position) : first
3595 : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
3596 };
3597 };
3598
3599 var stringMultibyte = {
3600 // `String.prototype.codePointAt` method
3601 // https://tc39.github.io/ecma262/#sec-string.prototype.codepointat
3602 codeAt: createMethod$5(false),
3603 // `String.prototype.at` method
3604 // https://github.com/mathiasbynens/String.prototype.at
3605 charAt: createMethod$5(true)
3606 };
3607
3608 var charAt = stringMultibyte.charAt;
3609
3610
3611
3612 var STRING_ITERATOR = 'String Iterator';
3613 var setInternalState$3 = internalState.set;
3614 var getInternalState$3 = internalState.getterFor(STRING_ITERATOR);
3615
3616 // `String.prototype[@@iterator]` method
3617 // https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator
3618 defineIterator(String, 'String', function (iterated) {
3619 setInternalState$3(this, {
3620 type: STRING_ITERATOR,
3621 string: String(iterated),
3622 index: 0
3623 });
3624 // `%StringIteratorPrototype%.next` method
3625 // https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next
3626 }, function next() {
3627 var state = getInternalState$3(this);
3628 var string = state.string;
3629 var index = state.index;
3630 var point;
3631 if (index >= string.length) return { value: undefined, done: true };
3632 point = charAt(string, index);
3633 state.index += point.length;
3634 return { value: point, done: false };
3635 });
3636
3637 var SPECIES$5 = wellKnownSymbol('species');
3638
3639 var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
3640 // #replace needs built-in support for named groups.
3641 // #match works fine because it just return the exec results, even if it has
3642 // a "grops" property.
3643 var re = /./;
3644 re.exec = function () {
3645 var result = [];
3646 result.groups = { a: '7' };
3647 return result;
3648 };
3649 return ''.replace(re, '$<a>') !== '7';
3650 });
3651
3652 // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
3653 // Weex JS has frozen built-in prototypes, so use try / catch wrapper
3654 var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
3655 var re = /(?:)/;
3656 var originalExec = re.exec;
3657 re.exec = function () { return originalExec.apply(this, arguments); };
3658 var result = 'ab'.split(re);
3659 return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
3660 });
3661
3662 var fixRegexpWellKnownSymbolLogic = function (KEY, length, exec, sham) {
3663 var SYMBOL = wellKnownSymbol(KEY);
3664
3665 var DELEGATES_TO_SYMBOL = !fails(function () {
3666 // String methods call symbol-named RegEp methods
3667 var O = {};
3668 O[SYMBOL] = function () { return 7; };
3669 return ''[KEY](O) != 7;
3670 });
3671
3672 var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
3673 // Symbol-named RegExp methods call .exec
3674 var execCalled = false;
3675 var re = /a/;
3676
3677 if (KEY === 'split') {
3678 // We can't use real regex here since it causes deoptimization
3679 // and serious performance degradation in V8
3680 // https://github.com/zloirock/core-js/issues/306
3681 re = {};
3682 // RegExp[@@split] doesn't call the regex's exec method, but first creates
3683 // a new one. We need to return the patched regex when creating the new one.
3684 re.constructor = {};
3685 re.constructor[SPECIES$5] = function () { return re; };
3686 re.flags = '';
3687 re[SYMBOL] = /./[SYMBOL];
3688 }
3689
3690 re.exec = function () { execCalled = true; return null; };
3691
3692 re[SYMBOL]('');
3693 return !execCalled;
3694 });
3695
3696 if (
3697 !DELEGATES_TO_SYMBOL ||
3698 !DELEGATES_TO_EXEC ||
3699 (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||
3700 (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
3701 ) {
3702 var nativeRegExpMethod = /./[SYMBOL];
3703 var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
3704 if (regexp.exec === regexpExec) {
3705 if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
3706 // The native String method already delegates to @@method (this
3707 // polyfilled function), leasing to infinite recursion.
3708 // We avoid it by directly calling the native @@method method.
3709 return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
3710 }
3711 return { done: true, value: nativeMethod.call(str, regexp, arg2) };
3712 }
3713 return { done: false };
3714 });
3715 var stringMethod = methods[0];
3716 var regexMethod = methods[1];
3717
3718 redefine(String.prototype, KEY, stringMethod);
3719 redefine(RegExp.prototype, SYMBOL, length == 2
3720 // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
3721 // 21.2.5.11 RegExp.prototype[@@split](string, limit)
3722 ? function (string, arg) { return regexMethod.call(string, this, arg); }
3723 // 21.2.5.6 RegExp.prototype[@@match](string)
3724 // 21.2.5.9 RegExp.prototype[@@search](string)
3725 : function (string) { return regexMethod.call(string, this); }
3726 );
3727 if (sham) createNonEnumerableProperty(RegExp.prototype[SYMBOL], 'sham', true);
3728 }
3729 };
3730
3731 var charAt$1 = stringMultibyte.charAt;
3732
3733 // `AdvanceStringIndex` abstract operation
3734 // https://tc39.github.io/ecma262/#sec-advancestringindex
3735 var advanceStringIndex = function (S, index, unicode) {
3736 return index + (unicode ? charAt$1(S, index).length : 1);
3737 };
3738
3739 // `RegExpExec` abstract operation
3740 // https://tc39.github.io/ecma262/#sec-regexpexec
3741 var regexpExecAbstract = function (R, S) {
3742 var exec = R.exec;
3743 if (typeof exec === 'function') {
3744 var result = exec.call(R, S);
3745 if (typeof result !== 'object') {
3746 throw TypeError('RegExp exec method returned something other than an Object or null');
3747 }
3748 return result;
3749 }
3750
3751 if (classofRaw(R) !== 'RegExp') {
3752 throw TypeError('RegExp#exec called on incompatible receiver');
3753 }
3754
3755 return regexpExec.call(R, S);
3756 };
3757
3758 // @@match logic
3759 fixRegexpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {
3760 return [
3761 // `String.prototype.match` method
3762 // https://tc39.github.io/ecma262/#sec-string.prototype.match
3763 function match(regexp) {
3764 var O = requireObjectCoercible(this);
3765 var matcher = regexp == undefined ? undefined : regexp[MATCH];
3766 return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
3767 },
3768 // `RegExp.prototype[@@match]` method
3769 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match
3770 function (regexp) {
3771 var res = maybeCallNative(nativeMatch, regexp, this);
3772 if (res.done) return res.value;
3773
3774 var rx = anObject(regexp);
3775 var S = String(this);
3776
3777 if (!rx.global) return regexpExecAbstract(rx, S);
3778
3779 var fullUnicode = rx.unicode;
3780 rx.lastIndex = 0;
3781 var A = [];
3782 var n = 0;
3783 var result;
3784 while ((result = regexpExecAbstract(rx, S)) !== null) {
3785 var matchStr = String(result[0]);
3786 A[n] = matchStr;
3787 if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
3788 n++;
3789 }
3790 return n === 0 ? null : A;
3791 }
3792 ];
3793 });
3794
3795 var max$3 = Math.max;
3796 var min$3 = Math.min;
3797 var floor$3 = Math.floor;
3798 var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d\d?|<[^>]*>)/g;
3799 var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d\d?)/g;
3800
3801 var maybeToString = function (it) {
3802 return it === undefined ? it : String(it);
3803 };
3804
3805 // @@replace logic
3806 fixRegexpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative) {
3807 return [
3808 // `String.prototype.replace` method
3809 // https://tc39.github.io/ecma262/#sec-string.prototype.replace
3810 function replace(searchValue, replaceValue) {
3811 var O = requireObjectCoercible(this);
3812 var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
3813 return replacer !== undefined
3814 ? replacer.call(searchValue, O, replaceValue)
3815 : nativeReplace.call(String(O), searchValue, replaceValue);
3816 },
3817 // `RegExp.prototype[@@replace]` method
3818 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
3819 function (regexp, replaceValue) {
3820 var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
3821 if (res.done) return res.value;
3822
3823 var rx = anObject(regexp);
3824 var S = String(this);
3825
3826 var functionalReplace = typeof replaceValue === 'function';
3827 if (!functionalReplace) replaceValue = String(replaceValue);
3828
3829 var global = rx.global;
3830 if (global) {
3831 var fullUnicode = rx.unicode;
3832 rx.lastIndex = 0;
3833 }
3834 var results = [];
3835 while (true) {
3836 var result = regexpExecAbstract(rx, S);
3837 if (result === null) break;
3838
3839 results.push(result);
3840 if (!global) break;
3841
3842 var matchStr = String(result[0]);
3843 if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
3844 }
3845
3846 var accumulatedResult = '';
3847 var nextSourcePosition = 0;
3848 for (var i = 0; i < results.length; i++) {
3849 result = results[i];
3850
3851 var matched = String(result[0]);
3852 var position = max$3(min$3(toInteger(result.index), S.length), 0);
3853 var captures = [];
3854 // NOTE: This is equivalent to
3855 // captures = result.slice(1).map(maybeToString)
3856 // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
3857 // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
3858 // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
3859 for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
3860 var namedCaptures = result.groups;
3861 if (functionalReplace) {
3862 var replacerArgs = [matched].concat(captures, position, S);
3863 if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
3864 var replacement = String(replaceValue.apply(undefined, replacerArgs));
3865 } else {
3866 replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
3867 }
3868 if (position >= nextSourcePosition) {
3869 accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
3870 nextSourcePosition = position + matched.length;
3871 }
3872 }
3873 return accumulatedResult + S.slice(nextSourcePosition);
3874 }
3875 ];
3876
3877 // https://tc39.github.io/ecma262/#sec-getsubstitution
3878 function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
3879 var tailPos = position + matched.length;
3880 var m = captures.length;
3881 var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
3882 if (namedCaptures !== undefined) {
3883 namedCaptures = toObject(namedCaptures);
3884 symbols = SUBSTITUTION_SYMBOLS;
3885 }
3886 return nativeReplace.call(replacement, symbols, function (match, ch) {
3887 var capture;
3888 switch (ch.charAt(0)) {
3889 case '$': return '$';
3890 case '&': return matched;
3891 case '`': return str.slice(0, position);
3892 case "'": return str.slice(tailPos);
3893 case '<':
3894 capture = namedCaptures[ch.slice(1, -1)];
3895 break;
3896 default: // \d\d?
3897 var n = +ch;
3898 if (n === 0) return match;
3899 if (n > m) {
3900 var f = floor$3(n / 10);
3901 if (f === 0) return match;
3902 if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
3903 return match;
3904 }
3905 capture = captures[n - 1];
3906 }
3907 return capture === undefined ? '' : capture;
3908 });
3909 }
3910 });
3911
3912 var arrayPush = [].push;
3913 var min$4 = Math.min;
3914 var MAX_UINT32 = 0xFFFFFFFF;
3915
3916 // babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
3917 var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });
3918
3919 // @@split logic
3920 fixRegexpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
3921 var internalSplit;
3922 if (
3923 'abbc'.split(/(b)*/)[1] == 'c' ||
3924 'test'.split(/(?:)/, -1).length != 4 ||
3925 'ab'.split(/(?:ab)*/).length != 2 ||
3926 '.'.split(/(.?)(.?)/).length != 4 ||
3927 '.'.split(/()()/).length > 1 ||
3928 ''.split(/.?/).length
3929 ) {
3930 // based on es5-shim implementation, need to rework it
3931 internalSplit = function (separator, limit) {
3932 var string = String(requireObjectCoercible(this));
3933 var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
3934 if (lim === 0) return [];
3935 if (separator === undefined) return [string];
3936 // If `separator` is not a regex, use native split
3937 if (!isRegexp(separator)) {
3938 return nativeSplit.call(string, separator, lim);
3939 }
3940 var output = [];
3941 var flags = (separator.ignoreCase ? 'i' : '') +
3942 (separator.multiline ? 'm' : '') +
3943 (separator.unicode ? 'u' : '') +
3944 (separator.sticky ? 'y' : '');
3945 var lastLastIndex = 0;
3946 // Make `global` and avoid `lastIndex` issues by working with a copy
3947 var separatorCopy = new RegExp(separator.source, flags + 'g');
3948 var match, lastIndex, lastLength;
3949 while (match = regexpExec.call(separatorCopy, string)) {
3950 lastIndex = separatorCopy.lastIndex;
3951 if (lastIndex > lastLastIndex) {
3952 output.push(string.slice(lastLastIndex, match.index));
3953 if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
3954 lastLength = match[0].length;
3955 lastLastIndex = lastIndex;
3956 if (output.length >= lim) break;
3957 }
3958 if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
3959 }
3960 if (lastLastIndex === string.length) {
3961 if (lastLength || !separatorCopy.test('')) output.push('');
3962 } else output.push(string.slice(lastLastIndex));
3963 return output.length > lim ? output.slice(0, lim) : output;
3964 };
3965 // Chakra, V8
3966 } else if ('0'.split(undefined, 0).length) {
3967 internalSplit = function (separator, limit) {
3968 return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
3969 };
3970 } else internalSplit = nativeSplit;
3971
3972 return [
3973 // `String.prototype.split` method
3974 // https://tc39.github.io/ecma262/#sec-string.prototype.split
3975 function split(separator, limit) {
3976 var O = requireObjectCoercible(this);
3977 var splitter = separator == undefined ? undefined : separator[SPLIT];
3978 return splitter !== undefined
3979 ? splitter.call(separator, O, limit)
3980 : internalSplit.call(String(O), separator, limit);
3981 },
3982 // `RegExp.prototype[@@split]` method
3983 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
3984 //
3985 // NOTE: This cannot be properly polyfilled in engines that don't support
3986 // the 'y' flag.
3987 function (regexp, limit) {
3988 var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
3989 if (res.done) return res.value;
3990
3991 var rx = anObject(regexp);
3992 var S = String(this);
3993 var C = speciesConstructor(rx, RegExp);
3994
3995 var unicodeMatching = rx.unicode;
3996 var flags = (rx.ignoreCase ? 'i' : '') +
3997 (rx.multiline ? 'm' : '') +
3998 (rx.unicode ? 'u' : '') +
3999 (SUPPORTS_Y ? 'y' : 'g');
4000
4001 // ^(? + rx + ) is needed, in combination with some S slicing, to
4002 // simulate the 'y' flag.
4003 var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
4004 var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
4005 if (lim === 0) return [];
4006 if (S.length === 0) return regexpExecAbstract(splitter, S) === null ? [S] : [];
4007 var p = 0;
4008 var q = 0;
4009 var A = [];
4010 while (q < S.length) {
4011 splitter.lastIndex = SUPPORTS_Y ? q : 0;
4012 var z = regexpExecAbstract(splitter, SUPPORTS_Y ? S : S.slice(q));
4013 var e;
4014 if (
4015 z === null ||
4016 (e = min$4(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
4017 ) {
4018 q = advanceStringIndex(S, q, unicodeMatching);
4019 } else {
4020 A.push(S.slice(p, q));
4021 if (A.length === lim) return A;
4022 for (var i = 1; i <= z.length - 1; i++) {
4023 A.push(z[i]);
4024 if (A.length === lim) return A;
4025 }
4026 q = p = e;
4027 }
4028 }
4029 A.push(S.slice(p));
4030 return A;
4031 }
4032 ];
4033 }, !SUPPORTS_Y);
4034
4035 var non = '\u200B\u0085\u180E';
4036
4037 // check that a method works with the correct list
4038 // of whitespaces and has a correct name
4039 var forcedStringTrimMethod = function (METHOD_NAME) {
4040 return fails(function () {
4041 return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;
4042 });
4043 };
4044
4045 var $trim = stringTrim.trim;
4046
4047
4048 // `String.prototype.trim` method
4049 // https://tc39.github.io/ecma262/#sec-string.prototype.trim
4050 _export({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, {
4051 trim: function trim() {
4052 return $trim(this);
4053 }
4054 });
4055
4056 /* eslint-disable no-new */
4057
4058
4059
4060 var NATIVE_ARRAY_BUFFER_VIEWS$1 = arrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;
4061
4062 var ArrayBuffer$1 = global_1.ArrayBuffer;
4063 var Int8Array$2 = global_1.Int8Array;
4064
4065 var typedArraysConstructorsRequiresWrappers = !NATIVE_ARRAY_BUFFER_VIEWS$1 || !fails(function () {
4066 Int8Array$2(1);
4067 }) || !fails(function () {
4068 new Int8Array$2(-1);
4069 }) || !checkCorrectnessOfIteration(function (iterable) {
4070 new Int8Array$2();
4071 new Int8Array$2(null);
4072 new Int8Array$2(1.5);
4073 new Int8Array$2(iterable);
4074 }, true) || fails(function () {
4075 // Safari 11 bug
4076 return new Int8Array$2(new ArrayBuffer$1(2), 1, undefined).length !== 1;
4077 });
4078
4079 var toPositiveInteger = function (it) {
4080 var result = toInteger(it);
4081 if (result < 0) throw RangeError("The argument can't be less than 0");
4082 return result;
4083 };
4084
4085 var toOffset = function (it, BYTES) {
4086 var offset = toPositiveInteger(it);
4087 if (offset % BYTES) throw RangeError('Wrong offset');
4088 return offset;
4089 };
4090
4091 var aTypedArrayConstructor$1 = arrayBufferViewCore.aTypedArrayConstructor;
4092
4093 var typedArrayFrom = function from(source /* , mapfn, thisArg */) {
4094 var O = toObject(source);
4095 var argumentsLength = arguments.length;
4096 var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
4097 var mapping = mapfn !== undefined;
4098 var iteratorMethod = getIteratorMethod(O);
4099 var i, length, result, step, iterator, next;
4100 if (iteratorMethod != undefined && !isArrayIteratorMethod(iteratorMethod)) {
4101 iterator = iteratorMethod.call(O);
4102 next = iterator.next;
4103 O = [];
4104 while (!(step = next.call(iterator)).done) {
4105 O.push(step.value);
4106 }
4107 }
4108 if (mapping && argumentsLength > 2) {
4109 mapfn = bindContext(mapfn, arguments[2], 2);
4110 }
4111 length = toLength(O.length);
4112 result = new (aTypedArrayConstructor$1(this))(length);
4113 for (i = 0; length > i; i++) {
4114 result[i] = mapping ? mapfn(O[i], i) : O[i];
4115 }
4116 return result;
4117 };
4118
4119 var typedArrayConstructor = createCommonjsModule(function (module) {
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138 var getOwnPropertyNames = objectGetOwnPropertyNames.f;
4139
4140 var forEach = arrayIteration.forEach;
4141
4142
4143
4144
4145
4146 var getInternalState = internalState.get;
4147 var setInternalState = internalState.set;
4148 var nativeDefineProperty = objectDefineProperty.f;
4149 var nativeGetOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
4150 var round = Math.round;
4151 var RangeError = global_1.RangeError;
4152 var ArrayBuffer = arrayBuffer.ArrayBuffer;
4153 var DataView = arrayBuffer.DataView;
4154 var NATIVE_ARRAY_BUFFER_VIEWS = arrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;
4155 var TYPED_ARRAY_TAG = arrayBufferViewCore.TYPED_ARRAY_TAG;
4156 var TypedArray = arrayBufferViewCore.TypedArray;
4157 var TypedArrayPrototype = arrayBufferViewCore.TypedArrayPrototype;
4158 var aTypedArrayConstructor = arrayBufferViewCore.aTypedArrayConstructor;
4159 var isTypedArray = arrayBufferViewCore.isTypedArray;
4160 var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';
4161 var WRONG_LENGTH = 'Wrong length';
4162
4163 var fromList = function (C, list) {
4164 var index = 0;
4165 var length = list.length;
4166 var result = new (aTypedArrayConstructor(C))(length);
4167 while (length > index) result[index] = list[index++];
4168 return result;
4169 };
4170
4171 var addGetter = function (it, key) {
4172 nativeDefineProperty(it, key, { get: function () {
4173 return getInternalState(this)[key];
4174 } });
4175 };
4176
4177 var isArrayBuffer = function (it) {
4178 var klass;
4179 return it instanceof ArrayBuffer || (klass = classof(it)) == 'ArrayBuffer' || klass == 'SharedArrayBuffer';
4180 };
4181
4182 var isTypedArrayIndex = function (target, key) {
4183 return isTypedArray(target)
4184 && typeof key != 'symbol'
4185 && key in target
4186 && String(+key) == String(key);
4187 };
4188
4189 var wrappedGetOwnPropertyDescriptor = function getOwnPropertyDescriptor(target, key) {
4190 return isTypedArrayIndex(target, key = toPrimitive(key, true))
4191 ? createPropertyDescriptor(2, target[key])
4192 : nativeGetOwnPropertyDescriptor(target, key);
4193 };
4194
4195 var wrappedDefineProperty = function defineProperty(target, key, descriptor) {
4196 if (isTypedArrayIndex(target, key = toPrimitive(key, true))
4197 && isObject(descriptor)
4198 && has(descriptor, 'value')
4199 && !has(descriptor, 'get')
4200 && !has(descriptor, 'set')
4201 // TODO: add validation descriptor w/o calling accessors
4202 && !descriptor.configurable
4203 && (!has(descriptor, 'writable') || descriptor.writable)
4204 && (!has(descriptor, 'enumerable') || descriptor.enumerable)
4205 ) {
4206 target[key] = descriptor.value;
4207 return target;
4208 } return nativeDefineProperty(target, key, descriptor);
4209 };
4210
4211 if (descriptors) {
4212 if (!NATIVE_ARRAY_BUFFER_VIEWS) {
4213 objectGetOwnPropertyDescriptor.f = wrappedGetOwnPropertyDescriptor;
4214 objectDefineProperty.f = wrappedDefineProperty;
4215 addGetter(TypedArrayPrototype, 'buffer');
4216 addGetter(TypedArrayPrototype, 'byteOffset');
4217 addGetter(TypedArrayPrototype, 'byteLength');
4218 addGetter(TypedArrayPrototype, 'length');
4219 }
4220
4221 _export({ target: 'Object', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, {
4222 getOwnPropertyDescriptor: wrappedGetOwnPropertyDescriptor,
4223 defineProperty: wrappedDefineProperty
4224 });
4225
4226 module.exports = function (TYPE, BYTES, wrapper, CLAMPED) {
4227 var CONSTRUCTOR_NAME = TYPE + (CLAMPED ? 'Clamped' : '') + 'Array';
4228 var GETTER = 'get' + TYPE;
4229 var SETTER = 'set' + TYPE;
4230 var NativeTypedArrayConstructor = global_1[CONSTRUCTOR_NAME];
4231 var TypedArrayConstructor = NativeTypedArrayConstructor;
4232 var TypedArrayConstructorPrototype = TypedArrayConstructor && TypedArrayConstructor.prototype;
4233 var exported = {};
4234
4235 var getter = function (that, index) {
4236 var data = getInternalState(that);
4237 return data.view[GETTER](index * BYTES + data.byteOffset, true);
4238 };
4239
4240 var setter = function (that, index, value) {
4241 var data = getInternalState(that);
4242 if (CLAMPED) value = (value = round(value)) < 0 ? 0 : value > 0xFF ? 0xFF : value & 0xFF;
4243 data.view[SETTER](index * BYTES + data.byteOffset, value, true);
4244 };
4245
4246 var addElement = function (that, index) {
4247 nativeDefineProperty(that, index, {
4248 get: function () {
4249 return getter(this, index);
4250 },
4251 set: function (value) {
4252 return setter(this, index, value);
4253 },
4254 enumerable: true
4255 });
4256 };
4257
4258 if (!NATIVE_ARRAY_BUFFER_VIEWS) {
4259 TypedArrayConstructor = wrapper(function (that, data, offset, $length) {
4260 anInstance(that, TypedArrayConstructor, CONSTRUCTOR_NAME);
4261 var index = 0;
4262 var byteOffset = 0;
4263 var buffer, byteLength, length;
4264 if (!isObject(data)) {
4265 length = toIndex(data);
4266 byteLength = length * BYTES;
4267 buffer = new ArrayBuffer(byteLength);
4268 } else if (isArrayBuffer(data)) {
4269 buffer = data;
4270 byteOffset = toOffset(offset, BYTES);
4271 var $len = data.byteLength;
4272 if ($length === undefined) {
4273 if ($len % BYTES) throw RangeError(WRONG_LENGTH);
4274 byteLength = $len - byteOffset;
4275 if (byteLength < 0) throw RangeError(WRONG_LENGTH);
4276 } else {
4277 byteLength = toLength($length) * BYTES;
4278 if (byteLength + byteOffset > $len) throw RangeError(WRONG_LENGTH);
4279 }
4280 length = byteLength / BYTES;
4281 } else if (isTypedArray(data)) {
4282 return fromList(TypedArrayConstructor, data);
4283 } else {
4284 return typedArrayFrom.call(TypedArrayConstructor, data);
4285 }
4286 setInternalState(that, {
4287 buffer: buffer,
4288 byteOffset: byteOffset,
4289 byteLength: byteLength,
4290 length: length,
4291 view: new DataView(buffer)
4292 });
4293 while (index < length) addElement(that, index++);
4294 });
4295
4296 if (objectSetPrototypeOf) objectSetPrototypeOf(TypedArrayConstructor, TypedArray);
4297 TypedArrayConstructorPrototype = TypedArrayConstructor.prototype = objectCreate(TypedArrayPrototype);
4298 } else if (typedArraysConstructorsRequiresWrappers) {
4299 TypedArrayConstructor = wrapper(function (dummy, data, typedArrayOffset, $length) {
4300 anInstance(dummy, TypedArrayConstructor, CONSTRUCTOR_NAME);
4301 if (!isObject(data)) return new NativeTypedArrayConstructor(toIndex(data));
4302 if (isArrayBuffer(data)) return $length !== undefined
4303 ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES), $length)
4304 : typedArrayOffset !== undefined
4305 ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES))
4306 : new NativeTypedArrayConstructor(data);
4307 if (isTypedArray(data)) return fromList(TypedArrayConstructor, data);
4308 return typedArrayFrom.call(TypedArrayConstructor, data);
4309 });
4310
4311 if (objectSetPrototypeOf) objectSetPrototypeOf(TypedArrayConstructor, TypedArray);
4312 forEach(getOwnPropertyNames(NativeTypedArrayConstructor), function (key) {
4313 if (!(key in TypedArrayConstructor)) {
4314 createNonEnumerableProperty(TypedArrayConstructor, key, NativeTypedArrayConstructor[key]);
4315 }
4316 });
4317 TypedArrayConstructor.prototype = TypedArrayConstructorPrototype;
4318 }
4319
4320 if (TypedArrayConstructorPrototype.constructor !== TypedArrayConstructor) {
4321 createNonEnumerableProperty(TypedArrayConstructorPrototype, 'constructor', TypedArrayConstructor);
4322 }
4323
4324 if (TYPED_ARRAY_TAG) {
4325 createNonEnumerableProperty(TypedArrayConstructorPrototype, TYPED_ARRAY_TAG, CONSTRUCTOR_NAME);
4326 }
4327
4328 exported[CONSTRUCTOR_NAME] = TypedArrayConstructor;
4329
4330 _export({
4331 global: true, forced: TypedArrayConstructor != NativeTypedArrayConstructor, sham: !NATIVE_ARRAY_BUFFER_VIEWS
4332 }, exported);
4333
4334 if (!(BYTES_PER_ELEMENT in TypedArrayConstructor)) {
4335 createNonEnumerableProperty(TypedArrayConstructor, BYTES_PER_ELEMENT, BYTES);
4336 }
4337
4338 if (!(BYTES_PER_ELEMENT in TypedArrayConstructorPrototype)) {
4339 createNonEnumerableProperty(TypedArrayConstructorPrototype, BYTES_PER_ELEMENT, BYTES);
4340 }
4341
4342 setSpecies(CONSTRUCTOR_NAME);
4343 };
4344 } else module.exports = function () { /* empty */ };
4345 });
4346
4347 // `Uint8Array` constructor
4348 // https://tc39.github.io/ecma262/#sec-typedarray-objects
4349 typedArrayConstructor('Uint8', 1, function (init) {
4350 return function Uint8Array(data, byteOffset, length) {
4351 return init(this, data, byteOffset, length);
4352 };
4353 });
4354
4355 var min$5 = Math.min;
4356
4357 // `Array.prototype.copyWithin` method implementation
4358 // https://tc39.github.io/ecma262/#sec-array.prototype.copywithin
4359 var arrayCopyWithin = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {
4360 var O = toObject(this);
4361 var len = toLength(O.length);
4362 var to = toAbsoluteIndex(target, len);
4363 var from = toAbsoluteIndex(start, len);
4364 var end = arguments.length > 2 ? arguments[2] : undefined;
4365 var count = min$5((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);
4366 var inc = 1;
4367 if (from < to && to < from + count) {
4368 inc = -1;
4369 from += count - 1;
4370 to += count - 1;
4371 }
4372 while (count-- > 0) {
4373 if (from in O) O[to] = O[from];
4374 else delete O[to];
4375 to += inc;
4376 from += inc;
4377 } return O;
4378 };
4379
4380 var aTypedArray$1 = arrayBufferViewCore.aTypedArray;
4381
4382 // `%TypedArray%.prototype.copyWithin` method
4383 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.copywithin
4384 arrayBufferViewCore.exportProto('copyWithin', function copyWithin(target, start /* , end */) {
4385 return arrayCopyWithin.call(aTypedArray$1(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
4386 });
4387
4388 var $every = arrayIteration.every;
4389
4390 var aTypedArray$2 = arrayBufferViewCore.aTypedArray;
4391
4392 // `%TypedArray%.prototype.every` method
4393 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.every
4394 arrayBufferViewCore.exportProto('every', function every(callbackfn /* , thisArg */) {
4395 return $every(aTypedArray$2(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
4396 });
4397
4398 var aTypedArray$3 = arrayBufferViewCore.aTypedArray;
4399
4400 // `%TypedArray%.prototype.fill` method
4401 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.fill
4402 // eslint-disable-next-line no-unused-vars
4403 arrayBufferViewCore.exportProto('fill', function fill(value /* , start, end */) {
4404 return arrayFill.apply(aTypedArray$3(this), arguments);
4405 });
4406
4407 var $filter$1 = arrayIteration.filter;
4408
4409
4410 var aTypedArray$4 = arrayBufferViewCore.aTypedArray;
4411 var aTypedArrayConstructor$2 = arrayBufferViewCore.aTypedArrayConstructor;
4412
4413 // `%TypedArray%.prototype.filter` method
4414 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.filter
4415 arrayBufferViewCore.exportProto('filter', function filter(callbackfn /* , thisArg */) {
4416 var list = $filter$1(aTypedArray$4(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
4417 var C = speciesConstructor(this, this.constructor);
4418 var index = 0;
4419 var length = list.length;
4420 var result = new (aTypedArrayConstructor$2(C))(length);
4421 while (length > index) result[index] = list[index++];
4422 return result;
4423 });
4424
4425 var $find = arrayIteration.find;
4426
4427 var aTypedArray$5 = arrayBufferViewCore.aTypedArray;
4428
4429 // `%TypedArray%.prototype.find` method
4430 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.find
4431 arrayBufferViewCore.exportProto('find', function find(predicate /* , thisArg */) {
4432 return $find(aTypedArray$5(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
4433 });
4434
4435 var $findIndex = arrayIteration.findIndex;
4436
4437 var aTypedArray$6 = arrayBufferViewCore.aTypedArray;
4438
4439 // `%TypedArray%.prototype.findIndex` method
4440 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.findindex
4441 arrayBufferViewCore.exportProto('findIndex', function findIndex(predicate /* , thisArg */) {
4442 return $findIndex(aTypedArray$6(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
4443 });
4444
4445 var $forEach$2 = arrayIteration.forEach;
4446
4447 var aTypedArray$7 = arrayBufferViewCore.aTypedArray;
4448
4449 // `%TypedArray%.prototype.forEach` method
4450 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.foreach
4451 arrayBufferViewCore.exportProto('forEach', function forEach(callbackfn /* , thisArg */) {
4452 $forEach$2(aTypedArray$7(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
4453 });
4454
4455 var $includes = arrayIncludes.includes;
4456
4457 var aTypedArray$8 = arrayBufferViewCore.aTypedArray;
4458
4459 // `%TypedArray%.prototype.includes` method
4460 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.includes
4461 arrayBufferViewCore.exportProto('includes', function includes(searchElement /* , fromIndex */) {
4462 return $includes(aTypedArray$8(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
4463 });
4464
4465 var $indexOf$1 = arrayIncludes.indexOf;
4466
4467 var aTypedArray$9 = arrayBufferViewCore.aTypedArray;
4468
4469 // `%TypedArray%.prototype.indexOf` method
4470 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.indexof
4471 arrayBufferViewCore.exportProto('indexOf', function indexOf(searchElement /* , fromIndex */) {
4472 return $indexOf$1(aTypedArray$9(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
4473 });
4474
4475 var ITERATOR$5 = wellKnownSymbol('iterator');
4476 var Uint8Array$1 = global_1.Uint8Array;
4477 var arrayValues = es_array_iterator.values;
4478 var arrayKeys = es_array_iterator.keys;
4479 var arrayEntries = es_array_iterator.entries;
4480 var aTypedArray$a = arrayBufferViewCore.aTypedArray;
4481 var exportProto$1 = arrayBufferViewCore.exportProto;
4482 var nativeTypedArrayIterator = Uint8Array$1 && Uint8Array$1.prototype[ITERATOR$5];
4483
4484 var CORRECT_ITER_NAME = !!nativeTypedArrayIterator
4485 && (nativeTypedArrayIterator.name == 'values' || nativeTypedArrayIterator.name == undefined);
4486
4487 var typedArrayValues = function values() {
4488 return arrayValues.call(aTypedArray$a(this));
4489 };
4490
4491 // `%TypedArray%.prototype.entries` method
4492 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.entries
4493 exportProto$1('entries', function entries() {
4494 return arrayEntries.call(aTypedArray$a(this));
4495 });
4496 // `%TypedArray%.prototype.keys` method
4497 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.keys
4498 exportProto$1('keys', function keys() {
4499 return arrayKeys.call(aTypedArray$a(this));
4500 });
4501 // `%TypedArray%.prototype.values` method
4502 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.values
4503 exportProto$1('values', typedArrayValues, !CORRECT_ITER_NAME);
4504 // `%TypedArray%.prototype[@@iterator]` method
4505 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype-@@iterator
4506 exportProto$1(ITERATOR$5, typedArrayValues, !CORRECT_ITER_NAME);
4507
4508 var aTypedArray$b = arrayBufferViewCore.aTypedArray;
4509 var $join = [].join;
4510
4511 // `%TypedArray%.prototype.join` method
4512 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.join
4513 // eslint-disable-next-line no-unused-vars
4514 arrayBufferViewCore.exportProto('join', function join(separator) {
4515 return $join.apply(aTypedArray$b(this), arguments);
4516 });
4517
4518 var min$6 = Math.min;
4519 var nativeLastIndexOf = [].lastIndexOf;
4520 var NEGATIVE_ZERO$1 = !!nativeLastIndexOf && 1 / [1].lastIndexOf(1, -0) < 0;
4521 var SLOPPY_METHOD$3 = sloppyArrayMethod('lastIndexOf');
4522
4523 // `Array.prototype.lastIndexOf` method implementation
4524 // https://tc39.github.io/ecma262/#sec-array.prototype.lastindexof
4525 var arrayLastIndexOf = (NEGATIVE_ZERO$1 || SLOPPY_METHOD$3) ? function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {
4526 // convert -0 to +0
4527 if (NEGATIVE_ZERO$1) return nativeLastIndexOf.apply(this, arguments) || 0;
4528 var O = toIndexedObject(this);
4529 var length = toLength(O.length);
4530 var index = length - 1;
4531 if (arguments.length > 1) index = min$6(index, toInteger(arguments[1]));
4532 if (index < 0) index = length + index;
4533 for (;index >= 0; index--) if (index in O && O[index] === searchElement) return index || 0;
4534 return -1;
4535 } : nativeLastIndexOf;
4536
4537 var aTypedArray$c = arrayBufferViewCore.aTypedArray;
4538
4539 // `%TypedArray%.prototype.lastIndexOf` method
4540 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.lastindexof
4541 // eslint-disable-next-line no-unused-vars
4542 arrayBufferViewCore.exportProto('lastIndexOf', function lastIndexOf(searchElement /* , fromIndex */) {
4543 return arrayLastIndexOf.apply(aTypedArray$c(this), arguments);
4544 });
4545
4546 var $map$1 = arrayIteration.map;
4547
4548
4549 var aTypedArray$d = arrayBufferViewCore.aTypedArray;
4550 var aTypedArrayConstructor$3 = arrayBufferViewCore.aTypedArrayConstructor;
4551
4552 // `%TypedArray%.prototype.map` method
4553 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.map
4554 arrayBufferViewCore.exportProto('map', function map(mapfn /* , thisArg */) {
4555 return $map$1(aTypedArray$d(this), mapfn, arguments.length > 1 ? arguments[1] : undefined, function (O, length) {
4556 return new (aTypedArrayConstructor$3(speciesConstructor(O, O.constructor)))(length);
4557 });
4558 });
4559
4560 // `Array.prototype.{ reduce, reduceRight }` methods implementation
4561 var createMethod$6 = function (IS_RIGHT) {
4562 return function (that, callbackfn, argumentsLength, memo) {
4563 aFunction$1(callbackfn);
4564 var O = toObject(that);
4565 var self = indexedObject(O);
4566 var length = toLength(O.length);
4567 var index = IS_RIGHT ? length - 1 : 0;
4568 var i = IS_RIGHT ? -1 : 1;
4569 if (argumentsLength < 2) while (true) {
4570 if (index in self) {
4571 memo = self[index];
4572 index += i;
4573 break;
4574 }
4575 index += i;
4576 if (IS_RIGHT ? index < 0 : length <= index) {
4577 throw TypeError('Reduce of empty array with no initial value');
4578 }
4579 }
4580 for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {
4581 memo = callbackfn(memo, self[index], index, O);
4582 }
4583 return memo;
4584 };
4585 };
4586
4587 var arrayReduce = {
4588 // `Array.prototype.reduce` method
4589 // https://tc39.github.io/ecma262/#sec-array.prototype.reduce
4590 left: createMethod$6(false),
4591 // `Array.prototype.reduceRight` method
4592 // https://tc39.github.io/ecma262/#sec-array.prototype.reduceright
4593 right: createMethod$6(true)
4594 };
4595
4596 var $reduce = arrayReduce.left;
4597
4598 var aTypedArray$e = arrayBufferViewCore.aTypedArray;
4599
4600 // `%TypedArray%.prototype.reduce` method
4601 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduce
4602 arrayBufferViewCore.exportProto('reduce', function reduce(callbackfn /* , initialValue */) {
4603 return $reduce(aTypedArray$e(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
4604 });
4605
4606 var $reduceRight = arrayReduce.right;
4607
4608 var aTypedArray$f = arrayBufferViewCore.aTypedArray;
4609
4610 // `%TypedArray%.prototype.reduceRicht` method
4611 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduceright
4612 arrayBufferViewCore.exportProto('reduceRight', function reduceRight(callbackfn /* , initialValue */) {
4613 return $reduceRight(aTypedArray$f(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
4614 });
4615
4616 var aTypedArray$g = arrayBufferViewCore.aTypedArray;
4617 var floor$4 = Math.floor;
4618
4619 // `%TypedArray%.prototype.reverse` method
4620 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reverse
4621 arrayBufferViewCore.exportProto('reverse', function reverse() {
4622 var that = this;
4623 var length = aTypedArray$g(that).length;
4624 var middle = floor$4(length / 2);
4625 var index = 0;
4626 var value;
4627 while (index < middle) {
4628 value = that[index];
4629 that[index++] = that[--length];
4630 that[length] = value;
4631 } return that;
4632 });
4633
4634 var aTypedArray$h = arrayBufferViewCore.aTypedArray;
4635
4636 var FORCED$8 = fails(function () {
4637 // eslint-disable-next-line no-undef
4638 new Int8Array(1).set({});
4639 });
4640
4641 // `%TypedArray%.prototype.set` method
4642 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.set
4643 arrayBufferViewCore.exportProto('set', function set(arrayLike /* , offset */) {
4644 aTypedArray$h(this);
4645 var offset = toOffset(arguments.length > 1 ? arguments[1] : undefined, 1);
4646 var length = this.length;
4647 var src = toObject(arrayLike);
4648 var len = toLength(src.length);
4649 var index = 0;
4650 if (len + offset > length) throw RangeError('Wrong length');
4651 while (index < len) this[offset + index] = src[index++];
4652 }, FORCED$8);
4653
4654 var aTypedArray$i = arrayBufferViewCore.aTypedArray;
4655 var aTypedArrayConstructor$4 = arrayBufferViewCore.aTypedArrayConstructor;
4656 var $slice = [].slice;
4657
4658 var FORCED$9 = fails(function () {
4659 // eslint-disable-next-line no-undef
4660 new Int8Array(1).slice();
4661 });
4662
4663 // `%TypedArray%.prototype.slice` method
4664 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.slice
4665 arrayBufferViewCore.exportProto('slice', function slice(start, end) {
4666 var list = $slice.call(aTypedArray$i(this), start, end);
4667 var C = speciesConstructor(this, this.constructor);
4668 var index = 0;
4669 var length = list.length;
4670 var result = new (aTypedArrayConstructor$4(C))(length);
4671 while (length > index) result[index] = list[index++];
4672 return result;
4673 }, FORCED$9);
4674
4675 var $some$1 = arrayIteration.some;
4676
4677 var aTypedArray$j = arrayBufferViewCore.aTypedArray;
4678
4679 // `%TypedArray%.prototype.some` method
4680 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.some
4681 arrayBufferViewCore.exportProto('some', function some(callbackfn /* , thisArg */) {
4682 return $some$1(aTypedArray$j(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
4683 });
4684
4685 var aTypedArray$k = arrayBufferViewCore.aTypedArray;
4686 var $sort = [].sort;
4687
4688 // `%TypedArray%.prototype.sort` method
4689 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.sort
4690 arrayBufferViewCore.exportProto('sort', function sort(comparefn) {
4691 return $sort.call(aTypedArray$k(this), comparefn);
4692 });
4693
4694 var aTypedArray$l = arrayBufferViewCore.aTypedArray;
4695
4696 // `%TypedArray%.prototype.subarray` method
4697 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.subarray
4698 arrayBufferViewCore.exportProto('subarray', function subarray(begin, end) {
4699 var O = aTypedArray$l(this);
4700 var length = O.length;
4701 var beginIndex = toAbsoluteIndex(begin, length);
4702 return new (speciesConstructor(O, O.constructor))(
4703 O.buffer,
4704 O.byteOffset + beginIndex * O.BYTES_PER_ELEMENT,
4705 toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - beginIndex)
4706 );
4707 });
4708
4709 var Int8Array$3 = global_1.Int8Array;
4710 var aTypedArray$m = arrayBufferViewCore.aTypedArray;
4711 var $toLocaleString = [].toLocaleString;
4712 var $slice$1 = [].slice;
4713
4714 // iOS Safari 6.x fails here
4715 var TO_LOCALE_STRING_BUG = !!Int8Array$3 && fails(function () {
4716 $toLocaleString.call(new Int8Array$3(1));
4717 });
4718
4719 var FORCED$a = fails(function () {
4720 return [1, 2].toLocaleString() != new Int8Array$3([1, 2]).toLocaleString();
4721 }) || !fails(function () {
4722 Int8Array$3.prototype.toLocaleString.call([1, 2]);
4723 });
4724
4725 // `%TypedArray%.prototype.toLocaleString` method
4726 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tolocalestring
4727 arrayBufferViewCore.exportProto('toLocaleString', function toLocaleString() {
4728 return $toLocaleString.apply(TO_LOCALE_STRING_BUG ? $slice$1.call(aTypedArray$m(this)) : aTypedArray$m(this), arguments);
4729 }, FORCED$a);
4730
4731 var Uint8Array$2 = global_1.Uint8Array;
4732 var Uint8ArrayPrototype = Uint8Array$2 && Uint8Array$2.prototype;
4733 var arrayToString = [].toString;
4734 var arrayJoin = [].join;
4735
4736 if (fails(function () { arrayToString.call({}); })) {
4737 arrayToString = function toString() {
4738 return arrayJoin.call(this);
4739 };
4740 }
4741
4742 // `%TypedArray%.prototype.toString` method
4743 // https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tostring
4744 arrayBufferViewCore.exportProto('toString', arrayToString, (Uint8ArrayPrototype || {}).toString != arrayToString);
4745
4746 // iterable DOM collections
4747 // flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
4748 var domIterables = {
4749 CSSRuleList: 0,
4750 CSSStyleDeclaration: 0,
4751 CSSValueList: 0,
4752 ClientRectList: 0,
4753 DOMRectList: 0,
4754 DOMStringList: 0,
4755 DOMTokenList: 1,
4756 DataTransferItemList: 0,
4757 FileList: 0,
4758 HTMLAllCollection: 0,
4759 HTMLCollection: 0,
4760 HTMLFormElement: 0,
4761 HTMLSelectElement: 0,
4762 MediaList: 0,
4763 MimeTypeArray: 0,
4764 NamedNodeMap: 0,
4765 NodeList: 1,
4766 PaintRequestList: 0,
4767 Plugin: 0,
4768 PluginArray: 0,
4769 SVGLengthList: 0,
4770 SVGNumberList: 0,
4771 SVGPathSegList: 0,
4772 SVGPointList: 0,
4773 SVGStringList: 0,
4774 SVGTransformList: 0,
4775 SourceBufferList: 0,
4776 StyleSheetList: 0,
4777 TextTrackCueList: 0,
4778 TextTrackList: 0,
4779 TouchList: 0
4780 };
4781
4782 for (var COLLECTION_NAME in domIterables) {
4783 var Collection = global_1[COLLECTION_NAME];
4784 var CollectionPrototype = Collection && Collection.prototype;
4785 // some Chrome versions have non-configurable methods on DOMTokenList
4786 if (CollectionPrototype && CollectionPrototype.forEach !== arrayForEach) try {
4787 createNonEnumerableProperty(CollectionPrototype, 'forEach', arrayForEach);
4788 } catch (error) {
4789 CollectionPrototype.forEach = arrayForEach;
4790 }
4791 }
4792
4793 var ITERATOR$6 = wellKnownSymbol('iterator');
4794 var TO_STRING_TAG$4 = wellKnownSymbol('toStringTag');
4795 var ArrayValues = es_array_iterator.values;
4796
4797 for (var COLLECTION_NAME$1 in domIterables) {
4798 var Collection$1 = global_1[COLLECTION_NAME$1];
4799 var CollectionPrototype$1 = Collection$1 && Collection$1.prototype;
4800 if (CollectionPrototype$1) {
4801 // some Chrome versions have non-configurable methods on DOMTokenList
4802 if (CollectionPrototype$1[ITERATOR$6] !== ArrayValues) try {
4803 createNonEnumerableProperty(CollectionPrototype$1, ITERATOR$6, ArrayValues);
4804 } catch (error) {
4805 CollectionPrototype$1[ITERATOR$6] = ArrayValues;
4806 }
4807 if (!CollectionPrototype$1[TO_STRING_TAG$4]) {
4808 createNonEnumerableProperty(CollectionPrototype$1, TO_STRING_TAG$4, COLLECTION_NAME$1);
4809 }
4810 if (domIterables[COLLECTION_NAME$1]) for (var METHOD_NAME in es_array_iterator) {
4811 // some Chrome versions have non-configurable methods on DOMTokenList
4812 if (CollectionPrototype$1[METHOD_NAME] !== es_array_iterator[METHOD_NAME]) try {
4813 createNonEnumerableProperty(CollectionPrototype$1, METHOD_NAME, es_array_iterator[METHOD_NAME]);
4814 } catch (error) {
4815 CollectionPrototype$1[METHOD_NAME] = es_array_iterator[METHOD_NAME];
4816 }
4817 }
4818 }
4819 }
4820
4821 // `URL.prototype.toJSON` method
4822 // https://url.spec.whatwg.org/#dom-url-tojson
4823 _export({ target: 'URL', proto: true, enumerable: true }, {
4824 toJSON: function toJSON() {
4825 return URL.prototype.toString.call(this);
4826 }
4827 });
4828
4829 function _typeof(obj) {
4830 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
4831 _typeof = function (obj) {
4832 return typeof obj;
4833 };
4834 } else {
4835 _typeof = function (obj) {
4836 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
4837 };
4838 }
4839
4840 return _typeof(obj);
4841 }
4842
4843 function _classCallCheck(instance, Constructor) {
4844 if (!(instance instanceof Constructor)) {
4845 throw new TypeError("Cannot call a class as a function");
4846 }
4847 }
4848
4849 function _defineProperties(target, props) {
4850 for (var i = 0; i < props.length; i++) {
4851 var descriptor = props[i];
4852 descriptor.enumerable = descriptor.enumerable || false;
4853 descriptor.configurable = true;
4854 if ("value" in descriptor) descriptor.writable = true;
4855 Object.defineProperty(target, descriptor.key, descriptor);
4856 }
4857 }
4858
4859 function _createClass(Constructor, protoProps, staticProps) {
4860 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
4861 if (staticProps) _defineProperties(Constructor, staticProps);
4862 return Constructor;
4863 }
4864
4865 function _defineProperty(obj, key, value) {
4866 if (key in obj) {
4867 Object.defineProperty(obj, key, {
4868 value: value,
4869 enumerable: true,
4870 configurable: true,
4871 writable: true
4872 });
4873 } else {
4874 obj[key] = value;
4875 }
4876
4877 return obj;
4878 }
4879
4880 function ownKeys$1(object, enumerableOnly) {
4881 var keys = Object.keys(object);
4882
4883 if (Object.getOwnPropertySymbols) {
4884 var symbols = Object.getOwnPropertySymbols(object);
4885 if (enumerableOnly) symbols = symbols.filter(function (sym) {
4886 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
4887 });
4888 keys.push.apply(keys, symbols);
4889 }
4890
4891 return keys;
4892 }
4893
4894 function _objectSpread2(target) {
4895 for (var i = 1; i < arguments.length; i++) {
4896 var source = arguments[i] != null ? arguments[i] : {};
4897
4898 if (i % 2) {
4899 ownKeys$1(source, true).forEach(function (key) {
4900 _defineProperty(target, key, source[key]);
4901 });
4902 } else if (Object.getOwnPropertyDescriptors) {
4903 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
4904 } else {
4905 ownKeys$1(source).forEach(function (key) {
4906 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
4907 });
4908 }
4909 }
4910
4911 return target;
4912 }
4913
4914 function _inherits(subClass, superClass) {
4915 if (typeof superClass !== "function" && superClass !== null) {
4916 throw new TypeError("Super expression must either be null or a function");
4917 }
4918
4919 subClass.prototype = Object.create(superClass && superClass.prototype, {
4920 constructor: {
4921 value: subClass,
4922 writable: true,
4923 configurable: true
4924 }
4925 });
4926 if (superClass) _setPrototypeOf(subClass, superClass);
4927 }
4928
4929 function _getPrototypeOf(o) {
4930 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
4931 return o.__proto__ || Object.getPrototypeOf(o);
4932 };
4933 return _getPrototypeOf(o);
4934 }
4935
4936 function _setPrototypeOf(o, p) {
4937 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
4938 o.__proto__ = p;
4939 return o;
4940 };
4941
4942 return _setPrototypeOf(o, p);
4943 }
4944
4945 function _assertThisInitialized(self) {
4946 if (self === void 0) {
4947 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
4948 }
4949
4950 return self;
4951 }
4952
4953 function _possibleConstructorReturn(self, call) {
4954 if (call && (typeof call === "object" || typeof call === "function")) {
4955 return call;
4956 }
4957
4958 return _assertThisInitialized(self);
4959 }
4960
4961 function _superPropBase(object, property) {
4962 while (!Object.prototype.hasOwnProperty.call(object, property)) {
4963 object = _getPrototypeOf(object);
4964 if (object === null) break;
4965 }
4966
4967 return object;
4968 }
4969
4970 function _get(target, property, receiver) {
4971 if (typeof Reflect !== "undefined" && Reflect.get) {
4972 _get = Reflect.get;
4973 } else {
4974 _get = function _get(target, property, receiver) {
4975 var base = _superPropBase(target, property);
4976
4977 if (!base) return;
4978 var desc = Object.getOwnPropertyDescriptor(base, property);
4979
4980 if (desc.get) {
4981 return desc.get.call(receiver);
4982 }
4983
4984 return desc.value;
4985 };
4986 }
4987
4988 return _get(target, property, receiver || target);
4989 }
4990
4991 function _readOnlyError(name) {
4992 throw new Error("\"" + name + "\" is read-only");
4993 }
4994
4995 function _slicedToArray(arr, i) {
4996 return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
4997 }
4998
4999 function _arrayWithHoles(arr) {
5000 if (Array.isArray(arr)) return arr;
5001 }
5002
5003 function _iterableToArrayLimit(arr, i) {
5004 if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
5005 return;
5006 }
5007
5008 var _arr = [];
5009 var _n = true;
5010 var _d = false;
5011 var _e = undefined;
5012
5013 try {
5014 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
5015 _arr.push(_s.value);
5016
5017 if (i && _arr.length === i) break;
5018 }
5019 } catch (err) {
5020 _d = true;
5021 _e = err;
5022 } finally {
5023 try {
5024 if (!_n && _i["return"] != null) _i["return"]();
5025 } finally {
5026 if (_d) throw _e;
5027 }
5028 }
5029
5030 return _arr;
5031 }
5032
5033 function _nonIterableRest() {
5034 throw new TypeError("Invalid attempt to destructure non-iterable instance");
5035 }
5036
5037 var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5038
5039 function commonjsRequire() {
5040 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
5041 }
5042
5043 function createCommonjsModule$1(fn, module) {
5044 return module = {
5045 exports: {}
5046 }, fn(module, module.exports), module.exports;
5047 }
5048
5049 var _global = createCommonjsModule$1(function (module) {
5050 // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
5051 var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self // eslint-disable-next-line no-new-func
5052 : Function('return this')();
5053 if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
5054 });
5055
5056 var _core = createCommonjsModule$1(function (module) {
5057 var core = module.exports = {
5058 version: '2.6.9'
5059 };
5060 if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
5061 });
5062
5063 var _core_1 = _core.version;
5064 var _library = false;
5065
5066 var _shared = createCommonjsModule$1(function (module) {
5067 var SHARED = '__core-js_shared__';
5068 var store = _global[SHARED] || (_global[SHARED] = {});
5069 (module.exports = function (key, value) {
5070 return store[key] || (store[key] = value !== undefined ? value : {});
5071 })('versions', []).push({
5072 version: _core.version,
5073 mode: 'global',
5074 copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
5075 });
5076 });
5077
5078 var id$1 = 0;
5079 var px = Math.random();
5080
5081 var _uid = function _uid(key) {
5082 return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id$1 + px).toString(36));
5083 };
5084
5085 var _wks = createCommonjsModule$1(function (module) {
5086 var store = _shared('wks');
5087
5088 var _Symbol = _global.Symbol;
5089 var USE_SYMBOL = typeof _Symbol == 'function';
5090
5091 var $exports = module.exports = function (name) {
5092 return store[name] || (store[name] = USE_SYMBOL && _Symbol[name] || (USE_SYMBOL ? _Symbol : _uid)('Symbol.' + name));
5093 };
5094
5095 $exports.store = store;
5096 });
5097
5098 var f$7 = _wks;
5099 var _wksExt = {
5100 f: f$7
5101 };
5102
5103 var _isObject = function _isObject(it) {
5104 return _typeof(it) === 'object' ? it !== null : typeof it === 'function';
5105 };
5106
5107 var _anObject = function _anObject(it) {
5108 if (!_isObject(it)) throw TypeError(it + ' is not an object!');
5109 return it;
5110 };
5111
5112 var _fails = function _fails(exec) {
5113 try {
5114 return !!exec();
5115 } catch (e) {
5116 return true;
5117 }
5118 };
5119
5120 var _descriptors = !_fails(function () {
5121 return Object.defineProperty({}, 'a', {
5122 get: function get() {
5123 return 7;
5124 }
5125 }).a != 7;
5126 });
5127
5128 var document$1$1 = _global.document; // typeof document.createElement is 'object' in old IE
5129
5130 var is = _isObject(document$1$1) && _isObject(document$1$1.createElement);
5131
5132 var _domCreate = function _domCreate(it) {
5133 return is ? document$1$1.createElement(it) : {};
5134 };
5135
5136 var _ie8DomDefine = !_descriptors && !_fails(function () {
5137 return Object.defineProperty(_domCreate('div'), 'a', {
5138 get: function get() {
5139 return 7;
5140 }
5141 }).a != 7;
5142 }); // instead of the ES6 spec version, we didn't implement @@toPrimitive case
5143 // and the second argument - flag - preferred type is a string
5144
5145
5146 var _toPrimitive = function _toPrimitive(it, S) {
5147 if (!_isObject(it)) return it;
5148 var fn, val;
5149 if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
5150 if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
5151 if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
5152 throw TypeError("Can't convert object to primitive value");
5153 };
5154
5155 var dP = Object.defineProperty;
5156 var f$1$1 = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
5157 _anObject(O);
5158
5159 P = _toPrimitive(P, true);
5160
5161 _anObject(Attributes);
5162
5163 if (_ie8DomDefine) try {
5164 return dP(O, P, Attributes);
5165 } catch (e) {
5166 /* empty */
5167 }
5168 if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
5169 if ('value' in Attributes) O[P] = Attributes.value;
5170 return O;
5171 };
5172 var _objectDp = {
5173 f: f$1$1
5174 };
5175 var defineProperty$8 = _objectDp.f;
5176
5177 var _wksDefine = function _wksDefine(name) {
5178 var $Symbol = _core.Symbol || (_core.Symbol = _global.Symbol || {});
5179 if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty$8($Symbol, name, {
5180 value: _wksExt.f(name)
5181 });
5182 };
5183
5184 _wksDefine('asyncIterator');
5185
5186 var hasOwnProperty$1 = {}.hasOwnProperty;
5187
5188 var _has = function _has(it, key) {
5189 return hasOwnProperty$1.call(it, key);
5190 };
5191
5192 var _propertyDesc = function _propertyDesc(bitmap, value) {
5193 return {
5194 enumerable: !(bitmap & 1),
5195 configurable: !(bitmap & 2),
5196 writable: !(bitmap & 4),
5197 value: value
5198 };
5199 };
5200
5201 var _hide = _descriptors ? function (object, key, value) {
5202 return _objectDp.f(object, key, _propertyDesc(1, value));
5203 } : function (object, key, value) {
5204 object[key] = value;
5205 return object;
5206 };
5207
5208 var _functionToString = _shared('native-function-to-string', Function.toString);
5209
5210 var _redefine = createCommonjsModule$1(function (module) {
5211 var SRC = _uid('src');
5212
5213 var TO_STRING = 'toString';
5214
5215 var TPL = ('' + _functionToString).split(TO_STRING);
5216
5217 _core.inspectSource = function (it) {
5218 return _functionToString.call(it);
5219 };
5220
5221 (module.exports = function (O, key, val, safe) {
5222 var isFunction = typeof val == 'function';
5223 if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
5224 if (O[key] === val) return;
5225 if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
5226
5227 if (O === _global) {
5228 O[key] = val;
5229 } else if (!safe) {
5230 delete O[key];
5231
5232 _hide(O, key, val);
5233 } else if (O[key]) {
5234 O[key] = val;
5235 } else {
5236 _hide(O, key, val);
5237 } // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
5238
5239 })(Function.prototype, TO_STRING, function toString() {
5240 return typeof this == 'function' && this[SRC] || _functionToString.call(this);
5241 });
5242 });
5243
5244 var _aFunction = function _aFunction(it) {
5245 if (typeof it != 'function') throw TypeError(it + ' is not a function!');
5246 return it;
5247 };
5248
5249 var _ctx = function _ctx(fn, that, length) {
5250 _aFunction(fn);
5251
5252 if (that === undefined) return fn;
5253
5254 switch (length) {
5255 case 1:
5256 return function (a) {
5257 return fn.call(that, a);
5258 };
5259
5260 case 2:
5261 return function (a, b) {
5262 return fn.call(that, a, b);
5263 };
5264
5265 case 3:
5266 return function (a, b, c) {
5267 return fn.call(that, a, b, c);
5268 };
5269 }
5270
5271 return function ()
5272 /* ...args */
5273 {
5274 return fn.apply(that, arguments);
5275 };
5276 };
5277
5278 var PROTOTYPE$3 = 'prototype';
5279
5280 var $export = function $export(type, name, source) {
5281 var IS_FORCED = type & $export.F;
5282 var IS_GLOBAL = type & $export.G;
5283 var IS_STATIC = type & $export.S;
5284 var IS_PROTO = type & $export.P;
5285 var IS_BIND = type & $export.B;
5286 var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE$3];
5287 var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
5288 var expProto = exports[PROTOTYPE$3] || (exports[PROTOTYPE$3] = {});
5289 var key, own, out, exp;
5290 if (IS_GLOBAL) source = name;
5291
5292 for (key in source) {
5293 // contains in native
5294 own = !IS_FORCED && target && target[key] !== undefined; // export native or passed
5295
5296 out = (own ? target : source)[key]; // bind timers to global for call from export context
5297
5298 exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; // extend global
5299
5300 if (target) _redefine(target, key, out, type & $export.U); // export
5301
5302 if (exports[key] != out) _hide(exports, key, exp);
5303 if (IS_PROTO && expProto[key] != out) expProto[key] = out;
5304 }
5305 };
5306
5307 _global.core = _core; // type bitmap
5308
5309 $export.F = 1; // forced
5310
5311 $export.G = 2; // global
5312
5313 $export.S = 4; // static
5314
5315 $export.P = 8; // proto
5316
5317 $export.B = 16; // bind
5318
5319 $export.W = 32; // wrap
5320
5321 $export.U = 64; // safe
5322
5323 $export.R = 128; // real proto method for `library`
5324
5325 var _export$1 = $export;
5326
5327 var _meta = createCommonjsModule$1(function (module) {
5328 var META = _uid('meta');
5329
5330 var setDesc = _objectDp.f;
5331 var id = 0;
5332
5333 var isExtensible = Object.isExtensible || function () {
5334 return true;
5335 };
5336
5337 var FREEZE = !_fails(function () {
5338 return isExtensible(Object.preventExtensions({}));
5339 });
5340
5341 var setMeta = function setMeta(it) {
5342 setDesc(it, META, {
5343 value: {
5344 i: 'O' + ++id,
5345 // object ID
5346 w: {} // weak collections IDs
5347
5348 }
5349 });
5350 };
5351
5352 var fastKey = function fastKey(it, create) {
5353 // return primitive with prefix
5354 if (!_isObject(it)) return _typeof(it) == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
5355
5356 if (!_has(it, META)) {
5357 // can't set metadata to uncaught frozen object
5358 if (!isExtensible(it)) return 'F'; // not necessary to add metadata
5359
5360 if (!create) return 'E'; // add missing metadata
5361
5362 setMeta(it); // return object ID
5363 }
5364
5365 return it[META].i;
5366 };
5367
5368 var getWeak = function getWeak(it, create) {
5369 if (!_has(it, META)) {
5370 // can't set metadata to uncaught frozen object
5371 if (!isExtensible(it)) return true; // not necessary to add metadata
5372
5373 if (!create) return false; // add missing metadata
5374
5375 setMeta(it); // return hash weak collections IDs
5376 }
5377
5378 return it[META].w;
5379 }; // add metadata on freeze-family methods calling
5380
5381
5382 var onFreeze = function onFreeze(it) {
5383 if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it);
5384 return it;
5385 };
5386
5387 var meta = module.exports = {
5388 KEY: META,
5389 NEED: false,
5390 fastKey: fastKey,
5391 getWeak: getWeak,
5392 onFreeze: onFreeze
5393 };
5394 });
5395
5396 var _meta_1 = _meta.KEY;
5397 var _meta_2 = _meta.NEED;
5398 var _meta_3 = _meta.fastKey;
5399 var _meta_4 = _meta.getWeak;
5400 var _meta_5 = _meta.onFreeze;
5401 var def = _objectDp.f;
5402
5403 var TAG = _wks('toStringTag');
5404
5405 var _setToStringTag = function _setToStringTag(it, tag, stat) {
5406 if (it && !_has(it = stat ? it : it.prototype, TAG)) def(it, TAG, {
5407 configurable: true,
5408 value: tag
5409 });
5410 };
5411
5412 var toString$2 = {}.toString;
5413
5414 var _cof = function _cof(it) {
5415 return toString$2.call(it).slice(8, -1);
5416 }; // eslint-disable-next-line no-prototype-builtins
5417
5418
5419 var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
5420 return _cof(it) == 'String' ? it.split('') : Object(it);
5421 }; // 7.2.1 RequireObjectCoercible(argument)
5422
5423
5424 var _defined = function _defined(it) {
5425 if (it == undefined) throw TypeError("Can't call method on " + it);
5426 return it;
5427 };
5428
5429 var _toIobject = function _toIobject(it) {
5430 return _iobject(_defined(it));
5431 }; // 7.1.4 ToInteger
5432
5433
5434 var ceil$2 = Math.ceil;
5435 var floor$5 = Math.floor;
5436
5437 var _toInteger = function _toInteger(it) {
5438 return isNaN(it = +it) ? 0 : (it > 0 ? floor$5 : ceil$2)(it);
5439 };
5440
5441 var min$7 = Math.min;
5442
5443 var _toLength = function _toLength(it) {
5444 return it > 0 ? min$7(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
5445 };
5446
5447 var max$4 = Math.max;
5448 var min$1$1 = Math.min;
5449
5450 var _toAbsoluteIndex = function _toAbsoluteIndex(index, length) {
5451 index = _toInteger(index);
5452 return index < 0 ? max$4(index + length, 0) : min$1$1(index, length);
5453 }; // true -> Array#includes
5454
5455
5456 var _arrayIncludes = function _arrayIncludes(IS_INCLUDES) {
5457 return function ($this, el, fromIndex) {
5458 var O = _toIobject($this);
5459
5460 var length = _toLength(O.length);
5461
5462 var index = _toAbsoluteIndex(fromIndex, length);
5463
5464 var value; // Array#includes uses SameValueZero equality algorithm
5465 // eslint-disable-next-line no-self-compare
5466
5467 if (IS_INCLUDES && el != el) while (length > index) {
5468 value = O[index++]; // eslint-disable-next-line no-self-compare
5469
5470 if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not
5471 } else for (; length > index; index++) {
5472 if (IS_INCLUDES || index in O) {
5473 if (O[index] === el) return IS_INCLUDES || index || 0;
5474 }
5475 }
5476 return !IS_INCLUDES && -1;
5477 };
5478 };
5479
5480 var shared$1 = _shared('keys');
5481
5482 var _sharedKey = function _sharedKey(key) {
5483 return shared$1[key] || (shared$1[key] = _uid(key));
5484 };
5485
5486 var arrayIndexOf = _arrayIncludes(false);
5487
5488 var IE_PROTO$2 = _sharedKey('IE_PROTO');
5489
5490 var _objectKeysInternal = function _objectKeysInternal(object, names) {
5491 var O = _toIobject(object);
5492
5493 var i = 0;
5494 var result = [];
5495 var key;
5496
5497 for (key in O) {
5498 if (key != IE_PROTO$2) _has(O, key) && result.push(key);
5499 } // Don't enum bug & hidden keys
5500
5501
5502 while (names.length > i) {
5503 if (_has(O, key = names[i++])) {
5504 ~arrayIndexOf(result, key) || result.push(key);
5505 }
5506 }
5507
5508 return result;
5509 }; // IE 8- don't enum bug keys
5510
5511
5512 var _enumBugKeys = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(',');
5513
5514 var _objectKeys = Object.keys || function keys(O) {
5515 return _objectKeysInternal(O, _enumBugKeys);
5516 };
5517
5518 var f$2$1 = Object.getOwnPropertySymbols;
5519 var _objectGops = {
5520 f: f$2$1
5521 };
5522 var f$3$1 = {}.propertyIsEnumerable;
5523 var _objectPie = {
5524 f: f$3$1
5525 };
5526
5527 var _enumKeys = function _enumKeys(it) {
5528 var result = _objectKeys(it);
5529
5530 var getSymbols = _objectGops.f;
5531
5532 if (getSymbols) {
5533 var symbols = getSymbols(it);
5534 var isEnum = _objectPie.f;
5535 var i = 0;
5536 var key;
5537
5538 while (symbols.length > i) {
5539 if (isEnum.call(it, key = symbols[i++])) result.push(key);
5540 }
5541 }
5542
5543 return result;
5544 };
5545
5546 var _isArray = Array.isArray || function isArray(arg) {
5547 return _cof(arg) == 'Array';
5548 };
5549
5550 var _toObject = function _toObject(it) {
5551 return Object(_defined(it));
5552 };
5553
5554 var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
5555 _anObject(O);
5556
5557 var keys = _objectKeys(Properties);
5558
5559 var length = keys.length;
5560 var i = 0;
5561 var P;
5562
5563 while (length > i) {
5564 _objectDp.f(O, P = keys[i++], Properties[P]);
5565 }
5566
5567 return O;
5568 };
5569
5570 var document$2 = _global.document;
5571
5572 var _html = document$2 && document$2.documentElement;
5573
5574 var IE_PROTO$1$1 = _sharedKey('IE_PROTO');
5575
5576 var Empty$1 = function Empty() {
5577 /* empty */
5578 };
5579
5580 var PROTOTYPE$1$1 = 'prototype'; // Create object with fake `null` prototype: use iframe Object with cleared prototype
5581
5582 var _createDict = function createDict() {
5583 // Thrash, waste and sodomy: IE GC bug
5584 var iframe = _domCreate('iframe');
5585
5586 var i = _enumBugKeys.length;
5587 var lt = '<';
5588 var gt = '>';
5589 var iframeDocument;
5590 iframe.style.display = 'none';
5591
5592 _html.appendChild(iframe);
5593
5594 iframe.src = 'javascript:'; // eslint-disable-line no-script-url
5595 // createDict = iframe.contentWindow.Object;
5596 // html.removeChild(iframe);
5597
5598 iframeDocument = iframe.contentWindow.document;
5599 iframeDocument.open();
5600 iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
5601 iframeDocument.close();
5602 _createDict = iframeDocument.F;
5603
5604 while (i--) {
5605 delete _createDict[PROTOTYPE$1$1][_enumBugKeys[i]];
5606 }
5607
5608 return _createDict();
5609 };
5610
5611 var _objectCreate = Object.create || function create(O, Properties) {
5612 var result;
5613
5614 if (O !== null) {
5615 Empty$1[PROTOTYPE$1$1] = _anObject(O);
5616 result = new Empty$1();
5617 Empty$1[PROTOTYPE$1$1] = null; // add "__proto__" for Object.getPrototypeOf polyfill
5618
5619 result[IE_PROTO$1$1] = O;
5620 } else result = _createDict();
5621
5622 return Properties === undefined ? result : _objectDps(result, Properties);
5623 };
5624
5625 var hiddenKeys$2 = _enumBugKeys.concat('length', 'prototype');
5626
5627 var f$4$1 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
5628 return _objectKeysInternal(O, hiddenKeys$2);
5629 };
5630
5631 var _objectGopn = {
5632 f: f$4$1
5633 };
5634 var gOPN = _objectGopn.f;
5635 var toString$1$1 = {}.toString;
5636 var windowNames$1 = (typeof window === "undefined" ? "undefined" : _typeof(window)) == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : [];
5637
5638 var getWindowNames$1 = function getWindowNames(it) {
5639 try {
5640 return gOPN(it);
5641 } catch (e) {
5642 return windowNames$1.slice();
5643 }
5644 };
5645
5646 var f$5$1 = function getOwnPropertyNames(it) {
5647 return windowNames$1 && toString$1$1.call(it) == '[object Window]' ? getWindowNames$1(it) : gOPN(_toIobject(it));
5648 };
5649
5650 var _objectGopnExt = {
5651 f: f$5$1
5652 };
5653 var gOPD = Object.getOwnPropertyDescriptor;
5654 var f$6$1 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) {
5655 O = _toIobject(O);
5656 P = _toPrimitive(P, true);
5657 if (_ie8DomDefine) try {
5658 return gOPD(O, P);
5659 } catch (e) {
5660 /* empty */
5661 }
5662 if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]);
5663 };
5664 var _objectGopd = {
5665 f: f$6$1
5666 };
5667 var META = _meta.KEY;
5668 var gOPD$1 = _objectGopd.f;
5669 var dP$1 = _objectDp.f;
5670 var gOPN$1 = _objectGopnExt.f;
5671 var $Symbol$1 = _global.Symbol;
5672 var $JSON = _global.JSON;
5673
5674 var _stringify = $JSON && $JSON.stringify;
5675
5676 var PROTOTYPE$2$1 = 'prototype';
5677
5678 var HIDDEN$1 = _wks('_hidden');
5679
5680 var TO_PRIMITIVE$1 = _wks('toPrimitive');
5681
5682 var isEnum = {}.propertyIsEnumerable;
5683
5684 var SymbolRegistry = _shared('symbol-registry');
5685
5686 var AllSymbols$1 = _shared('symbols');
5687
5688 var OPSymbols = _shared('op-symbols');
5689
5690 var ObjectProto = Object[PROTOTYPE$2$1];
5691 var USE_NATIVE = typeof $Symbol$1 == 'function' && !!_objectGops.f;
5692 var QObject$1 = _global.QObject; // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
5693
5694 var setter = !QObject$1 || !QObject$1[PROTOTYPE$2$1] || !QObject$1[PROTOTYPE$2$1].findChild; // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
5695
5696 var setSymbolDesc = _descriptors && _fails(function () {
5697 return _objectCreate(dP$1({}, 'a', {
5698 get: function get() {
5699 return dP$1(this, 'a', {
5700 value: 7
5701 }).a;
5702 }
5703 })).a != 7;
5704 }) ? function (it, key, D) {
5705 var protoDesc = gOPD$1(ObjectProto, key);
5706 if (protoDesc) delete ObjectProto[key];
5707 dP$1(it, key, D);
5708 if (protoDesc && it !== ObjectProto) dP$1(ObjectProto, key, protoDesc);
5709 } : dP$1;
5710
5711 var wrap$1 = function wrap(tag) {
5712 var sym = AllSymbols$1[tag] = _objectCreate($Symbol$1[PROTOTYPE$2$1]);
5713
5714 sym._k = tag;
5715 return sym;
5716 };
5717
5718 var isSymbol$1 = USE_NATIVE && _typeof($Symbol$1.iterator) == 'symbol' ? function (it) {
5719 return _typeof(it) == 'symbol';
5720 } : function (it) {
5721 return it instanceof $Symbol$1;
5722 };
5723
5724 var $defineProperty$1 = function defineProperty(it, key, D) {
5725 if (it === ObjectProto) $defineProperty$1(OPSymbols, key, D);
5726
5727 _anObject(it);
5728
5729 key = _toPrimitive(key, true);
5730
5731 _anObject(D);
5732
5733 if (_has(AllSymbols$1, key)) {
5734 if (!D.enumerable) {
5735 if (!_has(it, HIDDEN$1)) dP$1(it, HIDDEN$1, _propertyDesc(1, {}));
5736 it[HIDDEN$1][key] = true;
5737 } else {
5738 if (_has(it, HIDDEN$1) && it[HIDDEN$1][key]) it[HIDDEN$1][key] = false;
5739 D = _objectCreate(D, {
5740 enumerable: _propertyDesc(0, false)
5741 });
5742 }
5743
5744 return setSymbolDesc(it, key, D);
5745 }
5746
5747 return dP$1(it, key, D);
5748 };
5749
5750 var $defineProperties$1 = function defineProperties(it, P) {
5751 _anObject(it);
5752
5753 var keys = _enumKeys(P = _toIobject(P));
5754
5755 var i = 0;
5756 var l = keys.length;
5757 var key;
5758
5759 while (l > i) {
5760 $defineProperty$1(it, key = keys[i++], P[key]);
5761 }
5762
5763 return it;
5764 };
5765
5766 var $create$1 = function create(it, P) {
5767 return P === undefined ? _objectCreate(it) : $defineProperties$1(_objectCreate(it), P);
5768 };
5769
5770 var $propertyIsEnumerable$1 = function propertyIsEnumerable(key) {
5771 var E = isEnum.call(this, key = _toPrimitive(key, true));
5772 if (this === ObjectProto && _has(AllSymbols$1, key) && !_has(OPSymbols, key)) return false;
5773 return E || !_has(this, key) || !_has(AllSymbols$1, key) || _has(this, HIDDEN$1) && this[HIDDEN$1][key] ? E : true;
5774 };
5775
5776 var $getOwnPropertyDescriptor$1 = function getOwnPropertyDescriptor(it, key) {
5777 it = _toIobject(it);
5778 key = _toPrimitive(key, true);
5779 if (it === ObjectProto && _has(AllSymbols$1, key) && !_has(OPSymbols, key)) return;
5780 var D = gOPD$1(it, key);
5781 if (D && _has(AllSymbols$1, key) && !(_has(it, HIDDEN$1) && it[HIDDEN$1][key])) D.enumerable = true;
5782 return D;
5783 };
5784
5785 var $getOwnPropertyNames$1 = function getOwnPropertyNames(it) {
5786 var names = gOPN$1(_toIobject(it));
5787 var result = [];
5788 var i = 0;
5789 var key;
5790
5791 while (names.length > i) {
5792 if (!_has(AllSymbols$1, key = names[i++]) && key != HIDDEN$1 && key != META) result.push(key);
5793 }
5794
5795 return result;
5796 };
5797
5798 var $getOwnPropertySymbols$1 = function getOwnPropertySymbols(it) {
5799 var IS_OP = it === ObjectProto;
5800 var names = gOPN$1(IS_OP ? OPSymbols : _toIobject(it));
5801 var result = [];
5802 var i = 0;
5803 var key;
5804
5805 while (names.length > i) {
5806 if (_has(AllSymbols$1, key = names[i++]) && (IS_OP ? _has(ObjectProto, key) : true)) result.push(AllSymbols$1[key]);
5807 }
5808
5809 return result;
5810 }; // 19.4.1.1 Symbol([description])
5811
5812
5813 if (!USE_NATIVE) {
5814 $Symbol$1 = function _Symbol2() {
5815 if (this instanceof $Symbol$1) throw TypeError('Symbol is not a constructor!');
5816
5817 var tag = _uid(arguments.length > 0 ? arguments[0] : undefined);
5818
5819 var $set = function $set(value) {
5820 if (this === ObjectProto) $set.call(OPSymbols, value);
5821 if (_has(this, HIDDEN$1) && _has(this[HIDDEN$1], tag)) this[HIDDEN$1][tag] = false;
5822 setSymbolDesc(this, tag, _propertyDesc(1, value));
5823 };
5824
5825 if (_descriptors && setter) setSymbolDesc(ObjectProto, tag, {
5826 configurable: true,
5827 set: $set
5828 });
5829 return wrap$1(tag);
5830 };
5831
5832 _redefine($Symbol$1[PROTOTYPE$2$1], 'toString', function toString() {
5833 return this._k;
5834 });
5835
5836 _objectGopd.f = $getOwnPropertyDescriptor$1;
5837 _objectDp.f = $defineProperty$1;
5838 _objectGopn.f = _objectGopnExt.f = $getOwnPropertyNames$1;
5839 _objectPie.f = $propertyIsEnumerable$1;
5840 _objectGops.f = $getOwnPropertySymbols$1;
5841
5842 if (_descriptors && !_library) {
5843 _redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable$1, true);
5844 }
5845
5846 _wksExt.f = function (name) {
5847 return wrap$1(_wks(name));
5848 };
5849 }
5850
5851 _export$1(_export$1.G + _export$1.W + _export$1.F * !USE_NATIVE, {
5852 Symbol: $Symbol$1
5853 });
5854
5855 for (var es6Symbols = // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
5856 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'.split(','), j$2 = 0; es6Symbols.length > j$2;) {
5857 _wks(es6Symbols[j$2++]);
5858 }
5859
5860 for (var wellKnownSymbols = _objectKeys(_wks.store), k = 0; wellKnownSymbols.length > k;) {
5861 _wksDefine(wellKnownSymbols[k++]);
5862 }
5863
5864 _export$1(_export$1.S + _export$1.F * !USE_NATIVE, 'Symbol', {
5865 // 19.4.2.1 Symbol.for(key)
5866 'for': function _for(key) {
5867 return _has(SymbolRegistry, key += '') ? SymbolRegistry[key] : SymbolRegistry[key] = $Symbol$1(key);
5868 },
5869 // 19.4.2.5 Symbol.keyFor(sym)
5870 keyFor: function keyFor(sym) {
5871 if (!isSymbol$1(sym)) throw TypeError(sym + ' is not a symbol!');
5872
5873 for (var key in SymbolRegistry) {
5874 if (SymbolRegistry[key] === sym) return key;
5875 }
5876 },
5877 useSetter: function useSetter() {
5878 setter = true;
5879 },
5880 useSimple: function useSimple() {
5881 setter = false;
5882 }
5883 });
5884
5885 _export$1(_export$1.S + _export$1.F * !USE_NATIVE, 'Object', {
5886 // 19.1.2.2 Object.create(O [, Properties])
5887 create: $create$1,
5888 // 19.1.2.4 Object.defineProperty(O, P, Attributes)
5889 defineProperty: $defineProperty$1,
5890 // 19.1.2.3 Object.defineProperties(O, Properties)
5891 defineProperties: $defineProperties$1,
5892 // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
5893 getOwnPropertyDescriptor: $getOwnPropertyDescriptor$1,
5894 // 19.1.2.7 Object.getOwnPropertyNames(O)
5895 getOwnPropertyNames: $getOwnPropertyNames$1,
5896 // 19.1.2.8 Object.getOwnPropertySymbols(O)
5897 getOwnPropertySymbols: $getOwnPropertySymbols$1
5898 }); // Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
5899 // https://bugs.chromium.org/p/v8/issues/detail?id=3443
5900
5901
5902 var FAILS_ON_PRIMITIVES$8 = _fails(function () {
5903 _objectGops.f(1);
5904 });
5905
5906 _export$1(_export$1.S + _export$1.F * FAILS_ON_PRIMITIVES$8, 'Object', {
5907 getOwnPropertySymbols: function getOwnPropertySymbols(it) {
5908 return _objectGops.f(_toObject(it));
5909 }
5910 }); // 24.3.2 JSON.stringify(value [, replacer [, space]])
5911
5912
5913 $JSON && _export$1(_export$1.S + _export$1.F * (!USE_NATIVE || _fails(function () {
5914 var S = $Symbol$1(); // MS Edge converts symbol values to JSON as {}
5915 // WebKit converts symbol values to JSON as null
5916 // V8 throws on boxed symbols
5917
5918 return _stringify([S]) != '[null]' || _stringify({
5919 a: S
5920 }) != '{}' || _stringify(Object(S)) != '{}';
5921 })), 'JSON', {
5922 stringify: function stringify(it) {
5923 var args = [it];
5924 var i = 1;
5925 var replacer, $replacer;
5926
5927 while (arguments.length > i) {
5928 args.push(arguments[i++]);
5929 }
5930
5931 $replacer = replacer = args[1];
5932 if (!_isObject(replacer) && it === undefined || isSymbol$1(it)) return; // IE8 returns string on undefined
5933
5934 if (!_isArray(replacer)) replacer = function replacer(key, value) {
5935 if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
5936 if (!isSymbol$1(value)) return value;
5937 };
5938 args[1] = replacer;
5939 return _stringify.apply($JSON, args);
5940 }
5941 }); // 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
5942
5943 $Symbol$1[PROTOTYPE$2$1][TO_PRIMITIVE$1] || _hide($Symbol$1[PROTOTYPE$2$1], TO_PRIMITIVE$1, $Symbol$1[PROTOTYPE$2$1].valueOf); // 19.4.3.5 Symbol.prototype[@@toStringTag]
5944
5945 _setToStringTag($Symbol$1, 'Symbol'); // 20.2.1.9 Math[@@toStringTag]
5946
5947
5948 _setToStringTag(Math, 'Math', true); // 24.3.3 JSON[@@toStringTag]
5949
5950
5951 _setToStringTag(_global.JSON, 'JSON', true);
5952
5953 function _typeof$1(obj) {
5954 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
5955 _typeof$1 = function _typeof$1(obj) {
5956 return _typeof(obj);
5957 };
5958 } else {
5959 _typeof$1 = function _typeof$1(obj) {
5960 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
5961 };
5962 }
5963
5964 return _typeof$1(obj);
5965 }
5966
5967 function _defineProperty$1(obj, key, value) {
5968 if (key in obj) {
5969 Object.defineProperty(obj, key, {
5970 value: value,
5971 enumerable: true,
5972 configurable: true,
5973 writable: true
5974 });
5975 } else {
5976 obj[key] = value;
5977 }
5978
5979 return obj;
5980 }
5981
5982 function ownKeys$2(object, enumerableOnly) {
5983 var keys = Object.keys(object);
5984
5985 if (Object.getOwnPropertySymbols) {
5986 var symbols = Object.getOwnPropertySymbols(object);
5987 if (enumerableOnly) symbols = symbols.filter(function (sym) {
5988 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
5989 });
5990 keys.push.apply(keys, symbols);
5991 }
5992
5993 return keys;
5994 }
5995
5996 function _objectSpread2$1(target) {
5997 for (var i = 1; i < arguments.length; i++) {
5998 var source = arguments[i] != null ? arguments[i] : {};
5999
6000 if (i % 2) {
6001 ownKeys$2(source, true).forEach(function (key) {
6002 _defineProperty$1(target, key, source[key]);
6003 });
6004 } else if (Object.getOwnPropertyDescriptors) {
6005 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
6006 } else {
6007 ownKeys$2(source).forEach(function (key) {
6008 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
6009 });
6010 }
6011 }
6012
6013 return target;
6014 }
6015
6016 function _toConsumableArray(arr) {
6017 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
6018 }
6019
6020 function _arrayWithoutHoles(arr) {
6021 if (Array.isArray(arr)) {
6022 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
6023 arr2[i] = arr[i];
6024 }
6025
6026 return arr2;
6027 }
6028 }
6029
6030 function _iterableToArray(iter) {
6031 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
6032 }
6033
6034 function _nonIterableSpread() {
6035 throw new TypeError("Invalid attempt to spread non-iterable instance");
6036 }
6037
6038 var _objectSap = function _objectSap(KEY, exec) {
6039 var fn = (_core.Object || {})[KEY] || Object[KEY];
6040 var exp = {};
6041 exp[KEY] = exec(fn);
6042
6043 _export$1(_export$1.S + _export$1.F * _fails(function () {
6044 fn(1);
6045 }), 'Object', exp);
6046 };
6047
6048 _objectSap('keys', function () {
6049 return function keys(it) {
6050 return _objectKeys(_toObject(it));
6051 };
6052 });
6053
6054 var _flags = function _flags() {
6055 var that = _anObject(this);
6056
6057 var result = '';
6058 if (that.global) result += 'g';
6059 if (that.ignoreCase) result += 'i';
6060 if (that.multiline) result += 'm';
6061 if (that.unicode) result += 'u';
6062 if (that.sticky) result += 'y';
6063 return result;
6064 };
6065
6066 if (_descriptors && /./g.flags != 'g') _objectDp.f(RegExp.prototype, 'flags', {
6067 configurable: true,
6068 get: _flags
6069 });
6070 var TO_STRING$2 = 'toString';
6071 var $toString = /./[TO_STRING$2];
6072
6073 var define = function define(fn) {
6074 _redefine(RegExp.prototype, TO_STRING$2, fn, true);
6075 }; // 21.2.5.14 RegExp.prototype.toString()
6076
6077
6078 if (_fails(function () {
6079 return $toString.call({
6080 source: 'a',
6081 flags: 'b'
6082 }) != '/a/b';
6083 })) {
6084 define(function toString() {
6085 var R = _anObject(this);
6086
6087 return '/'.concat(R.source, '/', 'flags' in R ? R.flags : !_descriptors && R instanceof RegExp ? _flags.call(R) : undefined);
6088 }); // FF44- RegExp#toString has a wrong name
6089 } else if ($toString.name != TO_STRING$2) {
6090 define(function toString() {
6091 return $toString.call(this);
6092 });
6093 } // false -> String#codePointAt
6094
6095
6096 var _stringAt = function _stringAt(TO_STRING) {
6097 return function (that, pos) {
6098 var s = String(_defined(that));
6099
6100 var i = _toInteger(pos);
6101
6102 var l = s.length;
6103 var a, b;
6104 if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
6105 a = s.charCodeAt(i);
6106 return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
6107 };
6108 };
6109
6110 var at = _stringAt(true); // `AdvanceStringIndex` abstract operation
6111 // https://tc39.github.io/ecma262/#sec-advancestringindex
6112
6113
6114 var _advanceStringIndex = function _advanceStringIndex(S, index, unicode) {
6115 return index + (unicode ? at(S, index).length : 1);
6116 };
6117
6118 var TAG$1 = _wks('toStringTag'); // ES3 wrong here
6119
6120
6121 var ARG = _cof(function () {
6122 return arguments;
6123 }()) == 'Arguments'; // fallback for IE11 Script Access Denied error
6124
6125 var tryGet$1 = function tryGet(it, key) {
6126 try {
6127 return it[key];
6128 } catch (e) {
6129 /* empty */
6130 }
6131 };
6132
6133 var _classof = function _classof(it) {
6134 var O, T, B;
6135 return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case
6136 : typeof (T = tryGet$1(O = Object(it), TAG$1)) == 'string' ? T // builtinTag case
6137 : ARG ? _cof(O) // ES3 arguments fallback
6138 : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
6139 };
6140
6141 var builtinExec = RegExp.prototype.exec; // `RegExpExec` abstract operation
6142 // https://tc39.github.io/ecma262/#sec-regexpexec
6143
6144 var _regexpExecAbstract = function _regexpExecAbstract(R, S) {
6145 var exec = R.exec;
6146
6147 if (typeof exec === 'function') {
6148 var result = exec.call(R, S);
6149
6150 if (_typeof(result) !== 'object') {
6151 throw new TypeError('RegExp exec method returned something other than an Object or null');
6152 }
6153
6154 return result;
6155 }
6156
6157 if (_classof(R) !== 'RegExp') {
6158 throw new TypeError('RegExp#exec called on incompatible receiver');
6159 }
6160
6161 return builtinExec.call(R, S);
6162 };
6163
6164 var nativeExec$1 = RegExp.prototype.exec; // This always refers to the native implementation, because the
6165 // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
6166 // which loads this file before patching the method.
6167
6168 var nativeReplace$1 = String.prototype.replace;
6169 var patchedExec$1 = nativeExec$1;
6170 var LAST_INDEX = 'lastIndex';
6171
6172 var UPDATES_LAST_INDEX_WRONG$1 = function () {
6173 var re1 = /a/,
6174 re2 = /b*/g;
6175 nativeExec$1.call(re1, 'a');
6176 nativeExec$1.call(re2, 'a');
6177 return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;
6178 }(); // nonparticipating capturing group, copied from es5-shim's String#split patch.
6179
6180
6181 var NPCG_INCLUDED$1 = /()??/.exec('')[1] !== undefined;
6182 var PATCH$1 = UPDATES_LAST_INDEX_WRONG$1 || NPCG_INCLUDED$1;
6183
6184 if (PATCH$1) {
6185 patchedExec$1 = function exec(str) {
6186 var re = this;
6187 var lastIndex, reCopy, match, i;
6188
6189 if (NPCG_INCLUDED$1) {
6190 reCopy = new RegExp('^' + re.source + '$(?!\\s)', _flags.call(re));
6191 }
6192
6193 if (UPDATES_LAST_INDEX_WRONG$1) lastIndex = re[LAST_INDEX];
6194 match = nativeExec$1.call(re, str);
6195
6196 if (UPDATES_LAST_INDEX_WRONG$1 && match) {
6197 re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;
6198 }
6199
6200 if (NPCG_INCLUDED$1 && match && match.length > 1) {
6201 // Fix browsers whose `exec` methods don't consistently return `undefined`
6202 // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
6203 // eslint-disable-next-line no-loop-func
6204 nativeReplace$1.call(match[0], reCopy, function () {
6205 for (i = 1; i < arguments.length - 2; i++) {
6206 if (arguments[i] === undefined) match[i] = undefined;
6207 }
6208 });
6209 }
6210
6211 return match;
6212 };
6213 }
6214
6215 var _regexpExec = patchedExec$1;
6216
6217 _export$1({
6218 target: 'RegExp',
6219 proto: true,
6220 forced: _regexpExec !== /./.exec
6221 }, {
6222 exec: _regexpExec
6223 });
6224
6225 var SPECIES$6 = _wks('species');
6226
6227 var REPLACE_SUPPORTS_NAMED_GROUPS$1 = !_fails(function () {
6228 // #replace needs built-in support for named groups.
6229 // #match works fine because it just return the exec results, even if it has
6230 // a "grops" property.
6231 var re = /./;
6232
6233 re.exec = function () {
6234 var result = [];
6235 result.groups = {
6236 a: '7'
6237 };
6238 return result;
6239 };
6240
6241 return ''.replace(re, '$<a>') !== '7';
6242 });
6243
6244 var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC$1 = function () {
6245 // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
6246 var re = /(?:)/;
6247 var originalExec = re.exec;
6248
6249 re.exec = function () {
6250 return originalExec.apply(this, arguments);
6251 };
6252
6253 var result = 'ab'.split(re);
6254 return result.length === 2 && result[0] === 'a' && result[1] === 'b';
6255 }();
6256
6257 var _fixReWks = function _fixReWks(KEY, length, exec) {
6258 var SYMBOL = _wks(KEY);
6259
6260 var DELEGATES_TO_SYMBOL = !_fails(function () {
6261 // String methods call symbol-named RegEp methods
6262 var O = {};
6263
6264 O[SYMBOL] = function () {
6265 return 7;
6266 };
6267
6268 return ''[KEY](O) != 7;
6269 });
6270 var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !_fails(function () {
6271 // Symbol-named RegExp methods call .exec
6272 var execCalled = false;
6273 var re = /a/;
6274
6275 re.exec = function () {
6276 execCalled = true;
6277 return null;
6278 };
6279
6280 if (KEY === 'split') {
6281 // RegExp[@@split] doesn't call the regex's exec method, but first creates
6282 // a new one. We need to return the patched regex when creating the new one.
6283 re.constructor = {};
6284
6285 re.constructor[SPECIES$6] = function () {
6286 return re;
6287 };
6288 }
6289
6290 re[SYMBOL]('');
6291 return !execCalled;
6292 }) : undefined;
6293
6294 if (!DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS$1 || KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC$1) {
6295 var nativeRegExpMethod = /./[SYMBOL];
6296 var fns = exec(_defined, SYMBOL, ''[KEY], function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {
6297 if (regexp.exec === _regexpExec) {
6298 if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
6299 // The native String method already delegates to @@method (this
6300 // polyfilled function), leasing to infinite recursion.
6301 // We avoid it by directly calling the native @@method method.
6302 return {
6303 done: true,
6304 value: nativeRegExpMethod.call(regexp, str, arg2)
6305 };
6306 }
6307
6308 return {
6309 done: true,
6310 value: nativeMethod.call(str, regexp, arg2)
6311 };
6312 }
6313
6314 return {
6315 done: false
6316 };
6317 });
6318 var strfn = fns[0];
6319 var rxfn = fns[1];
6320
6321 _redefine(String.prototype, KEY, strfn);
6322
6323 _hide(RegExp.prototype, SYMBOL, length == 2 // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
6324 // 21.2.5.11 RegExp.prototype[@@split](string, limit)
6325 ? function (string, arg) {
6326 return rxfn.call(string, this, arg);
6327 } // 21.2.5.6 RegExp.prototype[@@match](string)
6328 // 21.2.5.9 RegExp.prototype[@@search](string)
6329 : function (string) {
6330 return rxfn.call(string, this);
6331 });
6332 }
6333 };
6334
6335 var max$1$1 = Math.max;
6336 var min$2$1 = Math.min;
6337 var floor$1$1 = Math.floor;
6338 var SUBSTITUTION_SYMBOLS$1 = /\$([$&`']|\d\d?|<[^>]*>)/g;
6339 var SUBSTITUTION_SYMBOLS_NO_NAMED$1 = /\$([$&`']|\d\d?)/g;
6340
6341 var maybeToString$1 = function maybeToString(it) {
6342 return it === undefined ? it : String(it);
6343 }; // @@replace logic
6344
6345
6346 _fixReWks('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {
6347 return [// `String.prototype.replace` method
6348 // https://tc39.github.io/ecma262/#sec-string.prototype.replace
6349 function replace(searchValue, replaceValue) {
6350 var O = defined(this);
6351 var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
6352 return fn !== undefined ? fn.call(searchValue, O, replaceValue) : $replace.call(String(O), searchValue, replaceValue);
6353 }, // `RegExp.prototype[@@replace]` method
6354 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
6355 function (regexp, replaceValue) {
6356 var res = maybeCallNative($replace, regexp, this, replaceValue);
6357 if (res.done) return res.value;
6358
6359 var rx = _anObject(regexp);
6360
6361 var S = String(this);
6362 var functionalReplace = typeof replaceValue === 'function';
6363 if (!functionalReplace) replaceValue = String(replaceValue);
6364 var global = rx.global;
6365
6366 if (global) {
6367 var fullUnicode = rx.unicode;
6368 rx.lastIndex = 0;
6369 }
6370
6371 var results = [];
6372
6373 while (true) {
6374 var result = _regexpExecAbstract(rx, S);
6375
6376 if (result === null) break;
6377 results.push(result);
6378 if (!global) break;
6379 var matchStr = String(result[0]);
6380 if (matchStr === '') rx.lastIndex = _advanceStringIndex(S, _toLength(rx.lastIndex), fullUnicode);
6381 }
6382
6383 var accumulatedResult = '';
6384 var nextSourcePosition = 0;
6385
6386 for (var i = 0; i < results.length; i++) {
6387 result = results[i];
6388 var matched = String(result[0]);
6389 var position = max$1$1(min$2$1(_toInteger(result.index), S.length), 0);
6390 var captures = []; // NOTE: This is equivalent to
6391 // captures = result.slice(1).map(maybeToString)
6392 // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
6393 // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
6394 // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
6395
6396 for (var j = 1; j < result.length; j++) {
6397 captures.push(maybeToString$1(result[j]));
6398 }
6399
6400 var namedCaptures = result.groups;
6401
6402 if (functionalReplace) {
6403 var replacerArgs = [matched].concat(captures, position, S);
6404 if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
6405 var replacement = String(replaceValue.apply(undefined, replacerArgs));
6406 } else {
6407 replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
6408 }
6409
6410 if (position >= nextSourcePosition) {
6411 accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
6412 nextSourcePosition = position + matched.length;
6413 }
6414 }
6415
6416 return accumulatedResult + S.slice(nextSourcePosition);
6417 }]; // https://tc39.github.io/ecma262/#sec-getsubstitution
6418
6419 function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
6420 var tailPos = position + matched.length;
6421 var m = captures.length;
6422 var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED$1;
6423
6424 if (namedCaptures !== undefined) {
6425 namedCaptures = _toObject(namedCaptures);
6426 symbols = SUBSTITUTION_SYMBOLS$1;
6427 }
6428
6429 return $replace.call(replacement, symbols, function (match, ch) {
6430 var capture;
6431
6432 switch (ch.charAt(0)) {
6433 case '$':
6434 return '$';
6435
6436 case '&':
6437 return matched;
6438
6439 case '`':
6440 return str.slice(0, position);
6441
6442 case "'":
6443 return str.slice(tailPos);
6444
6445 case '<':
6446 capture = namedCaptures[ch.slice(1, -1)];
6447 break;
6448
6449 default:
6450 // \d\d?
6451 var n = +ch;
6452 if (n === 0) return match;
6453
6454 if (n > m) {
6455 var f = floor$1$1(n / 10);
6456 if (f === 0) return match;
6457 if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
6458 return match;
6459 }
6460
6461 capture = captures[n - 1];
6462 }
6463
6464 return capture === undefined ? '' : capture;
6465 });
6466 }
6467 });
6468
6469 var UNSCOPABLES$1 = _wks('unscopables');
6470
6471 var ArrayProto = Array.prototype;
6472 if (ArrayProto[UNSCOPABLES$1] == undefined) _hide(ArrayProto, UNSCOPABLES$1, {});
6473
6474 var _addToUnscopables = function _addToUnscopables(key) {
6475 ArrayProto[UNSCOPABLES$1][key] = true;
6476 };
6477
6478 var _iterStep = function _iterStep(done, value) {
6479 return {
6480 value: value,
6481 done: !!done
6482 };
6483 };
6484
6485 var _iterators = {};
6486 var IteratorPrototype$3 = {}; // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
6487
6488 _hide(IteratorPrototype$3, _wks('iterator'), function () {
6489 return this;
6490 });
6491
6492 var _iterCreate = function _iterCreate(Constructor, NAME, next) {
6493 Constructor.prototype = _objectCreate(IteratorPrototype$3, {
6494 next: _propertyDesc(1, next)
6495 });
6496
6497 _setToStringTag(Constructor, NAME + ' Iterator');
6498 };
6499
6500 var IE_PROTO$2$1 = _sharedKey('IE_PROTO');
6501
6502 var ObjectProto$1 = Object.prototype;
6503
6504 var _objectGpo = Object.getPrototypeOf || function (O) {
6505 O = _toObject(O);
6506 if (_has(O, IE_PROTO$2$1)) return O[IE_PROTO$2$1];
6507
6508 if (typeof O.constructor == 'function' && O instanceof O.constructor) {
6509 return O.constructor.prototype;
6510 }
6511
6512 return O instanceof Object ? ObjectProto$1 : null;
6513 };
6514
6515 var ITERATOR$7 = _wks('iterator');
6516
6517 var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
6518
6519 var FF_ITERATOR = '@@iterator';
6520 var KEYS$1 = 'keys';
6521 var VALUES$1 = 'values';
6522
6523 var returnThis$3 = function returnThis() {
6524 return this;
6525 };
6526
6527 var _iterDefine = function _iterDefine(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
6528 _iterCreate(Constructor, NAME, next);
6529
6530 var getMethod = function getMethod(kind) {
6531 if (!BUGGY && kind in proto) return proto[kind];
6532
6533 switch (kind) {
6534 case KEYS$1:
6535 return function keys() {
6536 return new Constructor(this, kind);
6537 };
6538
6539 case VALUES$1:
6540 return function values() {
6541 return new Constructor(this, kind);
6542 };
6543 }
6544
6545 return function entries() {
6546 return new Constructor(this, kind);
6547 };
6548 };
6549
6550 var TAG = NAME + ' Iterator';
6551 var DEF_VALUES = DEFAULT == VALUES$1;
6552 var VALUES_BUG = false;
6553 var proto = Base.prototype;
6554 var $native = proto[ITERATOR$7] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
6555 var $default = $native || getMethod(DEFAULT);
6556 var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
6557 var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
6558 var methods, key, IteratorPrototype; // Fix native
6559
6560 if ($anyNative) {
6561 IteratorPrototype = _objectGpo($anyNative.call(new Base()));
6562
6563 if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
6564 // Set @@toStringTag to native iterators
6565 _setToStringTag(IteratorPrototype, TAG, true); // fix for some old engines
6566
6567
6568 if (typeof IteratorPrototype[ITERATOR$7] != 'function') _hide(IteratorPrototype, ITERATOR$7, returnThis$3);
6569 }
6570 } // fix Array#{values, @@iterator}.name in V8 / FF
6571
6572
6573 if (DEF_VALUES && $native && $native.name !== VALUES$1) {
6574 VALUES_BUG = true;
6575
6576 $default = function values() {
6577 return $native.call(this);
6578 };
6579 } // Define iterator
6580
6581
6582 if (BUGGY || VALUES_BUG || !proto[ITERATOR$7]) {
6583 _hide(proto, ITERATOR$7, $default);
6584 } // Plug for library
6585
6586
6587 _iterators[NAME] = $default;
6588 _iterators[TAG] = returnThis$3;
6589
6590 if (DEFAULT) {
6591 methods = {
6592 values: DEF_VALUES ? $default : getMethod(VALUES$1),
6593 keys: IS_SET ? $default : getMethod(KEYS$1),
6594 entries: $entries
6595 };
6596 if (FORCED) for (key in methods) {
6597 if (!(key in proto)) _redefine(proto, key, methods[key]);
6598 } else _export$1(_export$1.P + _export$1.F * (BUGGY || VALUES_BUG), NAME, methods);
6599 }
6600
6601 return methods;
6602 }; // 22.1.3.13 Array.prototype.keys()
6603 // 22.1.3.29 Array.prototype.values()
6604 // 22.1.3.30 Array.prototype[@@iterator]()
6605
6606
6607 var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
6608 this._t = _toIobject(iterated); // target
6609
6610 this._i = 0; // next index
6611
6612 this._k = kind; // kind
6613 // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
6614 }, function () {
6615 var O = this._t;
6616 var kind = this._k;
6617 var index = this._i++;
6618
6619 if (!O || index >= O.length) {
6620 this._t = undefined;
6621 return _iterStep(1);
6622 }
6623
6624 if (kind == 'keys') return _iterStep(0, index);
6625 if (kind == 'values') return _iterStep(0, O[index]);
6626 return _iterStep(0, [index, O[index]]);
6627 }, 'values'); // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
6628
6629
6630 _iterators.Arguments = _iterators.Array;
6631
6632 _addToUnscopables('keys');
6633
6634 _addToUnscopables('values');
6635
6636 _addToUnscopables('entries');
6637
6638 var ITERATOR$1$1 = _wks('iterator');
6639
6640 var TO_STRING_TAG$5 = _wks('toStringTag');
6641
6642 var ArrayValues$1 = _iterators.Array;
6643 var DOMIterables = {
6644 CSSRuleList: true,
6645 // TODO: Not spec compliant, should be false.
6646 CSSStyleDeclaration: false,
6647 CSSValueList: false,
6648 ClientRectList: false,
6649 DOMRectList: false,
6650 DOMStringList: false,
6651 DOMTokenList: true,
6652 DataTransferItemList: false,
6653 FileList: false,
6654 HTMLAllCollection: false,
6655 HTMLCollection: false,
6656 HTMLFormElement: false,
6657 HTMLSelectElement: false,
6658 MediaList: true,
6659 // TODO: Not spec compliant, should be false.
6660 MimeTypeArray: false,
6661 NamedNodeMap: false,
6662 NodeList: true,
6663 PaintRequestList: false,
6664 Plugin: false,
6665 PluginArray: false,
6666 SVGLengthList: false,
6667 SVGNumberList: false,
6668 SVGPathSegList: false,
6669 SVGPointList: false,
6670 SVGStringList: false,
6671 SVGTransformList: false,
6672 SourceBufferList: false,
6673 StyleSheetList: true,
6674 // TODO: Not spec compliant, should be false.
6675 TextTrackCueList: false,
6676 TextTrackList: false,
6677 TouchList: false
6678 };
6679
6680 for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
6681 var NAME$2 = collections[i];
6682 var explicit = DOMIterables[NAME$2];
6683 var Collection$2 = _global[NAME$2];
6684 var proto = Collection$2 && Collection$2.prototype;
6685 var key$2;
6686
6687 if (proto) {
6688 if (!proto[ITERATOR$1$1]) _hide(proto, ITERATOR$1$1, ArrayValues$1);
6689 if (!proto[TO_STRING_TAG$5]) _hide(proto, TO_STRING_TAG$5, NAME$2);
6690 _iterators[NAME$2] = ArrayValues$1;
6691 if (explicit) for (key$2 in es6_array_iterator) {
6692 if (!proto[key$2]) _redefine(proto, key$2, es6_array_iterator[key$2], true);
6693 }
6694 }
6695 }
6696
6697 var test$2 = {};
6698 test$2[_wks('toStringTag')] = 'z';
6699
6700 if (test$2 + '' != '[object z]') {
6701 _redefine(Object.prototype, 'toString', function toString() {
6702 return '[object ' + _classof(this) + ']';
6703 }, true);
6704 }
6705
6706 var isEnum$1 = _objectPie.f;
6707
6708 var _objectToArray = function _objectToArray(isEntries) {
6709 return function (it) {
6710 var O = _toIobject(it);
6711
6712 var keys = _objectKeys(O);
6713
6714 var length = keys.length;
6715 var i = 0;
6716 var result = [];
6717 var key;
6718
6719 while (length > i) {
6720 key = keys[i++];
6721
6722 if (!_descriptors || isEnum$1.call(O, key)) {
6723 result.push(isEntries ? [key, O[key]] : O[key]);
6724 }
6725 }
6726
6727 return result;
6728 };
6729 };
6730
6731 var $values$1 = _objectToArray(false);
6732
6733 _export$1(_export$1.S, 'Object', {
6734 values: function values(it) {
6735 return $values$1(it);
6736 }
6737 });
6738
6739 var MATCH$2 = _wks('match');
6740
6741 var _isRegexp = function _isRegexp(it) {
6742 var isRegExp;
6743 return _isObject(it) && ((isRegExp = it[MATCH$2]) !== undefined ? !!isRegExp : _cof(it) == 'RegExp');
6744 };
6745
6746 var SPECIES$1$1 = _wks('species');
6747
6748 var _speciesConstructor = function _speciesConstructor(O, D) {
6749 var C = _anObject(O).constructor;
6750
6751 var S;
6752 return C === undefined || (S = _anObject(C)[SPECIES$1$1]) == undefined ? D : _aFunction(S);
6753 };
6754
6755 var $min = Math.min;
6756 var $push = [].push;
6757 var $SPLIT = 'split';
6758 var LENGTH = 'length';
6759 var LAST_INDEX$1 = 'lastIndex';
6760 var MAX_UINT32$1 = 0xffffffff; // babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
6761
6762 var SUPPORTS_Y$1 = !_fails(function () {
6763 RegExp(MAX_UINT32$1, 'y');
6764 }); // @@split logic
6765
6766 _fixReWks('split', 2, function (defined, SPLIT, $split, maybeCallNative) {
6767 var internalSplit;
6768
6769 if ('abbc'[$SPLIT](/(b)*/)[1] == 'c' || 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 || 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 || '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 || '.'[$SPLIT](/()()/)[LENGTH] > 1 || ''[$SPLIT](/.?/)[LENGTH]) {
6770 // based on es5-shim implementation, need to rework it
6771 internalSplit = function internalSplit(separator, limit) {
6772 var string = String(this);
6773 if (separator === undefined && limit === 0) return []; // If `separator` is not a regex, use native split
6774
6775 if (!_isRegexp(separator)) return $split.call(string, separator, limit);
6776 var output = [];
6777 var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + (separator.sticky ? 'y' : '');
6778 var lastLastIndex = 0;
6779 var splitLimit = limit === undefined ? MAX_UINT32$1 : limit >>> 0; // Make `global` and avoid `lastIndex` issues by working with a copy
6780
6781 var separatorCopy = new RegExp(separator.source, flags + 'g');
6782 var match, lastIndex, lastLength;
6783
6784 while (match = _regexpExec.call(separatorCopy, string)) {
6785 lastIndex = separatorCopy[LAST_INDEX$1];
6786
6787 if (lastIndex > lastLastIndex) {
6788 output.push(string.slice(lastLastIndex, match.index));
6789 if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));
6790 lastLength = match[0][LENGTH];
6791 lastLastIndex = lastIndex;
6792 if (output[LENGTH] >= splitLimit) break;
6793 }
6794
6795 if (separatorCopy[LAST_INDEX$1] === match.index) separatorCopy[LAST_INDEX$1]++; // Avoid an infinite loop
6796 }
6797
6798 if (lastLastIndex === string[LENGTH]) {
6799 if (lastLength || !separatorCopy.test('')) output.push('');
6800 } else output.push(string.slice(lastLastIndex));
6801
6802 return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
6803 }; // Chakra, V8
6804
6805 } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {
6806 internalSplit = function internalSplit(separator, limit) {
6807 return separator === undefined && limit === 0 ? [] : $split.call(this, separator, limit);
6808 };
6809 } else {
6810 internalSplit = $split;
6811 }
6812
6813 return [// `String.prototype.split` method
6814 // https://tc39.github.io/ecma262/#sec-string.prototype.split
6815 function split(separator, limit) {
6816 var O = defined(this);
6817 var splitter = separator == undefined ? undefined : separator[SPLIT];
6818 return splitter !== undefined ? splitter.call(separator, O, limit) : internalSplit.call(String(O), separator, limit);
6819 }, // `RegExp.prototype[@@split]` method
6820 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
6821 //
6822 // NOTE: This cannot be properly polyfilled in engines that don't support
6823 // the 'y' flag.
6824 function (regexp, limit) {
6825 var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== $split);
6826 if (res.done) return res.value;
6827
6828 var rx = _anObject(regexp);
6829
6830 var S = String(this);
6831
6832 var C = _speciesConstructor(rx, RegExp);
6833
6834 var unicodeMatching = rx.unicode;
6835 var flags = (rx.ignoreCase ? 'i' : '') + (rx.multiline ? 'm' : '') + (rx.unicode ? 'u' : '') + (SUPPORTS_Y$1 ? 'y' : 'g'); // ^(? + rx + ) is needed, in combination with some S slicing, to
6836 // simulate the 'y' flag.
6837
6838 var splitter = new C(SUPPORTS_Y$1 ? rx : '^(?:' + rx.source + ')', flags);
6839 var lim = limit === undefined ? MAX_UINT32$1 : limit >>> 0;
6840 if (lim === 0) return [];
6841 if (S.length === 0) return _regexpExecAbstract(splitter, S) === null ? [S] : [];
6842 var p = 0;
6843 var q = 0;
6844 var A = [];
6845
6846 while (q < S.length) {
6847 splitter.lastIndex = SUPPORTS_Y$1 ? q : 0;
6848
6849 var z = _regexpExecAbstract(splitter, SUPPORTS_Y$1 ? S : S.slice(q));
6850
6851 var e;
6852
6853 if (z === null || (e = $min(_toLength(splitter.lastIndex + (SUPPORTS_Y$1 ? 0 : q)), S.length)) === p) {
6854 q = _advanceStringIndex(S, q, unicodeMatching);
6855 } else {
6856 A.push(S.slice(p, q));
6857 if (A.length === lim) return A;
6858
6859 for (var i = 1; i <= z.length - 1; i++) {
6860 A.push(z[i]);
6861 if (A.length === lim) return A;
6862 }
6863
6864 q = p = e;
6865 }
6866 }
6867
6868 A.push(S.slice(p));
6869 return A;
6870 }];
6871 });
6872
6873 var $assign = Object.assign; // should work with symbols and should have deterministic property order (V8 bug)
6874
6875 var _objectAssign = !$assign || _fails(function () {
6876 var A = {};
6877 var B = {}; // eslint-disable-next-line no-undef
6878
6879 var S = Symbol();
6880 var K = 'abcdefghijklmnopqrst';
6881 A[S] = 7;
6882 K.split('').forEach(function (k) {
6883 B[k] = k;
6884 });
6885 return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
6886 }) ? function assign(target, source) {
6887 // eslint-disable-line no-unused-vars
6888 var T = _toObject(target);
6889
6890 var aLen = arguments.length;
6891 var index = 1;
6892 var getSymbols = _objectGops.f;
6893 var isEnum = _objectPie.f;
6894
6895 while (aLen > index) {
6896 var S = _iobject(arguments[index++]);
6897
6898 var keys = getSymbols ? _objectKeys(S).concat(getSymbols(S)) : _objectKeys(S);
6899 var length = keys.length;
6900 var j = 0;
6901 var key;
6902
6903 while (length > j) {
6904 key = keys[j++];
6905 if (!_descriptors || isEnum.call(S, key)) T[key] = S[key];
6906 }
6907 }
6908
6909 return T;
6910 } : $assign;
6911
6912 _export$1(_export$1.S + _export$1.F, 'Object', {
6913 assign: _objectAssign
6914 });
6915 /* eslint-disable no-proto */
6916
6917
6918 var check$1 = function check(O, proto) {
6919 _anObject(O);
6920
6921 if (!_isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
6922 };
6923
6924 var _setProto = {
6925 set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
6926 function (test, buggy, set) {
6927 try {
6928 set = _ctx(Function.call, _objectGopd.f(Object.prototype, '__proto__').set, 2);
6929 set(test, []);
6930 buggy = !(test instanceof Array);
6931 } catch (e) {
6932 buggy = true;
6933 }
6934
6935 return function setPrototypeOf(O, proto) {
6936 check$1(O, proto);
6937 if (buggy) O.__proto__ = proto;else set(O, proto);
6938 return O;
6939 };
6940 }({}, false) : undefined),
6941 check: check$1
6942 };
6943 var setPrototypeOf = _setProto.set;
6944
6945 var _inheritIfRequired = function _inheritIfRequired(that, target, C) {
6946 var S = target.constructor;
6947 var P;
6948
6949 if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && _isObject(P) && setPrototypeOf) {
6950 setPrototypeOf(that, P);
6951 }
6952
6953 return that;
6954 };
6955
6956 var _stringWs = "\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF";
6957
6958 var space = '[' + _stringWs + ']';
6959 var non$1 = "\u200B\x85";
6960 var ltrim$1 = RegExp('^' + space + space + '*');
6961 var rtrim$1 = RegExp(space + space + '*$');
6962
6963 var exporter = function exporter(KEY, exec, ALIAS) {
6964 var exp = {};
6965
6966 var FORCE = _fails(function () {
6967 return !!_stringWs[KEY]() || non$1[KEY]() != non$1;
6968 });
6969
6970 var fn = exp[KEY] = FORCE ? exec(trim$3) : _stringWs[KEY];
6971 if (ALIAS) exp[ALIAS] = fn;
6972
6973 _export$1(_export$1.P + _export$1.F * FORCE, 'String', exp);
6974 }; // 1 -> String#trimLeft
6975 // 2 -> String#trimRight
6976 // 3 -> String#trim
6977
6978
6979 var trim$3 = exporter.trim = function (string, TYPE) {
6980 string = String(_defined(string));
6981 if (TYPE & 1) string = string.replace(ltrim$1, '');
6982 if (TYPE & 2) string = string.replace(rtrim$1, '');
6983 return string;
6984 };
6985
6986 var _stringTrim = exporter;
6987 var gOPN$2 = _objectGopn.f;
6988 var gOPD$2 = _objectGopd.f;
6989 var dP$2 = _objectDp.f;
6990 var $trim$1 = _stringTrim.trim;
6991 var NUMBER$1 = 'Number';
6992 var $Number = _global[NUMBER$1];
6993 var Base = $Number;
6994 var proto$1 = $Number.prototype; // Opera ~12 has broken Object#toString
6995
6996 var BROKEN_COF = _cof(_objectCreate(proto$1)) == NUMBER$1;
6997 var TRIM = 'trim' in String.prototype; // 7.1.3 ToNumber(argument)
6998
6999 var toNumber$1 = function toNumber(argument) {
7000 var it = _toPrimitive(argument, false);
7001
7002 if (typeof it == 'string' && it.length > 2) {
7003 it = TRIM ? it.trim() : $trim$1(it, 3);
7004 var first = it.charCodeAt(0);
7005 var third, radix, maxCode;
7006
7007 if (first === 43 || first === 45) {
7008 third = it.charCodeAt(2);
7009 if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
7010 } else if (first === 48) {
7011 switch (it.charCodeAt(1)) {
7012 case 66:
7013 case 98:
7014 radix = 2;
7015 maxCode = 49;
7016 break;
7017 // fast equal /^0b[01]+$/i
7018
7019 case 79:
7020 case 111:
7021 radix = 8;
7022 maxCode = 55;
7023 break;
7024 // fast equal /^0o[0-7]+$/i
7025
7026 default:
7027 return +it;
7028 }
7029
7030 for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {
7031 code = digits.charCodeAt(i); // parseInt parses a string to a first unavailable symbol
7032 // but ToNumber should return NaN if a string contains unavailable symbols
7033
7034 if (code < 48 || code > maxCode) return NaN;
7035 }
7036
7037 return parseInt(digits, radix);
7038 }
7039 }
7040
7041 return +it;
7042 };
7043
7044 if (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {
7045 $Number = function Number(value) {
7046 var it = arguments.length < 1 ? 0 : value;
7047 var that = this;
7048 return that instanceof $Number // check on 1..constructor(foo) case
7049 && (BROKEN_COF ? _fails(function () {
7050 proto$1.valueOf.call(that);
7051 }) : _cof(that) != NUMBER$1) ? _inheritIfRequired(new Base(toNumber$1(it)), that, $Number) : toNumber$1(it);
7052 };
7053
7054 for (var keys$4 = _descriptors ? gOPN$2(Base) : ( // ES3:
7055 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + // ES6 (in case, if modules with ES6 Number statics required before):
7056 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' + 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger').split(','), j$1$1 = 0, key$1$1; keys$4.length > j$1$1; j$1$1++) {
7057 if (_has(Base, key$1$1 = keys$4[j$1$1]) && !_has($Number, key$1$1)) {
7058 dP$2($Number, key$1$1, gOPD$2(Base, key$1$1));
7059 }
7060 }
7061
7062 $Number.prototype = proto$1;
7063 proto$1.constructor = $Number;
7064
7065 _redefine(_global, NUMBER$1, $Number);
7066 }
7067
7068 var moment = createCommonjsModule$1(function (module, exports) {
7069 (function (global, factory) {
7070 module.exports = factory();
7071 })(commonjsGlobal$1, function () {
7072 var hookCallback;
7073
7074 function hooks() {
7075 return hookCallback.apply(null, arguments);
7076 } // This is done to register the method called with moment()
7077 // without creating circular dependencies.
7078
7079
7080 function setHookCallback(callback) {
7081 hookCallback = callback;
7082 }
7083
7084 function isArray(input) {
7085 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
7086 }
7087
7088 function isObject(input) {
7089 // IE8 will treat undefined and null as object if it wasn't for
7090 // input != null
7091 return input != null && Object.prototype.toString.call(input) === '[object Object]';
7092 }
7093
7094 function isObjectEmpty(obj) {
7095 if (Object.getOwnPropertyNames) {
7096 return Object.getOwnPropertyNames(obj).length === 0;
7097 } else {
7098 var k;
7099
7100 for (k in obj) {
7101 if (obj.hasOwnProperty(k)) {
7102 return false;
7103 }
7104 }
7105
7106 return true;
7107 }
7108 }
7109
7110 function isUndefined(input) {
7111 return input === void 0;
7112 }
7113
7114 function isNumber(input) {
7115 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
7116 }
7117
7118 function isDate(input) {
7119 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
7120 }
7121
7122 function map(arr, fn) {
7123 var res = [],
7124 i;
7125
7126 for (i = 0; i < arr.length; ++i) {
7127 res.push(fn(arr[i], i));
7128 }
7129
7130 return res;
7131 }
7132
7133 function hasOwnProp(a, b) {
7134 return Object.prototype.hasOwnProperty.call(a, b);
7135 }
7136
7137 function extend(a, b) {
7138 for (var i in b) {
7139 if (hasOwnProp(b, i)) {
7140 a[i] = b[i];
7141 }
7142 }
7143
7144 if (hasOwnProp(b, 'toString')) {
7145 a.toString = b.toString;
7146 }
7147
7148 if (hasOwnProp(b, 'valueOf')) {
7149 a.valueOf = b.valueOf;
7150 }
7151
7152 return a;
7153 }
7154
7155 function createUTC(input, format, locale, strict) {
7156 return createLocalOrUTC(input, format, locale, strict, true).utc();
7157 }
7158
7159 function defaultParsingFlags() {
7160 // We need to deep clone this object.
7161 return {
7162 empty: false,
7163 unusedTokens: [],
7164 unusedInput: [],
7165 overflow: -2,
7166 charsLeftOver: 0,
7167 nullInput: false,
7168 invalidMonth: null,
7169 invalidFormat: false,
7170 userInvalidated: false,
7171 iso: false,
7172 parsedDateParts: [],
7173 meridiem: null,
7174 rfc2822: false,
7175 weekdayMismatch: false
7176 };
7177 }
7178
7179 function getParsingFlags(m) {
7180 if (m._pf == null) {
7181 m._pf = defaultParsingFlags();
7182 }
7183
7184 return m._pf;
7185 }
7186
7187 var some;
7188
7189 if (Array.prototype.some) {
7190 some = Array.prototype.some;
7191 } else {
7192 some = function some(fun) {
7193 var t = Object(this);
7194 var len = t.length >>> 0;
7195
7196 for (var i = 0; i < len; i++) {
7197 if (i in t && fun.call(this, t[i], i, t)) {
7198 return true;
7199 }
7200 }
7201
7202 return false;
7203 };
7204 }
7205
7206 function isValid(m) {
7207 if (m._isValid == null) {
7208 var flags = getParsingFlags(m);
7209 var parsedParts = some.call(flags.parsedDateParts, function (i) {
7210 return i != null;
7211 });
7212 var isNowValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || flags.meridiem && parsedParts);
7213
7214 if (m._strict) {
7215 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
7216 }
7217
7218 if (Object.isFrozen == null || !Object.isFrozen(m)) {
7219 m._isValid = isNowValid;
7220 } else {
7221 return isNowValid;
7222 }
7223 }
7224
7225 return m._isValid;
7226 }
7227
7228 function createInvalid(flags) {
7229 var m = createUTC(NaN);
7230
7231 if (flags != null) {
7232 extend(getParsingFlags(m), flags);
7233 } else {
7234 getParsingFlags(m).userInvalidated = true;
7235 }
7236
7237 return m;
7238 } // Plugins that add properties should also add the key here (null value),
7239 // so we can properly clone ourselves.
7240
7241
7242 var momentProperties = hooks.momentProperties = [];
7243
7244 function copyConfig(to, from) {
7245 var i, prop, val;
7246
7247 if (!isUndefined(from._isAMomentObject)) {
7248 to._isAMomentObject = from._isAMomentObject;
7249 }
7250
7251 if (!isUndefined(from._i)) {
7252 to._i = from._i;
7253 }
7254
7255 if (!isUndefined(from._f)) {
7256 to._f = from._f;
7257 }
7258
7259 if (!isUndefined(from._l)) {
7260 to._l = from._l;
7261 }
7262
7263 if (!isUndefined(from._strict)) {
7264 to._strict = from._strict;
7265 }
7266
7267 if (!isUndefined(from._tzm)) {
7268 to._tzm = from._tzm;
7269 }
7270
7271 if (!isUndefined(from._isUTC)) {
7272 to._isUTC = from._isUTC;
7273 }
7274
7275 if (!isUndefined(from._offset)) {
7276 to._offset = from._offset;
7277 }
7278
7279 if (!isUndefined(from._pf)) {
7280 to._pf = getParsingFlags(from);
7281 }
7282
7283 if (!isUndefined(from._locale)) {
7284 to._locale = from._locale;
7285 }
7286
7287 if (momentProperties.length > 0) {
7288 for (i = 0; i < momentProperties.length; i++) {
7289 prop = momentProperties[i];
7290 val = from[prop];
7291
7292 if (!isUndefined(val)) {
7293 to[prop] = val;
7294 }
7295 }
7296 }
7297
7298 return to;
7299 }
7300
7301 var updateInProgress = false; // Moment prototype object
7302
7303 function Moment(config) {
7304 copyConfig(this, config);
7305 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
7306
7307 if (!this.isValid()) {
7308 this._d = new Date(NaN);
7309 } // Prevent infinite loop in case updateOffset creates new moment
7310 // objects.
7311
7312
7313 if (updateInProgress === false) {
7314 updateInProgress = true;
7315 hooks.updateOffset(this);
7316 updateInProgress = false;
7317 }
7318 }
7319
7320 function isMoment(obj) {
7321 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
7322 }
7323
7324 function absFloor(number) {
7325 if (number < 0) {
7326 // -0 -> 0
7327 return Math.ceil(number) || 0;
7328 } else {
7329 return Math.floor(number);
7330 }
7331 }
7332
7333 function toInt(argumentForCoercion) {
7334 var coercedNumber = +argumentForCoercion,
7335 value = 0;
7336
7337 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
7338 value = absFloor(coercedNumber);
7339 }
7340
7341 return value;
7342 } // compare two arrays, return the number of differences
7343
7344
7345 function compareArrays(array1, array2, dontConvert) {
7346 var len = Math.min(array1.length, array2.length),
7347 lengthDiff = Math.abs(array1.length - array2.length),
7348 diffs = 0,
7349 i;
7350
7351 for (i = 0; i < len; i++) {
7352 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
7353 diffs++;
7354 }
7355 }
7356
7357 return diffs + lengthDiff;
7358 }
7359
7360 function warn(msg) {
7361 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
7362 console.warn('Deprecation warning: ' + msg);
7363 }
7364 }
7365
7366 function deprecate(msg, fn) {
7367 var firstTime = true;
7368 return extend(function () {
7369 if (hooks.deprecationHandler != null) {
7370 hooks.deprecationHandler(null, msg);
7371 }
7372
7373 if (firstTime) {
7374 var args = [];
7375 var arg;
7376
7377 for (var i = 0; i < arguments.length; i++) {
7378 arg = '';
7379
7380 if (_typeof(arguments[i]) === 'object') {
7381 arg += '\n[' + i + '] ';
7382
7383 for (var key in arguments[0]) {
7384 arg += key + ': ' + arguments[0][key] + ', ';
7385 }
7386
7387 arg = arg.slice(0, -2); // Remove trailing comma and space
7388 } else {
7389 arg = arguments[i];
7390 }
7391
7392 args.push(arg);
7393 }
7394
7395 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
7396 firstTime = false;
7397 }
7398
7399 return fn.apply(this, arguments);
7400 }, fn);
7401 }
7402
7403 var deprecations = {};
7404
7405 function deprecateSimple(name, msg) {
7406 if (hooks.deprecationHandler != null) {
7407 hooks.deprecationHandler(name, msg);
7408 }
7409
7410 if (!deprecations[name]) {
7411 warn(msg);
7412 deprecations[name] = true;
7413 }
7414 }
7415
7416 hooks.suppressDeprecationWarnings = false;
7417 hooks.deprecationHandler = null;
7418
7419 function isFunction(input) {
7420 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
7421 }
7422
7423 function set(config) {
7424 var prop, i;
7425
7426 for (i in config) {
7427 prop = config[i];
7428
7429 if (isFunction(prop)) {
7430 this[i] = prop;
7431 } else {
7432 this['_' + i] = prop;
7433 }
7434 }
7435
7436 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
7437 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
7438 // TODO: Remove "ordinalParse" fallback in next major release.
7439
7440 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
7441 }
7442
7443 function mergeConfigs(parentConfig, childConfig) {
7444 var res = extend({}, parentConfig),
7445 prop;
7446
7447 for (prop in childConfig) {
7448 if (hasOwnProp(childConfig, prop)) {
7449 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
7450 res[prop] = {};
7451 extend(res[prop], parentConfig[prop]);
7452 extend(res[prop], childConfig[prop]);
7453 } else if (childConfig[prop] != null) {
7454 res[prop] = childConfig[prop];
7455 } else {
7456 delete res[prop];
7457 }
7458 }
7459 }
7460
7461 for (prop in parentConfig) {
7462 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
7463 // make sure changes to properties don't modify parent config
7464 res[prop] = extend({}, res[prop]);
7465 }
7466 }
7467
7468 return res;
7469 }
7470
7471 function Locale(config) {
7472 if (config != null) {
7473 this.set(config);
7474 }
7475 }
7476
7477 var keys;
7478
7479 if (Object.keys) {
7480 keys = Object.keys;
7481 } else {
7482 keys = function keys(obj) {
7483 var i,
7484 res = [];
7485
7486 for (i in obj) {
7487 if (hasOwnProp(obj, i)) {
7488 res.push(i);
7489 }
7490 }
7491
7492 return res;
7493 };
7494 }
7495
7496 var defaultCalendar = {
7497 sameDay: '[Today at] LT',
7498 nextDay: '[Tomorrow at] LT',
7499 nextWeek: 'dddd [at] LT',
7500 lastDay: '[Yesterday at] LT',
7501 lastWeek: '[Last] dddd [at] LT',
7502 sameElse: 'L'
7503 };
7504
7505 function calendar(key, mom, now) {
7506 var output = this._calendar[key] || this._calendar['sameElse'];
7507 return isFunction(output) ? output.call(mom, now) : output;
7508 }
7509
7510 var defaultLongDateFormat = {
7511 LTS: 'h:mm:ss A',
7512 LT: 'h:mm A',
7513 L: 'MM/DD/YYYY',
7514 LL: 'MMMM D, YYYY',
7515 LLL: 'MMMM D, YYYY h:mm A',
7516 LLLL: 'dddd, MMMM D, YYYY h:mm A'
7517 };
7518
7519 function longDateFormat(key) {
7520 var format = this._longDateFormat[key],
7521 formatUpper = this._longDateFormat[key.toUpperCase()];
7522
7523 if (format || !formatUpper) {
7524 return format;
7525 }
7526
7527 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
7528 return val.slice(1);
7529 });
7530 return this._longDateFormat[key];
7531 }
7532
7533 var defaultInvalidDate = 'Invalid date';
7534
7535 function invalidDate() {
7536 return this._invalidDate;
7537 }
7538
7539 var defaultOrdinal = '%d';
7540 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
7541
7542 function ordinal(number) {
7543 return this._ordinal.replace('%d', number);
7544 }
7545
7546 var defaultRelativeTime = {
7547 future: 'in %s',
7548 past: '%s ago',
7549 s: 'a few seconds',
7550 ss: '%d seconds',
7551 m: 'a minute',
7552 mm: '%d minutes',
7553 h: 'an hour',
7554 hh: '%d hours',
7555 d: 'a day',
7556 dd: '%d days',
7557 M: 'a month',
7558 MM: '%d months',
7559 y: 'a year',
7560 yy: '%d years'
7561 };
7562
7563 function relativeTime(number, withoutSuffix, string, isFuture) {
7564 var output = this._relativeTime[string];
7565 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
7566 }
7567
7568 function pastFuture(diff, output) {
7569 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
7570 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
7571 }
7572
7573 var aliases = {};
7574
7575 function addUnitAlias(unit, shorthand) {
7576 var lowerCase = unit.toLowerCase();
7577 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
7578 }
7579
7580 function normalizeUnits(units) {
7581 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
7582 }
7583
7584 function normalizeObjectUnits(inputObject) {
7585 var normalizedInput = {},
7586 normalizedProp,
7587 prop;
7588
7589 for (prop in inputObject) {
7590 if (hasOwnProp(inputObject, prop)) {
7591 normalizedProp = normalizeUnits(prop);
7592
7593 if (normalizedProp) {
7594 normalizedInput[normalizedProp] = inputObject[prop];
7595 }
7596 }
7597 }
7598
7599 return normalizedInput;
7600 }
7601
7602 var priorities = {};
7603
7604 function addUnitPriority(unit, priority) {
7605 priorities[unit] = priority;
7606 }
7607
7608 function getPrioritizedUnits(unitsObj) {
7609 var units = [];
7610
7611 for (var u in unitsObj) {
7612 units.push({
7613 unit: u,
7614 priority: priorities[u]
7615 });
7616 }
7617
7618 units.sort(function (a, b) {
7619 return a.priority - b.priority;
7620 });
7621 return units;
7622 }
7623
7624 function zeroFill(number, targetLength, forceSign) {
7625 var absNumber = '' + Math.abs(number),
7626 zerosToFill = targetLength - absNumber.length,
7627 sign = number >= 0;
7628 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
7629 }
7630
7631 var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
7632 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
7633 var formatFunctions = {};
7634 var formatTokenFunctions = {}; // token: 'M'
7635 // padded: ['MM', 2]
7636 // ordinal: 'Mo'
7637 // callback: function () { this.month() + 1 }
7638
7639 function addFormatToken(token, padded, ordinal, callback) {
7640 var func = callback;
7641
7642 if (typeof callback === 'string') {
7643 func = function func() {
7644 return this[callback]();
7645 };
7646 }
7647
7648 if (token) {
7649 formatTokenFunctions[token] = func;
7650 }
7651
7652 if (padded) {
7653 formatTokenFunctions[padded[0]] = function () {
7654 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
7655 };
7656 }
7657
7658 if (ordinal) {
7659 formatTokenFunctions[ordinal] = function () {
7660 return this.localeData().ordinal(func.apply(this, arguments), token);
7661 };
7662 }
7663 }
7664
7665 function removeFormattingTokens(input) {
7666 if (input.match(/\[[\s\S]/)) {
7667 return input.replace(/^\[|\]$/g, '');
7668 }
7669
7670 return input.replace(/\\/g, '');
7671 }
7672
7673 function makeFormatFunction(format) {
7674 var array = format.match(formattingTokens),
7675 i,
7676 length;
7677
7678 for (i = 0, length = array.length; i < length; i++) {
7679 if (formatTokenFunctions[array[i]]) {
7680 array[i] = formatTokenFunctions[array[i]];
7681 } else {
7682 array[i] = removeFormattingTokens(array[i]);
7683 }
7684 }
7685
7686 return function (mom) {
7687 var output = '',
7688 i;
7689
7690 for (i = 0; i < length; i++) {
7691 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
7692 }
7693
7694 return output;
7695 };
7696 } // format date using native date object
7697
7698
7699 function formatMoment(m, format) {
7700 if (!m.isValid()) {
7701 return m.localeData().invalidDate();
7702 }
7703
7704 format = expandFormat(format, m.localeData());
7705 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
7706 return formatFunctions[format](m);
7707 }
7708
7709 function expandFormat(format, locale) {
7710 var i = 5;
7711
7712 function replaceLongDateFormatTokens(input) {
7713 return locale.longDateFormat(input) || input;
7714 }
7715
7716 localFormattingTokens.lastIndex = 0;
7717
7718 while (i >= 0 && localFormattingTokens.test(format)) {
7719 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
7720 localFormattingTokens.lastIndex = 0;
7721 i -= 1;
7722 }
7723
7724 return format;
7725 }
7726
7727 var match1 = /\d/; // 0 - 9
7728
7729 var match2 = /\d\d/; // 00 - 99
7730
7731 var match3 = /\d{3}/; // 000 - 999
7732
7733 var match4 = /\d{4}/; // 0000 - 9999
7734
7735 var match6 = /[+-]?\d{6}/; // -999999 - 999999
7736
7737 var match1to2 = /\d\d?/; // 0 - 99
7738
7739 var match3to4 = /\d\d\d\d?/; // 999 - 9999
7740
7741 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
7742
7743 var match1to3 = /\d{1,3}/; // 0 - 999
7744
7745 var match1to4 = /\d{1,4}/; // 0 - 9999
7746
7747 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
7748
7749 var matchUnsigned = /\d+/; // 0 - inf
7750
7751 var matchSigned = /[+-]?\d+/; // -inf - inf
7752
7753 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
7754
7755 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
7756
7757 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
7758 // any word (or two) characters or numbers including two/three word month in arabic.
7759 // includes scottish gaelic two word and hyphenated months
7760
7761 var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
7762 var regexes = {};
7763
7764 function addRegexToken(token, regex, strictRegex) {
7765 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
7766 return isStrict && strictRegex ? strictRegex : regex;
7767 };
7768 }
7769
7770 function getParseRegexForToken(token, config) {
7771 if (!hasOwnProp(regexes, token)) {
7772 return new RegExp(unescapeFormat(token));
7773 }
7774
7775 return regexes[token](config._strict, config._locale);
7776 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
7777
7778
7779 function unescapeFormat(s) {
7780 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
7781 return p1 || p2 || p3 || p4;
7782 }));
7783 }
7784
7785 function regexEscape(s) {
7786 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
7787 }
7788
7789 var tokens = {};
7790
7791 function addParseToken(token, callback) {
7792 var i,
7793 func = callback;
7794
7795 if (typeof token === 'string') {
7796 token = [token];
7797 }
7798
7799 if (isNumber(callback)) {
7800 func = function func(input, array) {
7801 array[callback] = toInt(input);
7802 };
7803 }
7804
7805 for (i = 0; i < token.length; i++) {
7806 tokens[token[i]] = func;
7807 }
7808 }
7809
7810 function addWeekParseToken(token, callback) {
7811 addParseToken(token, function (input, array, config, token) {
7812 config._w = config._w || {};
7813 callback(input, config._w, config, token);
7814 });
7815 }
7816
7817 function addTimeToArrayFromToken(token, input, config) {
7818 if (input != null && hasOwnProp(tokens, token)) {
7819 tokens[token](input, config._a, config, token);
7820 }
7821 }
7822
7823 var YEAR = 0;
7824 var MONTH = 1;
7825 var DATE = 2;
7826 var HOUR = 3;
7827 var MINUTE = 4;
7828 var SECOND = 5;
7829 var MILLISECOND = 6;
7830 var WEEK = 7;
7831 var WEEKDAY = 8; // FORMATTING
7832
7833 addFormatToken('Y', 0, 0, function () {
7834 var y = this.year();
7835 return y <= 9999 ? '' + y : '+' + y;
7836 });
7837 addFormatToken(0, ['YY', 2], 0, function () {
7838 return this.year() % 100;
7839 });
7840 addFormatToken(0, ['YYYY', 4], 0, 'year');
7841 addFormatToken(0, ['YYYYY', 5], 0, 'year');
7842 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
7843
7844 addUnitAlias('year', 'y'); // PRIORITIES
7845
7846 addUnitPriority('year', 1); // PARSING
7847
7848 addRegexToken('Y', matchSigned);
7849 addRegexToken('YY', match1to2, match2);
7850 addRegexToken('YYYY', match1to4, match4);
7851 addRegexToken('YYYYY', match1to6, match6);
7852 addRegexToken('YYYYYY', match1to6, match6);
7853 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
7854 addParseToken('YYYY', function (input, array) {
7855 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
7856 });
7857 addParseToken('YY', function (input, array) {
7858 array[YEAR] = hooks.parseTwoDigitYear(input);
7859 });
7860 addParseToken('Y', function (input, array) {
7861 array[YEAR] = parseInt(input, 10);
7862 }); // HELPERS
7863
7864 function daysInYear(year) {
7865 return isLeapYear(year) ? 366 : 365;
7866 }
7867
7868 function isLeapYear(year) {
7869 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
7870 } // HOOKS
7871
7872
7873 hooks.parseTwoDigitYear = function (input) {
7874 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
7875 }; // MOMENTS
7876
7877
7878 var getSetYear = makeGetSet('FullYear', true);
7879
7880 function getIsLeapYear() {
7881 return isLeapYear(this.year());
7882 }
7883
7884 function makeGetSet(unit, keepTime) {
7885 return function (value) {
7886 if (value != null) {
7887 set$1(this, unit, value);
7888 hooks.updateOffset(this, keepTime);
7889 return this;
7890 } else {
7891 return get(this, unit);
7892 }
7893 };
7894 }
7895
7896 function get(mom, unit) {
7897 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
7898 }
7899
7900 function set$1(mom, unit, value) {
7901 if (mom.isValid() && !isNaN(value)) {
7902 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
7903 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
7904 } else {
7905 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
7906 }
7907 }
7908 } // MOMENTS
7909
7910
7911 function stringGet(units) {
7912 units = normalizeUnits(units);
7913
7914 if (isFunction(this[units])) {
7915 return this[units]();
7916 }
7917
7918 return this;
7919 }
7920
7921 function stringSet(units, value) {
7922 if (_typeof(units) === 'object') {
7923 units = normalizeObjectUnits(units);
7924 var prioritized = getPrioritizedUnits(units);
7925
7926 for (var i = 0; i < prioritized.length; i++) {
7927 this[prioritized[i].unit](units[prioritized[i].unit]);
7928 }
7929 } else {
7930 units = normalizeUnits(units);
7931
7932 if (isFunction(this[units])) {
7933 return this[units](value);
7934 }
7935 }
7936
7937 return this;
7938 }
7939
7940 function mod(n, x) {
7941 return (n % x + x) % x;
7942 }
7943
7944 var indexOf;
7945
7946 if (Array.prototype.indexOf) {
7947 indexOf = Array.prototype.indexOf;
7948 } else {
7949 indexOf = function indexOf(o) {
7950 // I know
7951 var i;
7952
7953 for (i = 0; i < this.length; ++i) {
7954 if (this[i] === o) {
7955 return i;
7956 }
7957 }
7958
7959 return -1;
7960 };
7961 }
7962
7963 function daysInMonth(year, month) {
7964 if (isNaN(year) || isNaN(month)) {
7965 return NaN;
7966 }
7967
7968 var modMonth = mod(month, 12);
7969 year += (month - modMonth) / 12;
7970 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
7971 } // FORMATTING
7972
7973
7974 addFormatToken('M', ['MM', 2], 'Mo', function () {
7975 return this.month() + 1;
7976 });
7977 addFormatToken('MMM', 0, 0, function (format) {
7978 return this.localeData().monthsShort(this, format);
7979 });
7980 addFormatToken('MMMM', 0, 0, function (format) {
7981 return this.localeData().months(this, format);
7982 }); // ALIASES
7983
7984 addUnitAlias('month', 'M'); // PRIORITY
7985
7986 addUnitPriority('month', 8); // PARSING
7987
7988 addRegexToken('M', match1to2);
7989 addRegexToken('MM', match1to2, match2);
7990 addRegexToken('MMM', function (isStrict, locale) {
7991 return locale.monthsShortRegex(isStrict);
7992 });
7993 addRegexToken('MMMM', function (isStrict, locale) {
7994 return locale.monthsRegex(isStrict);
7995 });
7996 addParseToken(['M', 'MM'], function (input, array) {
7997 array[MONTH] = toInt(input) - 1;
7998 });
7999 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
8000 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
8001
8002
8003 if (month != null) {
8004 array[MONTH] = month;
8005 } else {
8006 getParsingFlags(config).invalidMonth = input;
8007 }
8008 }); // LOCALES
8009
8010 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
8011 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
8012
8013 function localeMonths(m, format) {
8014 if (!m) {
8015 return isArray(this._months) ? this._months : this._months['standalone'];
8016 }
8017
8018 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
8019 }
8020
8021 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
8022
8023 function localeMonthsShort(m, format) {
8024 if (!m) {
8025 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
8026 }
8027
8028 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
8029 }
8030
8031 function handleStrictParse(monthName, format, strict) {
8032 var i,
8033 ii,
8034 mom,
8035 llc = monthName.toLocaleLowerCase();
8036
8037 if (!this._monthsParse) {
8038 // this is not used
8039 this._monthsParse = [];
8040 this._longMonthsParse = [];
8041 this._shortMonthsParse = [];
8042
8043 for (i = 0; i < 12; ++i) {
8044 mom = createUTC([2000, i]);
8045 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
8046 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
8047 }
8048 }
8049
8050 if (strict) {
8051 if (format === 'MMM') {
8052 ii = indexOf.call(this._shortMonthsParse, llc);
8053 return ii !== -1 ? ii : null;
8054 } else {
8055 ii = indexOf.call(this._longMonthsParse, llc);
8056 return ii !== -1 ? ii : null;
8057 }
8058 } else {
8059 if (format === 'MMM') {
8060 ii = indexOf.call(this._shortMonthsParse, llc);
8061
8062 if (ii !== -1) {
8063 return ii;
8064 }
8065
8066 ii = indexOf.call(this._longMonthsParse, llc);
8067 return ii !== -1 ? ii : null;
8068 } else {
8069 ii = indexOf.call(this._longMonthsParse, llc);
8070
8071 if (ii !== -1) {
8072 return ii;
8073 }
8074
8075 ii = indexOf.call(this._shortMonthsParse, llc);
8076 return ii !== -1 ? ii : null;
8077 }
8078 }
8079 }
8080
8081 function localeMonthsParse(monthName, format, strict) {
8082 var i, mom, regex;
8083
8084 if (this._monthsParseExact) {
8085 return handleStrictParse.call(this, monthName, format, strict);
8086 }
8087
8088 if (!this._monthsParse) {
8089 this._monthsParse = [];
8090 this._longMonthsParse = [];
8091 this._shortMonthsParse = [];
8092 } // TODO: add sorting
8093 // Sorting makes sure if one month (or abbr) is a prefix of another
8094 // see sorting in computeMonthsParse
8095
8096
8097 for (i = 0; i < 12; i++) {
8098 // make the regex if we don't have it already
8099 mom = createUTC([2000, i]);
8100
8101 if (strict && !this._longMonthsParse[i]) {
8102 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
8103 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
8104 }
8105
8106 if (!strict && !this._monthsParse[i]) {
8107 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
8108 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
8109 } // test the regex
8110
8111
8112 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
8113 return i;
8114 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
8115 return i;
8116 } else if (!strict && this._monthsParse[i].test(monthName)) {
8117 return i;
8118 }
8119 }
8120 } // MOMENTS
8121
8122
8123 function setMonth(mom, value) {
8124 var dayOfMonth;
8125
8126 if (!mom.isValid()) {
8127 // No op
8128 return mom;
8129 }
8130
8131 if (typeof value === 'string') {
8132 if (/^\d+$/.test(value)) {
8133 value = toInt(value);
8134 } else {
8135 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
8136
8137 if (!isNumber(value)) {
8138 return mom;
8139 }
8140 }
8141 }
8142
8143 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
8144
8145 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
8146
8147 return mom;
8148 }
8149
8150 function getSetMonth(value) {
8151 if (value != null) {
8152 setMonth(this, value);
8153 hooks.updateOffset(this, true);
8154 return this;
8155 } else {
8156 return get(this, 'Month');
8157 }
8158 }
8159
8160 function getDaysInMonth() {
8161 return daysInMonth(this.year(), this.month());
8162 }
8163
8164 var defaultMonthsShortRegex = matchWord;
8165
8166 function monthsShortRegex(isStrict) {
8167 if (this._monthsParseExact) {
8168 if (!hasOwnProp(this, '_monthsRegex')) {
8169 computeMonthsParse.call(this);
8170 }
8171
8172 if (isStrict) {
8173 return this._monthsShortStrictRegex;
8174 } else {
8175 return this._monthsShortRegex;
8176 }
8177 } else {
8178 if (!hasOwnProp(this, '_monthsShortRegex')) {
8179 this._monthsShortRegex = defaultMonthsShortRegex;
8180 }
8181
8182 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
8183 }
8184 }
8185
8186 var defaultMonthsRegex = matchWord;
8187
8188 function monthsRegex(isStrict) {
8189 if (this._monthsParseExact) {
8190 if (!hasOwnProp(this, '_monthsRegex')) {
8191 computeMonthsParse.call(this);
8192 }
8193
8194 if (isStrict) {
8195 return this._monthsStrictRegex;
8196 } else {
8197 return this._monthsRegex;
8198 }
8199 } else {
8200 if (!hasOwnProp(this, '_monthsRegex')) {
8201 this._monthsRegex = defaultMonthsRegex;
8202 }
8203
8204 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
8205 }
8206 }
8207
8208 function computeMonthsParse() {
8209 function cmpLenRev(a, b) {
8210 return b.length - a.length;
8211 }
8212
8213 var shortPieces = [],
8214 longPieces = [],
8215 mixedPieces = [],
8216 i,
8217 mom;
8218
8219 for (i = 0; i < 12; i++) {
8220 // make the regex if we don't have it already
8221 mom = createUTC([2000, i]);
8222 shortPieces.push(this.monthsShort(mom, ''));
8223 longPieces.push(this.months(mom, ''));
8224 mixedPieces.push(this.months(mom, ''));
8225 mixedPieces.push(this.monthsShort(mom, ''));
8226 } // Sorting makes sure if one month (or abbr) is a prefix of another it
8227 // will match the longer piece.
8228
8229
8230 shortPieces.sort(cmpLenRev);
8231 longPieces.sort(cmpLenRev);
8232 mixedPieces.sort(cmpLenRev);
8233
8234 for (i = 0; i < 12; i++) {
8235 shortPieces[i] = regexEscape(shortPieces[i]);
8236 longPieces[i] = regexEscape(longPieces[i]);
8237 }
8238
8239 for (i = 0; i < 24; i++) {
8240 mixedPieces[i] = regexEscape(mixedPieces[i]);
8241 }
8242
8243 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
8244 this._monthsShortRegex = this._monthsRegex;
8245 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
8246 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
8247 }
8248
8249 function createDate(y, m, d, h, M, s, ms) {
8250 // can't just apply() to create a date:
8251 // https://stackoverflow.com/q/181348
8252 var date; // the date constructor remaps years 0-99 to 1900-1999
8253
8254 if (y < 100 && y >= 0) {
8255 // preserve leap years using a full 400 year cycle, then reset
8256 date = new Date(y + 400, m, d, h, M, s, ms);
8257
8258 if (isFinite(date.getFullYear())) {
8259 date.setFullYear(y);
8260 }
8261 } else {
8262 date = new Date(y, m, d, h, M, s, ms);
8263 }
8264
8265 return date;
8266 }
8267
8268 function createUTCDate(y) {
8269 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
8270
8271 if (y < 100 && y >= 0) {
8272 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
8273
8274 args[0] = y + 400;
8275 date = new Date(Date.UTC.apply(null, args));
8276
8277 if (isFinite(date.getUTCFullYear())) {
8278 date.setUTCFullYear(y);
8279 }
8280 } else {
8281 date = new Date(Date.UTC.apply(null, arguments));
8282 }
8283
8284 return date;
8285 } // start-of-first-week - start-of-year
8286
8287
8288 function firstWeekOffset(year, dow, doy) {
8289 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
8290 fwd = 7 + dow - doy,
8291 // first-week day local weekday -- which local weekday is fwd
8292 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
8293 return -fwdlw + fwd - 1;
8294 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
8295
8296
8297 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
8298 var localWeekday = (7 + weekday - dow) % 7,
8299 weekOffset = firstWeekOffset(year, dow, doy),
8300 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
8301 resYear,
8302 resDayOfYear;
8303
8304 if (dayOfYear <= 0) {
8305 resYear = year - 1;
8306 resDayOfYear = daysInYear(resYear) + dayOfYear;
8307 } else if (dayOfYear > daysInYear(year)) {
8308 resYear = year + 1;
8309 resDayOfYear = dayOfYear - daysInYear(year);
8310 } else {
8311 resYear = year;
8312 resDayOfYear = dayOfYear;
8313 }
8314
8315 return {
8316 year: resYear,
8317 dayOfYear: resDayOfYear
8318 };
8319 }
8320
8321 function weekOfYear(mom, dow, doy) {
8322 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
8323 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
8324 resWeek,
8325 resYear;
8326
8327 if (week < 1) {
8328 resYear = mom.year() - 1;
8329 resWeek = week + weeksInYear(resYear, dow, doy);
8330 } else if (week > weeksInYear(mom.year(), dow, doy)) {
8331 resWeek = week - weeksInYear(mom.year(), dow, doy);
8332 resYear = mom.year() + 1;
8333 } else {
8334 resYear = mom.year();
8335 resWeek = week;
8336 }
8337
8338 return {
8339 week: resWeek,
8340 year: resYear
8341 };
8342 }
8343
8344 function weeksInYear(year, dow, doy) {
8345 var weekOffset = firstWeekOffset(year, dow, doy),
8346 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
8347 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
8348 } // FORMATTING
8349
8350
8351 addFormatToken('w', ['ww', 2], 'wo', 'week');
8352 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
8353
8354 addUnitAlias('week', 'w');
8355 addUnitAlias('isoWeek', 'W'); // PRIORITIES
8356
8357 addUnitPriority('week', 5);
8358 addUnitPriority('isoWeek', 5); // PARSING
8359
8360 addRegexToken('w', match1to2);
8361 addRegexToken('ww', match1to2, match2);
8362 addRegexToken('W', match1to2);
8363 addRegexToken('WW', match1to2, match2);
8364 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
8365 week[token.substr(0, 1)] = toInt(input);
8366 }); // HELPERS
8367 // LOCALES
8368
8369 function localeWeek(mom) {
8370 return weekOfYear(mom, this._week.dow, this._week.doy).week;
8371 }
8372
8373 var defaultLocaleWeek = {
8374 dow: 0,
8375 // Sunday is the first day of the week.
8376 doy: 6 // The week that contains Jan 6th is the first week of the year.
8377
8378 };
8379
8380 function localeFirstDayOfWeek() {
8381 return this._week.dow;
8382 }
8383
8384 function localeFirstDayOfYear() {
8385 return this._week.doy;
8386 } // MOMENTS
8387
8388
8389 function getSetWeek(input) {
8390 var week = this.localeData().week(this);
8391 return input == null ? week : this.add((input - week) * 7, 'd');
8392 }
8393
8394 function getSetISOWeek(input) {
8395 var week = weekOfYear(this, 1, 4).week;
8396 return input == null ? week : this.add((input - week) * 7, 'd');
8397 } // FORMATTING
8398
8399
8400 addFormatToken('d', 0, 'do', 'day');
8401 addFormatToken('dd', 0, 0, function (format) {
8402 return this.localeData().weekdaysMin(this, format);
8403 });
8404 addFormatToken('ddd', 0, 0, function (format) {
8405 return this.localeData().weekdaysShort(this, format);
8406 });
8407 addFormatToken('dddd', 0, 0, function (format) {
8408 return this.localeData().weekdays(this, format);
8409 });
8410 addFormatToken('e', 0, 0, 'weekday');
8411 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
8412
8413 addUnitAlias('day', 'd');
8414 addUnitAlias('weekday', 'e');
8415 addUnitAlias('isoWeekday', 'E'); // PRIORITY
8416
8417 addUnitPriority('day', 11);
8418 addUnitPriority('weekday', 11);
8419 addUnitPriority('isoWeekday', 11); // PARSING
8420
8421 addRegexToken('d', match1to2);
8422 addRegexToken('e', match1to2);
8423 addRegexToken('E', match1to2);
8424 addRegexToken('dd', function (isStrict, locale) {
8425 return locale.weekdaysMinRegex(isStrict);
8426 });
8427 addRegexToken('ddd', function (isStrict, locale) {
8428 return locale.weekdaysShortRegex(isStrict);
8429 });
8430 addRegexToken('dddd', function (isStrict, locale) {
8431 return locale.weekdaysRegex(isStrict);
8432 });
8433 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
8434 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
8435
8436
8437 if (weekday != null) {
8438 week.d = weekday;
8439 } else {
8440 getParsingFlags(config).invalidWeekday = input;
8441 }
8442 });
8443 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
8444 week[token] = toInt(input);
8445 }); // HELPERS
8446
8447 function parseWeekday(input, locale) {
8448 if (typeof input !== 'string') {
8449 return input;
8450 }
8451
8452 if (!isNaN(input)) {
8453 return parseInt(input, 10);
8454 }
8455
8456 input = locale.weekdaysParse(input);
8457
8458 if (typeof input === 'number') {
8459 return input;
8460 }
8461
8462 return null;
8463 }
8464
8465 function parseIsoWeekday(input, locale) {
8466 if (typeof input === 'string') {
8467 return locale.weekdaysParse(input) % 7 || 7;
8468 }
8469
8470 return isNaN(input) ? null : input;
8471 } // LOCALES
8472
8473
8474 function shiftWeekdays(ws, n) {
8475 return ws.slice(n, 7).concat(ws.slice(0, n));
8476 }
8477
8478 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
8479
8480 function localeWeekdays(m, format) {
8481 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
8482 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
8483 }
8484
8485 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
8486
8487 function localeWeekdaysShort(m) {
8488 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
8489 }
8490
8491 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
8492
8493 function localeWeekdaysMin(m) {
8494 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
8495 }
8496
8497 function handleStrictParse$1(weekdayName, format, strict) {
8498 var i,
8499 ii,
8500 mom,
8501 llc = weekdayName.toLocaleLowerCase();
8502
8503 if (!this._weekdaysParse) {
8504 this._weekdaysParse = [];
8505 this._shortWeekdaysParse = [];
8506 this._minWeekdaysParse = [];
8507
8508 for (i = 0; i < 7; ++i) {
8509 mom = createUTC([2000, 1]).day(i);
8510 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
8511 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
8512 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
8513 }
8514 }
8515
8516 if (strict) {
8517 if (format === 'dddd') {
8518 ii = indexOf.call(this._weekdaysParse, llc);
8519 return ii !== -1 ? ii : null;
8520 } else if (format === 'ddd') {
8521 ii = indexOf.call(this._shortWeekdaysParse, llc);
8522 return ii !== -1 ? ii : null;
8523 } else {
8524 ii = indexOf.call(this._minWeekdaysParse, llc);
8525 return ii !== -1 ? ii : null;
8526 }
8527 } else {
8528 if (format === 'dddd') {
8529 ii = indexOf.call(this._weekdaysParse, llc);
8530
8531 if (ii !== -1) {
8532 return ii;
8533 }
8534
8535 ii = indexOf.call(this._shortWeekdaysParse, llc);
8536
8537 if (ii !== -1) {
8538 return ii;
8539 }
8540
8541 ii = indexOf.call(this._minWeekdaysParse, llc);
8542 return ii !== -1 ? ii : null;
8543 } else if (format === 'ddd') {
8544 ii = indexOf.call(this._shortWeekdaysParse, llc);
8545
8546 if (ii !== -1) {
8547 return ii;
8548 }
8549
8550 ii = indexOf.call(this._weekdaysParse, llc);
8551
8552 if (ii !== -1) {
8553 return ii;
8554 }
8555
8556 ii = indexOf.call(this._minWeekdaysParse, llc);
8557 return ii !== -1 ? ii : null;
8558 } else {
8559 ii = indexOf.call(this._minWeekdaysParse, llc);
8560
8561 if (ii !== -1) {
8562 return ii;
8563 }
8564
8565 ii = indexOf.call(this._weekdaysParse, llc);
8566
8567 if (ii !== -1) {
8568 return ii;
8569 }
8570
8571 ii = indexOf.call(this._shortWeekdaysParse, llc);
8572 return ii !== -1 ? ii : null;
8573 }
8574 }
8575 }
8576
8577 function localeWeekdaysParse(weekdayName, format, strict) {
8578 var i, mom, regex;
8579
8580 if (this._weekdaysParseExact) {
8581 return handleStrictParse$1.call(this, weekdayName, format, strict);
8582 }
8583
8584 if (!this._weekdaysParse) {
8585 this._weekdaysParse = [];
8586 this._minWeekdaysParse = [];
8587 this._shortWeekdaysParse = [];
8588 this._fullWeekdaysParse = [];
8589 }
8590
8591 for (i = 0; i < 7; i++) {
8592 // make the regex if we don't have it already
8593 mom = createUTC([2000, 1]).day(i);
8594
8595 if (strict && !this._fullWeekdaysParse[i]) {
8596 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
8597 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
8598 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
8599 }
8600
8601 if (!this._weekdaysParse[i]) {
8602 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
8603 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
8604 } // test the regex
8605
8606
8607 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
8608 return i;
8609 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
8610 return i;
8611 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
8612 return i;
8613 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
8614 return i;
8615 }
8616 }
8617 } // MOMENTS
8618
8619
8620 function getSetDayOfWeek(input) {
8621 if (!this.isValid()) {
8622 return input != null ? this : NaN;
8623 }
8624
8625 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
8626
8627 if (input != null) {
8628 input = parseWeekday(input, this.localeData());
8629 return this.add(input - day, 'd');
8630 } else {
8631 return day;
8632 }
8633 }
8634
8635 function getSetLocaleDayOfWeek(input) {
8636 if (!this.isValid()) {
8637 return input != null ? this : NaN;
8638 }
8639
8640 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
8641 return input == null ? weekday : this.add(input - weekday, 'd');
8642 }
8643
8644 function getSetISODayOfWeek(input) {
8645 if (!this.isValid()) {
8646 return input != null ? this : NaN;
8647 } // behaves the same as moment#day except
8648 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
8649 // as a setter, sunday should belong to the previous week.
8650
8651
8652 if (input != null) {
8653 var weekday = parseIsoWeekday(input, this.localeData());
8654 return this.day(this.day() % 7 ? weekday : weekday - 7);
8655 } else {
8656 return this.day() || 7;
8657 }
8658 }
8659
8660 var defaultWeekdaysRegex = matchWord;
8661
8662 function weekdaysRegex(isStrict) {
8663 if (this._weekdaysParseExact) {
8664 if (!hasOwnProp(this, '_weekdaysRegex')) {
8665 computeWeekdaysParse.call(this);
8666 }
8667
8668 if (isStrict) {
8669 return this._weekdaysStrictRegex;
8670 } else {
8671 return this._weekdaysRegex;
8672 }
8673 } else {
8674 if (!hasOwnProp(this, '_weekdaysRegex')) {
8675 this._weekdaysRegex = defaultWeekdaysRegex;
8676 }
8677
8678 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
8679 }
8680 }
8681
8682 var defaultWeekdaysShortRegex = matchWord;
8683
8684 function weekdaysShortRegex(isStrict) {
8685 if (this._weekdaysParseExact) {
8686 if (!hasOwnProp(this, '_weekdaysRegex')) {
8687 computeWeekdaysParse.call(this);
8688 }
8689
8690 if (isStrict) {
8691 return this._weekdaysShortStrictRegex;
8692 } else {
8693 return this._weekdaysShortRegex;
8694 }
8695 } else {
8696 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
8697 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
8698 }
8699
8700 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
8701 }
8702 }
8703
8704 var defaultWeekdaysMinRegex = matchWord;
8705
8706 function weekdaysMinRegex(isStrict) {
8707 if (this._weekdaysParseExact) {
8708 if (!hasOwnProp(this, '_weekdaysRegex')) {
8709 computeWeekdaysParse.call(this);
8710 }
8711
8712 if (isStrict) {
8713 return this._weekdaysMinStrictRegex;
8714 } else {
8715 return this._weekdaysMinRegex;
8716 }
8717 } else {
8718 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
8719 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
8720 }
8721
8722 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
8723 }
8724 }
8725
8726 function computeWeekdaysParse() {
8727 function cmpLenRev(a, b) {
8728 return b.length - a.length;
8729 }
8730
8731 var minPieces = [],
8732 shortPieces = [],
8733 longPieces = [],
8734 mixedPieces = [],
8735 i,
8736 mom,
8737 minp,
8738 shortp,
8739 longp;
8740
8741 for (i = 0; i < 7; i++) {
8742 // make the regex if we don't have it already
8743 mom = createUTC([2000, 1]).day(i);
8744 minp = this.weekdaysMin(mom, '');
8745 shortp = this.weekdaysShort(mom, '');
8746 longp = this.weekdays(mom, '');
8747 minPieces.push(minp);
8748 shortPieces.push(shortp);
8749 longPieces.push(longp);
8750 mixedPieces.push(minp);
8751 mixedPieces.push(shortp);
8752 mixedPieces.push(longp);
8753 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
8754 // will match the longer piece.
8755
8756
8757 minPieces.sort(cmpLenRev);
8758 shortPieces.sort(cmpLenRev);
8759 longPieces.sort(cmpLenRev);
8760 mixedPieces.sort(cmpLenRev);
8761
8762 for (i = 0; i < 7; i++) {
8763 shortPieces[i] = regexEscape(shortPieces[i]);
8764 longPieces[i] = regexEscape(longPieces[i]);
8765 mixedPieces[i] = regexEscape(mixedPieces[i]);
8766 }
8767
8768 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
8769 this._weekdaysShortRegex = this._weekdaysRegex;
8770 this._weekdaysMinRegex = this._weekdaysRegex;
8771 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
8772 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
8773 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
8774 } // FORMATTING
8775
8776
8777 function hFormat() {
8778 return this.hours() % 12 || 12;
8779 }
8780
8781 function kFormat() {
8782 return this.hours() || 24;
8783 }
8784
8785 addFormatToken('H', ['HH', 2], 0, 'hour');
8786 addFormatToken('h', ['hh', 2], 0, hFormat);
8787 addFormatToken('k', ['kk', 2], 0, kFormat);
8788 addFormatToken('hmm', 0, 0, function () {
8789 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
8790 });
8791 addFormatToken('hmmss', 0, 0, function () {
8792 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
8793 });
8794 addFormatToken('Hmm', 0, 0, function () {
8795 return '' + this.hours() + zeroFill(this.minutes(), 2);
8796 });
8797 addFormatToken('Hmmss', 0, 0, function () {
8798 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
8799 });
8800
8801 function meridiem(token, lowercase) {
8802 addFormatToken(token, 0, 0, function () {
8803 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
8804 });
8805 }
8806
8807 meridiem('a', true);
8808 meridiem('A', false); // ALIASES
8809
8810 addUnitAlias('hour', 'h'); // PRIORITY
8811
8812 addUnitPriority('hour', 13); // PARSING
8813
8814 function matchMeridiem(isStrict, locale) {
8815 return locale._meridiemParse;
8816 }
8817
8818 addRegexToken('a', matchMeridiem);
8819 addRegexToken('A', matchMeridiem);
8820 addRegexToken('H', match1to2);
8821 addRegexToken('h', match1to2);
8822 addRegexToken('k', match1to2);
8823 addRegexToken('HH', match1to2, match2);
8824 addRegexToken('hh', match1to2, match2);
8825 addRegexToken('kk', match1to2, match2);
8826 addRegexToken('hmm', match3to4);
8827 addRegexToken('hmmss', match5to6);
8828 addRegexToken('Hmm', match3to4);
8829 addRegexToken('Hmmss', match5to6);
8830 addParseToken(['H', 'HH'], HOUR);
8831 addParseToken(['k', 'kk'], function (input, array, config) {
8832 var kInput = toInt(input);
8833 array[HOUR] = kInput === 24 ? 0 : kInput;
8834 });
8835 addParseToken(['a', 'A'], function (input, array, config) {
8836 config._isPm = config._locale.isPM(input);
8837 config._meridiem = input;
8838 });
8839 addParseToken(['h', 'hh'], function (input, array, config) {
8840 array[HOUR] = toInt(input);
8841 getParsingFlags(config).bigHour = true;
8842 });
8843 addParseToken('hmm', function (input, array, config) {
8844 var pos = input.length - 2;
8845 array[HOUR] = toInt(input.substr(0, pos));
8846 array[MINUTE] = toInt(input.substr(pos));
8847 getParsingFlags(config).bigHour = true;
8848 });
8849 addParseToken('hmmss', function (input, array, config) {
8850 var pos1 = input.length - 4;
8851 var pos2 = input.length - 2;
8852 array[HOUR] = toInt(input.substr(0, pos1));
8853 array[MINUTE] = toInt(input.substr(pos1, 2));
8854 array[SECOND] = toInt(input.substr(pos2));
8855 getParsingFlags(config).bigHour = true;
8856 });
8857 addParseToken('Hmm', function (input, array, config) {
8858 var pos = input.length - 2;
8859 array[HOUR] = toInt(input.substr(0, pos));
8860 array[MINUTE] = toInt(input.substr(pos));
8861 });
8862 addParseToken('Hmmss', function (input, array, config) {
8863 var pos1 = input.length - 4;
8864 var pos2 = input.length - 2;
8865 array[HOUR] = toInt(input.substr(0, pos1));
8866 array[MINUTE] = toInt(input.substr(pos1, 2));
8867 array[SECOND] = toInt(input.substr(pos2));
8868 }); // LOCALES
8869
8870 function localeIsPM(input) {
8871 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
8872 // Using charAt should be more compatible.
8873 return (input + '').toLowerCase().charAt(0) === 'p';
8874 }
8875
8876 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
8877
8878 function localeMeridiem(hours, minutes, isLower) {
8879 if (hours > 11) {
8880 return isLower ? 'pm' : 'PM';
8881 } else {
8882 return isLower ? 'am' : 'AM';
8883 }
8884 } // MOMENTS
8885 // Setting the hour should keep the time, because the user explicitly
8886 // specified which hour they want. So trying to maintain the same hour (in
8887 // a new timezone) makes sense. Adding/subtracting hours does not follow
8888 // this rule.
8889
8890
8891 var getSetHour = makeGetSet('Hours', true);
8892 var baseConfig = {
8893 calendar: defaultCalendar,
8894 longDateFormat: defaultLongDateFormat,
8895 invalidDate: defaultInvalidDate,
8896 ordinal: defaultOrdinal,
8897 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
8898 relativeTime: defaultRelativeTime,
8899 months: defaultLocaleMonths,
8900 monthsShort: defaultLocaleMonthsShort,
8901 week: defaultLocaleWeek,
8902 weekdays: defaultLocaleWeekdays,
8903 weekdaysMin: defaultLocaleWeekdaysMin,
8904 weekdaysShort: defaultLocaleWeekdaysShort,
8905 meridiemParse: defaultLocaleMeridiemParse
8906 }; // internal storage for locale config files
8907
8908 var locales = {};
8909 var localeFamilies = {};
8910 var globalLocale;
8911
8912 function normalizeLocale(key) {
8913 return key ? key.toLowerCase().replace('_', '-') : key;
8914 } // pick the locale from the array
8915 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
8916 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
8917
8918
8919 function chooseLocale(names) {
8920 var i = 0,
8921 j,
8922 next,
8923 locale,
8924 split;
8925
8926 while (i < names.length) {
8927 split = normalizeLocale(names[i]).split('-');
8928 j = split.length;
8929 next = normalizeLocale(names[i + 1]);
8930 next = next ? next.split('-') : null;
8931
8932 while (j > 0) {
8933 locale = loadLocale(split.slice(0, j).join('-'));
8934
8935 if (locale) {
8936 return locale;
8937 }
8938
8939 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
8940 //the next array item is better than a shallower substring of this one
8941 break;
8942 }
8943
8944 j--;
8945 }
8946
8947 i++;
8948 }
8949
8950 return globalLocale;
8951 }
8952
8953 function loadLocale(name) {
8954 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
8955
8956 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
8957 try {
8958 oldLocale = globalLocale._abbr;
8959 var aliasedRequire = commonjsRequire;
8960 aliasedRequire('./locale/' + name);
8961 getSetGlobalLocale(oldLocale);
8962 } catch (e) {}
8963 }
8964
8965 return locales[name];
8966 } // This function will load locale and then set the global locale. If
8967 // no arguments are passed in, it will simply return the current global
8968 // locale key.
8969
8970
8971 function getSetGlobalLocale(key, values) {
8972 var data;
8973
8974 if (key) {
8975 if (isUndefined(values)) {
8976 data = getLocale(key);
8977 } else {
8978 data = defineLocale(key, values);
8979 }
8980
8981 if (data) {
8982 // moment.duration._locale = moment._locale = data;
8983 globalLocale = data;
8984 } else {
8985 if (typeof console !== 'undefined' && console.warn) {
8986 //warn user if arguments are passed but the locale could not be set
8987 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
8988 }
8989 }
8990 }
8991
8992 return globalLocale._abbr;
8993 }
8994
8995 function defineLocale(name, config) {
8996 if (config !== null) {
8997 var locale,
8998 parentConfig = baseConfig;
8999 config.abbr = name;
9000
9001 if (locales[name] != null) {
9002 deprecateSimple('defineLocaleOverride', 'use moment.updateLocale(localeName, config) to change ' + 'an existing locale. moment.defineLocale(localeName, ' + 'config) should only be used for creating a new locale ' + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
9003 parentConfig = locales[name]._config;
9004 } else if (config.parentLocale != null) {
9005 if (locales[config.parentLocale] != null) {
9006 parentConfig = locales[config.parentLocale]._config;
9007 } else {
9008 locale = loadLocale(config.parentLocale);
9009
9010 if (locale != null) {
9011 parentConfig = locale._config;
9012 } else {
9013 if (!localeFamilies[config.parentLocale]) {
9014 localeFamilies[config.parentLocale] = [];
9015 }
9016
9017 localeFamilies[config.parentLocale].push({
9018 name: name,
9019 config: config
9020 });
9021 return null;
9022 }
9023 }
9024 }
9025
9026 locales[name] = new Locale(mergeConfigs(parentConfig, config));
9027
9028 if (localeFamilies[name]) {
9029 localeFamilies[name].forEach(function (x) {
9030 defineLocale(x.name, x.config);
9031 });
9032 } // backwards compat for now: also set the locale
9033 // make sure we set the locale AFTER all child locales have been
9034 // created, so we won't end up with the child locale set.
9035
9036
9037 getSetGlobalLocale(name);
9038 return locales[name];
9039 } else {
9040 // useful for testing
9041 delete locales[name];
9042 return null;
9043 }
9044 }
9045
9046 function updateLocale(name, config) {
9047 if (config != null) {
9048 var locale,
9049 tmpLocale,
9050 parentConfig = baseConfig; // MERGE
9051
9052 tmpLocale = loadLocale(name);
9053
9054 if (tmpLocale != null) {
9055 parentConfig = tmpLocale._config;
9056 }
9057
9058 config = mergeConfigs(parentConfig, config);
9059 locale = new Locale(config);
9060 locale.parentLocale = locales[name];
9061 locales[name] = locale; // backwards compat for now: also set the locale
9062
9063 getSetGlobalLocale(name);
9064 } else {
9065 // pass null for config to unupdate, useful for tests
9066 if (locales[name] != null) {
9067 if (locales[name].parentLocale != null) {
9068 locales[name] = locales[name].parentLocale;
9069 } else if (locales[name] != null) {
9070 delete locales[name];
9071 }
9072 }
9073 }
9074
9075 return locales[name];
9076 } // returns locale data
9077
9078
9079 function getLocale(key) {
9080 var locale;
9081
9082 if (key && key._locale && key._locale._abbr) {
9083 key = key._locale._abbr;
9084 }
9085
9086 if (!key) {
9087 return globalLocale;
9088 }
9089
9090 if (!isArray(key)) {
9091 //short-circuit everything else
9092 locale = loadLocale(key);
9093
9094 if (locale) {
9095 return locale;
9096 }
9097
9098 key = [key];
9099 }
9100
9101 return chooseLocale(key);
9102 }
9103
9104 function listLocales() {
9105 return keys(locales);
9106 }
9107
9108 function checkOverflow(m) {
9109 var overflow;
9110 var a = m._a;
9111
9112 if (a && getParsingFlags(m).overflow === -2) {
9113 overflow = a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : a[HOUR] < 0 || a[HOUR] > 24 || a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0) ? HOUR : a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : -1;
9114
9115 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
9116 overflow = DATE;
9117 }
9118
9119 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
9120 overflow = WEEK;
9121 }
9122
9123 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
9124 overflow = WEEKDAY;
9125 }
9126
9127 getParsingFlags(m).overflow = overflow;
9128 }
9129
9130 return m;
9131 } // Pick the first defined of two or three arguments.
9132
9133
9134 function defaults(a, b, c) {
9135 if (a != null) {
9136 return a;
9137 }
9138
9139 if (b != null) {
9140 return b;
9141 }
9142
9143 return c;
9144 }
9145
9146 function currentDateArray(config) {
9147 // hooks is actually the exported moment object
9148 var nowValue = new Date(hooks.now());
9149
9150 if (config._useUTC) {
9151 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
9152 }
9153
9154 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
9155 } // convert an array to a date.
9156 // the array should mirror the parameters below
9157 // note: all values past the year are optional and will default to the lowest possible value.
9158 // [year, month, day , hour, minute, second, millisecond]
9159
9160
9161 function configFromArray(config) {
9162 var i,
9163 date,
9164 input = [],
9165 currentDate,
9166 expectedWeekday,
9167 yearToUse;
9168
9169 if (config._d) {
9170 return;
9171 }
9172
9173 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
9174
9175 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
9176 dayOfYearFromWeekInfo(config);
9177 } //if the day of the year is set, figure out what it is
9178
9179
9180 if (config._dayOfYear != null) {
9181 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
9182
9183 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
9184 getParsingFlags(config)._overflowDayOfYear = true;
9185 }
9186
9187 date = createUTCDate(yearToUse, 0, config._dayOfYear);
9188 config._a[MONTH] = date.getUTCMonth();
9189 config._a[DATE] = date.getUTCDate();
9190 } // Default to current date.
9191 // * if no year, month, day of month are given, default to today
9192 // * if day of month is given, default month and year
9193 // * if month is given, default only year
9194 // * if year is given, don't default anything
9195
9196
9197 for (i = 0; i < 3 && config._a[i] == null; ++i) {
9198 config._a[i] = input[i] = currentDate[i];
9199 } // Zero out whatever was not defaulted, including time
9200
9201
9202 for (; i < 7; i++) {
9203 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
9204 } // Check for 24:00:00.000
9205
9206
9207 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
9208 config._nextDay = true;
9209 config._a[HOUR] = 0;
9210 }
9211
9212 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
9213 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
9214 // with parseZone.
9215
9216 if (config._tzm != null) {
9217 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
9218 }
9219
9220 if (config._nextDay) {
9221 config._a[HOUR] = 24;
9222 } // check for mismatching day of week
9223
9224
9225 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
9226 getParsingFlags(config).weekdayMismatch = true;
9227 }
9228 }
9229
9230 function dayOfYearFromWeekInfo(config) {
9231 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
9232 w = config._w;
9233
9234 if (w.GG != null || w.W != null || w.E != null) {
9235 dow = 1;
9236 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
9237 // how we interpret now (local, utc, fixed offset). So create
9238 // a now version of current config (take local/utc/offset flags, and
9239 // create now).
9240
9241 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
9242 week = defaults(w.W, 1);
9243 weekday = defaults(w.E, 1);
9244
9245 if (weekday < 1 || weekday > 7) {
9246 weekdayOverflow = true;
9247 }
9248 } else {
9249 dow = config._locale._week.dow;
9250 doy = config._locale._week.doy;
9251 var curWeek = weekOfYear(createLocal(), dow, doy);
9252 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
9253
9254 week = defaults(w.w, curWeek.week);
9255
9256 if (w.d != null) {
9257 // weekday -- low day numbers are considered next week
9258 weekday = w.d;
9259
9260 if (weekday < 0 || weekday > 6) {
9261 weekdayOverflow = true;
9262 }
9263 } else if (w.e != null) {
9264 // local weekday -- counting starts from beginning of week
9265 weekday = w.e + dow;
9266
9267 if (w.e < 0 || w.e > 6) {
9268 weekdayOverflow = true;
9269 }
9270 } else {
9271 // default to beginning of week
9272 weekday = dow;
9273 }
9274 }
9275
9276 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
9277 getParsingFlags(config)._overflowWeeks = true;
9278 } else if (weekdayOverflow != null) {
9279 getParsingFlags(config)._overflowWeekday = true;
9280 } else {
9281 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
9282 config._a[YEAR] = temp.year;
9283 config._dayOfYear = temp.dayOfYear;
9284 }
9285 } // iso 8601 regex
9286 // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
9287
9288
9289 var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
9290 var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
9291 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
9292 var isoDates = [['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], ['GGGG-[W]WW', /\d{4}-W\d\d/, false], ['YYYY-DDD', /\d{4}-\d{3}/], ['YYYY-MM', /\d{4}-\d\d/, false], ['YYYYYYMMDD', /[+-]\d{10}/], ['YYYYMMDD', /\d{8}/], // YYYYMM is NOT allowed by the standard
9293 ['GGGG[W]WWE', /\d{4}W\d{3}/], ['GGGG[W]WW', /\d{4}W\d{2}/, false], ['YYYYDDD', /\d{7}/]]; // iso time formats and regexes
9294
9295 var isoTimes = [['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], ['HH:mm:ss', /\d\d:\d\d:\d\d/], ['HH:mm', /\d\d:\d\d/], ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], ['HHmmss', /\d\d\d\d\d\d/], ['HHmm', /\d\d\d\d/], ['HH', /\d\d/]];
9296 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
9297
9298 function configFromISO(config) {
9299 var i,
9300 l,
9301 string = config._i,
9302 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
9303 allowTime,
9304 dateFormat,
9305 timeFormat,
9306 tzFormat;
9307
9308 if (match) {
9309 getParsingFlags(config).iso = true;
9310
9311 for (i = 0, l = isoDates.length; i < l; i++) {
9312 if (isoDates[i][1].exec(match[1])) {
9313 dateFormat = isoDates[i][0];
9314 allowTime = isoDates[i][2] !== false;
9315 break;
9316 }
9317 }
9318
9319 if (dateFormat == null) {
9320 config._isValid = false;
9321 return;
9322 }
9323
9324 if (match[3]) {
9325 for (i = 0, l = isoTimes.length; i < l; i++) {
9326 if (isoTimes[i][1].exec(match[3])) {
9327 // match[2] should be 'T' or space
9328 timeFormat = (match[2] || ' ') + isoTimes[i][0];
9329 break;
9330 }
9331 }
9332
9333 if (timeFormat == null) {
9334 config._isValid = false;
9335 return;
9336 }
9337 }
9338
9339 if (!allowTime && timeFormat != null) {
9340 config._isValid = false;
9341 return;
9342 }
9343
9344 if (match[4]) {
9345 if (tzRegex.exec(match[4])) {
9346 tzFormat = 'Z';
9347 } else {
9348 config._isValid = false;
9349 return;
9350 }
9351 }
9352
9353 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
9354 configFromStringAndFormat(config);
9355 } else {
9356 config._isValid = false;
9357 }
9358 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
9359
9360
9361 var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
9362
9363 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
9364 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
9365
9366 if (secondStr) {
9367 result.push(parseInt(secondStr, 10));
9368 }
9369
9370 return result;
9371 }
9372
9373 function untruncateYear(yearStr) {
9374 var year = parseInt(yearStr, 10);
9375
9376 if (year <= 49) {
9377 return 2000 + year;
9378 } else if (year <= 999) {
9379 return 1900 + year;
9380 }
9381
9382 return year;
9383 }
9384
9385 function preprocessRFC2822(s) {
9386 // Remove comments and folding whitespace and replace multiple-spaces with a single space
9387 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
9388 }
9389
9390 function checkWeekday(weekdayStr, parsedInput, config) {
9391 if (weekdayStr) {
9392 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
9393 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
9394 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
9395
9396 if (weekdayProvided !== weekdayActual) {
9397 getParsingFlags(config).weekdayMismatch = true;
9398 config._isValid = false;
9399 return false;
9400 }
9401 }
9402
9403 return true;
9404 }
9405
9406 var obsOffsets = {
9407 UT: 0,
9408 GMT: 0,
9409 EDT: -4 * 60,
9410 EST: -5 * 60,
9411 CDT: -5 * 60,
9412 CST: -6 * 60,
9413 MDT: -6 * 60,
9414 MST: -7 * 60,
9415 PDT: -7 * 60,
9416 PST: -8 * 60
9417 };
9418
9419 function calculateOffset(obsOffset, militaryOffset, numOffset) {
9420 if (obsOffset) {
9421 return obsOffsets[obsOffset];
9422 } else if (militaryOffset) {
9423 // the only allowed military tz is Z
9424 return 0;
9425 } else {
9426 var hm = parseInt(numOffset, 10);
9427 var m = hm % 100,
9428 h = (hm - m) / 100;
9429 return h * 60 + m;
9430 }
9431 } // date and time from ref 2822 format
9432
9433
9434 function configFromRFC2822(config) {
9435 var match = rfc2822.exec(preprocessRFC2822(config._i));
9436
9437 if (match) {
9438 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
9439
9440 if (!checkWeekday(match[1], parsedArray, config)) {
9441 return;
9442 }
9443
9444 config._a = parsedArray;
9445 config._tzm = calculateOffset(match[8], match[9], match[10]);
9446 config._d = createUTCDate.apply(null, config._a);
9447
9448 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
9449
9450 getParsingFlags(config).rfc2822 = true;
9451 } else {
9452 config._isValid = false;
9453 }
9454 } // date from iso format or fallback
9455
9456
9457 function configFromString(config) {
9458 var matched = aspNetJsonRegex.exec(config._i);
9459
9460 if (matched !== null) {
9461 config._d = new Date(+matched[1]);
9462 return;
9463 }
9464
9465 configFromISO(config);
9466
9467 if (config._isValid === false) {
9468 delete config._isValid;
9469 } else {
9470 return;
9471 }
9472
9473 configFromRFC2822(config);
9474
9475 if (config._isValid === false) {
9476 delete config._isValid;
9477 } else {
9478 return;
9479 } // Final attempt, use Input Fallback
9480
9481
9482 hooks.createFromInputFallback(config);
9483 }
9484
9485 hooks.createFromInputFallback = deprecate('value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 'discouraged and will be removed in an upcoming major release. Please refer to ' + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', function (config) {
9486 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
9487 }); // constant that refers to the ISO standard
9488
9489 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
9490
9491
9492 hooks.RFC_2822 = function () {}; // date from string and format string
9493
9494
9495 function configFromStringAndFormat(config) {
9496 // TODO: Move this to another part of the creation flow to prevent circular deps
9497 if (config._f === hooks.ISO_8601) {
9498 configFromISO(config);
9499 return;
9500 }
9501
9502 if (config._f === hooks.RFC_2822) {
9503 configFromRFC2822(config);
9504 return;
9505 }
9506
9507 config._a = [];
9508 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
9509
9510 var string = '' + config._i,
9511 i,
9512 parsedInput,
9513 tokens,
9514 token,
9515 skipped,
9516 stringLength = string.length,
9517 totalParsedInputLength = 0;
9518 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
9519
9520 for (i = 0; i < tokens.length; i++) {
9521 token = tokens[i];
9522 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
9523 // 'regex', getParseRegexForToken(token, config));
9524
9525 if (parsedInput) {
9526 skipped = string.substr(0, string.indexOf(parsedInput));
9527
9528 if (skipped.length > 0) {
9529 getParsingFlags(config).unusedInput.push(skipped);
9530 }
9531
9532 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
9533 totalParsedInputLength += parsedInput.length;
9534 } // don't parse if it's not a known token
9535
9536
9537 if (formatTokenFunctions[token]) {
9538 if (parsedInput) {
9539 getParsingFlags(config).empty = false;
9540 } else {
9541 getParsingFlags(config).unusedTokens.push(token);
9542 }
9543
9544 addTimeToArrayFromToken(token, parsedInput, config);
9545 } else if (config._strict && !parsedInput) {
9546 getParsingFlags(config).unusedTokens.push(token);
9547 }
9548 } // add remaining unparsed input length to the string
9549
9550
9551 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
9552
9553 if (string.length > 0) {
9554 getParsingFlags(config).unusedInput.push(string);
9555 } // clear _12h flag if hour is <= 12
9556
9557
9558 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
9559 getParsingFlags(config).bigHour = undefined;
9560 }
9561
9562 getParsingFlags(config).parsedDateParts = config._a.slice(0);
9563 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
9564
9565 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
9566 configFromArray(config);
9567 checkOverflow(config);
9568 }
9569
9570 function meridiemFixWrap(locale, hour, meridiem) {
9571 var isPm;
9572
9573 if (meridiem == null) {
9574 // nothing to do
9575 return hour;
9576 }
9577
9578 if (locale.meridiemHour != null) {
9579 return locale.meridiemHour(hour, meridiem);
9580 } else if (locale.isPM != null) {
9581 // Fallback
9582 isPm = locale.isPM(meridiem);
9583
9584 if (isPm && hour < 12) {
9585 hour += 12;
9586 }
9587
9588 if (!isPm && hour === 12) {
9589 hour = 0;
9590 }
9591
9592 return hour;
9593 } else {
9594 // this is not supposed to happen
9595 return hour;
9596 }
9597 } // date from string and array of format strings
9598
9599
9600 function configFromStringAndArray(config) {
9601 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
9602
9603 if (config._f.length === 0) {
9604 getParsingFlags(config).invalidFormat = true;
9605 config._d = new Date(NaN);
9606 return;
9607 }
9608
9609 for (i = 0; i < config._f.length; i++) {
9610 currentScore = 0;
9611 tempConfig = copyConfig({}, config);
9612
9613 if (config._useUTC != null) {
9614 tempConfig._useUTC = config._useUTC;
9615 }
9616
9617 tempConfig._f = config._f[i];
9618 configFromStringAndFormat(tempConfig);
9619
9620 if (!isValid(tempConfig)) {
9621 continue;
9622 } // if there is any input that was not parsed add a penalty for that format
9623
9624
9625 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
9626
9627 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
9628 getParsingFlags(tempConfig).score = currentScore;
9629
9630 if (scoreToBeat == null || currentScore < scoreToBeat) {
9631 scoreToBeat = currentScore;
9632 bestMoment = tempConfig;
9633 }
9634 }
9635
9636 extend(config, bestMoment || tempConfig);
9637 }
9638
9639 function configFromObject(config) {
9640 if (config._d) {
9641 return;
9642 }
9643
9644 var i = normalizeObjectUnits(config._i);
9645 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
9646 return obj && parseInt(obj, 10);
9647 });
9648 configFromArray(config);
9649 }
9650
9651 function createFromConfig(config) {
9652 var res = new Moment(checkOverflow(prepareConfig(config)));
9653
9654 if (res._nextDay) {
9655 // Adding is smart enough around DST
9656 res.add(1, 'd');
9657 res._nextDay = undefined;
9658 }
9659
9660 return res;
9661 }
9662
9663 function prepareConfig(config) {
9664 var input = config._i,
9665 format = config._f;
9666 config._locale = config._locale || getLocale(config._l);
9667
9668 if (input === null || format === undefined && input === '') {
9669 return createInvalid({
9670 nullInput: true
9671 });
9672 }
9673
9674 if (typeof input === 'string') {
9675 config._i = input = config._locale.preparse(input);
9676 }
9677
9678 if (isMoment(input)) {
9679 return new Moment(checkOverflow(input));
9680 } else if (isDate(input)) {
9681 config._d = input;
9682 } else if (isArray(format)) {
9683 configFromStringAndArray(config);
9684 } else if (format) {
9685 configFromStringAndFormat(config);
9686 } else {
9687 configFromInput(config);
9688 }
9689
9690 if (!isValid(config)) {
9691 config._d = null;
9692 }
9693
9694 return config;
9695 }
9696
9697 function configFromInput(config) {
9698 var input = config._i;
9699
9700 if (isUndefined(input)) {
9701 config._d = new Date(hooks.now());
9702 } else if (isDate(input)) {
9703 config._d = new Date(input.valueOf());
9704 } else if (typeof input === 'string') {
9705 configFromString(config);
9706 } else if (isArray(input)) {
9707 config._a = map(input.slice(0), function (obj) {
9708 return parseInt(obj, 10);
9709 });
9710 configFromArray(config);
9711 } else if (isObject(input)) {
9712 configFromObject(config);
9713 } else if (isNumber(input)) {
9714 // from milliseconds
9715 config._d = new Date(input);
9716 } else {
9717 hooks.createFromInputFallback(config);
9718 }
9719 }
9720
9721 function createLocalOrUTC(input, format, locale, strict, isUTC) {
9722 var c = {};
9723
9724 if (locale === true || locale === false) {
9725 strict = locale;
9726 locale = undefined;
9727 }
9728
9729 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
9730 input = undefined;
9731 } // object construction must be done this way.
9732 // https://github.com/moment/moment/issues/1423
9733
9734
9735 c._isAMomentObject = true;
9736 c._useUTC = c._isUTC = isUTC;
9737 c._l = locale;
9738 c._i = input;
9739 c._f = format;
9740 c._strict = strict;
9741 return createFromConfig(c);
9742 }
9743
9744 function createLocal(input, format, locale, strict) {
9745 return createLocalOrUTC(input, format, locale, strict, false);
9746 }
9747
9748 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
9749 var other = createLocal.apply(null, arguments);
9750
9751 if (this.isValid() && other.isValid()) {
9752 return other < this ? this : other;
9753 } else {
9754 return createInvalid();
9755 }
9756 });
9757 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
9758 var other = createLocal.apply(null, arguments);
9759
9760 if (this.isValid() && other.isValid()) {
9761 return other > this ? this : other;
9762 } else {
9763 return createInvalid();
9764 }
9765 }); // Pick a moment m from moments so that m[fn](other) is true for all
9766 // other. This relies on the function fn to be transitive.
9767 //
9768 // moments should either be an array of moment objects or an array, whose
9769 // first element is an array of moment objects.
9770
9771 function pickBy(fn, moments) {
9772 var res, i;
9773
9774 if (moments.length === 1 && isArray(moments[0])) {
9775 moments = moments[0];
9776 }
9777
9778 if (!moments.length) {
9779 return createLocal();
9780 }
9781
9782 res = moments[0];
9783
9784 for (i = 1; i < moments.length; ++i) {
9785 if (!moments[i].isValid() || moments[i][fn](res)) {
9786 res = moments[i];
9787 }
9788 }
9789
9790 return res;
9791 } // TODO: Use [].sort instead?
9792
9793
9794 function min() {
9795 var args = [].slice.call(arguments, 0);
9796 return pickBy('isBefore', args);
9797 }
9798
9799 function max() {
9800 var args = [].slice.call(arguments, 0);
9801 return pickBy('isAfter', args);
9802 }
9803
9804 var now = function now() {
9805 return Date.now ? Date.now() : +new Date();
9806 };
9807
9808 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
9809
9810 function isDurationValid(m) {
9811 for (var key in m) {
9812 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
9813 return false;
9814 }
9815 }
9816
9817 var unitHasDecimal = false;
9818
9819 for (var i = 0; i < ordering.length; ++i) {
9820 if (m[ordering[i]]) {
9821 if (unitHasDecimal) {
9822 return false; // only allow non-integers for smallest unit
9823 }
9824
9825 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
9826 unitHasDecimal = true;
9827 }
9828 }
9829 }
9830
9831 return true;
9832 }
9833
9834 function isValid$1() {
9835 return this._isValid;
9836 }
9837
9838 function createInvalid$1() {
9839 return createDuration(NaN);
9840 }
9841
9842 function Duration(duration) {
9843 var normalizedInput = normalizeObjectUnits(duration),
9844 years = normalizedInput.year || 0,
9845 quarters = normalizedInput.quarter || 0,
9846 months = normalizedInput.month || 0,
9847 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
9848 days = normalizedInput.day || 0,
9849 hours = normalizedInput.hour || 0,
9850 minutes = normalizedInput.minute || 0,
9851 seconds = normalizedInput.second || 0,
9852 milliseconds = normalizedInput.millisecond || 0;
9853 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
9854
9855 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
9856 minutes * 6e4 + // 1000 * 60
9857 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
9858 // Because of dateAddRemove treats 24 hours as different from a
9859 // day when working around DST, we need to store them separately
9860
9861 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
9862 // which months you are are talking about, so we have to store
9863 // it separately.
9864
9865 this._months = +months + quarters * 3 + years * 12;
9866 this._data = {};
9867 this._locale = getLocale();
9868
9869 this._bubble();
9870 }
9871
9872 function isDuration(obj) {
9873 return obj instanceof Duration;
9874 }
9875
9876 function absRound(number) {
9877 if (number < 0) {
9878 return Math.round(-1 * number) * -1;
9879 } else {
9880 return Math.round(number);
9881 }
9882 } // FORMATTING
9883
9884
9885 function offset(token, separator) {
9886 addFormatToken(token, 0, 0, function () {
9887 var offset = this.utcOffset();
9888 var sign = '+';
9889
9890 if (offset < 0) {
9891 offset = -offset;
9892 sign = '-';
9893 }
9894
9895 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
9896 });
9897 }
9898
9899 offset('Z', ':');
9900 offset('ZZ', ''); // PARSING
9901
9902 addRegexToken('Z', matchShortOffset);
9903 addRegexToken('ZZ', matchShortOffset);
9904 addParseToken(['Z', 'ZZ'], function (input, array, config) {
9905 config._useUTC = true;
9906 config._tzm = offsetFromString(matchShortOffset, input);
9907 }); // HELPERS
9908 // timezone chunker
9909 // '+10:00' > ['10', '00']
9910 // '-1530' > ['-15', '30']
9911
9912 var chunkOffset = /([\+\-]|\d\d)/gi;
9913
9914 function offsetFromString(matcher, string) {
9915 var matches = (string || '').match(matcher);
9916
9917 if (matches === null) {
9918 return null;
9919 }
9920
9921 var chunk = matches[matches.length - 1] || [];
9922 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
9923 var minutes = +(parts[1] * 60) + toInt(parts[2]);
9924 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
9925 } // Return a moment from input, that is local/utc/zone equivalent to model.
9926
9927
9928 function cloneWithOffset(input, model) {
9929 var res, diff;
9930
9931 if (model._isUTC) {
9932 res = model.clone();
9933 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
9934
9935 res._d.setTime(res._d.valueOf() + diff);
9936
9937 hooks.updateOffset(res, false);
9938 return res;
9939 } else {
9940 return createLocal(input).local();
9941 }
9942 }
9943
9944 function getDateOffset(m) {
9945 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
9946 // https://github.com/moment/moment/pull/1871
9947 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
9948 } // HOOKS
9949 // This function will be called whenever a moment is mutated.
9950 // It is intended to keep the offset in sync with the timezone.
9951
9952
9953 hooks.updateOffset = function () {}; // MOMENTS
9954 // keepLocalTime = true means only change the timezone, without
9955 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
9956 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
9957 // +0200, so we adjust the time as needed, to be valid.
9958 //
9959 // Keeping the time actually adds/subtracts (one hour)
9960 // from the actual represented time. That is why we call updateOffset
9961 // a second time. In case it wants us to change the offset again
9962 // _changeInProgress == true case, then we have to adjust, because
9963 // there is no such time in the given timezone.
9964
9965
9966 function getSetOffset(input, keepLocalTime, keepMinutes) {
9967 var offset = this._offset || 0,
9968 localAdjust;
9969
9970 if (!this.isValid()) {
9971 return input != null ? this : NaN;
9972 }
9973
9974 if (input != null) {
9975 if (typeof input === 'string') {
9976 input = offsetFromString(matchShortOffset, input);
9977
9978 if (input === null) {
9979 return this;
9980 }
9981 } else if (Math.abs(input) < 16 && !keepMinutes) {
9982 input = input * 60;
9983 }
9984
9985 if (!this._isUTC && keepLocalTime) {
9986 localAdjust = getDateOffset(this);
9987 }
9988
9989 this._offset = input;
9990 this._isUTC = true;
9991
9992 if (localAdjust != null) {
9993 this.add(localAdjust, 'm');
9994 }
9995
9996 if (offset !== input) {
9997 if (!keepLocalTime || this._changeInProgress) {
9998 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
9999 } else if (!this._changeInProgress) {
10000 this._changeInProgress = true;
10001 hooks.updateOffset(this, true);
10002 this._changeInProgress = null;
10003 }
10004 }
10005
10006 return this;
10007 } else {
10008 return this._isUTC ? offset : getDateOffset(this);
10009 }
10010 }
10011
10012 function getSetZone(input, keepLocalTime) {
10013 if (input != null) {
10014 if (typeof input !== 'string') {
10015 input = -input;
10016 }
10017
10018 this.utcOffset(input, keepLocalTime);
10019 return this;
10020 } else {
10021 return -this.utcOffset();
10022 }
10023 }
10024
10025 function setOffsetToUTC(keepLocalTime) {
10026 return this.utcOffset(0, keepLocalTime);
10027 }
10028
10029 function setOffsetToLocal(keepLocalTime) {
10030 if (this._isUTC) {
10031 this.utcOffset(0, keepLocalTime);
10032 this._isUTC = false;
10033
10034 if (keepLocalTime) {
10035 this.subtract(getDateOffset(this), 'm');
10036 }
10037 }
10038
10039 return this;
10040 }
10041
10042 function setOffsetToParsedOffset() {
10043 if (this._tzm != null) {
10044 this.utcOffset(this._tzm, false, true);
10045 } else if (typeof this._i === 'string') {
10046 var tZone = offsetFromString(matchOffset, this._i);
10047
10048 if (tZone != null) {
10049 this.utcOffset(tZone);
10050 } else {
10051 this.utcOffset(0, true);
10052 }
10053 }
10054
10055 return this;
10056 }
10057
10058 function hasAlignedHourOffset(input) {
10059 if (!this.isValid()) {
10060 return false;
10061 }
10062
10063 input = input ? createLocal(input).utcOffset() : 0;
10064 return (this.utcOffset() - input) % 60 === 0;
10065 }
10066
10067 function isDaylightSavingTime() {
10068 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
10069 }
10070
10071 function isDaylightSavingTimeShifted() {
10072 if (!isUndefined(this._isDSTShifted)) {
10073 return this._isDSTShifted;
10074 }
10075
10076 var c = {};
10077 copyConfig(c, this);
10078 c = prepareConfig(c);
10079
10080 if (c._a) {
10081 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
10082 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
10083 } else {
10084 this._isDSTShifted = false;
10085 }
10086
10087 return this._isDSTShifted;
10088 }
10089
10090 function isLocal() {
10091 return this.isValid() ? !this._isUTC : false;
10092 }
10093
10094 function isUtcOffset() {
10095 return this.isValid() ? this._isUTC : false;
10096 }
10097
10098 function isUtc() {
10099 return this.isValid() ? this._isUTC && this._offset === 0 : false;
10100 } // ASP.NET json date format regex
10101
10102
10103 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
10104 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
10105 // and further modified to allow for strings containing both week and day
10106
10107 var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
10108
10109 function createDuration(input, key) {
10110 var duration = input,
10111 // matching against regexp is expensive, do it on demand
10112 match = null,
10113 sign,
10114 ret,
10115 diffRes;
10116
10117 if (isDuration(input)) {
10118 duration = {
10119 ms: input._milliseconds,
10120 d: input._days,
10121 M: input._months
10122 };
10123 } else if (isNumber(input)) {
10124 duration = {};
10125
10126 if (key) {
10127 duration[key] = input;
10128 } else {
10129 duration.milliseconds = input;
10130 }
10131 } else if (!!(match = aspNetRegex.exec(input))) {
10132 sign = match[1] === '-' ? -1 : 1;
10133 duration = {
10134 y: 0,
10135 d: toInt(match[DATE]) * sign,
10136 h: toInt(match[HOUR]) * sign,
10137 m: toInt(match[MINUTE]) * sign,
10138 s: toInt(match[SECOND]) * sign,
10139 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
10140
10141 };
10142 } else if (!!(match = isoRegex.exec(input))) {
10143 sign = match[1] === '-' ? -1 : 1;
10144 duration = {
10145 y: parseIso(match[2], sign),
10146 M: parseIso(match[3], sign),
10147 w: parseIso(match[4], sign),
10148 d: parseIso(match[5], sign),
10149 h: parseIso(match[6], sign),
10150 m: parseIso(match[7], sign),
10151 s: parseIso(match[8], sign)
10152 };
10153 } else if (duration == null) {
10154 // checks for null or undefined
10155 duration = {};
10156 } else if (_typeof(duration) === 'object' && ('from' in duration || 'to' in duration)) {
10157 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
10158 duration = {};
10159 duration.ms = diffRes.milliseconds;
10160 duration.M = diffRes.months;
10161 }
10162
10163 ret = new Duration(duration);
10164
10165 if (isDuration(input) && hasOwnProp(input, '_locale')) {
10166 ret._locale = input._locale;
10167 }
10168
10169 return ret;
10170 }
10171
10172 createDuration.fn = Duration.prototype;
10173 createDuration.invalid = createInvalid$1;
10174
10175 function parseIso(inp, sign) {
10176 // We'd normally use ~~inp for this, but unfortunately it also
10177 // converts floats to ints.
10178 // inp may be undefined, so careful calling replace on it.
10179 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
10180
10181 return (isNaN(res) ? 0 : res) * sign;
10182 }
10183
10184 function positiveMomentsDifference(base, other) {
10185 var res = {};
10186 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
10187
10188 if (base.clone().add(res.months, 'M').isAfter(other)) {
10189 --res.months;
10190 }
10191
10192 res.milliseconds = +other - +base.clone().add(res.months, 'M');
10193 return res;
10194 }
10195
10196 function momentsDifference(base, other) {
10197 var res;
10198
10199 if (!(base.isValid() && other.isValid())) {
10200 return {
10201 milliseconds: 0,
10202 months: 0
10203 };
10204 }
10205
10206 other = cloneWithOffset(other, base);
10207
10208 if (base.isBefore(other)) {
10209 res = positiveMomentsDifference(base, other);
10210 } else {
10211 res = positiveMomentsDifference(other, base);
10212 res.milliseconds = -res.milliseconds;
10213 res.months = -res.months;
10214 }
10215
10216 return res;
10217 } // TODO: remove 'name' arg after deprecation is removed
10218
10219
10220 function createAdder(direction, name) {
10221 return function (val, period) {
10222 var dur, tmp; //invert the arguments, but complain about it
10223
10224 if (period !== null && !isNaN(+period)) {
10225 deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
10226 tmp = val;
10227 val = period;
10228 period = tmp;
10229 }
10230
10231 val = typeof val === 'string' ? +val : val;
10232 dur = createDuration(val, period);
10233 addSubtract(this, dur, direction);
10234 return this;
10235 };
10236 }
10237
10238 function addSubtract(mom, duration, isAdding, updateOffset) {
10239 var milliseconds = duration._milliseconds,
10240 days = absRound(duration._days),
10241 months = absRound(duration._months);
10242
10243 if (!mom.isValid()) {
10244 // No op
10245 return;
10246 }
10247
10248 updateOffset = updateOffset == null ? true : updateOffset;
10249
10250 if (months) {
10251 setMonth(mom, get(mom, 'Month') + months * isAdding);
10252 }
10253
10254 if (days) {
10255 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
10256 }
10257
10258 if (milliseconds) {
10259 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
10260 }
10261
10262 if (updateOffset) {
10263 hooks.updateOffset(mom, days || months);
10264 }
10265 }
10266
10267 var add = createAdder(1, 'add');
10268 var subtract = createAdder(-1, 'subtract');
10269
10270 function getCalendarFormat(myMoment, now) {
10271 var diff = myMoment.diff(now, 'days', true);
10272 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
10273 }
10274
10275 function calendar$1(time, formats) {
10276 // We want to compare the start of today, vs this.
10277 // Getting start-of-today depends on whether we're local/utc/offset or not.
10278 var now = time || createLocal(),
10279 sod = cloneWithOffset(now, this).startOf('day'),
10280 format = hooks.calendarFormat(this, sod) || 'sameElse';
10281 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
10282 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
10283 }
10284
10285 function clone() {
10286 return new Moment(this);
10287 }
10288
10289 function isAfter(input, units) {
10290 var localInput = isMoment(input) ? input : createLocal(input);
10291
10292 if (!(this.isValid() && localInput.isValid())) {
10293 return false;
10294 }
10295
10296 units = normalizeUnits(units) || 'millisecond';
10297
10298 if (units === 'millisecond') {
10299 return this.valueOf() > localInput.valueOf();
10300 } else {
10301 return localInput.valueOf() < this.clone().startOf(units).valueOf();
10302 }
10303 }
10304
10305 function isBefore(input, units) {
10306 var localInput = isMoment(input) ? input : createLocal(input);
10307
10308 if (!(this.isValid() && localInput.isValid())) {
10309 return false;
10310 }
10311
10312 units = normalizeUnits(units) || 'millisecond';
10313
10314 if (units === 'millisecond') {
10315 return this.valueOf() < localInput.valueOf();
10316 } else {
10317 return this.clone().endOf(units).valueOf() < localInput.valueOf();
10318 }
10319 }
10320
10321 function isBetween(from, to, units, inclusivity) {
10322 var localFrom = isMoment(from) ? from : createLocal(from),
10323 localTo = isMoment(to) ? to : createLocal(to);
10324
10325 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
10326 return false;
10327 }
10328
10329 inclusivity = inclusivity || '()';
10330 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
10331 }
10332
10333 function isSame(input, units) {
10334 var localInput = isMoment(input) ? input : createLocal(input),
10335 inputMs;
10336
10337 if (!(this.isValid() && localInput.isValid())) {
10338 return false;
10339 }
10340
10341 units = normalizeUnits(units) || 'millisecond';
10342
10343 if (units === 'millisecond') {
10344 return this.valueOf() === localInput.valueOf();
10345 } else {
10346 inputMs = localInput.valueOf();
10347 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
10348 }
10349 }
10350
10351 function isSameOrAfter(input, units) {
10352 return this.isSame(input, units) || this.isAfter(input, units);
10353 }
10354
10355 function isSameOrBefore(input, units) {
10356 return this.isSame(input, units) || this.isBefore(input, units);
10357 }
10358
10359 function diff(input, units, asFloat) {
10360 var that, zoneDelta, output;
10361
10362 if (!this.isValid()) {
10363 return NaN;
10364 }
10365
10366 that = cloneWithOffset(input, this);
10367
10368 if (!that.isValid()) {
10369 return NaN;
10370 }
10371
10372 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
10373 units = normalizeUnits(units);
10374
10375 switch (units) {
10376 case 'year':
10377 output = monthDiff(this, that) / 12;
10378 break;
10379
10380 case 'month':
10381 output = monthDiff(this, that);
10382 break;
10383
10384 case 'quarter':
10385 output = monthDiff(this, that) / 3;
10386 break;
10387
10388 case 'second':
10389 output = (this - that) / 1e3;
10390 break;
10391 // 1000
10392
10393 case 'minute':
10394 output = (this - that) / 6e4;
10395 break;
10396 // 1000 * 60
10397
10398 case 'hour':
10399 output = (this - that) / 36e5;
10400 break;
10401 // 1000 * 60 * 60
10402
10403 case 'day':
10404 output = (this - that - zoneDelta) / 864e5;
10405 break;
10406 // 1000 * 60 * 60 * 24, negate dst
10407
10408 case 'week':
10409 output = (this - that - zoneDelta) / 6048e5;
10410 break;
10411 // 1000 * 60 * 60 * 24 * 7, negate dst
10412
10413 default:
10414 output = this - that;
10415 }
10416
10417 return asFloat ? output : absFloor(output);
10418 }
10419
10420 function monthDiff(a, b) {
10421 // difference in months
10422 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
10423 // b is in (anchor - 1 month, anchor + 1 month)
10424 anchor = a.clone().add(wholeMonthDiff, 'months'),
10425 anchor2,
10426 adjust;
10427
10428 if (b - anchor < 0) {
10429 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
10430
10431 adjust = (b - anchor) / (anchor - anchor2);
10432 } else {
10433 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
10434
10435 adjust = (b - anchor) / (anchor2 - anchor);
10436 } //check for negative zero, return zero if negative zero
10437
10438
10439 return -(wholeMonthDiff + adjust) || 0;
10440 }
10441
10442 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
10443 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
10444
10445 function toString() {
10446 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
10447 }
10448
10449 function toISOString(keepOffset) {
10450 if (!this.isValid()) {
10451 return null;
10452 }
10453
10454 var utc = keepOffset !== true;
10455 var m = utc ? this.clone().utc() : this;
10456
10457 if (m.year() < 0 || m.year() > 9999) {
10458 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
10459 }
10460
10461 if (isFunction(Date.prototype.toISOString)) {
10462 // native implementation is ~50x faster, use it when we can
10463 if (utc) {
10464 return this.toDate().toISOString();
10465 } else {
10466 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
10467 }
10468 }
10469
10470 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
10471 }
10472 /**
10473 * Return a human readable representation of a moment that can
10474 * also be evaluated to get a new moment which is the same
10475 *
10476 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
10477 */
10478
10479
10480 function inspect() {
10481 if (!this.isValid()) {
10482 return 'moment.invalid(/* ' + this._i + ' */)';
10483 }
10484
10485 var func = 'moment';
10486 var zone = '';
10487
10488 if (!this.isLocal()) {
10489 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
10490 zone = 'Z';
10491 }
10492
10493 var prefix = '[' + func + '("]';
10494 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
10495 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
10496 var suffix = zone + '[")]';
10497 return this.format(prefix + year + datetime + suffix);
10498 }
10499
10500 function format(inputString) {
10501 if (!inputString) {
10502 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
10503 }
10504
10505 var output = formatMoment(this, inputString);
10506 return this.localeData().postformat(output);
10507 }
10508
10509 function from(time, withoutSuffix) {
10510 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
10511 return createDuration({
10512 to: this,
10513 from: time
10514 }).locale(this.locale()).humanize(!withoutSuffix);
10515 } else {
10516 return this.localeData().invalidDate();
10517 }
10518 }
10519
10520 function fromNow(withoutSuffix) {
10521 return this.from(createLocal(), withoutSuffix);
10522 }
10523
10524 function to(time, withoutSuffix) {
10525 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
10526 return createDuration({
10527 from: this,
10528 to: time
10529 }).locale(this.locale()).humanize(!withoutSuffix);
10530 } else {
10531 return this.localeData().invalidDate();
10532 }
10533 }
10534
10535 function toNow(withoutSuffix) {
10536 return this.to(createLocal(), withoutSuffix);
10537 } // If passed a locale key, it will set the locale for this
10538 // instance. Otherwise, it will return the locale configuration
10539 // variables for this instance.
10540
10541
10542 function locale(key) {
10543 var newLocaleData;
10544
10545 if (key === undefined) {
10546 return this._locale._abbr;
10547 } else {
10548 newLocaleData = getLocale(key);
10549
10550 if (newLocaleData != null) {
10551 this._locale = newLocaleData;
10552 }
10553
10554 return this;
10555 }
10556 }
10557
10558 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
10559 if (key === undefined) {
10560 return this.localeData();
10561 } else {
10562 return this.locale(key);
10563 }
10564 });
10565
10566 function localeData() {
10567 return this._locale;
10568 }
10569
10570 var MS_PER_SECOND = 1000;
10571 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
10572 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
10573 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
10574
10575 function mod$1(dividend, divisor) {
10576 return (dividend % divisor + divisor) % divisor;
10577 }
10578
10579 function localStartOfDate(y, m, d) {
10580 // the date constructor remaps years 0-99 to 1900-1999
10581 if (y < 100 && y >= 0) {
10582 // preserve leap years using a full 400 year cycle, then reset
10583 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
10584 } else {
10585 return new Date(y, m, d).valueOf();
10586 }
10587 }
10588
10589 function utcStartOfDate(y, m, d) {
10590 // Date.UTC remaps years 0-99 to 1900-1999
10591 if (y < 100 && y >= 0) {
10592 // preserve leap years using a full 400 year cycle, then reset
10593 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
10594 } else {
10595 return Date.UTC(y, m, d);
10596 }
10597 }
10598
10599 function startOf(units) {
10600 var time;
10601 units = normalizeUnits(units);
10602
10603 if (units === undefined || units === 'millisecond' || !this.isValid()) {
10604 return this;
10605 }
10606
10607 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
10608
10609 switch (units) {
10610 case 'year':
10611 time = startOfDate(this.year(), 0, 1);
10612 break;
10613
10614 case 'quarter':
10615 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
10616 break;
10617
10618 case 'month':
10619 time = startOfDate(this.year(), this.month(), 1);
10620 break;
10621
10622 case 'week':
10623 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
10624 break;
10625
10626 case 'isoWeek':
10627 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
10628 break;
10629
10630 case 'day':
10631 case 'date':
10632 time = startOfDate(this.year(), this.month(), this.date());
10633 break;
10634
10635 case 'hour':
10636 time = this._d.valueOf();
10637 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
10638 break;
10639
10640 case 'minute':
10641 time = this._d.valueOf();
10642 time -= mod$1(time, MS_PER_MINUTE);
10643 break;
10644
10645 case 'second':
10646 time = this._d.valueOf();
10647 time -= mod$1(time, MS_PER_SECOND);
10648 break;
10649 }
10650
10651 this._d.setTime(time);
10652
10653 hooks.updateOffset(this, true);
10654 return this;
10655 }
10656
10657 function endOf(units) {
10658 var time;
10659 units = normalizeUnits(units);
10660
10661 if (units === undefined || units === 'millisecond' || !this.isValid()) {
10662 return this;
10663 }
10664
10665 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
10666
10667 switch (units) {
10668 case 'year':
10669 time = startOfDate(this.year() + 1, 0, 1) - 1;
10670 break;
10671
10672 case 'quarter':
10673 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
10674 break;
10675
10676 case 'month':
10677 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
10678 break;
10679
10680 case 'week':
10681 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
10682 break;
10683
10684 case 'isoWeek':
10685 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
10686 break;
10687
10688 case 'day':
10689 case 'date':
10690 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
10691 break;
10692
10693 case 'hour':
10694 time = this._d.valueOf();
10695 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
10696 break;
10697
10698 case 'minute':
10699 time = this._d.valueOf();
10700 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
10701 break;
10702
10703 case 'second':
10704 time = this._d.valueOf();
10705 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
10706 break;
10707 }
10708
10709 this._d.setTime(time);
10710
10711 hooks.updateOffset(this, true);
10712 return this;
10713 }
10714
10715 function valueOf() {
10716 return this._d.valueOf() - (this._offset || 0) * 60000;
10717 }
10718
10719 function unix() {
10720 return Math.floor(this.valueOf() / 1000);
10721 }
10722
10723 function toDate() {
10724 return new Date(this.valueOf());
10725 }
10726
10727 function toArray() {
10728 var m = this;
10729 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
10730 }
10731
10732 function toObject() {
10733 var m = this;
10734 return {
10735 years: m.year(),
10736 months: m.month(),
10737 date: m.date(),
10738 hours: m.hours(),
10739 minutes: m.minutes(),
10740 seconds: m.seconds(),
10741 milliseconds: m.milliseconds()
10742 };
10743 }
10744
10745 function toJSON() {
10746 // new Date(NaN).toJSON() === null
10747 return this.isValid() ? this.toISOString() : null;
10748 }
10749
10750 function isValid$2() {
10751 return isValid(this);
10752 }
10753
10754 function parsingFlags() {
10755 return extend({}, getParsingFlags(this));
10756 }
10757
10758 function invalidAt() {
10759 return getParsingFlags(this).overflow;
10760 }
10761
10762 function creationData() {
10763 return {
10764 input: this._i,
10765 format: this._f,
10766 locale: this._locale,
10767 isUTC: this._isUTC,
10768 strict: this._strict
10769 };
10770 } // FORMATTING
10771
10772
10773 addFormatToken(0, ['gg', 2], 0, function () {
10774 return this.weekYear() % 100;
10775 });
10776 addFormatToken(0, ['GG', 2], 0, function () {
10777 return this.isoWeekYear() % 100;
10778 });
10779
10780 function addWeekYearFormatToken(token, getter) {
10781 addFormatToken(0, [token, token.length], 0, getter);
10782 }
10783
10784 addWeekYearFormatToken('gggg', 'weekYear');
10785 addWeekYearFormatToken('ggggg', 'weekYear');
10786 addWeekYearFormatToken('GGGG', 'isoWeekYear');
10787 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
10788
10789 addUnitAlias('weekYear', 'gg');
10790 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
10791
10792 addUnitPriority('weekYear', 1);
10793 addUnitPriority('isoWeekYear', 1); // PARSING
10794
10795 addRegexToken('G', matchSigned);
10796 addRegexToken('g', matchSigned);
10797 addRegexToken('GG', match1to2, match2);
10798 addRegexToken('gg', match1to2, match2);
10799 addRegexToken('GGGG', match1to4, match4);
10800 addRegexToken('gggg', match1to4, match4);
10801 addRegexToken('GGGGG', match1to6, match6);
10802 addRegexToken('ggggg', match1to6, match6);
10803 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
10804 week[token.substr(0, 2)] = toInt(input);
10805 });
10806 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
10807 week[token] = hooks.parseTwoDigitYear(input);
10808 }); // MOMENTS
10809
10810 function getSetWeekYear(input) {
10811 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
10812 }
10813
10814 function getSetISOWeekYear(input) {
10815 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
10816 }
10817
10818 function getISOWeeksInYear() {
10819 return weeksInYear(this.year(), 1, 4);
10820 }
10821
10822 function getWeeksInYear() {
10823 var weekInfo = this.localeData()._week;
10824
10825 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
10826 }
10827
10828 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
10829 var weeksTarget;
10830
10831 if (input == null) {
10832 return weekOfYear(this, dow, doy).year;
10833 } else {
10834 weeksTarget = weeksInYear(input, dow, doy);
10835
10836 if (week > weeksTarget) {
10837 week = weeksTarget;
10838 }
10839
10840 return setWeekAll.call(this, input, week, weekday, dow, doy);
10841 }
10842 }
10843
10844 function setWeekAll(weekYear, week, weekday, dow, doy) {
10845 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
10846 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
10847 this.year(date.getUTCFullYear());
10848 this.month(date.getUTCMonth());
10849 this.date(date.getUTCDate());
10850 return this;
10851 } // FORMATTING
10852
10853
10854 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
10855
10856 addUnitAlias('quarter', 'Q'); // PRIORITY
10857
10858 addUnitPriority('quarter', 7); // PARSING
10859
10860 addRegexToken('Q', match1);
10861 addParseToken('Q', function (input, array) {
10862 array[MONTH] = (toInt(input) - 1) * 3;
10863 }); // MOMENTS
10864
10865 function getSetQuarter(input) {
10866 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
10867 } // FORMATTING
10868
10869
10870 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
10871
10872 addUnitAlias('date', 'D'); // PRIORITY
10873
10874 addUnitPriority('date', 9); // PARSING
10875
10876 addRegexToken('D', match1to2);
10877 addRegexToken('DD', match1to2, match2);
10878 addRegexToken('Do', function (isStrict, locale) {
10879 // TODO: Remove "ordinalParse" fallback in next major release.
10880 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
10881 });
10882 addParseToken(['D', 'DD'], DATE);
10883 addParseToken('Do', function (input, array) {
10884 array[DATE] = toInt(input.match(match1to2)[0]);
10885 }); // MOMENTS
10886
10887 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
10888
10889 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
10890
10891 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
10892
10893 addUnitPriority('dayOfYear', 4); // PARSING
10894
10895 addRegexToken('DDD', match1to3);
10896 addRegexToken('DDDD', match3);
10897 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
10898 config._dayOfYear = toInt(input);
10899 }); // HELPERS
10900 // MOMENTS
10901
10902 function getSetDayOfYear(input) {
10903 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
10904 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
10905 } // FORMATTING
10906
10907
10908 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
10909
10910 addUnitAlias('minute', 'm'); // PRIORITY
10911
10912 addUnitPriority('minute', 14); // PARSING
10913
10914 addRegexToken('m', match1to2);
10915 addRegexToken('mm', match1to2, match2);
10916 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
10917
10918 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
10919
10920 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
10921
10922 addUnitAlias('second', 's'); // PRIORITY
10923
10924 addUnitPriority('second', 15); // PARSING
10925
10926 addRegexToken('s', match1to2);
10927 addRegexToken('ss', match1to2, match2);
10928 addParseToken(['s', 'ss'], SECOND); // MOMENTS
10929
10930 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
10931
10932 addFormatToken('S', 0, 0, function () {
10933 return ~~(this.millisecond() / 100);
10934 });
10935 addFormatToken(0, ['SS', 2], 0, function () {
10936 return ~~(this.millisecond() / 10);
10937 });
10938 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
10939 addFormatToken(0, ['SSSS', 4], 0, function () {
10940 return this.millisecond() * 10;
10941 });
10942 addFormatToken(0, ['SSSSS', 5], 0, function () {
10943 return this.millisecond() * 100;
10944 });
10945 addFormatToken(0, ['SSSSSS', 6], 0, function () {
10946 return this.millisecond() * 1000;
10947 });
10948 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
10949 return this.millisecond() * 10000;
10950 });
10951 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
10952 return this.millisecond() * 100000;
10953 });
10954 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
10955 return this.millisecond() * 1000000;
10956 }); // ALIASES
10957
10958 addUnitAlias('millisecond', 'ms'); // PRIORITY
10959
10960 addUnitPriority('millisecond', 16); // PARSING
10961
10962 addRegexToken('S', match1to3, match1);
10963 addRegexToken('SS', match1to3, match2);
10964 addRegexToken('SSS', match1to3, match3);
10965 var token;
10966
10967 for (token = 'SSSS'; token.length <= 9; token += 'S') {
10968 addRegexToken(token, matchUnsigned);
10969 }
10970
10971 function parseMs(input, array) {
10972 array[MILLISECOND] = toInt(('0.' + input) * 1000);
10973 }
10974
10975 for (token = 'S'; token.length <= 9; token += 'S') {
10976 addParseToken(token, parseMs);
10977 } // MOMENTS
10978
10979
10980 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
10981
10982 addFormatToken('z', 0, 0, 'zoneAbbr');
10983 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
10984
10985 function getZoneAbbr() {
10986 return this._isUTC ? 'UTC' : '';
10987 }
10988
10989 function getZoneName() {
10990 return this._isUTC ? 'Coordinated Universal Time' : '';
10991 }
10992
10993 var proto = Moment.prototype;
10994 proto.add = add;
10995 proto.calendar = calendar$1;
10996 proto.clone = clone;
10997 proto.diff = diff;
10998 proto.endOf = endOf;
10999 proto.format = format;
11000 proto.from = from;
11001 proto.fromNow = fromNow;
11002 proto.to = to;
11003 proto.toNow = toNow;
11004 proto.get = stringGet;
11005 proto.invalidAt = invalidAt;
11006 proto.isAfter = isAfter;
11007 proto.isBefore = isBefore;
11008 proto.isBetween = isBetween;
11009 proto.isSame = isSame;
11010 proto.isSameOrAfter = isSameOrAfter;
11011 proto.isSameOrBefore = isSameOrBefore;
11012 proto.isValid = isValid$2;
11013 proto.lang = lang;
11014 proto.locale = locale;
11015 proto.localeData = localeData;
11016 proto.max = prototypeMax;
11017 proto.min = prototypeMin;
11018 proto.parsingFlags = parsingFlags;
11019 proto.set = stringSet;
11020 proto.startOf = startOf;
11021 proto.subtract = subtract;
11022 proto.toArray = toArray;
11023 proto.toObject = toObject;
11024 proto.toDate = toDate;
11025 proto.toISOString = toISOString;
11026 proto.inspect = inspect;
11027 proto.toJSON = toJSON;
11028 proto.toString = toString;
11029 proto.unix = unix;
11030 proto.valueOf = valueOf;
11031 proto.creationData = creationData;
11032 proto.year = getSetYear;
11033 proto.isLeapYear = getIsLeapYear;
11034 proto.weekYear = getSetWeekYear;
11035 proto.isoWeekYear = getSetISOWeekYear;
11036 proto.quarter = proto.quarters = getSetQuarter;
11037 proto.month = getSetMonth;
11038 proto.daysInMonth = getDaysInMonth;
11039 proto.week = proto.weeks = getSetWeek;
11040 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
11041 proto.weeksInYear = getWeeksInYear;
11042 proto.isoWeeksInYear = getISOWeeksInYear;
11043 proto.date = getSetDayOfMonth;
11044 proto.day = proto.days = getSetDayOfWeek;
11045 proto.weekday = getSetLocaleDayOfWeek;
11046 proto.isoWeekday = getSetISODayOfWeek;
11047 proto.dayOfYear = getSetDayOfYear;
11048 proto.hour = proto.hours = getSetHour;
11049 proto.minute = proto.minutes = getSetMinute;
11050 proto.second = proto.seconds = getSetSecond;
11051 proto.millisecond = proto.milliseconds = getSetMillisecond;
11052 proto.utcOffset = getSetOffset;
11053 proto.utc = setOffsetToUTC;
11054 proto.local = setOffsetToLocal;
11055 proto.parseZone = setOffsetToParsedOffset;
11056 proto.hasAlignedHourOffset = hasAlignedHourOffset;
11057 proto.isDST = isDaylightSavingTime;
11058 proto.isLocal = isLocal;
11059 proto.isUtcOffset = isUtcOffset;
11060 proto.isUtc = isUtc;
11061 proto.isUTC = isUtc;
11062 proto.zoneAbbr = getZoneAbbr;
11063 proto.zoneName = getZoneName;
11064 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
11065 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
11066 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
11067 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
11068 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
11069
11070 function createUnix(input) {
11071 return createLocal(input * 1000);
11072 }
11073
11074 function createInZone() {
11075 return createLocal.apply(null, arguments).parseZone();
11076 }
11077
11078 function preParsePostFormat(string) {
11079 return string;
11080 }
11081
11082 var proto$1 = Locale.prototype;
11083 proto$1.calendar = calendar;
11084 proto$1.longDateFormat = longDateFormat;
11085 proto$1.invalidDate = invalidDate;
11086 proto$1.ordinal = ordinal;
11087 proto$1.preparse = preParsePostFormat;
11088 proto$1.postformat = preParsePostFormat;
11089 proto$1.relativeTime = relativeTime;
11090 proto$1.pastFuture = pastFuture;
11091 proto$1.set = set;
11092 proto$1.months = localeMonths;
11093 proto$1.monthsShort = localeMonthsShort;
11094 proto$1.monthsParse = localeMonthsParse;
11095 proto$1.monthsRegex = monthsRegex;
11096 proto$1.monthsShortRegex = monthsShortRegex;
11097 proto$1.week = localeWeek;
11098 proto$1.firstDayOfYear = localeFirstDayOfYear;
11099 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
11100 proto$1.weekdays = localeWeekdays;
11101 proto$1.weekdaysMin = localeWeekdaysMin;
11102 proto$1.weekdaysShort = localeWeekdaysShort;
11103 proto$1.weekdaysParse = localeWeekdaysParse;
11104 proto$1.weekdaysRegex = weekdaysRegex;
11105 proto$1.weekdaysShortRegex = weekdaysShortRegex;
11106 proto$1.weekdaysMinRegex = weekdaysMinRegex;
11107 proto$1.isPM = localeIsPM;
11108 proto$1.meridiem = localeMeridiem;
11109
11110 function get$1(format, index, field, setter) {
11111 var locale = getLocale();
11112 var utc = createUTC().set(setter, index);
11113 return locale[field](utc, format);
11114 }
11115
11116 function listMonthsImpl(format, index, field) {
11117 if (isNumber(format)) {
11118 index = format;
11119 format = undefined;
11120 }
11121
11122 format = format || '';
11123
11124 if (index != null) {
11125 return get$1(format, index, field, 'month');
11126 }
11127
11128 var i;
11129 var out = [];
11130
11131 for (i = 0; i < 12; i++) {
11132 out[i] = get$1(format, i, field, 'month');
11133 }
11134
11135 return out;
11136 } // ()
11137 // (5)
11138 // (fmt, 5)
11139 // (fmt)
11140 // (true)
11141 // (true, 5)
11142 // (true, fmt, 5)
11143 // (true, fmt)
11144
11145
11146 function listWeekdaysImpl(localeSorted, format, index, field) {
11147 if (typeof localeSorted === 'boolean') {
11148 if (isNumber(format)) {
11149 index = format;
11150 format = undefined;
11151 }
11152
11153 format = format || '';
11154 } else {
11155 format = localeSorted;
11156 index = format;
11157 localeSorted = false;
11158
11159 if (isNumber(format)) {
11160 index = format;
11161 format = undefined;
11162 }
11163
11164 format = format || '';
11165 }
11166
11167 var locale = getLocale(),
11168 shift = localeSorted ? locale._week.dow : 0;
11169
11170 if (index != null) {
11171 return get$1(format, (index + shift) % 7, field, 'day');
11172 }
11173
11174 var i;
11175 var out = [];
11176
11177 for (i = 0; i < 7; i++) {
11178 out[i] = get$1(format, (i + shift) % 7, field, 'day');
11179 }
11180
11181 return out;
11182 }
11183
11184 function listMonths(format, index) {
11185 return listMonthsImpl(format, index, 'months');
11186 }
11187
11188 function listMonthsShort(format, index) {
11189 return listMonthsImpl(format, index, 'monthsShort');
11190 }
11191
11192 function listWeekdays(localeSorted, format, index) {
11193 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
11194 }
11195
11196 function listWeekdaysShort(localeSorted, format, index) {
11197 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
11198 }
11199
11200 function listWeekdaysMin(localeSorted, format, index) {
11201 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
11202 }
11203
11204 getSetGlobalLocale('en', {
11205 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
11206 ordinal: function ordinal(number) {
11207 var b = number % 10,
11208 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
11209 return number + output;
11210 }
11211 }); // Side effect imports
11212
11213 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
11214 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
11215 var mathAbs = Math.abs;
11216
11217 function abs() {
11218 var data = this._data;
11219 this._milliseconds = mathAbs(this._milliseconds);
11220 this._days = mathAbs(this._days);
11221 this._months = mathAbs(this._months);
11222 data.milliseconds = mathAbs(data.milliseconds);
11223 data.seconds = mathAbs(data.seconds);
11224 data.minutes = mathAbs(data.minutes);
11225 data.hours = mathAbs(data.hours);
11226 data.months = mathAbs(data.months);
11227 data.years = mathAbs(data.years);
11228 return this;
11229 }
11230
11231 function addSubtract$1(duration, input, value, direction) {
11232 var other = createDuration(input, value);
11233 duration._milliseconds += direction * other._milliseconds;
11234 duration._days += direction * other._days;
11235 duration._months += direction * other._months;
11236 return duration._bubble();
11237 } // supports only 2.0-style add(1, 's') or add(duration)
11238
11239
11240 function add$1(input, value) {
11241 return addSubtract$1(this, input, value, 1);
11242 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
11243
11244
11245 function subtract$1(input, value) {
11246 return addSubtract$1(this, input, value, -1);
11247 }
11248
11249 function absCeil(number) {
11250 if (number < 0) {
11251 return Math.floor(number);
11252 } else {
11253 return Math.ceil(number);
11254 }
11255 }
11256
11257 function bubble() {
11258 var milliseconds = this._milliseconds;
11259 var days = this._days;
11260 var months = this._months;
11261 var data = this._data;
11262 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
11263 // check: https://github.com/moment/moment/issues/2166
11264
11265 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
11266 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
11267 days = 0;
11268 months = 0;
11269 } // The following code bubbles up values, see the tests for
11270 // examples of what that means.
11271
11272
11273 data.milliseconds = milliseconds % 1000;
11274 seconds = absFloor(milliseconds / 1000);
11275 data.seconds = seconds % 60;
11276 minutes = absFloor(seconds / 60);
11277 data.minutes = minutes % 60;
11278 hours = absFloor(minutes / 60);
11279 data.hours = hours % 24;
11280 days += absFloor(hours / 24); // convert days to months
11281
11282 monthsFromDays = absFloor(daysToMonths(days));
11283 months += monthsFromDays;
11284 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
11285
11286 years = absFloor(months / 12);
11287 months %= 12;
11288 data.days = days;
11289 data.months = months;
11290 data.years = years;
11291 return this;
11292 }
11293
11294 function daysToMonths(days) {
11295 // 400 years have 146097 days (taking into account leap year rules)
11296 // 400 years have 12 months === 4800
11297 return days * 4800 / 146097;
11298 }
11299
11300 function monthsToDays(months) {
11301 // the reverse of daysToMonths
11302 return months * 146097 / 4800;
11303 }
11304
11305 function as(units) {
11306 if (!this.isValid()) {
11307 return NaN;
11308 }
11309
11310 var days;
11311 var months;
11312 var milliseconds = this._milliseconds;
11313 units = normalizeUnits(units);
11314
11315 if (units === 'month' || units === 'quarter' || units === 'year') {
11316 days = this._days + milliseconds / 864e5;
11317 months = this._months + daysToMonths(days);
11318
11319 switch (units) {
11320 case 'month':
11321 return months;
11322
11323 case 'quarter':
11324 return months / 3;
11325
11326 case 'year':
11327 return months / 12;
11328 }
11329 } else {
11330 // handle milliseconds separately because of floating point math errors (issue #1867)
11331 days = this._days + Math.round(monthsToDays(this._months));
11332
11333 switch (units) {
11334 case 'week':
11335 return days / 7 + milliseconds / 6048e5;
11336
11337 case 'day':
11338 return days + milliseconds / 864e5;
11339
11340 case 'hour':
11341 return days * 24 + milliseconds / 36e5;
11342
11343 case 'minute':
11344 return days * 1440 + milliseconds / 6e4;
11345
11346 case 'second':
11347 return days * 86400 + milliseconds / 1000;
11348 // Math.floor prevents floating point math errors here
11349
11350 case 'millisecond':
11351 return Math.floor(days * 864e5) + milliseconds;
11352
11353 default:
11354 throw new Error('Unknown unit ' + units);
11355 }
11356 }
11357 } // TODO: Use this.as('ms')?
11358
11359
11360 function valueOf$1() {
11361 if (!this.isValid()) {
11362 return NaN;
11363 }
11364
11365 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
11366 }
11367
11368 function makeAs(alias) {
11369 return function () {
11370 return this.as(alias);
11371 };
11372 }
11373
11374 var asMilliseconds = makeAs('ms');
11375 var asSeconds = makeAs('s');
11376 var asMinutes = makeAs('m');
11377 var asHours = makeAs('h');
11378 var asDays = makeAs('d');
11379 var asWeeks = makeAs('w');
11380 var asMonths = makeAs('M');
11381 var asQuarters = makeAs('Q');
11382 var asYears = makeAs('y');
11383
11384 function clone$1() {
11385 return createDuration(this);
11386 }
11387
11388 function get$2(units) {
11389 units = normalizeUnits(units);
11390 return this.isValid() ? this[units + 's']() : NaN;
11391 }
11392
11393 function makeGetter(name) {
11394 return function () {
11395 return this.isValid() ? this._data[name] : NaN;
11396 };
11397 }
11398
11399 var milliseconds = makeGetter('milliseconds');
11400 var seconds = makeGetter('seconds');
11401 var minutes = makeGetter('minutes');
11402 var hours = makeGetter('hours');
11403 var days = makeGetter('days');
11404 var months = makeGetter('months');
11405 var years = makeGetter('years');
11406
11407 function weeks() {
11408 return absFloor(this.days() / 7);
11409 }
11410
11411 var round = Math.round;
11412 var thresholds = {
11413 ss: 44,
11414 // a few seconds to seconds
11415 s: 45,
11416 // seconds to minute
11417 m: 45,
11418 // minutes to hour
11419 h: 22,
11420 // hours to day
11421 d: 26,
11422 // days to month
11423 M: 11 // months to year
11424
11425 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
11426
11427 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
11428 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
11429 }
11430
11431 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
11432 var duration = createDuration(posNegDuration).abs();
11433 var seconds = round(duration.as('s'));
11434 var minutes = round(duration.as('m'));
11435 var hours = round(duration.as('h'));
11436 var days = round(duration.as('d'));
11437 var months = round(duration.as('M'));
11438 var years = round(duration.as('y'));
11439 var a = seconds <= thresholds.ss && ['s', seconds] || seconds < thresholds.s && ['ss', seconds] || minutes <= 1 && ['m'] || minutes < thresholds.m && ['mm', minutes] || hours <= 1 && ['h'] || hours < thresholds.h && ['hh', hours] || days <= 1 && ['d'] || days < thresholds.d && ['dd', days] || months <= 1 && ['M'] || months < thresholds.M && ['MM', months] || years <= 1 && ['y'] || ['yy', years];
11440 a[2] = withoutSuffix;
11441 a[3] = +posNegDuration > 0;
11442 a[4] = locale;
11443 return substituteTimeAgo.apply(null, a);
11444 } // This function allows you to set the rounding function for relative time strings
11445
11446
11447 function getSetRelativeTimeRounding(roundingFunction) {
11448 if (roundingFunction === undefined) {
11449 return round;
11450 }
11451
11452 if (typeof roundingFunction === 'function') {
11453 round = roundingFunction;
11454 return true;
11455 }
11456
11457 return false;
11458 } // This function allows you to set a threshold for relative time strings
11459
11460
11461 function getSetRelativeTimeThreshold(threshold, limit) {
11462 if (thresholds[threshold] === undefined) {
11463 return false;
11464 }
11465
11466 if (limit === undefined) {
11467 return thresholds[threshold];
11468 }
11469
11470 thresholds[threshold] = limit;
11471
11472 if (threshold === 's') {
11473 thresholds.ss = limit - 1;
11474 }
11475
11476 return true;
11477 }
11478
11479 function humanize(withSuffix) {
11480 if (!this.isValid()) {
11481 return this.localeData().invalidDate();
11482 }
11483
11484 var locale = this.localeData();
11485 var output = relativeTime$1(this, !withSuffix, locale);
11486
11487 if (withSuffix) {
11488 output = locale.pastFuture(+this, output);
11489 }
11490
11491 return locale.postformat(output);
11492 }
11493
11494 var abs$1 = Math.abs;
11495
11496 function sign(x) {
11497 return (x > 0) - (x < 0) || +x;
11498 }
11499
11500 function toISOString$1() {
11501 // for ISO strings we do not use the normal bubbling rules:
11502 // * milliseconds bubble up until they become hours
11503 // * days do not bubble at all
11504 // * months bubble up until they become years
11505 // This is because there is no context-free conversion between hours and days
11506 // (think of clock changes)
11507 // and also not between days and months (28-31 days per month)
11508 if (!this.isValid()) {
11509 return this.localeData().invalidDate();
11510 }
11511
11512 var seconds = abs$1(this._milliseconds) / 1000;
11513 var days = abs$1(this._days);
11514 var months = abs$1(this._months);
11515 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
11516
11517 minutes = absFloor(seconds / 60);
11518 hours = absFloor(minutes / 60);
11519 seconds %= 60;
11520 minutes %= 60; // 12 months -> 1 year
11521
11522 years = absFloor(months / 12);
11523 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
11524
11525 var Y = years;
11526 var M = months;
11527 var D = days;
11528 var h = hours;
11529 var m = minutes;
11530 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
11531 var total = this.asSeconds();
11532
11533 if (!total) {
11534 // this is the same as C#'s (Noda) and python (isodate)...
11535 // but not other JS (goog.date)
11536 return 'P0D';
11537 }
11538
11539 var totalSign = total < 0 ? '-' : '';
11540 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
11541 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
11542 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
11543 return totalSign + 'P' + (Y ? ymSign + Y + 'Y' : '') + (M ? ymSign + M + 'M' : '') + (D ? daysSign + D + 'D' : '') + (h || m || s ? 'T' : '') + (h ? hmsSign + h + 'H' : '') + (m ? hmsSign + m + 'M' : '') + (s ? hmsSign + s + 'S' : '');
11544 }
11545
11546 var proto$2 = Duration.prototype;
11547 proto$2.isValid = isValid$1;
11548 proto$2.abs = abs;
11549 proto$2.add = add$1;
11550 proto$2.subtract = subtract$1;
11551 proto$2.as = as;
11552 proto$2.asMilliseconds = asMilliseconds;
11553 proto$2.asSeconds = asSeconds;
11554 proto$2.asMinutes = asMinutes;
11555 proto$2.asHours = asHours;
11556 proto$2.asDays = asDays;
11557 proto$2.asWeeks = asWeeks;
11558 proto$2.asMonths = asMonths;
11559 proto$2.asQuarters = asQuarters;
11560 proto$2.asYears = asYears;
11561 proto$2.valueOf = valueOf$1;
11562 proto$2._bubble = bubble;
11563 proto$2.clone = clone$1;
11564 proto$2.get = get$2;
11565 proto$2.milliseconds = milliseconds;
11566 proto$2.seconds = seconds;
11567 proto$2.minutes = minutes;
11568 proto$2.hours = hours;
11569 proto$2.days = days;
11570 proto$2.weeks = weeks;
11571 proto$2.months = months;
11572 proto$2.years = years;
11573 proto$2.humanize = humanize;
11574 proto$2.toISOString = toISOString$1;
11575 proto$2.toString = toISOString$1;
11576 proto$2.toJSON = toISOString$1;
11577 proto$2.locale = locale;
11578 proto$2.localeData = localeData;
11579 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
11580 proto$2.lang = lang; // Side effect imports
11581 // FORMATTING
11582
11583 addFormatToken('X', 0, 0, 'unix');
11584 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
11585
11586 addRegexToken('x', matchSigned);
11587 addRegexToken('X', matchTimestamp);
11588 addParseToken('X', function (input, array, config) {
11589 config._d = new Date(parseFloat(input, 10) * 1000);
11590 });
11591 addParseToken('x', function (input, array, config) {
11592 config._d = new Date(toInt(input));
11593 }); // Side effect imports
11594
11595 hooks.version = '2.24.0';
11596 setHookCallback(createLocal);
11597 hooks.fn = proto;
11598 hooks.min = min;
11599 hooks.max = max;
11600 hooks.now = now;
11601 hooks.utc = createUTC;
11602 hooks.unix = createUnix;
11603 hooks.months = listMonths;
11604 hooks.isDate = isDate;
11605 hooks.locale = getSetGlobalLocale;
11606 hooks.invalid = createInvalid;
11607 hooks.duration = createDuration;
11608 hooks.isMoment = isMoment;
11609 hooks.weekdays = listWeekdays;
11610 hooks.parseZone = createInZone;
11611 hooks.localeData = getLocale;
11612 hooks.isDuration = isDuration;
11613 hooks.monthsShort = listMonthsShort;
11614 hooks.weekdaysMin = listWeekdaysMin;
11615 hooks.defineLocale = defineLocale;
11616 hooks.updateLocale = updateLocale;
11617 hooks.locales = listLocales;
11618 hooks.weekdaysShort = listWeekdaysShort;
11619 hooks.normalizeUnits = normalizeUnits;
11620 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
11621 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
11622 hooks.calendarFormat = getCalendarFormat;
11623 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
11624
11625 hooks.HTML5_FMT = {
11626 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
11627 // <input type="datetime-local" />
11628 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
11629 // <input type="datetime-local" step="1" />
11630 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
11631 // <input type="datetime-local" step="0.001" />
11632 DATE: 'YYYY-MM-DD',
11633 // <input type="date" />
11634 TIME: 'HH:mm',
11635 // <input type="time" />
11636 TIME_SECONDS: 'HH:mm:ss',
11637 // <input type="time" step="1" />
11638 TIME_MS: 'HH:mm:ss.SSS',
11639 // <input type="time" step="0.001" />
11640 WEEK: 'GGGG-[W]WW',
11641 // <input type="week" />
11642 MONTH: 'YYYY-MM' // <input type="month" />
11643
11644 };
11645 return hooks;
11646 });
11647 }); // Maps for number <-> hex string conversion
11648
11649 var byteToHex = [];
11650
11651 for (var i$1 = 0; i$1 < 256; i$1++) {
11652 byteToHex[i$1] = (i$1 + 0x100).toString(16).substr(1);
11653 }
11654 /**
11655 * Represent binary UUID into it's string representation.
11656 *
11657 * @param buf - Buffer containing UUID bytes.
11658 * @param offset - Offset from the start of the buffer where the UUID is saved (not needed if the buffer starts with the UUID).
11659 *
11660 * @returns String representation of the UUID.
11661 */
11662
11663
11664 function stringifyUUID(buf, offset) {
11665 var i = offset || 0;
11666 var bth = byteToHex;
11667 return bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]];
11668 }
11669 /**
11670 * Generate 16 random bytes to be used as a base for UUID.
11671 *
11672 * @ignore
11673 */
11674
11675
11676 var random = function () {
11677 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
11678 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
11679 // Moderately fast, high quality
11680 var _rnds8 = new Uint8Array(16);
11681
11682 return function whatwgRNG() {
11683 crypto.getRandomValues(_rnds8);
11684 return _rnds8;
11685 };
11686 } // Math.random()-based (RNG)
11687 //
11688 // If all else fails, use Math.random().
11689 // It's fast, but is of unspecified quality.
11690
11691
11692 var _rnds = new Array(16);
11693
11694 return function () {
11695 for (var i = 0, r; i < 16; i++) {
11696 if ((i & 0x03) === 0) {
11697 r = Math.random() * 0x100000000;
11698 }
11699
11700 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
11701 }
11702
11703 return _rnds;
11704 }; // uuid.js
11705 //
11706 // Copyright (c) 2010-2012 Robert Kieffer
11707 // MIT License - http://opensource.org/licenses/mit-license.php
11708 // Unique ID creation requires a high quality random # generator. We feature
11709 // detect to determine the best RNG source, normalizing to a function that
11710 // returns 128-bits of randomness, since that's what's usually required
11711 // return require('./rng');
11712 }();
11713
11714 var byteToHex$1 = [];
11715
11716 for (var i$1$1 = 0; i$1$1 < 256; i$1$1++) {
11717 byteToHex$1[i$1$1] = (i$1$1 + 0x100).toString(16).substr(1);
11718 } // **`v1()` - Generate time-based UUID**
11719 //
11720 // Inspired by https://github.com/LiosK/UUID.js
11721 // and http://docs.python.org/library/uuid.html
11722 // random #'s we need to init node and clockseq
11723
11724
11725 var seedBytes = random(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
11726
11727 var defaultNodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; // Per 4.2.2, randomize (14 bit) clockseq
11728
11729 var defaultClockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; // Previous uuid creation time
11730
11731 /**
11732 * UUIDv4 options.
11733 */
11734
11735 /**
11736 * Generate UUIDv4
11737 *
11738 * @param options - Options to be used instead of default generated values.
11739 * String 'binary' is a shorthand for uuid4({}, new Array(16)).
11740 * @param buf - If present the buffer will be filled with the generated UUID.
11741 * @param offset - Offset of the UUID from the start of the buffer.
11742 *
11743 * @returns UUIDv4
11744 */
11745
11746 function uuid4() {
11747 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11748 var buf = arguments.length > 1 ? arguments[1] : undefined;
11749 var offset = arguments.length > 2 ? arguments[2] : undefined; // Deprecated - 'format' argument, as supported in v1.2
11750
11751 var i = buf && offset || 0;
11752
11753 if (typeof options === 'string') {
11754 buf = options === 'binary' ? new Array(16) : undefined;
11755 options = {};
11756 }
11757
11758 var rnds = options.random || (options.rng || random)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
11759
11760 rnds[6] = rnds[6] & 0x0f | 0x40;
11761 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
11762
11763 if (buf) {
11764 for (var ii = 0; ii < 16; ii++) {
11765 buf[i + ii] = rnds[ii];
11766 }
11767 }
11768
11769 return buf || stringifyUUID(rnds);
11770 } // Rollup will complain about mixing default and named exports in UMD build,
11771 // for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
11772 // code from http://momentjs.com/
11773
11774
11775 var ASPDateRegex = /^\/?Date\((-?\d+)/i; // Color REs
11776
11777 var fullHexRE = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
11778 var shortHexRE = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
11779 var 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;
11780 var 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;
11781 /**
11782 * Hue, Saturation, Value.
11783 */
11784
11785 /**
11786 * Test whether given object is a number
11787 *
11788 * @param value - Input value of unknown type.
11789 *
11790 * @returns True if number, false otherwise.
11791 */
11792
11793 function isNumber(value) {
11794 return value instanceof Number || typeof value === "number";
11795 }
11796 /**
11797 * Remove everything in the DOM object
11798 *
11799 * @param DOMobject - Node whose child nodes will be recursively deleted.
11800 */
11801
11802
11803 function recursiveDOMDelete(DOMobject) {
11804 if (DOMobject) {
11805 while (DOMobject.hasChildNodes() === true) {
11806 var child = DOMobject.firstChild;
11807
11808 if (child) {
11809 recursiveDOMDelete(child);
11810 DOMobject.removeChild(child);
11811 }
11812 }
11813 }
11814 }
11815 /**
11816 * Test whether given object is a string
11817 *
11818 * @param value - Input value of unknown type.
11819 *
11820 * @returns True if string, false otherwise.
11821 */
11822
11823
11824 function isString(value) {
11825 return value instanceof String || typeof value === "string";
11826 }
11827 /**
11828 * Test whether given object is a object (not primitive or null).
11829 *
11830 * @param value - Input value of unknown type.
11831 *
11832 * @returns True if not null object, false otherwise.
11833 */
11834
11835
11836 function isObject$1(value) {
11837 return _typeof$1(value) === "object" && value !== null;
11838 }
11839 /**
11840 * Test whether given object is a Date, or a String containing a Date
11841 *
11842 * @param value - Input value of unknown type.
11843 *
11844 * @returns True if Date instance or string date representation, false otherwise.
11845 */
11846
11847
11848 function isDate(value) {
11849 if (value instanceof Date) {
11850 return true;
11851 } else if (isString(value)) {
11852 // test whether this string contains a date
11853 var match = ASPDateRegex.exec(value);
11854
11855 if (match) {
11856 return true;
11857 } else if (!isNaN(Date.parse(value))) {
11858 return true;
11859 }
11860 }
11861
11862 return false;
11863 }
11864 /**
11865 * Test whether given object is a Moment date.
11866 * @TODO: This is basically a workaround, if Moment was imported property it wouldn't necessary as moment.isMoment is a TS type guard.
11867 *
11868 * @param value - Input value of unknown type.
11869 *
11870 * @returns True if Moment instance, false otherwise.
11871 */
11872
11873
11874 function isMoment(value) {
11875 return moment.isMoment(value);
11876 }
11877 /**
11878 * Copy property from b to a if property present in a.
11879 * If property in b explicitly set to null, delete it if `allowDeletion` set.
11880 *
11881 * Internal helper routine, should not be exported. Not added to `exports` for that reason.
11882 *
11883 * @param a - Target object.
11884 * @param b - Source object.
11885 * @param prop - Name of property to copy from b to a.
11886 * @param allowDeletion if true, delete property in a if explicitly set to null in b
11887 */
11888
11889
11890 function copyOrDelete(a, b, prop, allowDeletion) {
11891 var doDeletion = false;
11892
11893 if (allowDeletion === true) {
11894 doDeletion = b[prop] === null && a[prop] !== undefined;
11895 }
11896
11897 if (doDeletion) {
11898 delete a[prop];
11899 } else {
11900 a[prop] = b[prop]; // Remember, this is a reference copy!
11901 }
11902 }
11903 /**
11904 * Fill an object with a possibly partially defined other object.
11905 *
11906 * Only copies values for the properties already present in a.
11907 * That means an object is not created on a property if only the b object has it.
11908 *
11909 * @param a - The object that will have it's properties updated.
11910 * @param b - The object with property updates.
11911 * @param allowDeletion - if true, delete properties in a that are explicitly set to null in b
11912 */
11913
11914
11915 function fillIfDefined(a, b) {
11916 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; // NOTE: iteration of properties of a
11917 // NOTE: prototype properties iterated over as well
11918
11919 for (var prop in a) {
11920 if (b[prop] !== undefined) {
11921 if (b[prop] === null || _typeof$1(b[prop]) !== "object") {
11922 // Note: typeof null === 'object'
11923 copyOrDelete(a, b, prop, allowDeletion);
11924 } else {
11925 var aProp = a[prop];
11926 var bProp = b[prop];
11927
11928 if (isObject$1(aProp) && isObject$1(bProp)) {
11929 fillIfDefined(aProp, bProp, allowDeletion);
11930 }
11931 }
11932 }
11933 }
11934 }
11935 /**
11936 * Copy the values of all of the enumerable own properties from one or more source objects to a
11937 * target object. Returns the target object.
11938 *
11939 * @param target - The target object to copy to.
11940 * @param source - The source object from which to copy properties.
11941 *
11942 * @return The target object.
11943 */
11944
11945
11946 var extend = Object.assign;
11947 /**
11948 * Extend object a with selected properties of object b or a series of objects
11949 * Only properties with defined values are copied
11950 *
11951 * @param props - Properties to be copied to a.
11952 * @param a - The target.
11953 * @param others - The sources.
11954 *
11955 * @returns Argument a.
11956 */
11957
11958 function selectiveExtend(props, a) {
11959 if (!Array.isArray(props)) {
11960 throw new Error("Array with property names expected as first argument");
11961 }
11962
11963 for (var _len = arguments.length, others = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
11964 others[_key - 2] = arguments[_key];
11965 }
11966
11967 for (var _i = 0, _others = others; _i < _others.length; _i++) {
11968 var other = _others[_i];
11969
11970 for (var p = 0; p < props.length; p++) {
11971 var prop = props[p];
11972
11973 if (other && Object.prototype.hasOwnProperty.call(other, prop)) {
11974 a[prop] = other[prop];
11975 }
11976 }
11977 }
11978
11979 return a;
11980 }
11981 /**
11982 * Extend object a with selected properties of object b.
11983 * Only properties with defined values are copied.
11984 *
11985 * **Note:** Previous version of this routine implied that multiple source objects
11986 * could be used; however, the implementation was **wrong**.
11987 * Since multiple (>1) sources weren't used anywhere in the `vis.js` code,
11988 * this has been removed
11989 *
11990 * @param props - Names of first-level properties to copy over.
11991 * @param a - Target object.
11992 * @param b - Source object.
11993 * @param allowDeletion - If true, delete property in a if explicitly set to null in b.
11994 *
11995 * @returns Argument a.
11996 */
11997
11998
11999 function selectiveDeepExtend(props, a, b) {
12000 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TODO: add support for Arrays to deepExtend
12001
12002 if (Array.isArray(b)) {
12003 throw new TypeError("Arrays are not supported by deepExtend");
12004 }
12005
12006 for (var p = 0; p < props.length; p++) {
12007 var prop = props[p];
12008
12009 if (Object.prototype.hasOwnProperty.call(b, prop)) {
12010 if (b[prop] && b[prop].constructor === Object) {
12011 if (a[prop] === undefined) {
12012 a[prop] = {};
12013 }
12014
12015 if (a[prop].constructor === Object) {
12016 deepExtend(a[prop], b[prop], false, allowDeletion);
12017 } else {
12018 copyOrDelete(a, b, prop, allowDeletion);
12019 }
12020 } else if (Array.isArray(b[prop])) {
12021 throw new TypeError("Arrays are not supported by deepExtend");
12022 } else {
12023 copyOrDelete(a, b, prop, allowDeletion);
12024 }
12025 }
12026 }
12027
12028 return a;
12029 }
12030 /**
12031 * Extend object `a` with properties of object `b`, ignoring properties which are explicitly
12032 * specified to be excluded.
12033 *
12034 * The properties of `b` are considered for copying.
12035 * Properties which are themselves objects are are also extended.
12036 * Only properties with defined values are copied
12037 *
12038 * @param propsToExclude - Names of properties which should *not* be copied.
12039 * @param a - Object to extend.
12040 * @param b - Object to take properties from for extension.
12041 * @param allowDeletion - If true, delete properties in a that are explicitly set to null in b.
12042 *
12043 * @returns Argument a.
12044 */
12045
12046
12047 function selectiveNotDeepExtend(propsToExclude, a, b) {
12048 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TODO: add support for Arrays to deepExtend
12049 // NOTE: array properties have an else-below; apparently, there is a problem here.
12050
12051 if (Array.isArray(b)) {
12052 throw new TypeError("Arrays are not supported by deepExtend");
12053 }
12054
12055 for (var prop in b) {
12056 if (!Object.prototype.hasOwnProperty.call(b, prop)) {
12057 continue;
12058 } // Handle local properties only
12059
12060
12061 if (propsToExclude.indexOf(prop) !== -1) {
12062 continue;
12063 } // In exclusion list, skip
12064
12065
12066 if (b[prop] && b[prop].constructor === Object) {
12067 if (a[prop] === undefined) {
12068 a[prop] = {};
12069 }
12070
12071 if (a[prop].constructor === Object) {
12072 deepExtend(a[prop], b[prop]); // NOTE: allowDeletion not propagated!
12073 } else {
12074 copyOrDelete(a, b, prop, allowDeletion);
12075 }
12076 } else if (Array.isArray(b[prop])) {
12077 a[prop] = [];
12078
12079 for (var i = 0; i < b[prop].length; i++) {
12080 a[prop].push(b[prop][i]);
12081 }
12082 } else {
12083 copyOrDelete(a, b, prop, allowDeletion);
12084 }
12085 }
12086
12087 return a;
12088 }
12089 /**
12090 * Deep extend an object a with the properties of object b
12091 *
12092 * @param a - Target object.
12093 * @param b - Source object.
12094 * @param protoExtend - If true, the prototype values will also be extended
12095 * (ie. the options objects that inherit from others will also get the inherited options).
12096 * @param allowDeletion - If true, the values of fields that are null will be deleted.
12097 *
12098 * @returns Argument a.
12099 */
12100
12101
12102 function deepExtend(a, b) {
12103 var protoExtend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
12104 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
12105
12106 for (var prop in b) {
12107 if (Object.prototype.hasOwnProperty.call(b, prop) || protoExtend === true) {
12108 if (_typeof$1(b[prop]) === "object" && b[prop] !== null && Object.getPrototypeOf(b[prop]) === Object.prototype) {
12109 if (a[prop] === undefined) {
12110 a[prop] = deepExtend({}, b[prop], protoExtend); // NOTE: allowDeletion not propagated!
12111 } else if (_typeof$1(a[prop]) === "object" && a[prop] !== null && Object.getPrototypeOf(a[prop]) === Object.prototype) {
12112 deepExtend(a[prop], b[prop], protoExtend); // NOTE: allowDeletion not propagated!
12113 } else {
12114 copyOrDelete(a, b, prop, allowDeletion);
12115 }
12116 } else if (Array.isArray(b[prop])) {
12117 a[prop] = b[prop].slice();
12118 } else {
12119 copyOrDelete(a, b, prop, allowDeletion);
12120 }
12121 }
12122 }
12123
12124 return a;
12125 }
12126 /**
12127 * Test whether all elements in two arrays are equal.
12128 *
12129 * @param a - First array.
12130 * @param b - Second array.
12131 *
12132 * @returns True if both arrays have the same length and same elements (1 = '1').
12133 */
12134
12135
12136 function equalArray(a, b) {
12137 if (a.length !== b.length) {
12138 return false;
12139 }
12140
12141 for (var i = 0, len = a.length; i < len; i++) {
12142 if (a[i] != b[i]) {
12143 return false;
12144 }
12145 }
12146
12147 return true;
12148 }
12149 /**
12150 * Convert an object into another type
12151 *
12152 * @param object - Value of unknown type.
12153 * @param type - Name of the desired type.
12154 *
12155 * @returns Object in the desired type.
12156 * @throws Error
12157 */
12158
12159
12160 function convert(object, type) {
12161 var match;
12162
12163 if (object === undefined) {
12164 return undefined;
12165 }
12166
12167 if (object === null) {
12168 return null;
12169 }
12170
12171 if (!type) {
12172 return object;
12173 }
12174
12175 if (!(typeof type === "string") && !(type instanceof String)) {
12176 throw new Error("Type must be a string");
12177 } //noinspection FallthroughInSwitchStatementJS
12178
12179
12180 switch (type) {
12181 case "boolean":
12182 case "Boolean":
12183 return Boolean(object);
12184
12185 case "number":
12186 case "Number":
12187 if (isString(object) && !isNaN(Date.parse(object))) {
12188 return moment(object).valueOf();
12189 } else {
12190 // @TODO: I don't think that Number and String constructors are a good idea.
12191 // This could also fail if the object doesn't have valueOf method or if it's redefined.
12192 // For example: Object.create(null) or { valueOf: 7 }.
12193 return Number(object.valueOf());
12194 }
12195
12196 case "string":
12197 case "String":
12198 return String(object);
12199
12200 case "Date":
12201 if (isNumber(object)) {
12202 return new Date(object);
12203 }
12204
12205 if (object instanceof Date) {
12206 return new Date(object.valueOf());
12207 } else if (isMoment(object)) {
12208 return new Date(object.valueOf());
12209 }
12210
12211 if (isString(object)) {
12212 match = ASPDateRegex.exec(object);
12213
12214 if (match) {
12215 // object is an ASP date
12216 return new Date(Number(match[1])); // parse number
12217 } else {
12218 return moment(new Date(object)).toDate(); // parse string
12219 }
12220 } else {
12221 throw new Error("Cannot convert object of type " + getType(object) + " to type Date");
12222 }
12223
12224 case "Moment":
12225 if (isNumber(object)) {
12226 return moment(object);
12227 }
12228
12229 if (object instanceof Date) {
12230 return moment(object.valueOf());
12231 } else if (isMoment(object)) {
12232 return moment(object);
12233 }
12234
12235 if (isString(object)) {
12236 match = ASPDateRegex.exec(object);
12237
12238 if (match) {
12239 // object is an ASP date
12240 return moment(Number(match[1])); // parse number
12241 } else {
12242 return moment(object); // parse string
12243 }
12244 } else {
12245 throw new Error("Cannot convert object of type " + getType(object) + " to type Date");
12246 }
12247
12248 case "ISODate":
12249 if (isNumber(object)) {
12250 return new Date(object);
12251 } else if (object instanceof Date) {
12252 return object.toISOString();
12253 } else if (isMoment(object)) {
12254 return object.toDate().toISOString();
12255 } else if (isString(object)) {
12256 match = ASPDateRegex.exec(object);
12257
12258 if (match) {
12259 // object is an ASP date
12260 return new Date(Number(match[1])).toISOString(); // parse number
12261 } else {
12262 return moment(object).format(); // ISO 8601
12263 }
12264 } else {
12265 throw new Error("Cannot convert object of type " + getType(object) + " to type ISODate");
12266 }
12267
12268 case "ASPDate":
12269 if (isNumber(object)) {
12270 return "/Date(" + object + ")/";
12271 } else if (object instanceof Date || isMoment(object)) {
12272 return "/Date(" + object.valueOf() + ")/";
12273 } else if (isString(object)) {
12274 match = ASPDateRegex.exec(object);
12275
12276 var _value;
12277
12278 if (match) {
12279 // object is an ASP date
12280 _value = new Date(Number(match[1])).valueOf(); // parse number
12281 } else {
12282 _value = new Date(object).valueOf(); // parse string
12283 }
12284
12285 return "/Date(" + _value + ")/";
12286 } else {
12287 throw new Error("Cannot convert object of type " + getType(object) + " to type ASPDate");
12288 }
12289
12290 default:
12291 var never = type;
12292 throw new Error("Unknown type ".concat(never));
12293 }
12294 }
12295 /**
12296 * Get the type of an object, for example exports.getType([]) returns 'Array'
12297 *
12298 * @param object - Input value of unknown type.
12299 *
12300 * @returns Detected type.
12301 */
12302
12303
12304 function getType(object) {
12305 var type = _typeof$1(object);
12306
12307 if (type === "object") {
12308 if (object === null) {
12309 return "null";
12310 }
12311
12312 if (object instanceof Boolean) {
12313 return "Boolean";
12314 }
12315
12316 if (object instanceof Number) {
12317 return "Number";
12318 }
12319
12320 if (object instanceof String) {
12321 return "String";
12322 }
12323
12324 if (Array.isArray(object)) {
12325 return "Array";
12326 }
12327
12328 if (object instanceof Date) {
12329 return "Date";
12330 }
12331
12332 return "Object";
12333 }
12334
12335 if (type === "number") {
12336 return "Number";
12337 }
12338
12339 if (type === "boolean") {
12340 return "Boolean";
12341 }
12342
12343 if (type === "string") {
12344 return "String";
12345 }
12346
12347 if (type === undefined) {
12348 return "undefined";
12349 }
12350
12351 return type;
12352 }
12353 /**
12354 * Used to extend an array and copy it. This is used to propagate paths recursively.
12355 *
12356 * @param arr - First part.
12357 * @param newValue - The value to be aadded into the array.
12358 *
12359 * @returns A new array with all items from arr and newValue (which is last).
12360 */
12361
12362
12363 function copyAndExtendArray(arr, newValue) {
12364 return [].concat(_toConsumableArray(arr), [newValue]);
12365 }
12366 /**
12367 * Used to extend an array and copy it. This is used to propagate paths recursively.
12368 *
12369 * @param arr - The array to be copied.
12370 *
12371 * @returns Shallow copy of arr.
12372 */
12373
12374
12375 function copyArray(arr) {
12376 return arr.slice();
12377 }
12378 /**
12379 * Retrieve the absolute left value of a DOM element
12380 *
12381 * @param elem - A dom element, for example a div.
12382 *
12383 * @returns The absolute left position of this element in the browser page.
12384 */
12385
12386
12387 function getAbsoluteLeft(elem) {
12388 return elem.getBoundingClientRect().left;
12389 }
12390 /**
12391 * Retrieve the absolute right value of a DOM element
12392 *
12393 * @param elem - A dom element, for example a div.
12394 *
12395 * @returns The absolute right position of this element in the browser page.
12396 */
12397
12398
12399 function getAbsoluteRight(elem) {
12400 return elem.getBoundingClientRect().right;
12401 }
12402 /**
12403 * Retrieve the absolute top value of a DOM element
12404 *
12405 * @param elem - A dom element, for example a div.
12406 *
12407 * @returns The absolute top position of this element in the browser page.
12408 */
12409
12410
12411 function getAbsoluteTop(elem) {
12412 return elem.getBoundingClientRect().top;
12413 }
12414 /**
12415 * Add a className to the given elements style.
12416 *
12417 * @param elem - The element to which the classes will be added.
12418 * @param classNames - Space separated list of classes.
12419 */
12420
12421
12422 function addClassName(elem, classNames) {
12423 var classes = elem.className.split(" ");
12424 var newClasses = classNames.split(" ");
12425 classes = classes.concat(newClasses.filter(function (className) {
12426 return classes.indexOf(className) < 0;
12427 }));
12428 elem.className = classes.join(" ");
12429 }
12430 /**
12431 * Remove a className from the given elements style.
12432 *
12433 * @param elem - The element from which the classes will be removed.
12434 * @param classNames - Space separated list of classes.
12435 */
12436
12437
12438 function removeClassName(elem, classNames) {
12439 var classes = elem.className.split(" ");
12440 var oldClasses = classNames.split(" ");
12441 classes = classes.filter(function (className) {
12442 return oldClasses.indexOf(className) < 0;
12443 });
12444 elem.className = classes.join(" ");
12445 }
12446 /**
12447 * For each method for both arrays and objects.
12448 * In case of an array, the built-in Array.forEach() is applied (**No, it's not!**).
12449 * In case of an Object, the method loops over all properties of the object.
12450 *
12451 * @param object - An Object or Array to be iterated over.
12452 * @param callback - Array.forEach-like callback.
12453 */
12454
12455
12456 function forEach(object, callback) {
12457 if (Array.isArray(object)) {
12458 // array
12459 var len = object.length;
12460
12461 for (var i = 0; i < len; i++) {
12462 callback(object[i], i, object);
12463 }
12464 } else {
12465 // object
12466 for (var _key2 in object) {
12467 if (Object.prototype.hasOwnProperty.call(object, _key2)) {
12468 callback(object[_key2], _key2, object);
12469 }
12470 }
12471 }
12472 }
12473 /**
12474 * Convert an object into an array: all objects properties are put into the array. The resulting array is unordered.
12475 *
12476 * @param o - Object that contains the properties and methods.
12477 *
12478 * @returns An array of unordered values.
12479 */
12480
12481
12482 var toArray = Object.values;
12483 /**
12484 * Update a property in an object
12485 *
12486 * @param object - The object whose property will be updated.
12487 * @param key - Name of the property to be updated.
12488 * @param value - The new value to be assigned.
12489 *
12490 * @returns Whether the value was updated (true) or already strictly the same in the original object (false).
12491 */
12492
12493 function updateProperty(object, key, value) {
12494 if (object[key] !== value) {
12495 object[key] = value;
12496 return true;
12497 } else {
12498 return false;
12499 }
12500 }
12501 /**
12502 * Throttle the given function to be only executed once per animation frame.
12503 *
12504 * @param fn - The original function.
12505 *
12506 * @returns The throttled function.
12507 */
12508
12509
12510 function throttle(fn) {
12511 var scheduled = false;
12512 return function () {
12513 if (!scheduled) {
12514 scheduled = true;
12515 requestAnimationFrame(function () {
12516 scheduled = false;
12517 fn();
12518 });
12519 }
12520 };
12521 }
12522 /**
12523 * Add and event listener. Works for all browsers.
12524 *
12525 * @param element - The element to bind the event listener to.
12526 * @param action - Same as Element.addEventListener(action, —, —).
12527 * @param listener - Same as Element.addEventListener(—, listener, —).
12528 * @param useCapture - Same as Element.addEventListener(—, —, useCapture).
12529 */
12530
12531
12532 function addEventListener(element, action, listener, useCapture) {
12533 if (element.addEventListener) {
12534 if (useCapture === undefined) {
12535 useCapture = false;
12536 }
12537
12538 if (action === "mousewheel" && navigator.userAgent.indexOf("Firefox") >= 0) {
12539 action = "DOMMouseScroll"; // For Firefox
12540 }
12541
12542 element.addEventListener(action, listener, useCapture);
12543 } else {
12544 // @TODO: IE types? Does anyone care?
12545 element.attachEvent("on" + action, listener); // IE browsers
12546 }
12547 }
12548 /**
12549 * Remove an event listener from an element
12550 *
12551 * @param element - The element to bind the event listener to.
12552 * @param action - Same as Element.removeEventListener(action, —, —).
12553 * @param listener - Same as Element.removeEventListener(—, listener, —).
12554 * @param useCapture - Same as Element.removeEventListener(—, —, useCapture).
12555 */
12556
12557
12558 function removeEventListener(element, action, listener, useCapture) {
12559 if (element.removeEventListener) {
12560 // non-IE browsers
12561 if (useCapture === undefined) {
12562 useCapture = false;
12563 }
12564
12565 if (action === "mousewheel" && navigator.userAgent.indexOf("Firefox") >= 0) {
12566 action = "DOMMouseScroll"; // For Firefox
12567 }
12568
12569 element.removeEventListener(action, listener, useCapture);
12570 } else {
12571 // @TODO: IE types? Does anyone care?
12572 element.detachEvent("on" + action, listener); // IE browsers
12573 }
12574 }
12575 /**
12576 * Cancels the event's default action if it is cancelable, without stopping further propagation of the event.
12577 *
12578 * @param event - The event whose default action should be prevented.
12579 */
12580
12581
12582 function preventDefault(event) {
12583 if (!event) {
12584 event = window.event;
12585 }
12586
12587 if (!event) ;else if (event.preventDefault) {
12588 event.preventDefault(); // non-IE browsers
12589 } else {
12590 // @TODO: IE types? Does anyone care?
12591 event.returnValue = false; // IE browsers
12592 }
12593 }
12594 /**
12595 * Get HTML element which is the target of the event.
12596 *
12597 * @param event - The event.
12598 *
12599 * @returns The element or null if not obtainable.
12600 */
12601
12602
12603 function getTarget() {
12604 var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.event; // code from http://www.quirksmode.org/js/events_properties.html
12605 // @TODO: EventTarget can be almost anything, is it okay to return only Elements?
12606
12607 var target = null;
12608 if (!event) ;else if (event.target) {
12609 target = event.target;
12610 } else if (event.srcElement) {
12611 target = event.srcElement;
12612 }
12613
12614 if (!(target instanceof Element)) {
12615 return null;
12616 }
12617
12618 if (target.nodeType != null && target.nodeType == 3) {
12619 // defeat Safari bug
12620 target = target.parentNode;
12621
12622 if (!(target instanceof Element)) {
12623 return null;
12624 }
12625 }
12626
12627 return target;
12628 }
12629 /**
12630 * Check if given element contains given parent somewhere in the DOM tree
12631 *
12632 * @param element - The element to be tested.
12633 * @param parent - The ancestor (not necessarily parent) of the element.
12634 *
12635 * @returns True if parent is an ancestor of the element, false otherwise.
12636 */
12637
12638
12639 function hasParent(element, parent) {
12640 var elem = element;
12641
12642 while (elem) {
12643 if (elem === parent) {
12644 return true;
12645 } else if (elem.parentNode) {
12646 elem = elem.parentNode;
12647 } else {
12648 return false;
12649 }
12650 }
12651
12652 return false;
12653 }
12654
12655 var option = {
12656 /**
12657 * Convert a value into a boolean.
12658 *
12659 * @param value - Value to be converted intoboolean, a function will be executed as (() => unknown).
12660 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
12661 *
12662 * @returns Corresponding boolean value, if none then the default value, if none then null.
12663 */
12664 asBoolean: function asBoolean(value, defaultValue) {
12665 if (typeof value == "function") {
12666 value = value();
12667 }
12668
12669 if (value != null) {
12670 return value != false;
12671 }
12672
12673 return defaultValue || null;
12674 },
12675
12676 /**
12677 * Convert a value into a number.
12678 *
12679 * @param value - Value to be converted intonumber, a function will be executed as (() => unknown).
12680 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
12681 *
12682 * @returns Corresponding **boxed** number value, if none then the default value, if none then null.
12683 */
12684 asNumber: function asNumber(value, defaultValue) {
12685 if (typeof value == "function") {
12686 value = value();
12687 }
12688
12689 if (value != null) {
12690 return Number(value) || defaultValue || null;
12691 }
12692
12693 return defaultValue || null;
12694 },
12695
12696 /**
12697 * Convert a value into a string.
12698 *
12699 * @param value - Value to be converted intostring, a function will be executed as (() => unknown).
12700 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
12701 *
12702 * @returns Corresponding **boxed** string value, if none then the default value, if none then null.
12703 */
12704 asString: function asString(value, defaultValue) {
12705 if (typeof value == "function") {
12706 value = value();
12707 }
12708
12709 if (value != null) {
12710 return String(value);
12711 }
12712
12713 return defaultValue || null;
12714 },
12715
12716 /**
12717 * Convert a value into a size.
12718 *
12719 * @param value - Value to be converted intosize, a function will be executed as (() => unknown).
12720 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
12721 *
12722 * @returns Corresponding string value (number + 'px'), if none then the default value, if none then null.
12723 */
12724 asSize: function asSize(value, defaultValue) {
12725 if (typeof value == "function") {
12726 value = value();
12727 }
12728
12729 if (isString(value)) {
12730 return value;
12731 } else if (isNumber(value)) {
12732 return value + "px";
12733 } else {
12734 return defaultValue || null;
12735 }
12736 },
12737
12738 /**
12739 * Convert a value into a DOM Element.
12740 *
12741 * @param value - Value to be converted into DOM Element, a function will be executed as (() => unknown).
12742 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
12743 *
12744 * @returns The DOM Element, if none then the default value, if none then null.
12745 */
12746 asElement: function asElement(value, defaultValue) {
12747 if (typeof value == "function") {
12748 value = value();
12749 }
12750
12751 return value || defaultValue || null;
12752 }
12753 };
12754 /**
12755 * Convert hex color string into RGB color object.
12756 * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
12757 *
12758 * @param hex - Hex color string (3 or 6 digits, with or without #).
12759 *
12760 * @returns RGB color object.
12761 */
12762
12763 function hexToRGB(hex) {
12764 var result;
12765
12766 switch (hex.length) {
12767 case 3:
12768 case 4:
12769 result = shortHexRE.exec(hex);
12770 return result ? {
12771 r: parseInt(result[1] + result[1], 16),
12772 g: parseInt(result[2] + result[2], 16),
12773 b: parseInt(result[3] + result[3], 16)
12774 } : null;
12775
12776 case 6:
12777 case 7:
12778 result = fullHexRE.exec(hex);
12779 return result ? {
12780 r: parseInt(result[1], 16),
12781 g: parseInt(result[2], 16),
12782 b: parseInt(result[3], 16)
12783 } : null;
12784
12785 default:
12786 return null;
12787 }
12788 }
12789 /**
12790 * This function takes string color in hex or RGB format and adds the opacity, RGBA is passed through unchanged.
12791 *
12792 * @param color - The color string (hex, RGB, RGBA).
12793 * @param opacity - The new opacity.
12794 *
12795 * @returns RGBA string, for example 'rgba(255, 0, 127, 0.3)'.
12796 */
12797
12798
12799 function overrideOpacity(color, opacity) {
12800 if (color.indexOf("rgba") !== -1) {
12801 return color;
12802 } else if (color.indexOf("rgb") !== -1) {
12803 var rgb = color.substr(color.indexOf("(") + 1).replace(")", "").split(",");
12804 return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + opacity + ")";
12805 } else {
12806 var _rgb = hexToRGB(color);
12807
12808 if (_rgb == null) {
12809 return color;
12810 } else {
12811 return "rgba(" + _rgb.r + "," + _rgb.g + "," + _rgb.b + "," + opacity + ")";
12812 }
12813 }
12814 }
12815 /**
12816 * Convert RGB <0, 255> into hex color string.
12817 *
12818 * @param red - Red channel.
12819 * @param green - Green channel.
12820 * @param blue - Blue channel.
12821 *
12822 * @returns Hex color string (for example: '#0acdc0').
12823 */
12824
12825
12826 function RGBToHex(red, green, blue) {
12827 return "#" + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1);
12828 }
12829 /**
12830 * Parse a color property into an object with border, background, and highlight colors
12831 *
12832 * @param inputColor - Shorthand color string or input color object.
12833 * @param defaultColor - Full color object to fill in missing values in inputColor.
12834 *
12835 * @returns Color object.
12836 */
12837
12838
12839 function parseColor(inputColor, defaultColor) {
12840 if (isString(inputColor)) {
12841 var colorStr = inputColor;
12842
12843 if (isValidRGB(colorStr)) {
12844 var rgb = colorStr.substr(4).substr(0, colorStr.length - 5).split(",").map(function (value) {
12845 return parseInt(value);
12846 });
12847 colorStr = RGBToHex(rgb[0], rgb[1], rgb[2]);
12848 }
12849
12850 if (isValidHex(colorStr) === true) {
12851 var hsv = hexToHSV(colorStr);
12852 var lighterColorHSV = {
12853 h: hsv.h,
12854 s: hsv.s * 0.8,
12855 v: Math.min(1, hsv.v * 1.02)
12856 };
12857 var darkerColorHSV = {
12858 h: hsv.h,
12859 s: Math.min(1, hsv.s * 1.25),
12860 v: hsv.v * 0.8
12861 };
12862 var darkerColorHex = HSVToHex(darkerColorHSV.h, darkerColorHSV.s, darkerColorHSV.v);
12863 var lighterColorHex = HSVToHex(lighterColorHSV.h, lighterColorHSV.s, lighterColorHSV.v);
12864 return {
12865 background: colorStr,
12866 border: darkerColorHex,
12867 highlight: {
12868 background: lighterColorHex,
12869 border: darkerColorHex
12870 },
12871 hover: {
12872 background: lighterColorHex,
12873 border: darkerColorHex
12874 }
12875 };
12876 } else {
12877 return {
12878 background: colorStr,
12879 border: colorStr,
12880 highlight: {
12881 background: colorStr,
12882 border: colorStr
12883 },
12884 hover: {
12885 background: colorStr,
12886 border: colorStr
12887 }
12888 };
12889 }
12890 } else {
12891 if (defaultColor) {
12892 var color = {
12893 background: inputColor.background || defaultColor.background,
12894 border: inputColor.border || defaultColor.border,
12895 highlight: isString(inputColor.highlight) ? {
12896 border: inputColor.highlight,
12897 background: inputColor.highlight
12898 } : {
12899 background: inputColor.highlight && inputColor.highlight.background || defaultColor.highlight.background,
12900 border: inputColor.highlight && inputColor.highlight.border || defaultColor.highlight.border
12901 },
12902 hover: isString(inputColor.hover) ? {
12903 border: inputColor.hover,
12904 background: inputColor.hover
12905 } : {
12906 border: inputColor.hover && inputColor.hover.border || defaultColor.hover.border,
12907 background: inputColor.hover && inputColor.hover.background || defaultColor.hover.background
12908 }
12909 };
12910 return color;
12911 } else {
12912 var _color = {
12913 background: inputColor.background || undefined,
12914 border: inputColor.border || undefined,
12915 highlight: isString(inputColor.highlight) ? {
12916 border: inputColor.highlight,
12917 background: inputColor.highlight
12918 } : {
12919 background: inputColor.highlight && inputColor.highlight.background || undefined,
12920 border: inputColor.highlight && inputColor.highlight.border || undefined
12921 },
12922 hover: isString(inputColor.hover) ? {
12923 border: inputColor.hover,
12924 background: inputColor.hover
12925 } : {
12926 border: inputColor.hover && inputColor.hover.border || undefined,
12927 background: inputColor.hover && inputColor.hover.background || undefined
12928 }
12929 };
12930 return _color;
12931 }
12932 }
12933 }
12934 /**
12935 * Convert RGB <0, 255> into HSV object.
12936 * http://www.javascripter.net/faq/rgb2hsv.htm
12937 *
12938 * @param red - Red channel.
12939 * @param green - Green channel.
12940 * @param blue - Blue channel.
12941 *
12942 * @returns HSV color object.
12943 */
12944
12945
12946 function RGBToHSV(red, green, blue) {
12947 red = red / 255;
12948 green = green / 255;
12949 blue = blue / 255;
12950 var minRGB = Math.min(red, Math.min(green, blue));
12951 var maxRGB = Math.max(red, Math.max(green, blue)); // Black-gray-white
12952
12953 if (minRGB === maxRGB) {
12954 return {
12955 h: 0,
12956 s: 0,
12957 v: minRGB
12958 };
12959 } // Colors other than black-gray-white:
12960
12961
12962 var d = red === minRGB ? green - blue : blue === minRGB ? red - green : blue - red;
12963 var h = red === minRGB ? 3 : blue === minRGB ? 1 : 5;
12964 var hue = 60 * (h - d / (maxRGB - minRGB)) / 360;
12965 var saturation = (maxRGB - minRGB) / maxRGB;
12966 var value = maxRGB;
12967 return {
12968 h: hue,
12969 s: saturation,
12970 v: value
12971 };
12972 }
12973
12974 var cssUtil = {
12975 // split a string with css styles into an object with key/values
12976 split: function split(cssText) {
12977 var styles = {};
12978 cssText.split(";").forEach(function (style) {
12979 if (style.trim() != "") {
12980 var parts = style.split(":");
12981
12982 var _key3 = parts[0].trim();
12983
12984 var _value2 = parts[1].trim();
12985
12986 styles[_key3] = _value2;
12987 }
12988 });
12989 return styles;
12990 },
12991 // build a css text string from an object with key/values
12992 join: function join(styles) {
12993 return Object.keys(styles).map(function (key) {
12994 return key + ": " + styles[key];
12995 }).join("; ");
12996 }
12997 };
12998 /**
12999 * Append a string with css styles to an element
13000 *
13001 * @param element - The element that will receive new styles.
13002 * @param cssText - The styles to be appended.
13003 */
13004
13005 function addCssText(element, cssText) {
13006 var currentStyles = cssUtil.split(element.style.cssText);
13007 var newStyles = cssUtil.split(cssText);
13008
13009 var styles = _objectSpread2$1({}, currentStyles, {}, newStyles);
13010
13011 element.style.cssText = cssUtil.join(styles);
13012 }
13013 /**
13014 * Remove a string with css styles from an element
13015 *
13016 * @param element - The element from which styles should be removed.
13017 * @param cssText - The styles to be removed.
13018 */
13019
13020
13021 function removeCssText(element, cssText) {
13022 var styles = cssUtil.split(element.style.cssText);
13023 var removeStyles = cssUtil.split(cssText);
13024
13025 for (var _key4 in removeStyles) {
13026 if (Object.prototype.hasOwnProperty.call(removeStyles, _key4)) {
13027 delete styles[_key4];
13028 }
13029 }
13030
13031 element.style.cssText = cssUtil.join(styles);
13032 }
13033 /**
13034 * Convert HSV <0, 1> into RGB color object.
13035 * https://gist.github.com/mjijackson/5311256
13036 *
13037 * @param h - Hue
13038 * @param s - Saturation
13039 * @param v - Value
13040 *
13041 * @returns RGB color object.
13042 */
13043
13044
13045 function HSVToRGB(h, s, v) {
13046 var r;
13047 var g;
13048 var b;
13049 var i = Math.floor(h * 6);
13050 var f = h * 6 - i;
13051 var p = v * (1 - s);
13052 var q = v * (1 - f * s);
13053 var t = v * (1 - (1 - f) * s);
13054
13055 switch (i % 6) {
13056 case 0:
13057 r = v, g = t, b = p;
13058 break;
13059
13060 case 1:
13061 r = q, g = v, b = p;
13062 break;
13063
13064 case 2:
13065 r = p, g = v, b = t;
13066 break;
13067
13068 case 3:
13069 r = p, g = q, b = v;
13070 break;
13071
13072 case 4:
13073 r = t, g = p, b = v;
13074 break;
13075
13076 case 5:
13077 r = v, g = p, b = q;
13078 break;
13079 }
13080
13081 return {
13082 r: Math.floor(r * 255),
13083 g: Math.floor(g * 255),
13084 b: Math.floor(b * 255)
13085 };
13086 }
13087 /**
13088 * Convert HSV <0, 1> into hex color string.
13089 *
13090 * @param h - Hue
13091 * @param s - Saturation
13092 * @param v - Value
13093 *
13094 * @returns Hex color string.
13095 */
13096
13097
13098 function HSVToHex(h, s, v) {
13099 var rgb = HSVToRGB(h, s, v);
13100 return RGBToHex(rgb.r, rgb.g, rgb.b);
13101 }
13102 /**
13103 * Convert hex color string into HSV <0, 1>.
13104 *
13105 * @param hex - Hex color string.
13106 *
13107 * @returns HSV color object.
13108 */
13109
13110
13111 function hexToHSV(hex) {
13112 var rgb = hexToRGB(hex);
13113
13114 if (!rgb) {
13115 throw new TypeError("'".concat(hex, "' is not a valid color."));
13116 }
13117
13118 return RGBToHSV(rgb.r, rgb.g, rgb.b);
13119 }
13120 /**
13121 * Validate hex color string.
13122 *
13123 * @param hex - Unknown string that may contain a color.
13124 *
13125 * @returns True if the string is valid, false otherwise.
13126 */
13127
13128
13129 function isValidHex(hex) {
13130 var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
13131 return isOk;
13132 }
13133 /**
13134 * Validate RGB color string.
13135 *
13136 * @param rgb - Unknown string that may contain a color.
13137 *
13138 * @returns True if the string is valid, false otherwise.
13139 */
13140
13141
13142 function isValidRGB(rgb) {
13143 return rgbRE.test(rgb);
13144 }
13145 /**
13146 * Validate RGBA color string.
13147 *
13148 * @param rgba - Unknown string that may contain a color.
13149 *
13150 * @returns True if the string is valid, false otherwise.
13151 */
13152
13153
13154 function isValidRGBA(rgba) {
13155 return rgbaRE.test(rgba);
13156 }
13157 /**
13158 * This recursively redirects the prototype of JSON objects to the referenceObject.
13159 * This is used for default options.
13160 *
13161 * @param fields - Names of properties to be bridged.
13162 * @param referenceObject - The original object.
13163 *
13164 * @returns A new object inheriting from the referenceObject.
13165 */
13166
13167
13168 function selectiveBridgeObject(fields, referenceObject) {
13169 if (referenceObject !== null && _typeof$1(referenceObject) === "object") {
13170 // !!! typeof null === 'object'
13171 var objectTo = Object.create(referenceObject);
13172
13173 for (var i = 0; i < fields.length; i++) {
13174 if (Object.prototype.hasOwnProperty.call(referenceObject, fields[i])) {
13175 if (_typeof$1(referenceObject[fields[i]]) == "object") {
13176 objectTo[fields[i]] = bridgeObject(referenceObject[fields[i]]);
13177 }
13178 }
13179 }
13180
13181 return objectTo;
13182 } else {
13183 return null;
13184 }
13185 }
13186 /**
13187 * This recursively redirects the prototype of JSON objects to the referenceObject.
13188 * This is used for default options.
13189 *
13190 * @param referenceObject - The original object.
13191 *
13192 * @returns The Element if the referenceObject is an Element, or a new object inheriting from the referenceObject.
13193 */
13194
13195
13196 function bridgeObject(referenceObject) {
13197 if (referenceObject === null || _typeof$1(referenceObject) !== "object") {
13198 return null;
13199 }
13200
13201 if (referenceObject instanceof Element) {
13202 // Avoid bridging DOM objects
13203 return referenceObject;
13204 }
13205
13206 var objectTo = Object.create(referenceObject);
13207
13208 for (var i in referenceObject) {
13209 if (Object.prototype.hasOwnProperty.call(referenceObject, i)) {
13210 if (_typeof$1(referenceObject[i]) == "object") {
13211 objectTo[i] = bridgeObject(referenceObject[i]);
13212 }
13213 }
13214 }
13215
13216 return objectTo;
13217 }
13218 /**
13219 * This method provides a stable sort implementation, very fast for presorted data.
13220 *
13221 * @param a - The array to be sorted (in-place).
13222 * @param compare - An order comparator.
13223 *
13224 * @returns The argument a.
13225 */
13226
13227
13228 function insertSort(a, compare) {
13229 for (var i = 0; i < a.length; i++) {
13230 var k = a[i];
13231 var j = void 0;
13232
13233 for (j = i; j > 0 && compare(k, a[j - 1]) < 0; j--) {
13234 a[j] = a[j - 1];
13235 }
13236
13237 a[j] = k;
13238 }
13239
13240 return a;
13241 }
13242 /**
13243 * This is used to set the options of subobjects in the options object.
13244 *
13245 * A requirement of these subobjects is that they have an 'enabled' element
13246 * which is optional for the user but mandatory for the program.
13247 *
13248 * The added value here of the merge is that option 'enabled' is set as required.
13249 *
13250 * @param mergeTarget - Either this.options or the options used for the groups.
13251 * @param options - Options.
13252 * @param option - Option key in the options argument.
13253 * @param globalOptions - Global options, passed in to determine value of option 'enabled'.
13254 */
13255
13256
13257 function mergeOptions(mergeTarget, options, option) {
13258 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; // Local helpers
13259
13260 var isPresent = function isPresent(obj) {
13261 return obj !== null && obj !== undefined;
13262 };
13263
13264 var isObject = function isObject(obj) {
13265 return obj !== null && _typeof$1(obj) === "object";
13266 }; // https://stackoverflow.com/a/34491287/1223531
13267
13268
13269 var isEmpty = function isEmpty(obj) {
13270 for (var x in obj) {
13271 if (Object.prototype.hasOwnProperty.call(obj, x)) {
13272 return false;
13273 }
13274 }
13275
13276 return true;
13277 }; // Guards
13278
13279
13280 if (!isObject(mergeTarget)) {
13281 throw new Error("Parameter mergeTarget must be an object");
13282 }
13283
13284 if (!isObject(options)) {
13285 throw new Error("Parameter options must be an object");
13286 }
13287
13288 if (!isPresent(option)) {
13289 throw new Error("Parameter option must have a value");
13290 }
13291
13292 if (!isObject(globalOptions)) {
13293 throw new Error("Parameter globalOptions must be an object");
13294 } //
13295 // Actual merge routine, separated from main logic
13296 // Only a single level of options is merged. Deeper levels are ref'd. This may actually be an issue.
13297 //
13298
13299
13300 var doMerge = function doMerge(target, options, option) {
13301 if (!isObject(target[option])) {
13302 target[option] = {};
13303 }
13304
13305 var src = options[option];
13306 var dst = target[option];
13307
13308 for (var prop in src) {
13309 if (Object.prototype.hasOwnProperty.call(src, prop)) {
13310 dst[prop] = src[prop];
13311 }
13312 }
13313 }; // Local initialization
13314
13315
13316 var srcOption = options[option];
13317 var globalPassed = isObject(globalOptions) && !isEmpty(globalOptions);
13318 var globalOption = globalPassed ? globalOptions[option] : undefined;
13319 var globalEnabled = globalOption ? globalOption.enabled : undefined; /////////////////////////////////////////
13320 // Main routine
13321 /////////////////////////////////////////
13322
13323 if (srcOption === undefined) {
13324 return; // Nothing to do
13325 }
13326
13327 if (typeof srcOption === "boolean") {
13328 if (!isObject(mergeTarget[option])) {
13329 mergeTarget[option] = {};
13330 }
13331
13332 mergeTarget[option].enabled = srcOption;
13333 return;
13334 }
13335
13336 if (srcOption === null && !isObject(mergeTarget[option])) {
13337 // If possible, explicit copy from globals
13338 if (isPresent(globalOption)) {
13339 mergeTarget[option] = Object.create(globalOption);
13340 } else {
13341 return; // Nothing to do
13342 }
13343 }
13344
13345 if (!isObject(srcOption)) {
13346 return;
13347 } //
13348 // Ensure that 'enabled' is properly set. It is required internally
13349 // Note that the value from options will always overwrite the existing value
13350 //
13351
13352
13353 var enabled = true; // default value
13354
13355 if (srcOption.enabled !== undefined) {
13356 enabled = srcOption.enabled;
13357 } else {
13358 // Take from globals, if present
13359 if (globalEnabled !== undefined) {
13360 enabled = globalOption.enabled;
13361 }
13362 }
13363
13364 doMerge(mergeTarget, options, option);
13365 mergeTarget[option].enabled = enabled;
13366 }
13367 /**
13368 * This function does a binary search for a visible item in a sorted list. If we find a visible item, the code that uses
13369 * this function will then iterate in both directions over this sorted list to find all visible items.
13370 *
13371 * @param orderedItems - Items ordered by start
13372 * @param comparator - -1 is lower, 0 is equal, 1 is higher
13373 * @param field - Property name on an item (i.e. item[field]).
13374 * @param field2 - Second property name on an item (i.e. item[field][field2]).
13375 *
13376 * @returns Index of the found item or -1 if nothing was found.
13377 */
13378
13379
13380 function binarySearchCustom(orderedItems, comparator, field, field2) {
13381 var maxIterations = 10000;
13382 var iteration = 0;
13383 var low = 0;
13384 var high = orderedItems.length - 1;
13385
13386 while (low <= high && iteration < maxIterations) {
13387 var middle = Math.floor((low + high) / 2);
13388 var item = orderedItems[middle];
13389
13390 var _value3 = field2 === undefined ? item[field] : item[field][field2];
13391
13392 var searchResult = comparator(_value3);
13393
13394 if (searchResult == 0) {
13395 // jihaa, found a visible item!
13396 return middle;
13397 } else if (searchResult == -1) {
13398 // it is too small --> increase low
13399 low = middle + 1;
13400 } else {
13401 // it is too big --> decrease high
13402 high = middle - 1;
13403 }
13404
13405 iteration++;
13406 }
13407
13408 return -1;
13409 }
13410 /**
13411 * This function does a binary search for a specific value in a sorted array. If it does not exist but is in between of
13412 * two values, we return either the one before or the one after, depending on user input
13413 * If it is found, we return the index, else -1.
13414 *
13415 * @param orderedItems - Sorted array.
13416 * @param target - The searched value.
13417 * @param field - Name of the property in items to be searched.
13418 * @param sidePreference - If the target is between two values, should the index of the before or the after be returned?
13419 * @param comparator - An optional comparator, returning -1, 0, 1 for <, ===, >.
13420 *
13421 * @returns The index of found value or -1 if nothing was found.
13422 */
13423
13424
13425 function binarySearchValue(orderedItems, target, field, sidePreference, comparator) {
13426 var maxIterations = 10000;
13427 var iteration = 0;
13428 var low = 0;
13429 var high = orderedItems.length - 1;
13430 var prevValue;
13431 var value;
13432 var nextValue;
13433 var middle;
13434 comparator = comparator != undefined ? comparator : function (a, b) {
13435 return a == b ? 0 : a < b ? -1 : 1;
13436 };
13437
13438 while (low <= high && iteration < maxIterations) {
13439 // get a new guess
13440 middle = Math.floor(0.5 * (high + low));
13441 prevValue = orderedItems[Math.max(0, middle - 1)][field];
13442 value = orderedItems[middle][field];
13443 nextValue = orderedItems[Math.min(orderedItems.length - 1, middle + 1)][field];
13444
13445 if (comparator(value, target) == 0) {
13446 // we found the target
13447 return middle;
13448 } else if (comparator(prevValue, target) < 0 && comparator(value, target) > 0) {
13449 // target is in between of the previous and the current
13450 return sidePreference == "before" ? Math.max(0, middle - 1) : middle;
13451 } else if (comparator(value, target) < 0 && comparator(nextValue, target) > 0) {
13452 // target is in between of the current and the next
13453 return sidePreference == "before" ? middle : Math.min(orderedItems.length - 1, middle + 1);
13454 } else {
13455 // didnt find the target, we need to change our boundaries.
13456 if (comparator(value, target) < 0) {
13457 // it is too small --> increase low
13458 low = middle + 1;
13459 } else {
13460 // it is too big --> decrease high
13461 high = middle - 1;
13462 }
13463 }
13464
13465 iteration++;
13466 } // didnt find anything. Return -1.
13467
13468
13469 return -1;
13470 }
13471 /*
13472 * Easing Functions.
13473 * Only considering the t value for the range [0, 1] => [0, 1].
13474 *
13475 * Inspiration: from http://gizma.com/easing/
13476 * https://gist.github.com/gre/1650294
13477 */
13478
13479
13480 var easingFunctions = {
13481 /**
13482 * no easing, no acceleration
13483 *
13484 * @param t - Time.
13485 *
13486 * @returns Value at time t.
13487 */
13488 linear: function linear(t) {
13489 return t;
13490 },
13491
13492 /**
13493 * accelerating from zero velocity
13494 *
13495 * @param t - Time.
13496 *
13497 * @returns Value at time t.
13498 */
13499 easeInQuad: function easeInQuad(t) {
13500 return t * t;
13501 },
13502
13503 /**
13504 * decelerating to zero velocity
13505 *
13506 * @param t - Time.
13507 *
13508 * @returns Value at time t.
13509 */
13510 easeOutQuad: function easeOutQuad(t) {
13511 return t * (2 - t);
13512 },
13513
13514 /**
13515 * acceleration until halfway, then deceleration
13516 *
13517 * @param t - Time.
13518 *
13519 * @returns Value at time t.
13520 */
13521 easeInOutQuad: function easeInOutQuad(t) {
13522 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
13523 },
13524
13525 /**
13526 * accelerating from zero velocity
13527 *
13528 * @param t - Time.
13529 *
13530 * @returns Value at time t.
13531 */
13532 easeInCubic: function easeInCubic(t) {
13533 return t * t * t;
13534 },
13535
13536 /**
13537 * decelerating to zero velocity
13538 *
13539 * @param t - Time.
13540 *
13541 * @returns Value at time t.
13542 */
13543 easeOutCubic: function easeOutCubic(t) {
13544 return --t * t * t + 1;
13545 },
13546
13547 /**
13548 * acceleration until halfway, then deceleration
13549 *
13550 * @param t - Time.
13551 *
13552 * @returns Value at time t.
13553 */
13554 easeInOutCubic: function easeInOutCubic(t) {
13555 return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
13556 },
13557
13558 /**
13559 * accelerating from zero velocity
13560 *
13561 * @param t - Time.
13562 *
13563 * @returns Value at time t.
13564 */
13565 easeInQuart: function easeInQuart(t) {
13566 return t * t * t * t;
13567 },
13568
13569 /**
13570 * decelerating to zero velocity
13571 *
13572 * @param t - Time.
13573 *
13574 * @returns Value at time t.
13575 */
13576 easeOutQuart: function easeOutQuart(t) {
13577 return 1 - --t * t * t * t;
13578 },
13579
13580 /**
13581 * acceleration until halfway, then deceleration
13582 *
13583 * @param t - Time.
13584 *
13585 * @returns Value at time t.
13586 */
13587 easeInOutQuart: function easeInOutQuart(t) {
13588 return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
13589 },
13590
13591 /**
13592 * accelerating from zero velocity
13593 *
13594 * @param t - Time.
13595 *
13596 * @returns Value at time t.
13597 */
13598 easeInQuint: function easeInQuint(t) {
13599 return t * t * t * t * t;
13600 },
13601
13602 /**
13603 * decelerating to zero velocity
13604 *
13605 * @param t - Time.
13606 *
13607 * @returns Value at time t.
13608 */
13609 easeOutQuint: function easeOutQuint(t) {
13610 return 1 + --t * t * t * t * t;
13611 },
13612
13613 /**
13614 * acceleration until halfway, then deceleration
13615 *
13616 * @param t - Time.
13617 *
13618 * @returns Value at time t.
13619 */
13620 easeInOutQuint: function easeInOutQuint(t) {
13621 return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
13622 }
13623 };
13624 /**
13625 * Experimentaly compute the width of the scrollbar for this browser.
13626 *
13627 * @returns The width in pixels.
13628 */
13629
13630 function getScrollBarWidth() {
13631 var inner = document.createElement("p");
13632 inner.style.width = "100%";
13633 inner.style.height = "200px";
13634 var outer = document.createElement("div");
13635 outer.style.position = "absolute";
13636 outer.style.top = "0px";
13637 outer.style.left = "0px";
13638 outer.style.visibility = "hidden";
13639 outer.style.width = "200px";
13640 outer.style.height = "150px";
13641 outer.style.overflow = "hidden";
13642 outer.appendChild(inner);
13643 document.body.appendChild(outer);
13644 var w1 = inner.offsetWidth;
13645 outer.style.overflow = "scroll";
13646 var w2 = inner.offsetWidth;
13647
13648 if (w1 == w2) {
13649 w2 = outer.clientWidth;
13650 }
13651
13652 document.body.removeChild(outer);
13653 return w1 - w2;
13654 } // @TODO: This doesn't work properly.
13655 // It works only for single property objects,
13656 // otherwise it combines all of the types in a union.
13657 // export function topMost<K1 extends string, V1> (
13658 // pile: Record<K1, undefined | V1>[],
13659 // accessors: K1 | [K1]
13660 // ): undefined | V1
13661 // export function topMost<K1 extends string, K2 extends string, V1, V2> (
13662 // pile: Record<K1, undefined | V1 | Record<K2, undefined | V2>>[],
13663 // accessors: [K1, K2]
13664 // ): undefined | V1 | V2
13665 // export function topMost<K1 extends string, K2 extends string, K3 extends string, V1, V2, V3> (
13666 // pile: Record<K1, undefined | V1 | Record<K2, undefined | V2 | Record<K3, undefined | V3>>>[],
13667 // accessors: [K1, K2, K3]
13668 // ): undefined | V1 | V2 | V3
13669
13670 /**
13671 * Get the top most property value from a pile of objects.
13672 *
13673 * @param pile - Array of objects, no required format.
13674 * @param accessors - Array of property names (e.g. object['foo']['bar'] → ['foo', 'bar']).
13675 *
13676 * @returns Value of the property with given accessors path from the first pile item where it's not undefined.
13677 */
13678
13679
13680 function topMost(pile, accessors) {
13681 var candidate;
13682
13683 if (!Array.isArray(accessors)) {
13684 accessors = [accessors];
13685 }
13686
13687 var _iteratorNormalCompletion = true;
13688 var _didIteratorError = false;
13689 var _iteratorError = undefined;
13690
13691 try {
13692 for (var _iterator = pile[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
13693 var member = _step.value;
13694
13695 if (member) {
13696 candidate = member[accessors[0]];
13697
13698 for (var i = 1; i < accessors.length; i++) {
13699 if (candidate) {
13700 candidate = candidate[accessors[i]];
13701 }
13702 }
13703
13704 if (typeof candidate !== "undefined") {
13705 break;
13706 }
13707 }
13708 }
13709 } catch (err) {
13710 _didIteratorError = true;
13711 _iteratorError = err;
13712 } finally {
13713 try {
13714 if (!_iteratorNormalCompletion && _iterator.return != null) {
13715 _iterator.return();
13716 }
13717 } finally {
13718 if (_didIteratorError) {
13719 throw _iteratorError;
13720 }
13721 }
13722 }
13723
13724 return candidate;
13725 }
13726
13727 var util =
13728 /*#__PURE__*/
13729 Object.freeze({
13730 isNumber: isNumber,
13731 recursiveDOMDelete: recursiveDOMDelete,
13732 isString: isString,
13733 isObject: isObject$1,
13734 isDate: isDate,
13735 isMoment: isMoment,
13736 fillIfDefined: fillIfDefined,
13737 extend: extend,
13738 selectiveExtend: selectiveExtend,
13739 selectiveDeepExtend: selectiveDeepExtend,
13740 selectiveNotDeepExtend: selectiveNotDeepExtend,
13741 deepExtend: deepExtend,
13742 equalArray: equalArray,
13743 convert: convert,
13744 getType: getType,
13745 copyAndExtendArray: copyAndExtendArray,
13746 copyArray: copyArray,
13747 getAbsoluteLeft: getAbsoluteLeft,
13748 getAbsoluteRight: getAbsoluteRight,
13749 getAbsoluteTop: getAbsoluteTop,
13750 addClassName: addClassName,
13751 removeClassName: removeClassName,
13752 forEach: forEach,
13753 toArray: toArray,
13754 updateProperty: updateProperty,
13755 throttle: throttle,
13756 addEventListener: addEventListener,
13757 removeEventListener: removeEventListener,
13758 preventDefault: preventDefault,
13759 getTarget: getTarget,
13760 hasParent: hasParent,
13761 option: option,
13762 hexToRGB: hexToRGB,
13763 overrideOpacity: overrideOpacity,
13764 RGBToHex: RGBToHex,
13765 parseColor: parseColor,
13766 RGBToHSV: RGBToHSV,
13767 addCssText: addCssText,
13768 removeCssText: removeCssText,
13769 HSVToRGB: HSVToRGB,
13770 HSVToHex: HSVToHex,
13771 hexToHSV: hexToHSV,
13772 isValidHex: isValidHex,
13773 isValidRGB: isValidRGB,
13774 isValidRGBA: isValidRGBA,
13775 selectiveBridgeObject: selectiveBridgeObject,
13776 bridgeObject: bridgeObject,
13777 insertSort: insertSort,
13778 mergeOptions: mergeOptions,
13779 binarySearchCustom: binarySearchCustom,
13780 binarySearchValue: binarySearchValue,
13781 easingFunctions: easingFunctions,
13782 getScrollBarWidth: getScrollBarWidth,
13783 topMost: topMost,
13784 randomUUID: uuid4
13785 }); // New API (tree shakeable).
13786
13787 var esm = /*#__PURE__*/Object.freeze({
13788 __proto__: null,
13789 'default': util,
13790 HSVToHex: HSVToHex,
13791 HSVToRGB: HSVToRGB,
13792 RGBToHSV: RGBToHSV,
13793 RGBToHex: RGBToHex,
13794 addClassName: addClassName,
13795 addCssText: addCssText,
13796 addEventListener: addEventListener,
13797 binarySearchCustom: binarySearchCustom,
13798 binarySearchValue: binarySearchValue,
13799 bridgeObject: bridgeObject,
13800 convert: convert,
13801 copyAndExtendArray: copyAndExtendArray,
13802 copyArray: copyArray,
13803 deepExtend: deepExtend,
13804 easingFunctions: easingFunctions,
13805 equalArray: equalArray,
13806 extend: extend,
13807 fillIfDefined: fillIfDefined,
13808 forEach: forEach,
13809 getAbsoluteLeft: getAbsoluteLeft,
13810 getAbsoluteRight: getAbsoluteRight,
13811 getAbsoluteTop: getAbsoluteTop,
13812 getScrollBarWidth: getScrollBarWidth,
13813 getTarget: getTarget,
13814 getType: getType,
13815 hasParent: hasParent,
13816 hexToHSV: hexToHSV,
13817 hexToRGB: hexToRGB,
13818 insertSort: insertSort,
13819 isDate: isDate,
13820 isMoment: isMoment,
13821 isNumber: isNumber,
13822 isObject: isObject$1,
13823 isString: isString,
13824 isValidHex: isValidHex,
13825 isValidRGB: isValidRGB,
13826 isValidRGBA: isValidRGBA,
13827 mergeOptions: mergeOptions,
13828 option: option,
13829 overrideOpacity: overrideOpacity,
13830 parseColor: parseColor,
13831 preventDefault: preventDefault,
13832 randomUUID: uuid4,
13833 recursiveDOMDelete: recursiveDOMDelete,
13834 removeClassName: removeClassName,
13835 removeCssText: removeCssText,
13836 removeEventListener: removeEventListener,
13837 selectiveBridgeObject: selectiveBridgeObject,
13838 selectiveDeepExtend: selectiveDeepExtend,
13839 selectiveExtend: selectiveExtend,
13840 selectiveNotDeepExtend: selectiveNotDeepExtend,
13841 throttle: throttle,
13842 toArray: toArray,
13843 topMost: topMost,
13844 updateProperty: updateProperty
13845 });
13846
13847 var $includes$1 = arrayIncludes.includes;
13848
13849
13850 // `Array.prototype.includes` method
13851 // https://tc39.github.io/ecma262/#sec-array.prototype.includes
13852 _export({ target: 'Array', proto: true }, {
13853 includes: function includes(el /* , fromIndex = 0 */) {
13854 return $includes$1(this, el, arguments.length > 1 ? arguments[1] : undefined);
13855 }
13856 });
13857
13858 // https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
13859 addToUnscopables('includes');
13860
13861 var notARegexp = function (it) {
13862 if (isRegexp(it)) {
13863 throw TypeError("The method doesn't accept regular expressions");
13864 } return it;
13865 };
13866
13867 var MATCH$3 = wellKnownSymbol('match');
13868
13869 var correctIsRegexpLogic = function (METHOD_NAME) {
13870 var regexp = /./;
13871 try {
13872 '/./'[METHOD_NAME](regexp);
13873 } catch (e) {
13874 try {
13875 regexp[MATCH$3] = false;
13876 return '/./'[METHOD_NAME](regexp);
13877 } catch (f) { /* empty */ }
13878 } return false;
13879 };
13880
13881 // `String.prototype.includes` method
13882 // https://tc39.github.io/ecma262/#sec-string.prototype.includes
13883 _export({ target: 'String', proto: true, forced: !correctIsRegexpLogic('includes') }, {
13884 includes: function includes(searchString /* , position = 0 */) {
13885 return !!~String(requireObjectCoercible(this))
13886 .indexOf(notARegexp(searchString), arguments.length > 1 ? arguments[1] : undefined);
13887 }
13888 });
13889
13890 /**
13891 * Parse a text source containing data in DOT language into a JSON object.
13892 * The object contains two lists: one with nodes and one with edges.
13893 *
13894 * DOT language reference: http://www.graphviz.org/doc/info/lang.html
13895 *
13896 * DOT language attributes: http://graphviz.org/content/attrs
13897 *
13898 * @param {string} data Text containing a graph in DOT-notation
13899 * @return {Object} graph An object containing two parameters:
13900 * {Object[]} nodes
13901 * {Object[]} edges
13902 *
13903 * -------------------------------------------
13904 * TODO
13905 * ====
13906 *
13907 * For label handling, this is an incomplete implementation. From docs (quote #3015):
13908 *
13909 * > the escape sequences "\n", "\l" and "\r" divide the label into lines, centered,
13910 * > left-justified, and right-justified, respectively.
13911 *
13912 * Source: http://www.graphviz.org/content/attrs#kescString
13913 *
13914 * > As another aid for readability, dot allows double-quoted strings to span multiple physical
13915 * > lines using the standard C convention of a backslash immediately preceding a newline
13916 * > character
13917 * > In addition, double-quoted strings can be concatenated using a '+' operator.
13918 * > As HTML strings can contain newline characters, which are used solely for formatting,
13919 * > the language does not allow escaped newlines or concatenation operators to be used
13920 * > within them.
13921 *
13922 * - Currently, only '\\n' is handled
13923 * - Note that text explicitly says 'labels'; the dot parser currently handles escape
13924 * sequences in **all** strings.
13925 */
13926 function parseDOT(data) {
13927 dot = data;
13928 return parseGraph();
13929 } // mapping of attributes from DOT (the keys) to vis.js (the values)
13930
13931
13932 var NODE_ATTR_MAPPING = {
13933 'fontsize': 'font.size',
13934 'fontcolor': 'font.color',
13935 'labelfontcolor': 'font.color',
13936 'fontname': 'font.face',
13937 'color': ['color.border', 'color.background'],
13938 'fillcolor': 'color.background',
13939 'tooltip': 'title',
13940 'labeltooltip': 'title'
13941 };
13942 var EDGE_ATTR_MAPPING = Object.create(NODE_ATTR_MAPPING);
13943 EDGE_ATTR_MAPPING.color = 'color.color';
13944 EDGE_ATTR_MAPPING.style = 'dashes'; // token types enumeration
13945
13946 var TOKENTYPE = {
13947 NULL: 0,
13948 DELIMITER: 1,
13949 IDENTIFIER: 2,
13950 UNKNOWN: 3
13951 }; // map with all delimiters
13952
13953 var DELIMITERS = {
13954 '{': true,
13955 '}': true,
13956 '[': true,
13957 ']': true,
13958 ';': true,
13959 '=': true,
13960 ',': true,
13961 '->': true,
13962 '--': true
13963 };
13964 var dot = ''; // current dot file
13965
13966 var index$1 = 0; // current index in dot file
13967
13968 var c = ''; // current token character in expr
13969
13970 var token = ''; // current token
13971
13972 var tokenType = TOKENTYPE.NULL; // type of the token
13973
13974 /**
13975 * Get the first character from the dot file.
13976 * The character is stored into the char c. If the end of the dot file is
13977 * reached, the function puts an empty string in c.
13978 */
13979
13980 function first() {
13981 index$1 = 0;
13982 c = dot.charAt(0);
13983 }
13984 /**
13985 * Get the next character from the dot file.
13986 * The character is stored into the char c. If the end of the dot file is
13987 * reached, the function puts an empty string in c.
13988 */
13989
13990
13991 function next() {
13992 index$1++;
13993 c = dot.charAt(index$1);
13994 }
13995 /**
13996 * Preview the next character from the dot file.
13997 * @return {string} cNext
13998 */
13999
14000
14001 function nextPreview() {
14002 return dot.charAt(index$1 + 1);
14003 }
14004
14005 var regexAlphaNumeric = /[a-zA-Z_0-9.:#]/;
14006 /**
14007 * Test whether given character is alphabetic or numeric
14008 * @param {string} c
14009 * @return {Boolean} isAlphaNumeric
14010 */
14011
14012 function isAlphaNumeric(c) {
14013 return regexAlphaNumeric.test(c);
14014 }
14015 /**
14016 * Merge all options of object b into object b
14017 * @param {Object} a
14018 * @param {Object} b
14019 * @return {Object} a
14020 */
14021
14022
14023 function merge(a, b) {
14024 if (!a) {
14025 a = {};
14026 }
14027
14028 if (b) {
14029 for (var name in b) {
14030 if (b.hasOwnProperty(name)) {
14031 a[name] = b[name];
14032 }
14033 }
14034 }
14035
14036 return a;
14037 }
14038 /**
14039 * Set a value in an object, where the provided parameter name can be a
14040 * path with nested parameters. For example:
14041 *
14042 * var obj = {a: 2};
14043 * setValue(obj, 'b.c', 3); // obj = {a: 2, b: {c: 3}}
14044 *
14045 * @param {Object} obj
14046 * @param {string} path A parameter name or dot-separated parameter path,
14047 * like "color.highlight.border".
14048 * @param {*} value
14049 */
14050
14051
14052 function setValue(obj, path, value) {
14053 var keys = path.split('.');
14054 var o = obj;
14055
14056 while (keys.length) {
14057 var key = keys.shift();
14058
14059 if (keys.length) {
14060 // this isn't the end point
14061 if (!o[key]) {
14062 o[key] = {};
14063 }
14064
14065 o = o[key];
14066 } else {
14067 // this is the end point
14068 o[key] = value;
14069 }
14070 }
14071 }
14072 /**
14073 * Add a node to a graph object. If there is already a node with
14074 * the same id, their attributes will be merged.
14075 * @param {Object} graph
14076 * @param {Object} node
14077 */
14078
14079
14080 function addNode(graph, node) {
14081 var i, len;
14082 var current = null; // find root graph (in case of subgraph)
14083
14084 var graphs = [graph]; // list with all graphs from current graph to root graph
14085
14086 var root = graph;
14087
14088 while (root.parent) {
14089 graphs.push(root.parent);
14090 root = root.parent;
14091 } // find existing node (at root level) by its id
14092
14093
14094 if (root.nodes) {
14095 for (i = 0, len = root.nodes.length; i < len; i++) {
14096 if (node.id === root.nodes[i].id) {
14097 current = root.nodes[i];
14098 break;
14099 }
14100 }
14101 }
14102
14103 if (!current) {
14104 // this is a new node
14105 current = {
14106 id: node.id
14107 };
14108
14109 if (graph.node) {
14110 // clone default attributes
14111 current.attr = merge(current.attr, graph.node);
14112 }
14113 } // add node to this (sub)graph and all its parent graphs
14114
14115
14116 for (i = graphs.length - 1; i >= 0; i--) {
14117 var g = graphs[i];
14118
14119 if (!g.nodes) {
14120 g.nodes = [];
14121 }
14122
14123 if (g.nodes.indexOf(current) === -1) {
14124 g.nodes.push(current);
14125 }
14126 } // merge attributes
14127
14128
14129 if (node.attr) {
14130 current.attr = merge(current.attr, node.attr);
14131 }
14132 }
14133 /**
14134 * Add an edge to a graph object
14135 * @param {Object} graph
14136 * @param {Object} edge
14137 */
14138
14139
14140 function addEdge(graph, edge) {
14141 if (!graph.edges) {
14142 graph.edges = [];
14143 }
14144
14145 graph.edges.push(edge);
14146
14147 if (graph.edge) {
14148 var attr = merge({}, graph.edge); // clone default attributes
14149
14150 edge.attr = merge(attr, edge.attr); // merge attributes
14151 }
14152 }
14153 /**
14154 * Create an edge to a graph object
14155 * @param {Object} graph
14156 * @param {string | number | Object} from
14157 * @param {string | number | Object} to
14158 * @param {string} type
14159 * @param {Object | null} attr
14160 * @return {Object} edge
14161 */
14162
14163
14164 function createEdge(graph, from, to, type, attr) {
14165 var edge = {
14166 from: from,
14167 to: to,
14168 type: type
14169 };
14170
14171 if (graph.edge) {
14172 edge.attr = merge({}, graph.edge); // clone default attributes
14173 }
14174
14175 edge.attr = merge(edge.attr || {}, attr); // merge attributes
14176 // Move arrows attribute from attr to edge temporally created in
14177 // parseAttributeList().
14178
14179 if (attr != null) {
14180 if (attr.hasOwnProperty('arrows') && attr['arrows'] != null) {
14181 edge['arrows'] = {
14182 to: {
14183 enabled: true,
14184 type: attr.arrows.type
14185 }
14186 };
14187 attr['arrows'] = null;
14188 }
14189 }
14190
14191 return edge;
14192 }
14193 /**
14194 * Get next token in the current dot file.
14195 * The token and token type are available as token and tokenType
14196 */
14197
14198
14199 function getToken() {
14200 tokenType = TOKENTYPE.NULL;
14201 token = ''; // skip over whitespaces
14202
14203 while (c === ' ' || c === '\t' || c === '\n' || c === '\r') {
14204 // space, tab, enter
14205 next();
14206 }
14207
14208 do {
14209 var isComment = false; // skip comment
14210
14211 if (c === '#') {
14212 // find the previous non-space character
14213 var i = index$1 - 1;
14214
14215 while (dot.charAt(i) === ' ' || dot.charAt(i) === '\t') {
14216 i--;
14217 }
14218
14219 if (dot.charAt(i) === '\n' || dot.charAt(i) === '') {
14220 // the # is at the start of a line, this is indeed a line comment
14221 while (c != '' && c != '\n') {
14222 next();
14223 }
14224
14225 isComment = true;
14226 }
14227 }
14228
14229 if (c === '/' && nextPreview() === '/') {
14230 // skip line comment
14231 while (c != '' && c != '\n') {
14232 next();
14233 }
14234
14235 isComment = true;
14236 }
14237
14238 if (c === '/' && nextPreview() === '*') {
14239 // skip block comment
14240 while (c != '') {
14241 if (c === '*' && nextPreview() === '/') {
14242 // end of block comment found. skip these last two characters
14243 next();
14244 next();
14245 break;
14246 } else {
14247 next();
14248 }
14249 }
14250
14251 isComment = true;
14252 } // skip over whitespaces
14253
14254
14255 while (c === ' ' || c === '\t' || c === '\n' || c === '\r') {
14256 // space, tab, enter
14257 next();
14258 }
14259 } while (isComment); // check for end of dot file
14260
14261
14262 if (c === '') {
14263 // token is still empty
14264 tokenType = TOKENTYPE.DELIMITER;
14265 return;
14266 } // check for delimiters consisting of 2 characters
14267
14268
14269 var c2 = c + nextPreview();
14270
14271 if (DELIMITERS[c2]) {
14272 tokenType = TOKENTYPE.DELIMITER;
14273 token = c2;
14274 next();
14275 next();
14276 return;
14277 } // check for delimiters consisting of 1 character
14278
14279
14280 if (DELIMITERS[c]) {
14281 tokenType = TOKENTYPE.DELIMITER;
14282 token = c;
14283 next();
14284 return;
14285 } // check for an identifier (number or string)
14286 // TODO: more precise parsing of numbers/strings (and the port separator ':')
14287
14288
14289 if (isAlphaNumeric(c) || c === '-') {
14290 token += c;
14291 next();
14292
14293 while (isAlphaNumeric(c)) {
14294 token += c;
14295 next();
14296 }
14297
14298 if (token === 'false') {
14299 token = false; // convert to boolean
14300 } else if (token === 'true') {
14301 token = true; // convert to boolean
14302 } else if (!isNaN(Number(token))) {
14303 token = Number(token); // convert to number
14304 }
14305
14306 tokenType = TOKENTYPE.IDENTIFIER;
14307 return;
14308 } // check for a string enclosed by double quotes
14309
14310
14311 if (c === '"') {
14312 next();
14313
14314 while (c != '' && (c != '"' || c === '"' && nextPreview() === '"')) {
14315 if (c === '"') {
14316 // skip the escape character
14317 token += c;
14318 next();
14319 } else if (c === '\\' && nextPreview() === 'n') {
14320 // Honor a newline escape sequence
14321 token += '\n';
14322 next();
14323 } else {
14324 token += c;
14325 }
14326
14327 next();
14328 }
14329
14330 if (c != '"') {
14331 throw newSyntaxError('End of string " expected');
14332 }
14333
14334 next();
14335 tokenType = TOKENTYPE.IDENTIFIER;
14336 return;
14337 } // something unknown is found, wrong characters, a syntax error
14338
14339
14340 tokenType = TOKENTYPE.UNKNOWN;
14341
14342 while (c != '') {
14343 token += c;
14344 next();
14345 }
14346
14347 throw new SyntaxError('Syntax error in part "' + chop(token, 30) + '"');
14348 }
14349 /**
14350 * Parse a graph.
14351 * @returns {Object} graph
14352 */
14353
14354
14355 function parseGraph() {
14356 var graph = {};
14357 first();
14358 getToken(); // optional strict keyword
14359
14360 if (token === 'strict') {
14361 graph.strict = true;
14362 getToken();
14363 } // graph or digraph keyword
14364
14365
14366 if (token === 'graph' || token === 'digraph') {
14367 graph.type = token;
14368 getToken();
14369 } // optional graph id
14370
14371
14372 if (tokenType === TOKENTYPE.IDENTIFIER) {
14373 graph.id = token;
14374 getToken();
14375 } // open angle bracket
14376
14377
14378 if (token != '{') {
14379 throw newSyntaxError('Angle bracket { expected');
14380 }
14381
14382 getToken(); // statements
14383
14384 parseStatements(graph); // close angle bracket
14385
14386 if (token != '}') {
14387 throw newSyntaxError('Angle bracket } expected');
14388 }
14389
14390 getToken(); // end of file
14391
14392 if (token !== '') {
14393 throw newSyntaxError('End of file expected');
14394 }
14395
14396 getToken(); // remove temporary default options
14397
14398 delete graph.node;
14399 delete graph.edge;
14400 delete graph.graph;
14401 return graph;
14402 }
14403 /**
14404 * Parse a list with statements.
14405 * @param {Object} graph
14406 */
14407
14408
14409 function parseStatements(graph) {
14410 while (token !== '' && token != '}') {
14411 parseStatement(graph);
14412
14413 if (token === ';') {
14414 getToken();
14415 }
14416 }
14417 }
14418 /**
14419 * Parse a single statement. Can be a an attribute statement, node
14420 * statement, a series of node statements and edge statements, or a
14421 * parameter.
14422 * @param {Object} graph
14423 */
14424
14425
14426 function parseStatement(graph) {
14427 // parse subgraph
14428 var subgraph = parseSubgraph(graph);
14429
14430 if (subgraph) {
14431 // edge statements
14432 parseEdge(graph, subgraph);
14433 return;
14434 } // parse an attribute statement
14435
14436
14437 var attr = parseAttributeStatement(graph);
14438
14439 if (attr) {
14440 return;
14441 } // parse node
14442
14443
14444 if (tokenType != TOKENTYPE.IDENTIFIER) {
14445 throw newSyntaxError('Identifier expected');
14446 }
14447
14448 var id = token; // id can be a string or a number
14449
14450 getToken();
14451
14452 if (token === '=') {
14453 // id statement
14454 getToken();
14455
14456 if (tokenType != TOKENTYPE.IDENTIFIER) {
14457 throw newSyntaxError('Identifier expected');
14458 }
14459
14460 graph[id] = token;
14461 getToken(); // TODO: implement comma separated list with "a_list: ID=ID [','] [a_list] "
14462 } else {
14463 parseNodeStatement(graph, id);
14464 }
14465 }
14466 /**
14467 * Parse a subgraph
14468 * @param {Object} graph parent graph object
14469 * @return {Object | null} subgraph
14470 */
14471
14472
14473 function parseSubgraph(graph) {
14474 var subgraph = null; // optional subgraph keyword
14475
14476 if (token === 'subgraph') {
14477 subgraph = {};
14478 subgraph.type = 'subgraph';
14479 getToken(); // optional graph id
14480
14481 if (tokenType === TOKENTYPE.IDENTIFIER) {
14482 subgraph.id = token;
14483 getToken();
14484 }
14485 } // open angle bracket
14486
14487
14488 if (token === '{') {
14489 getToken();
14490
14491 if (!subgraph) {
14492 subgraph = {};
14493 }
14494
14495 subgraph.parent = graph;
14496 subgraph.node = graph.node;
14497 subgraph.edge = graph.edge;
14498 subgraph.graph = graph.graph; // statements
14499
14500 parseStatements(subgraph); // close angle bracket
14501
14502 if (token != '}') {
14503 throw newSyntaxError('Angle bracket } expected');
14504 }
14505
14506 getToken(); // remove temporary default options
14507
14508 delete subgraph.node;
14509 delete subgraph.edge;
14510 delete subgraph.graph;
14511 delete subgraph.parent; // register at the parent graph
14512
14513 if (!graph.subgraphs) {
14514 graph.subgraphs = [];
14515 }
14516
14517 graph.subgraphs.push(subgraph);
14518 }
14519
14520 return subgraph;
14521 }
14522 /**
14523 * parse an attribute statement like "node [shape=circle fontSize=16]".
14524 * Available keywords are 'node', 'edge', 'graph'.
14525 * The previous list with default attributes will be replaced
14526 * @param {Object} graph
14527 * @returns {String | null} keyword Returns the name of the parsed attribute
14528 * (node, edge, graph), or null if nothing
14529 * is parsed.
14530 */
14531
14532
14533 function parseAttributeStatement(graph) {
14534 // attribute statements
14535 if (token === 'node') {
14536 getToken(); // node attributes
14537
14538 graph.node = parseAttributeList();
14539 return 'node';
14540 } else if (token === 'edge') {
14541 getToken(); // edge attributes
14542
14543 graph.edge = parseAttributeList();
14544 return 'edge';
14545 } else if (token === 'graph') {
14546 getToken(); // graph attributes
14547
14548 graph.graph = parseAttributeList();
14549 return 'graph';
14550 }
14551
14552 return null;
14553 }
14554 /**
14555 * parse a node statement
14556 * @param {Object} graph
14557 * @param {string | number} id
14558 */
14559
14560
14561 function parseNodeStatement(graph, id) {
14562 // node statement
14563 var node = {
14564 id: id
14565 };
14566 var attr = parseAttributeList();
14567
14568 if (attr) {
14569 node.attr = attr;
14570 }
14571
14572 addNode(graph, node); // edge statements
14573
14574 parseEdge(graph, id);
14575 }
14576 /**
14577 * Parse an edge or a series of edges
14578 * @param {Object} graph
14579 * @param {string | number} from Id of the from node
14580 */
14581
14582
14583 function parseEdge(graph, from) {
14584 while (token === '->' || token === '--') {
14585 var to;
14586 var type = token;
14587 getToken();
14588 var subgraph = parseSubgraph(graph);
14589
14590 if (subgraph) {
14591 to = subgraph;
14592 } else {
14593 if (tokenType != TOKENTYPE.IDENTIFIER) {
14594 throw newSyntaxError('Identifier or subgraph expected');
14595 }
14596
14597 to = token;
14598 addNode(graph, {
14599 id: to
14600 });
14601 getToken();
14602 } // parse edge attributes
14603
14604
14605 var attr = parseAttributeList(); // create edge
14606
14607 var edge = createEdge(graph, from, to, type, attr);
14608 addEdge(graph, edge);
14609 from = to;
14610 }
14611 }
14612 /**
14613 * Parse a set with attributes,
14614 * for example [label="1.000", shape=solid]
14615 * @return {Object | null} attr
14616 */
14617
14618
14619 function parseAttributeList() {
14620 var i;
14621 var attr = null; // edge styles of dot and vis
14622
14623 var edgeStyles = {
14624 'dashed': true,
14625 'solid': false,
14626 'dotted': [1, 5]
14627 };
14628 /**
14629 * Define arrow types.
14630 * vis currently supports types defined in 'arrowTypes'.
14631 * Details of arrow shapes are described in
14632 * http://www.graphviz.org/content/arrow-shapes
14633 */
14634
14635 var arrowTypes = {
14636 dot: 'circle',
14637 box: 'box',
14638 crow: 'crow',
14639 curve: 'curve',
14640 icurve: 'inv_curve',
14641 normal: 'triangle',
14642 inv: 'inv_triangle',
14643 diamond: 'diamond',
14644 tee: 'bar',
14645 vee: 'vee'
14646 };
14647 /**
14648 * 'attr_list' contains attributes for checking if some of them are affected
14649 * later. For instance, both of 'arrowhead' and 'dir' (edge style defined
14650 * in DOT) make changes to 'arrows' attribute in vis.
14651 */
14652
14653 var attr_list = new Array();
14654 var attr_names = new Array(); // used for checking the case.
14655 // parse attributes
14656
14657 while (token === '[') {
14658 getToken();
14659 attr = {};
14660
14661 while (token !== '' && token != ']') {
14662 if (tokenType != TOKENTYPE.IDENTIFIER) {
14663 throw newSyntaxError('Attribute name expected');
14664 }
14665
14666 var name = token;
14667 getToken();
14668
14669 if (token != '=') {
14670 throw newSyntaxError('Equal sign = expected');
14671 }
14672
14673 getToken();
14674
14675 if (tokenType != TOKENTYPE.IDENTIFIER) {
14676 throw newSyntaxError('Attribute value expected');
14677 }
14678
14679 var value = token; // convert from dot style to vis
14680
14681 if (name === 'style') {
14682 value = edgeStyles[value];
14683 }
14684
14685 var arrowType;
14686
14687 if (name === 'arrowhead') {
14688 arrowType = arrowTypes[value];
14689 name = 'arrows';
14690 value = {
14691 'to': {
14692 'enabled': true,
14693 'type': arrowType
14694 }
14695 };
14696 }
14697
14698 if (name === 'arrowtail') {
14699 arrowType = arrowTypes[value];
14700 name = 'arrows';
14701 value = {
14702 'from': {
14703 'enabled': true,
14704 'type': arrowType
14705 }
14706 };
14707 }
14708
14709 attr_list.push({
14710 'attr': attr,
14711 'name': name,
14712 'value': value
14713 });
14714 attr_names.push(name);
14715 getToken();
14716
14717 if (token == ',') {
14718 getToken();
14719 }
14720 }
14721
14722 if (token != ']') {
14723 throw newSyntaxError('Bracket ] expected');
14724 }
14725
14726 getToken();
14727 }
14728 /**
14729 * As explained in [1], graphviz has limitations for combination of
14730 * arrow[head|tail] and dir. If attribute list includes 'dir',
14731 * following cases just be supported.
14732 * 1. both or none + arrowhead, arrowtail
14733 * 2. forward + arrowhead (arrowtail is not affedted)
14734 * 3. back + arrowtail (arrowhead is not affected)
14735 * [1] https://www.graphviz.org/doc/info/attrs.html#h:undir_note
14736 */
14737
14738
14739 if (attr_names.includes('dir')) {
14740 var idx = {}; // get index of 'arrows' and 'dir'
14741
14742 idx.arrows = {};
14743
14744 for (i = 0; i < attr_list.length; i++) {
14745 if (attr_list[i].name === 'arrows') {
14746 if (attr_list[i].value.to != null) {
14747 idx.arrows.to = i;
14748 } else if (attr_list[i].value.from != null) {
14749 idx.arrows.from = i;
14750 } else {
14751 throw newSyntaxError('Invalid value of arrows');
14752 }
14753 } else if (attr_list[i].name === 'dir') {
14754 idx.dir = i;
14755 }
14756 } // first, add default arrow shape if it is not assigned to avoid error
14757
14758
14759 var dir_type = attr_list[idx.dir].value;
14760
14761 if (!attr_names.includes('arrows')) {
14762 if (dir_type === 'both') {
14763 attr_list.push({
14764 'attr': attr_list[idx.dir].attr,
14765 'name': 'arrows',
14766 'value': {
14767 to: {
14768 enabled: true
14769 }
14770 }
14771 });
14772 idx.arrows.to = attr_list.length - 1;
14773 attr_list.push({
14774 'attr': attr_list[idx.dir].attr,
14775 'name': 'arrows',
14776 'value': {
14777 from: {
14778 enabled: true
14779 }
14780 }
14781 });
14782 idx.arrows.from = attr_list.length - 1;
14783 } else if (dir_type === 'forward') {
14784 attr_list.push({
14785 'attr': attr_list[idx.dir].attr,
14786 'name': 'arrows',
14787 'value': {
14788 to: {
14789 enabled: true
14790 }
14791 }
14792 });
14793 idx.arrows.to = attr_list.length - 1;
14794 } else if (dir_type === 'back') {
14795 attr_list.push({
14796 'attr': attr_list[idx.dir].attr,
14797 'name': 'arrows',
14798 'value': {
14799 from: {
14800 enabled: true
14801 }
14802 }
14803 });
14804 idx.arrows.from = attr_list.length - 1;
14805 } else if (dir_type === 'none') {
14806 attr_list.push({
14807 'attr': attr_list[idx.dir].attr,
14808 'name': 'arrows',
14809 'value': ''
14810 });
14811 idx.arrows.to = attr_list.length - 1;
14812 } else {
14813 throw newSyntaxError('Invalid dir type "' + dir_type + '"');
14814 }
14815 }
14816
14817 var from_type;
14818 var to_type; // update 'arrows' attribute from 'dir'.
14819
14820 if (dir_type === 'both') {
14821 // both of shapes of 'from' and 'to' are given
14822 if (idx.arrows.to && idx.arrows.from) {
14823 to_type = attr_list[idx.arrows.to].value.to.type;
14824 from_type = attr_list[idx.arrows.from].value.from.type;
14825 attr_list[idx.arrows.to] = {
14826 'attr': attr_list[idx.arrows.to].attr,
14827 'name': attr_list[idx.arrows.to].name,
14828 'value': {
14829 to: {
14830 enabled: true,
14831 type: to_type
14832 },
14833 from: {
14834 enabled: true,
14835 type: from_type
14836 }
14837 }
14838 };
14839 attr_list.splice(idx.arrows.from, 1); // shape of 'to' is assigned and use default to 'from'
14840 } else if (idx.arrows.to) {
14841 to_type = attr_list[idx.arrows.to].value.to.type;
14842 from_type = 'arrow';
14843 attr_list[idx.arrows.to] = {
14844 'attr': attr_list[idx.arrows.to].attr,
14845 'name': attr_list[idx.arrows.to].name,
14846 'value': {
14847 to: {
14848 enabled: true,
14849 type: to_type
14850 },
14851 from: {
14852 enabled: true,
14853 type: from_type
14854 }
14855 }
14856 }; // only shape of 'from' is assigned and use default for 'to'
14857 } else if (idx.arrows.from) {
14858 to_type = 'arrow';
14859 from_type = attr_list[idx.arrows.from].value.from.type;
14860 attr_list[idx.arrows.from] = {
14861 'attr': attr_list[idx.arrows.from].attr,
14862 'name': attr_list[idx.arrows.from].name,
14863 'value': {
14864 to: {
14865 enabled: true,
14866 type: to_type
14867 },
14868 from: {
14869 enabled: true,
14870 type: from_type
14871 }
14872 }
14873 };
14874 }
14875 } else if (dir_type === 'back') {
14876 // given both of shapes, but use only 'from'
14877 if (idx.arrows.to && idx.arrows.from) {
14878 to_type = '';
14879 from_type = attr_list[idx.arrows.from].value.from.type;
14880 attr_list[idx.arrows.from] = {
14881 'attr': attr_list[idx.arrows.from].attr,
14882 'name': attr_list[idx.arrows.from].name,
14883 'value': {
14884 to: {
14885 enabled: true,
14886 type: to_type
14887 },
14888 from: {
14889 enabled: true,
14890 type: from_type
14891 }
14892 }
14893 }; // given shape of 'to', but does not use it
14894 } else if (idx.arrows.to) {
14895 to_type = '';
14896 from_type = 'arrow';
14897 idx.arrows.from = idx.arrows.to;
14898 attr_list[idx.arrows.from] = {
14899 'attr': attr_list[idx.arrows.from].attr,
14900 'name': attr_list[idx.arrows.from].name,
14901 'value': {
14902 to: {
14903 enabled: true,
14904 type: to_type
14905 },
14906 from: {
14907 enabled: true,
14908 type: from_type
14909 }
14910 }
14911 }; // assign given 'from' shape
14912 } else if (idx.arrows.from) {
14913 to_type = '';
14914 from_type = attr_list[idx.arrows.from].value.from.type;
14915 attr_list[idx.arrows.to] = {
14916 'attr': attr_list[idx.arrows.from].attr,
14917 'name': attr_list[idx.arrows.from].name,
14918 'value': {
14919 to: {
14920 enabled: true,
14921 type: to_type
14922 },
14923 from: {
14924 enabled: true,
14925 type: from_type
14926 }
14927 }
14928 };
14929 }
14930
14931 attr_list[idx.arrows.from] = {
14932 'attr': attr_list[idx.arrows.from].attr,
14933 'name': attr_list[idx.arrows.from].name,
14934 'value': {
14935 from: {
14936 enabled: true,
14937 type: attr_list[idx.arrows.from].value.from.type
14938 }
14939 }
14940 };
14941 } else if (dir_type === 'none') {
14942 var idx_arrow;
14943
14944 if (idx.arrows.to) {
14945 idx_arrow = idx.arrows.to;
14946 } else {
14947 idx_arrow = idx.arrows.from;
14948 }
14949
14950 attr_list[idx_arrow] = {
14951 'attr': attr_list[idx_arrow].attr,
14952 'name': attr_list[idx_arrow].name,
14953 'value': ''
14954 };
14955 } else if (dir_type === 'forward') {
14956 // given both of shapes, but use only 'to'
14957 if (idx.arrows.to && idx.arrows.from) {
14958 to_type = attr_list[idx.arrows.to].value.to.type;
14959 from_type = '';
14960 attr_list[idx.arrows.to] = {
14961 'attr': attr_list[idx.arrows.to].attr,
14962 'name': attr_list[idx.arrows.to].name,
14963 'value': {
14964 to: {
14965 enabled: true,
14966 type: to_type
14967 },
14968 from: {
14969 enabled: true,
14970 type: from_type
14971 }
14972 }
14973 }; // assign given 'to' shape
14974 } else if (idx.arrows.to) {
14975 to_type = attr_list[idx.arrows.to].value.to.type;
14976 from_type = '';
14977 attr_list[idx.arrows.to] = {
14978 'attr': attr_list[idx.arrows.to].attr,
14979 'name': attr_list[idx.arrows.to].name,
14980 'value': {
14981 to: {
14982 enabled: true,
14983 type: to_type
14984 },
14985 from: {
14986 enabled: true,
14987 type: from_type
14988 }
14989 }
14990 }; // given shape of 'from', but does not use it
14991 } else if (idx.arrows.from) {
14992 to_type = 'arrow';
14993 from_type = '';
14994 idx.arrows.to = idx.arrows.from;
14995 attr_list[idx.arrows.to] = {
14996 'attr': attr_list[idx.arrows.to].attr,
14997 'name': attr_list[idx.arrows.to].name,
14998 'value': {
14999 to: {
15000 enabled: true,
15001 type: to_type
15002 },
15003 from: {
15004 enabled: true,
15005 type: from_type
15006 }
15007 }
15008 };
15009 }
15010
15011 attr_list[idx.arrows.to] = {
15012 'attr': attr_list[idx.arrows.to].attr,
15013 'name': attr_list[idx.arrows.to].name,
15014 'value': {
15015 to: {
15016 enabled: true,
15017 type: attr_list[idx.arrows.to].value.to.type
15018 }
15019 }
15020 };
15021 } else {
15022 throw newSyntaxError('Invalid dir type "' + dir_type + '"');
15023 } // remove 'dir' attribute no need anymore
15024
15025
15026 attr_list.splice(idx.dir, 1);
15027 } // parse 'penwidth'
15028
15029
15030 var nof_attr_list;
15031
15032 if (attr_names.includes('penwidth')) {
15033 var tmp_attr_list = [];
15034 nof_attr_list = attr_list.length;
15035
15036 for (i = 0; i < nof_attr_list; i++) {
15037 // exclude 'width' from attr_list if 'penwidth' exists
15038 if (attr_list[i].name !== 'width') {
15039 if (attr_list[i].name === 'penwidth') {
15040 attr_list[i].name = 'width';
15041 }
15042
15043 tmp_attr_list.push(attr_list[i]);
15044 }
15045 }
15046
15047 attr_list = tmp_attr_list;
15048 }
15049
15050 nof_attr_list = attr_list.length;
15051
15052 for (i = 0; i < nof_attr_list; i++) {
15053 setValue(attr_list[i].attr, attr_list[i].name, attr_list[i].value);
15054 }
15055
15056 return attr;
15057 }
15058 /**
15059 * Create a syntax error with extra information on current token and index.
15060 * @param {string} message
15061 * @returns {SyntaxError} err
15062 */
15063
15064
15065 function newSyntaxError(message) {
15066 return new SyntaxError(message + ', got "' + chop(token, 30) + '" (char ' + index$1 + ')');
15067 }
15068 /**
15069 * Chop off text after a maximum length
15070 * @param {string} text
15071 * @param {number} maxLength
15072 * @returns {String}
15073 */
15074
15075
15076 function chop(text, maxLength) {
15077 return text.length <= maxLength ? text : text.substr(0, 27) + '...';
15078 }
15079 /**
15080 * Execute a function fn for each pair of elements in two arrays
15081 * @param {Array | *} array1
15082 * @param {Array | *} array2
15083 * @param {function} fn
15084 */
15085
15086
15087 function forEach2(array1, array2, fn) {
15088 if (Array.isArray(array1)) {
15089 array1.forEach(function (elem1) {
15090 if (Array.isArray(array2)) {
15091 array2.forEach(function (elem2) {
15092 fn(elem1, elem2);
15093 });
15094 } else {
15095 fn(elem1, array2);
15096 }
15097 });
15098 } else {
15099 if (Array.isArray(array2)) {
15100 array2.forEach(function (elem2) {
15101 fn(array1, elem2);
15102 });
15103 } else {
15104 fn(array1, array2);
15105 }
15106 }
15107 }
15108 /**
15109 * Set a nested property on an object
15110 * When nested objects are missing, they will be created.
15111 * For example setProp({}, 'font.color', 'red') will return {font: {color: 'red'}}
15112 * @param {Object} object
15113 * @param {string} path A dot separated string like 'font.color'
15114 * @param {*} value Value for the property
15115 * @return {Object} Returns the original object, allows for chaining.
15116 */
15117
15118
15119 function setProp(object, path, value) {
15120 var names = path.split('.');
15121 var prop = names.pop(); // traverse over the nested objects
15122
15123 var obj = object;
15124
15125 for (var i = 0; i < names.length; i++) {
15126 var name = names[i];
15127
15128 if (!(name in obj)) {
15129 obj[name] = {};
15130 }
15131
15132 obj = obj[name];
15133 } // set the property value
15134
15135
15136 obj[prop] = value;
15137 return object;
15138 }
15139 /**
15140 * Convert an object with DOT attributes to their vis.js equivalents.
15141 * @param {Object} attr Object with DOT attributes
15142 * @param {Object} mapping
15143 * @return {Object} Returns an object with vis.js attributes
15144 */
15145
15146
15147 function convertAttr(attr, mapping) {
15148 var converted = {};
15149
15150 for (var prop in attr) {
15151 if (attr.hasOwnProperty(prop)) {
15152 var visProp = mapping[prop];
15153
15154 if (Array.isArray(visProp)) {
15155 visProp.forEach(function (visPropI) {
15156 setProp(converted, visPropI, attr[prop]);
15157 });
15158 } else if (typeof visProp === 'string') {
15159 setProp(converted, visProp, attr[prop]);
15160 } else {
15161 setProp(converted, prop, attr[prop]);
15162 }
15163 }
15164 }
15165
15166 return converted;
15167 }
15168 /**
15169 * Convert a string containing a graph in DOT language into a map containing
15170 * with nodes and edges in the format of graph.
15171 * @param {string} data Text containing a graph in DOT-notation
15172 * @return {Object} graphData
15173 */
15174
15175
15176 function DOTToGraph(data) {
15177 // parse the DOT file
15178 var dotData = parseDOT(data);
15179 var graphData = {
15180 nodes: [],
15181 edges: [],
15182 options: {}
15183 }; // copy the nodes
15184
15185 if (dotData.nodes) {
15186 dotData.nodes.forEach(function (dotNode) {
15187 var graphNode = {
15188 id: dotNode.id,
15189 label: String(dotNode.label || dotNode.id)
15190 };
15191 merge(graphNode, convertAttr(dotNode.attr, NODE_ATTR_MAPPING));
15192
15193 if (graphNode.image) {
15194 graphNode.shape = 'image';
15195 }
15196
15197 graphData.nodes.push(graphNode);
15198 });
15199 } // copy the edges
15200
15201
15202 if (dotData.edges) {
15203 /**
15204 * Convert an edge in DOT format to an edge with VisGraph format
15205 * @param {Object} dotEdge
15206 * @returns {Object} graphEdge
15207 */
15208 var convertEdge = function convertEdge(dotEdge) {
15209 var graphEdge = {
15210 from: dotEdge.from,
15211 to: dotEdge.to
15212 };
15213 merge(graphEdge, convertAttr(dotEdge.attr, EDGE_ATTR_MAPPING)); // Add arrows attribute to default styled arrow.
15214 // The reason why default style is not added in parseAttributeList() is
15215 // because only default is cleared before here.
15216
15217 if (graphEdge.arrows == null && dotEdge.type === '->') {
15218 graphEdge.arrows = 'to';
15219 }
15220
15221 return graphEdge;
15222 };
15223
15224 dotData.edges.forEach(function (dotEdge) {
15225 var from, to;
15226
15227 if (dotEdge.from instanceof Object) {
15228 from = dotEdge.from.nodes;
15229 } else {
15230 from = {
15231 id: dotEdge.from
15232 };
15233 }
15234
15235 if (dotEdge.to instanceof Object) {
15236 to = dotEdge.to.nodes;
15237 } else {
15238 to = {
15239 id: dotEdge.to
15240 };
15241 }
15242
15243 if (dotEdge.from instanceof Object && dotEdge.from.edges) {
15244 dotEdge.from.edges.forEach(function (subEdge) {
15245 var graphEdge = convertEdge(subEdge);
15246 graphData.edges.push(graphEdge);
15247 });
15248 }
15249
15250 forEach2(from, to, function (from, to) {
15251 var subEdge = createEdge(graphData, from.id, to.id, dotEdge.type, dotEdge.attr);
15252 var graphEdge = convertEdge(subEdge);
15253 graphData.edges.push(graphEdge);
15254 });
15255
15256 if (dotEdge.to instanceof Object && dotEdge.to.edges) {
15257 dotEdge.to.edges.forEach(function (subEdge) {
15258 var graphEdge = convertEdge(subEdge);
15259 graphData.edges.push(graphEdge);
15260 });
15261 }
15262 });
15263 } // copy the options
15264
15265
15266 if (dotData.attr) {
15267 graphData.options = dotData.attr;
15268 }
15269
15270 return graphData;
15271 } // exports
15272
15273
15274 var parseDOT_1 = parseDOT;
15275 var DOTToGraph_1 = DOTToGraph;
15276 var dotparser = {
15277 parseDOT: parseDOT_1,
15278 DOTToGraph: DOTToGraph_1
15279 };
15280
15281 var dotparser$1 = /*#__PURE__*/Object.freeze({
15282 __proto__: null,
15283 'default': dotparser,
15284 __moduleExports: dotparser,
15285 parseDOT: parseDOT_1,
15286 DOTToGraph: DOTToGraph_1
15287 });
15288
15289 var quot = /"/g;
15290
15291 // B.2.3.2.1 CreateHTML(string, tag, attribute, value)
15292 // https://tc39.github.io/ecma262/#sec-createhtml
15293 var createHtml = function (string, tag, attribute, value) {
15294 var S = String(requireObjectCoercible(string));
15295 var p1 = '<' + tag;
15296 if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '&quot;') + '"';
15297 return p1 + '>' + S + '</' + tag + '>';
15298 };
15299
15300 // check the existence of a method, lowercase
15301 // of a tag and escaping quotes in arguments
15302 var forcedStringHtmlMethod = function (METHOD_NAME) {
15303 return fails(function () {
15304 var test = ''[METHOD_NAME]('"');
15305 return test !== test.toLowerCase() || test.split('"').length > 3;
15306 });
15307 };
15308
15309 // `String.prototype.fixed` method
15310 // https://tc39.github.io/ecma262/#sec-string.prototype.fixed
15311 _export({ target: 'String', proto: true, forced: forcedStringHtmlMethod('fixed') }, {
15312 fixed: function fixed() {
15313 return createHtml(this, 'tt', '', '');
15314 }
15315 });
15316
15317 /**
15318 * Convert Gephi to Vis.
15319 *
15320 * @param gephiJSON - The parsed JSON data in Gephi format.
15321 * @param optionsObj - Additional options.
15322 *
15323 * @returns The converted data ready to be used in Vis.
15324 */
15325 function parseGephi(gephiJSON, optionsObj) {
15326 var options = {
15327 edges: {
15328 inheritColor: false
15329 },
15330 nodes: {
15331 fixed: false,
15332 parseColor: false
15333 }
15334 };
15335
15336 if (optionsObj != null) {
15337 if (optionsObj.fixed != null) {
15338 options.nodes.fixed = optionsObj.fixed;
15339 }
15340
15341 if (optionsObj.parseColor != null) {
15342 options.nodes.parseColor = optionsObj.parseColor;
15343 }
15344
15345 if (optionsObj.inheritColor != null) {
15346 options.edges.inheritColor = optionsObj.inheritColor;
15347 }
15348 }
15349
15350 var gEdges = gephiJSON.edges;
15351 var vEdges = gEdges.map(function (gEdge) {
15352 var vEdge = {
15353 from: gEdge.source,
15354 id: gEdge.id,
15355 to: gEdge.target
15356 };
15357
15358 if (gEdge.attributes != null) {
15359 vEdge.attributes = gEdge.attributes;
15360 }
15361
15362 if (gEdge.label != null) {
15363 vEdge.label = gEdge.label;
15364 }
15365
15366 if (gEdge.attributes != null && gEdge.attributes.title != null) {
15367 vEdge.title = gEdge.attributes.title;
15368 }
15369
15370 if (gEdge.type === 'Directed') {
15371 vEdge.arrows = 'to';
15372 } // edge['value'] = gEdge.attributes != null ? gEdge.attributes.Weight : undefined;
15373 // edge['width'] = edge['value'] != null ? undefined : edgegEdge.size;
15374
15375
15376 if (gEdge.color && options.edges.inheritColor === false) {
15377 vEdge.color = gEdge.color;
15378 }
15379
15380 return vEdge;
15381 });
15382 var vNodes = gephiJSON.nodes.map(function (gNode) {
15383 var vNode = {
15384 id: gNode.id,
15385 fixed: options.nodes.fixed && gNode.x != null && gNode.y != null
15386 };
15387
15388 if (gNode.attributes != null) {
15389 vNode.attributes = gNode.attributes;
15390 }
15391
15392 if (gNode.label != null) {
15393 vNode.label = gNode.label;
15394 }
15395
15396 if (gNode.size != null) {
15397 vNode.size = gNode.size;
15398 }
15399
15400 if (gNode.attributes != null && gNode.attributes.title != null) {
15401 vNode.title = gNode.attributes.title;
15402 }
15403
15404 if (gNode.title != null) {
15405 vNode.title = gNode.title;
15406 }
15407
15408 if (gNode.x != null) {
15409 vNode.x = gNode.x;
15410 }
15411
15412 if (gNode.y != null) {
15413 vNode.y = gNode.y;
15414 }
15415
15416 if (gNode.color != null) {
15417 if (options.nodes.parseColor === true) {
15418 vNode.color = gNode.color;
15419 } else {
15420 vNode.color = {
15421 background: gNode.color,
15422 border: gNode.color,
15423 highlight: {
15424 background: gNode.color,
15425 border: gNode.color
15426 },
15427 hover: {
15428 background: gNode.color,
15429 border: gNode.color
15430 }
15431 };
15432 }
15433 }
15434
15435 return vNode;
15436 });
15437 return {
15438 nodes: vNodes,
15439 edges: vEdges
15440 };
15441 }
15442
15443 var gephiParser = /*#__PURE__*/Object.freeze({
15444 __proto__: null,
15445 parseGephi: parseGephi
15446 });
15447
15448 function styleInject(css, ref) {
15449 if (ref === void 0) ref = {};
15450 var insertAt = ref.insertAt;
15451
15452 if (!css || typeof document === 'undefined') {
15453 return;
15454 }
15455
15456 var head = document.head || document.getElementsByTagName('head')[0];
15457 var style = document.createElement('style');
15458 style.type = 'text/css';
15459
15460 if (insertAt === 'top') {
15461 if (head.firstChild) {
15462 head.insertBefore(style, head.firstChild);
15463 } else {
15464 head.appendChild(style);
15465 }
15466 } else {
15467 head.appendChild(style);
15468 }
15469
15470 if (style.styleSheet) {
15471 style.styleSheet.cssText = css;
15472 } else {
15473 style.appendChild(document.createTextNode(css));
15474 }
15475 }
15476
15477 var css = ".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\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkFjdGl2YXRvci5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSxrQkFBa0I7RUFDbEIsUUFBUTtFQUNSLFVBQVU7RUFDVixXQUFXO0VBQ1gsU0FBUzs7RUFFVCxnRUFBZ0U7RUFDaEUsV0FBVztBQUNiOztBQUVBO0VBQ0UsNEJBQTRCO0FBQzlCIiwiZmlsZSI6IkFjdGl2YXRvci5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIudmlzLW92ZXJsYXkge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMHB4O1xuICByaWdodDogMHB4O1xuICBib3R0b206IDBweDtcbiAgbGVmdDogMHB4O1xuXG4gIC8qIE11c3QgYmUgZGlzcGxheWVkIGFib3ZlIGZvciBleGFtcGxlIHNlbGVjdGVkIFRpbWVsaW5lIGl0ZW1zICovXG4gIHotaW5kZXg6IDEwO1xufVxuXG4udmlzLWFjdGl2ZSB7XG4gIGJveC1zaGFkb3c6IDAgMCAxMHB4ICM4NmQ1Zjg7XG59XG4iXX0= */";
15478 styleInject(css);
15479
15480 var Activator = /*#__PURE__*/Object.freeze({
15481 __proto__: null,
15482 'default': css
15483 });
15484
15485 var keycharm = createCommonjsModule(function (module, exports) {
15486 /**
15487 * Created by Alex on 11/6/2014.
15488 */
15489 // https://github.com/umdjs/umd/blob/master/returnExports.js#L40-L60
15490 // if the module has no dependencies, the above pattern can be simplified to
15491
15492 (function (root, factory) {
15493 {
15494 // Node. Does not work with strict CommonJS, but
15495 // only CommonJS-like environments that support module.exports,
15496 // like Node.
15497 module.exports = factory();
15498 }
15499 })(commonjsGlobal, function () {
15500 function keycharm(options) {
15501 var preventDefault = options && options.preventDefault || false;
15502 var container = options && options.container || window;
15503 var _exportFunctions = {};
15504 var _bound = {
15505 keydown: {},
15506 keyup: {}
15507 };
15508 var _keys = {};
15509 var i; // a - z
15510
15511 for (i = 97; i <= 122; i++) {
15512 _keys[String.fromCharCode(i)] = {
15513 code: 65 + (i - 97),
15514 shift: false
15515 };
15516 } // A - Z
15517
15518
15519 for (i = 65; i <= 90; i++) {
15520 _keys[String.fromCharCode(i)] = {
15521 code: i,
15522 shift: true
15523 };
15524 } // 0 - 9
15525
15526
15527 for (i = 0; i <= 9; i++) {
15528 _keys['' + i] = {
15529 code: 48 + i,
15530 shift: false
15531 };
15532 } // F1 - F12
15533
15534
15535 for (i = 1; i <= 12; i++) {
15536 _keys['F' + i] = {
15537 code: 111 + i,
15538 shift: false
15539 };
15540 } // num0 - num9
15541
15542
15543 for (i = 0; i <= 9; i++) {
15544 _keys['num' + i] = {
15545 code: 96 + i,
15546 shift: false
15547 };
15548 } // numpad misc
15549
15550
15551 _keys['num*'] = {
15552 code: 106,
15553 shift: false
15554 };
15555 _keys['num+'] = {
15556 code: 107,
15557 shift: false
15558 };
15559 _keys['num-'] = {
15560 code: 109,
15561 shift: false
15562 };
15563 _keys['num/'] = {
15564 code: 111,
15565 shift: false
15566 };
15567 _keys['num.'] = {
15568 code: 110,
15569 shift: false
15570 }; // arrows
15571
15572 _keys['left'] = {
15573 code: 37,
15574 shift: false
15575 };
15576 _keys['up'] = {
15577 code: 38,
15578 shift: false
15579 };
15580 _keys['right'] = {
15581 code: 39,
15582 shift: false
15583 };
15584 _keys['down'] = {
15585 code: 40,
15586 shift: false
15587 }; // extra keys
15588
15589 _keys['space'] = {
15590 code: 32,
15591 shift: false
15592 };
15593 _keys['enter'] = {
15594 code: 13,
15595 shift: false
15596 };
15597 _keys['shift'] = {
15598 code: 16,
15599 shift: undefined
15600 };
15601 _keys['esc'] = {
15602 code: 27,
15603 shift: false
15604 };
15605 _keys['backspace'] = {
15606 code: 8,
15607 shift: false
15608 };
15609 _keys['tab'] = {
15610 code: 9,
15611 shift: false
15612 };
15613 _keys['ctrl'] = {
15614 code: 17,
15615 shift: false
15616 };
15617 _keys['alt'] = {
15618 code: 18,
15619 shift: false
15620 };
15621 _keys['delete'] = {
15622 code: 46,
15623 shift: false
15624 };
15625 _keys['pageup'] = {
15626 code: 33,
15627 shift: false
15628 };
15629 _keys['pagedown'] = {
15630 code: 34,
15631 shift: false
15632 }; // symbols
15633
15634 _keys['='] = {
15635 code: 187,
15636 shift: false
15637 };
15638 _keys['-'] = {
15639 code: 189,
15640 shift: false
15641 };
15642 _keys[']'] = {
15643 code: 221,
15644 shift: false
15645 };
15646 _keys['['] = {
15647 code: 219,
15648 shift: false
15649 };
15650
15651 var down = function down(event) {
15652 handleEvent(event, 'keydown');
15653 };
15654
15655 var up = function up(event) {
15656 handleEvent(event, 'keyup');
15657 }; // handle the actualy bound key with the event
15658
15659
15660 var handleEvent = function handleEvent(event, type) {
15661 if (_bound[type][event.keyCode] !== undefined) {
15662 var bound = _bound[type][event.keyCode];
15663
15664 for (var i = 0; i < bound.length; i++) {
15665 if (bound[i].shift === undefined) {
15666 bound[i].fn(event);
15667 } else if (bound[i].shift == true && event.shiftKey == true) {
15668 bound[i].fn(event);
15669 } else if (bound[i].shift == false && event.shiftKey == false) {
15670 bound[i].fn(event);
15671 }
15672 }
15673
15674 if (preventDefault == true) {
15675 event.preventDefault();
15676 }
15677 }
15678 }; // bind a key to a callback
15679
15680
15681 _exportFunctions.bind = function (key, callback, type) {
15682 if (type === undefined) {
15683 type = 'keydown';
15684 }
15685
15686 if (_keys[key] === undefined) {
15687 throw new Error("unsupported key: " + key);
15688 }
15689
15690 if (_bound[type][_keys[key].code] === undefined) {
15691 _bound[type][_keys[key].code] = [];
15692 }
15693
15694 _bound[type][_keys[key].code].push({
15695 fn: callback,
15696 shift: _keys[key].shift
15697 });
15698 }; // bind all keys to a call back (demo purposes)
15699
15700
15701 _exportFunctions.bindAll = function (callback, type) {
15702 if (type === undefined) {
15703 type = 'keydown';
15704 }
15705
15706 for (var key in _keys) {
15707 if (_keys.hasOwnProperty(key)) {
15708 _exportFunctions.bind(key, callback, type);
15709 }
15710 }
15711 }; // get the key label from an event
15712
15713
15714 _exportFunctions.getKey = function (event) {
15715 for (var key in _keys) {
15716 if (_keys.hasOwnProperty(key)) {
15717 if (event.shiftKey == true && _keys[key].shift == true && event.keyCode == _keys[key].code) {
15718 return key;
15719 } else if (event.shiftKey == false && _keys[key].shift == false && event.keyCode == _keys[key].code) {
15720 return key;
15721 } else if (event.keyCode == _keys[key].code && key == 'shift') {
15722 return key;
15723 }
15724 }
15725 }
15726
15727 return "unknown key, currently not supported";
15728 }; // unbind either a specific callback from a key or all of them (by leaving callback undefined)
15729
15730
15731 _exportFunctions.unbind = function (key, callback, type) {
15732 if (type === undefined) {
15733 type = 'keydown';
15734 }
15735
15736 if (_keys[key] === undefined) {
15737 throw new Error("unsupported key: " + key);
15738 }
15739
15740 if (callback !== undefined) {
15741 var newBindings = [];
15742 var bound = _bound[type][_keys[key].code];
15743
15744 if (bound !== undefined) {
15745 for (var i = 0; i < bound.length; i++) {
15746 if (!(bound[i].fn == callback && bound[i].shift == _keys[key].shift)) {
15747 newBindings.push(_bound[type][_keys[key].code][i]);
15748 }
15749 }
15750 }
15751
15752 _bound[type][_keys[key].code] = newBindings;
15753 } else {
15754 _bound[type][_keys[key].code] = [];
15755 }
15756 }; // reset all bound variables.
15757
15758
15759 _exportFunctions.reset = function () {
15760 _bound = {
15761 keydown: {},
15762 keyup: {}
15763 };
15764 }; // unbind all listeners and reset all variables.
15765
15766
15767 _exportFunctions.destroy = function () {
15768 _bound = {
15769 keydown: {},
15770 keyup: {}
15771 };
15772 container.removeEventListener('keydown', down, true);
15773 container.removeEventListener('keyup', up, true);
15774 }; // create listeners.
15775
15776
15777 container.addEventListener('keydown', down, true);
15778 container.addEventListener('keyup', up, true); // return the public functions.
15779
15780 return _exportFunctions;
15781 }
15782
15783 return keycharm;
15784 });
15785 });
15786
15787 /*! Hammer.JS - v2.0.15 - 2019-04-04
15788 * http://naver.github.io/egjs
15789 *
15790 * Forked By Naver egjs
15791 * Copyright (c) hammerjs
15792 * Licensed under the MIT license */
15793 function _extends() {
15794 _extends = Object.assign || function (target) {
15795 for (var i = 1; i < arguments.length; i++) {
15796 var source = arguments[i];
15797
15798 for (var key in source) {
15799 if (Object.prototype.hasOwnProperty.call(source, key)) {
15800 target[key] = source[key];
15801 }
15802 }
15803 }
15804
15805 return target;
15806 };
15807
15808 return _extends.apply(this, arguments);
15809 }
15810
15811 function _inheritsLoose(subClass, superClass) {
15812 subClass.prototype = Object.create(superClass.prototype);
15813 subClass.prototype.constructor = subClass;
15814 subClass.__proto__ = superClass;
15815 }
15816
15817 function _assertThisInitialized$1(self) {
15818 if (self === void 0) {
15819 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
15820 }
15821
15822 return self;
15823 }
15824 /**
15825 * @private
15826 * extend object.
15827 * means that properties in dest will be overwritten by the ones in src.
15828 * @param {Object} target
15829 * @param {...Object} objects_to_assign
15830 * @returns {Object} target
15831 */
15832
15833
15834 var assign;
15835
15836 if (typeof Object.assign !== 'function') {
15837 assign = function assign(target) {
15838 if (target === undefined || target === null) {
15839 throw new TypeError('Cannot convert undefined or null to object');
15840 }
15841
15842 var output = Object(target);
15843
15844 for (var index = 1; index < arguments.length; index++) {
15845 var source = arguments[index];
15846
15847 if (source !== undefined && source !== null) {
15848 for (var nextKey in source) {
15849 if (source.hasOwnProperty(nextKey)) {
15850 output[nextKey] = source[nextKey];
15851 }
15852 }
15853 }
15854 }
15855
15856 return output;
15857 };
15858 } else {
15859 assign = Object.assign;
15860 }
15861
15862 var assign$1 = assign;
15863 var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
15864 var TEST_ELEMENT = typeof document === "undefined" ? {
15865 style: {}
15866 } : document.createElement('div');
15867 var TYPE_FUNCTION = 'function';
15868 var round = Math.round,
15869 abs$2 = Math.abs;
15870 var now = Date.now;
15871 /**
15872 * @private
15873 * get the prefixed property
15874 * @param {Object} obj
15875 * @param {String} property
15876 * @returns {String|Undefined} prefixed
15877 */
15878
15879 function prefixed(obj, property) {
15880 var prefix;
15881 var prop;
15882 var camelProp = property[0].toUpperCase() + property.slice(1);
15883 var i = 0;
15884
15885 while (i < VENDOR_PREFIXES.length) {
15886 prefix = VENDOR_PREFIXES[i];
15887 prop = prefix ? prefix + camelProp : property;
15888
15889 if (prop in obj) {
15890 return prop;
15891 }
15892
15893 i++;
15894 }
15895
15896 return undefined;
15897 }
15898 /* eslint-disable no-new-func, no-nested-ternary */
15899
15900
15901 var win;
15902
15903 if (typeof window === "undefined") {
15904 // window is undefined in node.js
15905 win = {};
15906 } else {
15907 win = window;
15908 }
15909
15910 var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
15911 var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
15912
15913 function getTouchActionProps() {
15914 if (!NATIVE_TOUCH_ACTION) {
15915 return false;
15916 }
15917
15918 var touchMap = {};
15919 var cssSupports = win.CSS && win.CSS.supports;
15920 ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
15921 // If css.supports is not supported but there is native touch-action assume it supports
15922 // all values. This is the case for IE 10 and 11.
15923 return touchMap[val] = cssSupports ? win.CSS.supports('touch-action', val) : true;
15924 });
15925 return touchMap;
15926 }
15927
15928 var TOUCH_ACTION_COMPUTE = 'compute';
15929 var TOUCH_ACTION_AUTO = 'auto';
15930 var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
15931
15932 var TOUCH_ACTION_NONE = 'none';
15933 var TOUCH_ACTION_PAN_X = 'pan-x';
15934 var TOUCH_ACTION_PAN_Y = 'pan-y';
15935 var TOUCH_ACTION_MAP = getTouchActionProps();
15936 var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
15937 var SUPPORT_TOUCH = 'ontouchstart' in win;
15938 var SUPPORT_POINTER_EVENTS = prefixed(win, 'PointerEvent') !== undefined;
15939 var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
15940 var INPUT_TYPE_TOUCH = 'touch';
15941 var INPUT_TYPE_PEN = 'pen';
15942 var INPUT_TYPE_MOUSE = 'mouse';
15943 var INPUT_TYPE_KINECT = 'kinect';
15944 var COMPUTE_INTERVAL = 25;
15945 var INPUT_START = 1;
15946 var INPUT_MOVE = 2;
15947 var INPUT_END = 4;
15948 var INPUT_CANCEL = 8;
15949 var DIRECTION_NONE = 1;
15950 var DIRECTION_LEFT = 2;
15951 var DIRECTION_RIGHT = 4;
15952 var DIRECTION_UP = 8;
15953 var DIRECTION_DOWN = 16;
15954 var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
15955 var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
15956 var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
15957 var PROPS_XY = ['x', 'y'];
15958 var PROPS_CLIENT_XY = ['clientX', 'clientY'];
15959 /**
15960 * @private
15961 * walk objects and arrays
15962 * @param {Object} obj
15963 * @param {Function} iterator
15964 * @param {Object} context
15965 */
15966
15967 function each(obj, iterator, context) {
15968 var i;
15969
15970 if (!obj) {
15971 return;
15972 }
15973
15974 if (obj.forEach) {
15975 obj.forEach(iterator, context);
15976 } else if (obj.length !== undefined) {
15977 i = 0;
15978
15979 while (i < obj.length) {
15980 iterator.call(context, obj[i], i, obj);
15981 i++;
15982 }
15983 } else {
15984 for (i in obj) {
15985 obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
15986 }
15987 }
15988 }
15989 /**
15990 * @private
15991 * let a boolean value also be a function that must return a boolean
15992 * this first item in args will be used as the context
15993 * @param {Boolean|Function} val
15994 * @param {Array} [args]
15995 * @returns {Boolean}
15996 */
15997
15998
15999 function boolOrFn(val, args) {
16000 if (_typeof(val) === TYPE_FUNCTION) {
16001 return val.apply(args ? args[0] || undefined : undefined, args);
16002 }
16003
16004 return val;
16005 }
16006 /**
16007 * @private
16008 * small indexOf wrapper
16009 * @param {String} str
16010 * @param {String} find
16011 * @returns {Boolean} found
16012 */
16013
16014
16015 function inStr(str, find) {
16016 return str.indexOf(find) > -1;
16017 }
16018 /**
16019 * @private
16020 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
16021 * @param {String} actions
16022 * @returns {*}
16023 */
16024
16025
16026 function cleanTouchActions(actions) {
16027 // none
16028 if (inStr(actions, TOUCH_ACTION_NONE)) {
16029 return TOUCH_ACTION_NONE;
16030 }
16031
16032 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
16033 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
16034 // for different directions, e.g. horizontal pan but vertical swipe?)
16035 // we need none (as otherwise with pan-x pan-y combined none of these
16036 // recognizers will work, since the browser would handle all panning
16037
16038 if (hasPanX && hasPanY) {
16039 return TOUCH_ACTION_NONE;
16040 } // pan-x OR pan-y
16041
16042
16043 if (hasPanX || hasPanY) {
16044 return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
16045 } // manipulation
16046
16047
16048 if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
16049 return TOUCH_ACTION_MANIPULATION;
16050 }
16051
16052 return TOUCH_ACTION_AUTO;
16053 }
16054 /**
16055 * @private
16056 * Touch Action
16057 * sets the touchAction property or uses the js alternative
16058 * @param {Manager} manager
16059 * @param {String} value
16060 * @constructor
16061 */
16062
16063
16064 var TouchAction =
16065 /*#__PURE__*/
16066 function () {
16067 function TouchAction(manager, value) {
16068 this.manager = manager;
16069 this.set(value);
16070 }
16071 /**
16072 * @private
16073 * set the touchAction value on the element or enable the polyfill
16074 * @param {String} value
16075 */
16076
16077
16078 var _proto = TouchAction.prototype;
16079
16080 _proto.set = function set(value) {
16081 // find out the touch-action by the event handlers
16082 if (value === TOUCH_ACTION_COMPUTE) {
16083 value = this.compute();
16084 }
16085
16086 if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
16087 this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
16088 }
16089
16090 this.actions = value.toLowerCase().trim();
16091 };
16092 /**
16093 * @private
16094 * just re-set the touchAction value
16095 */
16096
16097
16098 _proto.update = function update() {
16099 this.set(this.manager.options.touchAction);
16100 };
16101 /**
16102 * @private
16103 * compute the value for the touchAction property based on the recognizer's settings
16104 * @returns {String} value
16105 */
16106
16107
16108 _proto.compute = function compute() {
16109 var actions = [];
16110 each(this.manager.recognizers, function (recognizer) {
16111 if (boolOrFn(recognizer.options.enable, [recognizer])) {
16112 actions = actions.concat(recognizer.getTouchAction());
16113 }
16114 });
16115 return cleanTouchActions(actions.join(' '));
16116 };
16117 /**
16118 * @private
16119 * this method is called on each input cycle and provides the preventing of the browser behavior
16120 * @param {Object} input
16121 */
16122
16123
16124 _proto.preventDefaults = function preventDefaults(input) {
16125 var srcEvent = input.srcEvent;
16126 var direction = input.offsetDirection; // if the touch action did prevented once this session
16127
16128 if (this.manager.session.prevented) {
16129 srcEvent.preventDefault();
16130 return;
16131 }
16132
16133 var actions = this.actions;
16134 var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
16135 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
16136 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
16137
16138 if (hasNone) {
16139 // do not prevent defaults if this is a tap gesture
16140 var isTapPointer = input.pointers.length === 1;
16141 var isTapMovement = input.distance < 2;
16142 var isTapTouchTime = input.deltaTime < 250;
16143
16144 if (isTapPointer && isTapMovement && isTapTouchTime) {
16145 return;
16146 }
16147 }
16148
16149 if (hasPanX && hasPanY) {
16150 // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
16151 return;
16152 }
16153
16154 if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
16155 return this.preventSrc(srcEvent);
16156 }
16157 };
16158 /**
16159 * @private
16160 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
16161 * @param {Object} srcEvent
16162 */
16163
16164
16165 _proto.preventSrc = function preventSrc(srcEvent) {
16166 this.manager.session.prevented = true;
16167 srcEvent.preventDefault();
16168 };
16169
16170 return TouchAction;
16171 }();
16172 /**
16173 * @private
16174 * find if a node is in the given parent
16175 * @method hasParent
16176 * @param {HTMLElement} node
16177 * @param {HTMLElement} parent
16178 * @return {Boolean} found
16179 */
16180
16181
16182 function hasParent$1(node, parent) {
16183 while (node) {
16184 if (node === parent) {
16185 return true;
16186 }
16187
16188 node = node.parentNode;
16189 }
16190
16191 return false;
16192 }
16193 /**
16194 * @private
16195 * get the center of all the pointers
16196 * @param {Array} pointers
16197 * @return {Object} center contains `x` and `y` properties
16198 */
16199
16200
16201 function getCenter(pointers) {
16202 var pointersLength = pointers.length; // no need to loop when only one touch
16203
16204 if (pointersLength === 1) {
16205 return {
16206 x: round(pointers[0].clientX),
16207 y: round(pointers[0].clientY)
16208 };
16209 }
16210
16211 var x = 0;
16212 var y = 0;
16213 var i = 0;
16214
16215 while (i < pointersLength) {
16216 x += pointers[i].clientX;
16217 y += pointers[i].clientY;
16218 i++;
16219 }
16220
16221 return {
16222 x: round(x / pointersLength),
16223 y: round(y / pointersLength)
16224 };
16225 }
16226 /**
16227 * @private
16228 * create a simple clone from the input used for storage of firstInput and firstMultiple
16229 * @param {Object} input
16230 * @returns {Object} clonedInputData
16231 */
16232
16233
16234 function simpleCloneInputData(input) {
16235 // make a simple copy of the pointers because we will get a reference if we don't
16236 // we only need clientXY for the calculations
16237 var pointers = [];
16238 var i = 0;
16239
16240 while (i < input.pointers.length) {
16241 pointers[i] = {
16242 clientX: round(input.pointers[i].clientX),
16243 clientY: round(input.pointers[i].clientY)
16244 };
16245 i++;
16246 }
16247
16248 return {
16249 timeStamp: now(),
16250 pointers: pointers,
16251 center: getCenter(pointers),
16252 deltaX: input.deltaX,
16253 deltaY: input.deltaY
16254 };
16255 }
16256 /**
16257 * @private
16258 * calculate the absolute distance between two points
16259 * @param {Object} p1 {x, y}
16260 * @param {Object} p2 {x, y}
16261 * @param {Array} [props] containing x and y keys
16262 * @return {Number} distance
16263 */
16264
16265
16266 function getDistance(p1, p2, props) {
16267 if (!props) {
16268 props = PROPS_XY;
16269 }
16270
16271 var x = p2[props[0]] - p1[props[0]];
16272 var y = p2[props[1]] - p1[props[1]];
16273 return Math.sqrt(x * x + y * y);
16274 }
16275 /**
16276 * @private
16277 * calculate the angle between two coordinates
16278 * @param {Object} p1
16279 * @param {Object} p2
16280 * @param {Array} [props] containing x and y keys
16281 * @return {Number} angle
16282 */
16283
16284
16285 function getAngle(p1, p2, props) {
16286 if (!props) {
16287 props = PROPS_XY;
16288 }
16289
16290 var x = p2[props[0]] - p1[props[0]];
16291 var y = p2[props[1]] - p1[props[1]];
16292 return Math.atan2(y, x) * 180 / Math.PI;
16293 }
16294 /**
16295 * @private
16296 * get the direction between two points
16297 * @param {Number} x
16298 * @param {Number} y
16299 * @return {Number} direction
16300 */
16301
16302
16303 function getDirection(x, y) {
16304 if (x === y) {
16305 return DIRECTION_NONE;
16306 }
16307
16308 if (abs$2(x) >= abs$2(y)) {
16309 return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
16310 }
16311
16312 return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
16313 }
16314
16315 function computeDeltaXY(session, input) {
16316 var center = input.center; // let { offsetDelta:offset = {}, prevDelta = {}, prevInput = {} } = session;
16317 // jscs throwing error on defalut destructured values and without defaults tests fail
16318
16319 var offset = session.offsetDelta || {};
16320 var prevDelta = session.prevDelta || {};
16321 var prevInput = session.prevInput || {};
16322
16323 if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
16324 prevDelta = session.prevDelta = {
16325 x: prevInput.deltaX || 0,
16326 y: prevInput.deltaY || 0
16327 };
16328 offset = session.offsetDelta = {
16329 x: center.x,
16330 y: center.y
16331 };
16332 }
16333
16334 input.deltaX = prevDelta.x + (center.x - offset.x);
16335 input.deltaY = prevDelta.y + (center.y - offset.y);
16336 }
16337 /**
16338 * @private
16339 * calculate the velocity between two points. unit is in px per ms.
16340 * @param {Number} deltaTime
16341 * @param {Number} x
16342 * @param {Number} y
16343 * @return {Object} velocity `x` and `y`
16344 */
16345
16346
16347 function getVelocity(deltaTime, x, y) {
16348 return {
16349 x: x / deltaTime || 0,
16350 y: y / deltaTime || 0
16351 };
16352 }
16353 /**
16354 * @private
16355 * calculate the scale factor between two pointersets
16356 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
16357 * @param {Array} start array of pointers
16358 * @param {Array} end array of pointers
16359 * @return {Number} scale
16360 */
16361
16362
16363 function getScale(start, end) {
16364 return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
16365 }
16366 /**
16367 * @private
16368 * calculate the rotation degrees between two pointersets
16369 * @param {Array} start array of pointers
16370 * @param {Array} end array of pointers
16371 * @return {Number} rotation
16372 */
16373
16374
16375 function getRotation(start, end) {
16376 return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
16377 }
16378 /**
16379 * @private
16380 * velocity is calculated every x ms
16381 * @param {Object} session
16382 * @param {Object} input
16383 */
16384
16385
16386 function computeIntervalInputData(session, input) {
16387 var last = session.lastInterval || input;
16388 var deltaTime = input.timeStamp - last.timeStamp;
16389 var velocity;
16390 var velocityX;
16391 var velocityY;
16392 var direction;
16393
16394 if (input.eventType !== INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
16395 var deltaX = input.deltaX - last.deltaX;
16396 var deltaY = input.deltaY - last.deltaY;
16397 var v = getVelocity(deltaTime, deltaX, deltaY);
16398 velocityX = v.x;
16399 velocityY = v.y;
16400 velocity = abs$2(v.x) > abs$2(v.y) ? v.x : v.y;
16401 direction = getDirection(deltaX, deltaY);
16402 session.lastInterval = input;
16403 } else {
16404 // use latest velocity info if it doesn't overtake a minimum period
16405 velocity = last.velocity;
16406 velocityX = last.velocityX;
16407 velocityY = last.velocityY;
16408 direction = last.direction;
16409 }
16410
16411 input.velocity = velocity;
16412 input.velocityX = velocityX;
16413 input.velocityY = velocityY;
16414 input.direction = direction;
16415 }
16416 /**
16417 * @private
16418 * extend the data with some usable properties like scale, rotate, velocity etc
16419 * @param {Object} manager
16420 * @param {Object} input
16421 */
16422
16423
16424 function computeInputData(manager, input) {
16425 var session = manager.session;
16426 var pointers = input.pointers;
16427 var pointersLength = pointers.length; // store the first input to calculate the distance and direction
16428
16429 if (!session.firstInput) {
16430 session.firstInput = simpleCloneInputData(input);
16431 } // to compute scale and rotation we need to store the multiple touches
16432
16433
16434 if (pointersLength > 1 && !session.firstMultiple) {
16435 session.firstMultiple = simpleCloneInputData(input);
16436 } else if (pointersLength === 1) {
16437 session.firstMultiple = false;
16438 }
16439
16440 var firstInput = session.firstInput,
16441 firstMultiple = session.firstMultiple;
16442 var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
16443 var center = input.center = getCenter(pointers);
16444 input.timeStamp = now();
16445 input.deltaTime = input.timeStamp - firstInput.timeStamp;
16446 input.angle = getAngle(offsetCenter, center);
16447 input.distance = getDistance(offsetCenter, center);
16448 computeDeltaXY(session, input);
16449 input.offsetDirection = getDirection(input.deltaX, input.deltaY);
16450 var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
16451 input.overallVelocityX = overallVelocity.x;
16452 input.overallVelocityY = overallVelocity.y;
16453 input.overallVelocity = abs$2(overallVelocity.x) > abs$2(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
16454 input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
16455 input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
16456 input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
16457 computeIntervalInputData(session, input); // find the correct target
16458
16459 var target = manager.element;
16460
16461 if (hasParent$1(input.srcEvent.target, target)) {
16462 target = input.srcEvent.target;
16463 }
16464
16465 input.target = target;
16466 }
16467 /**
16468 * @private
16469 * handle input events
16470 * @param {Manager} manager
16471 * @param {String} eventType
16472 * @param {Object} input
16473 */
16474
16475
16476 function inputHandler(manager, eventType, input) {
16477 var pointersLen = input.pointers.length;
16478 var changedPointersLen = input.changedPointers.length;
16479 var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
16480 var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
16481 input.isFirst = !!isFirst;
16482 input.isFinal = !!isFinal;
16483
16484 if (isFirst) {
16485 manager.session = {};
16486 } // source event is the normalized value of the domEvents
16487 // like 'touchstart, mouseup, pointerdown'
16488
16489
16490 input.eventType = eventType; // compute scale, rotation etc
16491
16492 computeInputData(manager, input); // emit secret event
16493
16494 manager.emit('hammer.input', input);
16495 manager.recognize(input);
16496 manager.session.prevInput = input;
16497 }
16498 /**
16499 * @private
16500 * split string on whitespace
16501 * @param {String} str
16502 * @returns {Array} words
16503 */
16504
16505
16506 function splitStr(str) {
16507 return str.trim().split(/\s+/g);
16508 }
16509 /**
16510 * @private
16511 * addEventListener with multiple events at once
16512 * @param {EventTarget} target
16513 * @param {String} types
16514 * @param {Function} handler
16515 */
16516
16517
16518 function addEventListeners(target, types, handler) {
16519 each(splitStr(types), function (type) {
16520 target.addEventListener(type, handler, false);
16521 });
16522 }
16523 /**
16524 * @private
16525 * removeEventListener with multiple events at once
16526 * @param {EventTarget} target
16527 * @param {String} types
16528 * @param {Function} handler
16529 */
16530
16531
16532 function removeEventListeners(target, types, handler) {
16533 each(splitStr(types), function (type) {
16534 target.removeEventListener(type, handler, false);
16535 });
16536 }
16537 /**
16538 * @private
16539 * get the window object of an element
16540 * @param {HTMLElement} element
16541 * @returns {DocumentView|Window}
16542 */
16543
16544
16545 function getWindowForElement(element) {
16546 var doc = element.ownerDocument || element;
16547 return doc.defaultView || doc.parentWindow || window;
16548 }
16549 /**
16550 * @private
16551 * create new input type manager
16552 * @param {Manager} manager
16553 * @param {Function} callback
16554 * @returns {Input}
16555 * @constructor
16556 */
16557
16558
16559 var Input =
16560 /*#__PURE__*/
16561 function () {
16562 function Input(manager, callback) {
16563 var self = this;
16564 this.manager = manager;
16565 this.callback = callback;
16566 this.element = manager.element;
16567 this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager,
16568 // so when disabled the input events are completely bypassed.
16569
16570 this.domHandler = function (ev) {
16571 if (boolOrFn(manager.options.enable, [manager])) {
16572 self.handler(ev);
16573 }
16574 };
16575
16576 this.init();
16577 }
16578 /**
16579 * @private
16580 * should handle the inputEvent data and trigger the callback
16581 * @virtual
16582 */
16583
16584
16585 var _proto = Input.prototype;
16586
16587 _proto.handler = function handler() {};
16588 /**
16589 * @private
16590 * bind the events
16591 */
16592
16593
16594 _proto.init = function init() {
16595 this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
16596 this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
16597 this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
16598 };
16599 /**
16600 * @private
16601 * unbind the events
16602 */
16603
16604
16605 _proto.destroy = function destroy() {
16606 this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
16607 this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
16608 this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
16609 };
16610
16611 return Input;
16612 }();
16613 /**
16614 * @private
16615 * find if a array contains the object using indexOf or a simple polyFill
16616 * @param {Array} src
16617 * @param {String} find
16618 * @param {String} [findByKey]
16619 * @return {Boolean|Number} false when not found, or the index
16620 */
16621
16622
16623 function inArray(src, find, findByKey) {
16624 if (src.indexOf && !findByKey) {
16625 return src.indexOf(find);
16626 } else {
16627 var i = 0;
16628
16629 while (i < src.length) {
16630 if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
16631 // do not use === here, test fails
16632 return i;
16633 }
16634
16635 i++;
16636 }
16637
16638 return -1;
16639 }
16640 }
16641
16642 var POINTER_INPUT_MAP = {
16643 pointerdown: INPUT_START,
16644 pointermove: INPUT_MOVE,
16645 pointerup: INPUT_END,
16646 pointercancel: INPUT_CANCEL,
16647 pointerout: INPUT_CANCEL
16648 }; // in IE10 the pointer types is defined as an enum
16649
16650 var IE10_POINTER_TYPE_ENUM = {
16651 2: INPUT_TYPE_TOUCH,
16652 3: INPUT_TYPE_PEN,
16653 4: INPUT_TYPE_MOUSE,
16654 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
16655
16656 };
16657 var POINTER_ELEMENT_EVENTS = 'pointerdown';
16658 var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive
16659
16660 if (win.MSPointerEvent && !win.PointerEvent) {
16661 POINTER_ELEMENT_EVENTS = 'MSPointerDown';
16662 POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
16663 }
16664 /**
16665 * @private
16666 * Pointer events input
16667 * @constructor
16668 * @extends Input
16669 */
16670
16671
16672 var PointerEventInput =
16673 /*#__PURE__*/
16674 function (_Input) {
16675 _inheritsLoose(PointerEventInput, _Input);
16676
16677 function PointerEventInput() {
16678 var _this;
16679
16680 var proto = PointerEventInput.prototype;
16681 proto.evEl = POINTER_ELEMENT_EVENTS;
16682 proto.evWin = POINTER_WINDOW_EVENTS;
16683 _this = _Input.apply(this, arguments) || this;
16684 _this.store = _this.manager.session.pointerEvents = [];
16685 return _this;
16686 }
16687 /**
16688 * @private
16689 * handle mouse events
16690 * @param {Object} ev
16691 */
16692
16693
16694 var _proto = PointerEventInput.prototype;
16695
16696 _proto.handler = function handler(ev) {
16697 var store = this.store;
16698 var removePointer = false;
16699 var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
16700 var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
16701 var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
16702 var isTouch = pointerType === INPUT_TYPE_TOUCH; // get index of the event in the store
16703
16704 var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down
16705
16706 if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
16707 if (storeIndex < 0) {
16708 store.push(ev);
16709 storeIndex = store.length - 1;
16710 }
16711 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
16712 removePointer = true;
16713 } // it not found, so the pointer hasn't been down (so it's probably a hover)
16714
16715
16716 if (storeIndex < 0) {
16717 return;
16718 } // update the event in the store
16719
16720
16721 store[storeIndex] = ev;
16722 this.callback(this.manager, eventType, {
16723 pointers: store,
16724 changedPointers: [ev],
16725 pointerType: pointerType,
16726 srcEvent: ev
16727 });
16728
16729 if (removePointer) {
16730 // remove from the store
16731 store.splice(storeIndex, 1);
16732 }
16733 };
16734
16735 return PointerEventInput;
16736 }(Input);
16737 /**
16738 * @private
16739 * convert array-like objects to real arrays
16740 * @param {Object} obj
16741 * @returns {Array}
16742 */
16743
16744
16745 function toArray$1(obj) {
16746 return Array.prototype.slice.call(obj, 0);
16747 }
16748 /**
16749 * @private
16750 * unique array with objects based on a key (like 'id') or just by the array's value
16751 * @param {Array} src [{id:1},{id:2},{id:1}]
16752 * @param {String} [key]
16753 * @param {Boolean} [sort=False]
16754 * @returns {Array} [{id:1},{id:2}]
16755 */
16756
16757
16758 function uniqueArray(src, key, sort) {
16759 var results = [];
16760 var values = [];
16761 var i = 0;
16762
16763 while (i < src.length) {
16764 var val = key ? src[i][key] : src[i];
16765
16766 if (inArray(values, val) < 0) {
16767 results.push(src[i]);
16768 }
16769
16770 values[i] = val;
16771 i++;
16772 }
16773
16774 if (sort) {
16775 if (!key) {
16776 results = results.sort();
16777 } else {
16778 results = results.sort(function (a, b) {
16779 return a[key] > b[key];
16780 });
16781 }
16782 }
16783
16784 return results;
16785 }
16786
16787 var TOUCH_INPUT_MAP = {
16788 touchstart: INPUT_START,
16789 touchmove: INPUT_MOVE,
16790 touchend: INPUT_END,
16791 touchcancel: INPUT_CANCEL
16792 };
16793 var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
16794 /**
16795 * @private
16796 * Multi-user touch events input
16797 * @constructor
16798 * @extends Input
16799 */
16800
16801 var TouchInput =
16802 /*#__PURE__*/
16803 function (_Input) {
16804 _inheritsLoose(TouchInput, _Input);
16805
16806 function TouchInput() {
16807 var _this;
16808
16809 TouchInput.prototype.evTarget = TOUCH_TARGET_EVENTS;
16810 _this = _Input.apply(this, arguments) || this;
16811 _this.targetIds = {}; // this.evTarget = TOUCH_TARGET_EVENTS;
16812
16813 return _this;
16814 }
16815
16816 var _proto = TouchInput.prototype;
16817
16818 _proto.handler = function handler(ev) {
16819 var type = TOUCH_INPUT_MAP[ev.type];
16820 var touches = getTouches.call(this, ev, type);
16821
16822 if (!touches) {
16823 return;
16824 }
16825
16826 this.callback(this.manager, type, {
16827 pointers: touches[0],
16828 changedPointers: touches[1],
16829 pointerType: INPUT_TYPE_TOUCH,
16830 srcEvent: ev
16831 });
16832 };
16833
16834 return TouchInput;
16835 }(Input);
16836
16837 function getTouches(ev, type) {
16838 var allTouches = toArray$1(ev.touches);
16839 var targetIds = this.targetIds; // when there is only one touch, the process can be simplified
16840
16841 if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
16842 targetIds[allTouches[0].identifier] = true;
16843 return [allTouches, allTouches];
16844 }
16845
16846 var i;
16847 var targetTouches;
16848 var changedTouches = toArray$1(ev.changedTouches);
16849 var changedTargetTouches = [];
16850 var target = this.target; // get target touches from touches
16851
16852 targetTouches = allTouches.filter(function (touch) {
16853 return hasParent$1(touch.target, target);
16854 }); // collect touches
16855
16856 if (type === INPUT_START) {
16857 i = 0;
16858
16859 while (i < targetTouches.length) {
16860 targetIds[targetTouches[i].identifier] = true;
16861 i++;
16862 }
16863 } // filter changed touches to only contain touches that exist in the collected target ids
16864
16865
16866 i = 0;
16867
16868 while (i < changedTouches.length) {
16869 if (targetIds[changedTouches[i].identifier]) {
16870 changedTargetTouches.push(changedTouches[i]);
16871 } // cleanup removed touches
16872
16873
16874 if (type & (INPUT_END | INPUT_CANCEL)) {
16875 delete targetIds[changedTouches[i].identifier];
16876 }
16877
16878 i++;
16879 }
16880
16881 if (!changedTargetTouches.length) {
16882 return;
16883 }
16884
16885 return [// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
16886 uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches];
16887 }
16888
16889 var MOUSE_INPUT_MAP = {
16890 mousedown: INPUT_START,
16891 mousemove: INPUT_MOVE,
16892 mouseup: INPUT_END
16893 };
16894 var MOUSE_ELEMENT_EVENTS = 'mousedown';
16895 var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
16896 /**
16897 * @private
16898 * Mouse events input
16899 * @constructor
16900 * @extends Input
16901 */
16902
16903 var MouseInput =
16904 /*#__PURE__*/
16905 function (_Input) {
16906 _inheritsLoose(MouseInput, _Input);
16907
16908 function MouseInput() {
16909 var _this;
16910
16911 var proto = MouseInput.prototype;
16912 proto.evEl = MOUSE_ELEMENT_EVENTS;
16913 proto.evWin = MOUSE_WINDOW_EVENTS;
16914 _this = _Input.apply(this, arguments) || this;
16915 _this.pressed = false; // mousedown state
16916
16917 return _this;
16918 }
16919 /**
16920 * @private
16921 * handle mouse events
16922 * @param {Object} ev
16923 */
16924
16925
16926 var _proto = MouseInput.prototype;
16927
16928 _proto.handler = function handler(ev) {
16929 var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down
16930
16931 if (eventType & INPUT_START && ev.button === 0) {
16932 this.pressed = true;
16933 }
16934
16935 if (eventType & INPUT_MOVE && ev.which !== 1) {
16936 eventType = INPUT_END;
16937 } // mouse must be down
16938
16939
16940 if (!this.pressed) {
16941 return;
16942 }
16943
16944 if (eventType & INPUT_END) {
16945 this.pressed = false;
16946 }
16947
16948 this.callback(this.manager, eventType, {
16949 pointers: [ev],
16950 changedPointers: [ev],
16951 pointerType: INPUT_TYPE_MOUSE,
16952 srcEvent: ev
16953 });
16954 };
16955
16956 return MouseInput;
16957 }(Input);
16958 /**
16959 * @private
16960 * Combined touch and mouse input
16961 *
16962 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
16963 * This because touch devices also emit mouse events while doing a touch.
16964 *
16965 * @constructor
16966 * @extends Input
16967 */
16968
16969
16970 var DEDUP_TIMEOUT = 2500;
16971 var DEDUP_DISTANCE = 25;
16972
16973 function setLastTouch(eventData) {
16974 var _eventData$changedPoi = eventData.changedPointers,
16975 touch = _eventData$changedPoi[0];
16976
16977 if (touch.identifier === this.primaryTouch) {
16978 var lastTouch = {
16979 x: touch.clientX,
16980 y: touch.clientY
16981 };
16982 var lts = this.lastTouches;
16983 this.lastTouches.push(lastTouch);
16984
16985 var removeLastTouch = function removeLastTouch() {
16986 var i = lts.indexOf(lastTouch);
16987
16988 if (i > -1) {
16989 lts.splice(i, 1);
16990 }
16991 };
16992
16993 setTimeout(removeLastTouch, DEDUP_TIMEOUT);
16994 }
16995 }
16996
16997 function recordTouches(eventType, eventData) {
16998 if (eventType & INPUT_START) {
16999 this.primaryTouch = eventData.changedPointers[0].identifier;
17000 setLastTouch.call(this, eventData);
17001 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
17002 setLastTouch.call(this, eventData);
17003 }
17004 }
17005
17006 function isSyntheticEvent(eventData) {
17007 var x = eventData.srcEvent.clientX;
17008 var y = eventData.srcEvent.clientY;
17009
17010 for (var i = 0; i < this.lastTouches.length; i++) {
17011 var t = this.lastTouches[i];
17012 var dx = Math.abs(x - t.x);
17013 var dy = Math.abs(y - t.y);
17014
17015 if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
17016 return true;
17017 }
17018 }
17019
17020 return false;
17021 }
17022
17023 var TouchMouseInput =
17024 /*#__PURE__*/
17025 function () {
17026 var TouchMouseInput =
17027 /*#__PURE__*/
17028 function (_Input) {
17029 _inheritsLoose(TouchMouseInput, _Input);
17030
17031 function TouchMouseInput(_manager, callback) {
17032 var _this;
17033
17034 _this = _Input.call(this, _manager, callback) || this;
17035
17036 _this.handler = function (manager, inputEvent, inputData) {
17037 var isTouch = inputData.pointerType === INPUT_TYPE_TOUCH;
17038 var isMouse = inputData.pointerType === INPUT_TYPE_MOUSE;
17039
17040 if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
17041 return;
17042 } // when we're in a touch event, record touches to de-dupe synthetic mouse event
17043
17044
17045 if (isTouch) {
17046 recordTouches.call(_assertThisInitialized$1(_assertThisInitialized$1(_this)), inputEvent, inputData);
17047 } else if (isMouse && isSyntheticEvent.call(_assertThisInitialized$1(_assertThisInitialized$1(_this)), inputData)) {
17048 return;
17049 }
17050
17051 _this.callback(manager, inputEvent, inputData);
17052 };
17053
17054 _this.touch = new TouchInput(_this.manager, _this.handler);
17055 _this.mouse = new MouseInput(_this.manager, _this.handler);
17056 _this.primaryTouch = null;
17057 _this.lastTouches = [];
17058 return _this;
17059 }
17060 /**
17061 * @private
17062 * handle mouse and touch events
17063 * @param {Hammer} manager
17064 * @param {String} inputEvent
17065 * @param {Object} inputData
17066 */
17067
17068
17069 var _proto = TouchMouseInput.prototype;
17070 /**
17071 * @private
17072 * remove the event listeners
17073 */
17074
17075 _proto.destroy = function destroy() {
17076 this.touch.destroy();
17077 this.mouse.destroy();
17078 };
17079
17080 return TouchMouseInput;
17081 }(Input);
17082
17083 return TouchMouseInput;
17084 }();
17085 /**
17086 * @private
17087 * create new input type manager
17088 * called by the Manager constructor
17089 * @param {Hammer} manager
17090 * @returns {Input}
17091 */
17092
17093
17094 function createInputInstance(manager) {
17095 var Type; // let inputClass = manager.options.inputClass;
17096
17097 var inputClass = manager.options.inputClass;
17098
17099 if (inputClass) {
17100 Type = inputClass;
17101 } else if (SUPPORT_POINTER_EVENTS) {
17102 Type = PointerEventInput;
17103 } else if (SUPPORT_ONLY_TOUCH) {
17104 Type = TouchInput;
17105 } else if (!SUPPORT_TOUCH) {
17106 Type = MouseInput;
17107 } else {
17108 Type = TouchMouseInput;
17109 }
17110
17111 return new Type(manager, inputHandler);
17112 }
17113 /**
17114 * @private
17115 * if the argument is an array, we want to execute the fn on each entry
17116 * if it aint an array we don't want to do a thing.
17117 * this is used by all the methods that accept a single and array argument.
17118 * @param {*|Array} arg
17119 * @param {String} fn
17120 * @param {Object} [context]
17121 * @returns {Boolean}
17122 */
17123
17124
17125 function invokeArrayArg(arg, fn, context) {
17126 if (Array.isArray(arg)) {
17127 each(arg, context[fn], context);
17128 return true;
17129 }
17130
17131 return false;
17132 }
17133
17134 var STATE_POSSIBLE = 1;
17135 var STATE_BEGAN = 2;
17136 var STATE_CHANGED = 4;
17137 var STATE_ENDED = 8;
17138 var STATE_RECOGNIZED = STATE_ENDED;
17139 var STATE_CANCELLED = 16;
17140 var STATE_FAILED = 32;
17141 /**
17142 * @private
17143 * get a unique id
17144 * @returns {number} uniqueId
17145 */
17146
17147 var _uniqueId = 1;
17148
17149 function uniqueId() {
17150 return _uniqueId++;
17151 }
17152 /**
17153 * @private
17154 * get a recognizer by name if it is bound to a manager
17155 * @param {Recognizer|String} otherRecognizer
17156 * @param {Recognizer} recognizer
17157 * @returns {Recognizer}
17158 */
17159
17160
17161 function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
17162 var manager = recognizer.manager;
17163
17164 if (manager) {
17165 return manager.get(otherRecognizer);
17166 }
17167
17168 return otherRecognizer;
17169 }
17170 /**
17171 * @private
17172 * get a usable string, used as event postfix
17173 * @param {constant} state
17174 * @returns {String} state
17175 */
17176
17177
17178 function stateStr(state) {
17179 if (state & STATE_CANCELLED) {
17180 return 'cancel';
17181 } else if (state & STATE_ENDED) {
17182 return 'end';
17183 } else if (state & STATE_CHANGED) {
17184 return 'move';
17185 } else if (state & STATE_BEGAN) {
17186 return 'start';
17187 }
17188
17189 return '';
17190 }
17191 /**
17192 * @private
17193 * Recognizer flow explained; *
17194 * All recognizers have the initial state of POSSIBLE when a input session starts.
17195 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
17196 * Example session for mouse-input: mousedown -> mousemove -> mouseup
17197 *
17198 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
17199 * which determines with state it should be.
17200 *
17201 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
17202 * POSSIBLE to give it another change on the next cycle.
17203 *
17204 * Possible
17205 * |
17206 * +-----+---------------+
17207 * | |
17208 * +-----+-----+ |
17209 * | | |
17210 * Failed Cancelled |
17211 * +-------+------+
17212 * | |
17213 * Recognized Began
17214 * |
17215 * Changed
17216 * |
17217 * Ended/Recognized
17218 */
17219
17220 /**
17221 * @private
17222 * Recognizer
17223 * Every recognizer needs to extend from this class.
17224 * @constructor
17225 * @param {Object} options
17226 */
17227
17228
17229 var Recognizer =
17230 /*#__PURE__*/
17231 function () {
17232 function Recognizer(options) {
17233 if (options === void 0) {
17234 options = {};
17235 }
17236
17237 this.options = _extends({
17238 enable: true
17239 }, options);
17240 this.id = uniqueId();
17241 this.manager = null; // default is enable true
17242
17243 this.state = STATE_POSSIBLE;
17244 this.simultaneous = {};
17245 this.requireFail = [];
17246 }
17247 /**
17248 * @private
17249 * set options
17250 * @param {Object} options
17251 * @return {Recognizer}
17252 */
17253
17254
17255 var _proto = Recognizer.prototype;
17256
17257 _proto.set = function set(options) {
17258 assign$1(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state
17259
17260 this.manager && this.manager.touchAction.update();
17261 return this;
17262 };
17263 /**
17264 * @private
17265 * recognize simultaneous with an other recognizer.
17266 * @param {Recognizer} otherRecognizer
17267 * @returns {Recognizer} this
17268 */
17269
17270
17271 _proto.recognizeWith = function recognizeWith(otherRecognizer) {
17272 if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
17273 return this;
17274 }
17275
17276 var simultaneous = this.simultaneous;
17277 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
17278
17279 if (!simultaneous[otherRecognizer.id]) {
17280 simultaneous[otherRecognizer.id] = otherRecognizer;
17281 otherRecognizer.recognizeWith(this);
17282 }
17283
17284 return this;
17285 };
17286 /**
17287 * @private
17288 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
17289 * @param {Recognizer} otherRecognizer
17290 * @returns {Recognizer} this
17291 */
17292
17293
17294 _proto.dropRecognizeWith = function dropRecognizeWith(otherRecognizer) {
17295 if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
17296 return this;
17297 }
17298
17299 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
17300 delete this.simultaneous[otherRecognizer.id];
17301 return this;
17302 };
17303 /**
17304 * @private
17305 * recognizer can only run when an other is failing
17306 * @param {Recognizer} otherRecognizer
17307 * @returns {Recognizer} this
17308 */
17309
17310
17311 _proto.requireFailure = function requireFailure(otherRecognizer) {
17312 if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
17313 return this;
17314 }
17315
17316 var requireFail = this.requireFail;
17317 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
17318
17319 if (inArray(requireFail, otherRecognizer) === -1) {
17320 requireFail.push(otherRecognizer);
17321 otherRecognizer.requireFailure(this);
17322 }
17323
17324 return this;
17325 };
17326 /**
17327 * @private
17328 * drop the requireFailure link. it does not remove the link on the other recognizer.
17329 * @param {Recognizer} otherRecognizer
17330 * @returns {Recognizer} this
17331 */
17332
17333
17334 _proto.dropRequireFailure = function dropRequireFailure(otherRecognizer) {
17335 if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
17336 return this;
17337 }
17338
17339 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
17340 var index = inArray(this.requireFail, otherRecognizer);
17341
17342 if (index > -1) {
17343 this.requireFail.splice(index, 1);
17344 }
17345
17346 return this;
17347 };
17348 /**
17349 * @private
17350 * has require failures boolean
17351 * @returns {boolean}
17352 */
17353
17354
17355 _proto.hasRequireFailures = function hasRequireFailures() {
17356 return this.requireFail.length > 0;
17357 };
17358 /**
17359 * @private
17360 * if the recognizer can recognize simultaneous with an other recognizer
17361 * @param {Recognizer} otherRecognizer
17362 * @returns {Boolean}
17363 */
17364
17365
17366 _proto.canRecognizeWith = function canRecognizeWith(otherRecognizer) {
17367 return !!this.simultaneous[otherRecognizer.id];
17368 };
17369 /**
17370 * @private
17371 * You should use `tryEmit` instead of `emit` directly to check
17372 * that all the needed recognizers has failed before emitting.
17373 * @param {Object} input
17374 */
17375
17376
17377 _proto.emit = function emit(input) {
17378 var self = this;
17379 var state = this.state;
17380
17381 function emit(event) {
17382 self.manager.emit(event, input);
17383 } // 'panstart' and 'panmove'
17384
17385
17386 if (state < STATE_ENDED) {
17387 emit(self.options.event + stateStr(state));
17388 }
17389
17390 emit(self.options.event); // simple 'eventName' events
17391
17392 if (input.additionalEvent) {
17393 // additional event(panleft, panright, pinchin, pinchout...)
17394 emit(input.additionalEvent);
17395 } // panend and pancancel
17396
17397
17398 if (state >= STATE_ENDED) {
17399 emit(self.options.event + stateStr(state));
17400 }
17401 };
17402 /**
17403 * @private
17404 * Check that all the require failure recognizers has failed,
17405 * if true, it emits a gesture event,
17406 * otherwise, setup the state to FAILED.
17407 * @param {Object} input
17408 */
17409
17410
17411 _proto.tryEmit = function tryEmit(input) {
17412 if (this.canEmit()) {
17413 return this.emit(input);
17414 } // it's failing anyway
17415
17416
17417 this.state = STATE_FAILED;
17418 };
17419 /**
17420 * @private
17421 * can we emit?
17422 * @returns {boolean}
17423 */
17424
17425
17426 _proto.canEmit = function canEmit() {
17427 var i = 0;
17428
17429 while (i < this.requireFail.length) {
17430 if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
17431 return false;
17432 }
17433
17434 i++;
17435 }
17436
17437 return true;
17438 };
17439 /**
17440 * @private
17441 * update the recognizer
17442 * @param {Object} inputData
17443 */
17444
17445
17446 _proto.recognize = function recognize(inputData) {
17447 // make a new copy of the inputData
17448 // so we can change the inputData without messing up the other recognizers
17449 var inputDataClone = assign$1({}, inputData); // is is enabled and allow recognizing?
17450
17451 if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
17452 this.reset();
17453 this.state = STATE_FAILED;
17454 return;
17455 } // reset when we've reached the end
17456
17457
17458 if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
17459 this.state = STATE_POSSIBLE;
17460 }
17461
17462 this.state = this.process(inputDataClone); // the recognizer has recognized a gesture
17463 // so trigger an event
17464
17465 if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
17466 this.tryEmit(inputDataClone);
17467 }
17468 };
17469 /**
17470 * @private
17471 * return the state of the recognizer
17472 * the actual recognizing happens in this method
17473 * @virtual
17474 * @param {Object} inputData
17475 * @returns {constant} STATE
17476 */
17477
17478 /* jshint ignore:start */
17479
17480
17481 _proto.process = function process(inputData) {};
17482 /* jshint ignore:end */
17483
17484 /**
17485 * @private
17486 * return the preferred touch-action
17487 * @virtual
17488 * @returns {Array}
17489 */
17490
17491
17492 _proto.getTouchAction = function getTouchAction() {};
17493 /**
17494 * @private
17495 * called when the gesture isn't allowed to recognize
17496 * like when another is being recognized or it is disabled
17497 * @virtual
17498 */
17499
17500
17501 _proto.reset = function reset() {};
17502
17503 return Recognizer;
17504 }();
17505
17506 var defaults = {
17507 /**
17508 * @private
17509 * set if DOM events are being triggered.
17510 * But this is slower and unused by simple implementations, so disabled by default.
17511 * @type {Boolean}
17512 * @default false
17513 */
17514 domEvents: false,
17515
17516 /**
17517 * @private
17518 * The value for the touchAction property/fallback.
17519 * When set to `compute` it will magically set the correct value based on the added recognizers.
17520 * @type {String}
17521 * @default compute
17522 */
17523 touchAction: TOUCH_ACTION_COMPUTE,
17524
17525 /**
17526 * @private
17527 * @type {Boolean}
17528 * @default true
17529 */
17530 enable: true,
17531
17532 /**
17533 * @private
17534 * EXPERIMENTAL FEATURE -- can be removed/changed
17535 * Change the parent input target element.
17536 * If Null, then it is being set the to main element.
17537 * @type {Null|EventTarget}
17538 * @default null
17539 */
17540 inputTarget: null,
17541
17542 /**
17543 * @private
17544 * force an input class
17545 * @type {Null|Function}
17546 * @default null
17547 */
17548 inputClass: null,
17549
17550 /**
17551 * @private
17552 * Default recognizer setup when calling `Hammer()`
17553 * When creating a new Manager these will be skipped.
17554 * @type {Array}
17555 */
17556 preset: [],
17557
17558 /**
17559 * @private
17560 * Some CSS properties can be used to improve the working of Hammer.
17561 * Add them to this method and they will be set when creating a new Manager.
17562 * @namespace
17563 */
17564 cssProps: {
17565 /**
17566 * @private
17567 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
17568 * @type {String}
17569 * @default 'none'
17570 */
17571 userSelect: "none",
17572
17573 /**
17574 * @private
17575 * Disable the Windows Phone grippers when pressing an element.
17576 * @type {String}
17577 * @default 'none'
17578 */
17579 touchSelect: "none",
17580
17581 /**
17582 * @private
17583 * Disables the default callout shown when you touch and hold a touch target.
17584 * On iOS, when you touch and hold a touch target such as a link, Safari displays
17585 * a callout containing information about the link. This property allows you to disable that callout.
17586 * @type {String}
17587 * @default 'none'
17588 */
17589 touchCallout: "none",
17590
17591 /**
17592 * @private
17593 * Specifies whether zooming is enabled. Used by IE10>
17594 * @type {String}
17595 * @default 'none'
17596 */
17597 contentZooming: "none",
17598
17599 /**
17600 * @private
17601 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
17602 * @type {String}
17603 * @default 'none'
17604 */
17605 userDrag: "none",
17606
17607 /**
17608 * @private
17609 * Overrides the highlight color shown when the user taps a link or a JavaScript
17610 * clickable element in iOS. This property obeys the alpha value, if specified.
17611 * @type {String}
17612 * @default 'rgba(0,0,0,0)'
17613 */
17614 tapHighlightColor: "rgba(0,0,0,0)"
17615 }
17616 };
17617 var STOP = 1;
17618 var FORCED_STOP = 2;
17619 /**
17620 * @private
17621 * add/remove the css properties as defined in manager.options.cssProps
17622 * @param {Manager} manager
17623 * @param {Boolean} add
17624 */
17625
17626 function toggleCssProps(manager, add) {
17627 var element = manager.element;
17628
17629 if (!element.style) {
17630 return;
17631 }
17632
17633 var prop;
17634 each(manager.options.cssProps, function (value, name) {
17635 prop = prefixed(element.style, name);
17636
17637 if (add) {
17638 manager.oldCssProps[prop] = element.style[prop];
17639 element.style[prop] = value;
17640 } else {
17641 element.style[prop] = manager.oldCssProps[prop] || "";
17642 }
17643 });
17644
17645 if (!add) {
17646 manager.oldCssProps = {};
17647 }
17648 }
17649 /**
17650 * @private
17651 * trigger dom event
17652 * @param {String} event
17653 * @param {Object} data
17654 */
17655
17656
17657 function triggerDomEvent(event, data) {
17658 var gestureEvent = document.createEvent("Event");
17659 gestureEvent.initEvent(event, true, true);
17660 gestureEvent.gesture = data;
17661 data.target.dispatchEvent(gestureEvent);
17662 }
17663 /**
17664 * @private
17665 * Manager
17666 * @param {HTMLElement} element
17667 * @param {Object} [options]
17668 * @constructor
17669 */
17670
17671
17672 var Manager =
17673 /*#__PURE__*/
17674 function () {
17675 function Manager(element, options) {
17676 var _this = this;
17677
17678 this.options = assign$1({}, defaults, options || {});
17679 this.options.inputTarget = this.options.inputTarget || element;
17680 this.handlers = {};
17681 this.session = {};
17682 this.recognizers = [];
17683 this.oldCssProps = {};
17684 this.element = element;
17685 this.input = createInputInstance(this);
17686 this.touchAction = new TouchAction(this, this.options.touchAction);
17687 toggleCssProps(this, true);
17688 each(this.options.recognizers, function (item) {
17689 var recognizer = _this.add(new item[0](item[1]));
17690
17691 item[2] && recognizer.recognizeWith(item[2]);
17692 item[3] && recognizer.requireFailure(item[3]);
17693 }, this);
17694 }
17695 /**
17696 * @private
17697 * set options
17698 * @param {Object} options
17699 * @returns {Manager}
17700 */
17701
17702
17703 var _proto = Manager.prototype;
17704
17705 _proto.set = function set(options) {
17706 assign$1(this.options, options); // Options that need a little more setup
17707
17708 if (options.touchAction) {
17709 this.touchAction.update();
17710 }
17711
17712 if (options.inputTarget) {
17713 // Clean up existing event listeners and reinitialize
17714 this.input.destroy();
17715 this.input.target = options.inputTarget;
17716 this.input.init();
17717 }
17718
17719 return this;
17720 };
17721 /**
17722 * @private
17723 * stop recognizing for this session.
17724 * This session will be discarded, when a new [input]start event is fired.
17725 * When forced, the recognizer cycle is stopped immediately.
17726 * @param {Boolean} [force]
17727 */
17728
17729
17730 _proto.stop = function stop(force) {
17731 this.session.stopped = force ? FORCED_STOP : STOP;
17732 };
17733 /**
17734 * @private
17735 * run the recognizers!
17736 * called by the inputHandler function on every movement of the pointers (touches)
17737 * it walks through all the recognizers and tries to detect the gesture that is being made
17738 * @param {Object} inputData
17739 */
17740
17741
17742 _proto.recognize = function recognize(inputData) {
17743 var session = this.session;
17744
17745 if (session.stopped) {
17746 return;
17747 } // run the touch-action polyfill
17748
17749
17750 this.touchAction.preventDefaults(inputData);
17751 var recognizer;
17752 var recognizers = this.recognizers; // this holds the recognizer that is being recognized.
17753 // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
17754 // if no recognizer is detecting a thing, it is set to `null`
17755
17756 var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized
17757 // or when we're in a new session
17758
17759 if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
17760 session.curRecognizer = null;
17761 curRecognizer = null;
17762 }
17763
17764 var i = 0;
17765
17766 while (i < recognizers.length) {
17767 recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one.
17768 // 1. allow if the session is NOT forced stopped (see the .stop() method)
17769 // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
17770 // that is being recognized.
17771 // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
17772 // this can be setup with the `recognizeWith()` method on the recognizer.
17773
17774 if (session.stopped !== FORCED_STOP && ( // 1
17775 !curRecognizer || recognizer === curRecognizer || // 2
17776 recognizer.canRecognizeWith(curRecognizer))) {
17777 // 3
17778 recognizer.recognize(inputData);
17779 } else {
17780 recognizer.reset();
17781 } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
17782 // current active recognizer. but only if we don't already have an active recognizer
17783
17784
17785 if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
17786 session.curRecognizer = recognizer;
17787 curRecognizer = recognizer;
17788 }
17789
17790 i++;
17791 }
17792 };
17793 /**
17794 * @private
17795 * get a recognizer by its event name.
17796 * @param {Recognizer|String} recognizer
17797 * @returns {Recognizer|Null}
17798 */
17799
17800
17801 _proto.get = function get(recognizer) {
17802 if (recognizer instanceof Recognizer) {
17803 return recognizer;
17804 }
17805
17806 var recognizers = this.recognizers;
17807
17808 for (var i = 0; i < recognizers.length; i++) {
17809 if (recognizers[i].options.event === recognizer) {
17810 return recognizers[i];
17811 }
17812 }
17813
17814 return null;
17815 };
17816 /**
17817 * @private add a recognizer to the manager
17818 * existing recognizers with the same event name will be removed
17819 * @param {Recognizer} recognizer
17820 * @returns {Recognizer|Manager}
17821 */
17822
17823
17824 _proto.add = function add(recognizer) {
17825 if (invokeArrayArg(recognizer, "add", this)) {
17826 return this;
17827 } // remove existing
17828
17829
17830 var existing = this.get(recognizer.options.event);
17831
17832 if (existing) {
17833 this.remove(existing);
17834 }
17835
17836 this.recognizers.push(recognizer);
17837 recognizer.manager = this;
17838 this.touchAction.update();
17839 return recognizer;
17840 };
17841 /**
17842 * @private
17843 * remove a recognizer by name or instance
17844 * @param {Recognizer|String} recognizer
17845 * @returns {Manager}
17846 */
17847
17848
17849 _proto.remove = function remove(recognizer) {
17850 if (invokeArrayArg(recognizer, "remove", this)) {
17851 return this;
17852 }
17853
17854 var targetRecognizer = this.get(recognizer); // let's make sure this recognizer exists
17855
17856 if (recognizer) {
17857 var recognizers = this.recognizers;
17858 var index = inArray(recognizers, targetRecognizer);
17859
17860 if (index !== -1) {
17861 recognizers.splice(index, 1);
17862 this.touchAction.update();
17863 }
17864 }
17865
17866 return this;
17867 };
17868 /**
17869 * @private
17870 * bind event
17871 * @param {String} events
17872 * @param {Function} handler
17873 * @returns {EventEmitter} this
17874 */
17875
17876
17877 _proto.on = function on(events, handler) {
17878 if (events === undefined || handler === undefined) {
17879 return this;
17880 }
17881
17882 var handlers = this.handlers;
17883 each(splitStr(events), function (event) {
17884 handlers[event] = handlers[event] || [];
17885 handlers[event].push(handler);
17886 });
17887 return this;
17888 };
17889 /**
17890 * @private unbind event, leave emit blank to remove all handlers
17891 * @param {String} events
17892 * @param {Function} [handler]
17893 * @returns {EventEmitter} this
17894 */
17895
17896
17897 _proto.off = function off(events, handler) {
17898 if (events === undefined) {
17899 return this;
17900 }
17901
17902 var handlers = this.handlers;
17903 each(splitStr(events), function (event) {
17904 if (!handler) {
17905 delete handlers[event];
17906 } else {
17907 handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
17908 }
17909 });
17910 return this;
17911 };
17912 /**
17913 * @private emit event to the listeners
17914 * @param {String} event
17915 * @param {Object} data
17916 */
17917
17918
17919 _proto.emit = function emit(event, data) {
17920 // we also want to trigger dom events
17921 if (this.options.domEvents) {
17922 triggerDomEvent(event, data);
17923 } // no handlers, so skip it all
17924
17925
17926 var handlers = this.handlers[event] && this.handlers[event].slice();
17927
17928 if (!handlers || !handlers.length) {
17929 return;
17930 }
17931
17932 data.type = event;
17933
17934 data.preventDefault = function () {
17935 data.srcEvent.preventDefault();
17936 };
17937
17938 var i = 0;
17939
17940 while (i < handlers.length) {
17941 handlers[i](data);
17942 i++;
17943 }
17944 };
17945 /**
17946 * @private
17947 * destroy the manager and unbinds all events
17948 * it doesn't unbind dom events, that is the user own responsibility
17949 */
17950
17951
17952 _proto.destroy = function destroy() {
17953 this.element && toggleCssProps(this, false);
17954 this.handlers = {};
17955 this.session = {};
17956 this.input.destroy();
17957 this.element = null;
17958 };
17959
17960 return Manager;
17961 }();
17962
17963 var SINGLE_TOUCH_INPUT_MAP = {
17964 touchstart: INPUT_START,
17965 touchmove: INPUT_MOVE,
17966 touchend: INPUT_END,
17967 touchcancel: INPUT_CANCEL
17968 };
17969 var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
17970 var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
17971 /**
17972 * @private
17973 * Touch events input
17974 * @constructor
17975 * @extends Input
17976 */
17977
17978 var SingleTouchInput =
17979 /*#__PURE__*/
17980 function (_Input) {
17981 _inheritsLoose(SingleTouchInput, _Input);
17982
17983 function SingleTouchInput() {
17984 var _this;
17985
17986 var proto = SingleTouchInput.prototype;
17987 proto.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
17988 proto.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
17989 _this = _Input.apply(this, arguments) || this;
17990 _this.started = false;
17991 return _this;
17992 }
17993
17994 var _proto = SingleTouchInput.prototype;
17995
17996 _proto.handler = function handler(ev) {
17997 var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events?
17998
17999 if (type === INPUT_START) {
18000 this.started = true;
18001 }
18002
18003 if (!this.started) {
18004 return;
18005 }
18006
18007 var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state
18008
18009 if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
18010 this.started = false;
18011 }
18012
18013 this.callback(this.manager, type, {
18014 pointers: touches[0],
18015 changedPointers: touches[1],
18016 pointerType: INPUT_TYPE_TOUCH,
18017 srcEvent: ev
18018 });
18019 };
18020
18021 return SingleTouchInput;
18022 }(Input);
18023
18024 function normalizeSingleTouches(ev, type) {
18025 var all = toArray$1(ev.touches);
18026 var changed = toArray$1(ev.changedTouches);
18027
18028 if (type & (INPUT_END | INPUT_CANCEL)) {
18029 all = uniqueArray(all.concat(changed), 'identifier', true);
18030 }
18031
18032 return [all, changed];
18033 }
18034 /**
18035 * @private
18036 * This recognizer is just used as a base for the simple attribute recognizers.
18037 * @constructor
18038 * @extends Recognizer
18039 */
18040
18041
18042 var AttrRecognizer =
18043 /*#__PURE__*/
18044 function (_Recognizer) {
18045 _inheritsLoose(AttrRecognizer, _Recognizer);
18046
18047 function AttrRecognizer(options) {
18048 if (options === void 0) {
18049 options = {};
18050 }
18051
18052 return _Recognizer.call(this, _extends({
18053 pointers: 1
18054 }, options)) || this;
18055 }
18056 /**
18057 * @private
18058 * Used to check if it the recognizer receives valid input, like input.distance > 10.
18059 * @memberof AttrRecognizer
18060 * @param {Object} input
18061 * @returns {Boolean} recognized
18062 */
18063
18064
18065 var _proto = AttrRecognizer.prototype;
18066
18067 _proto.attrTest = function attrTest(input) {
18068 var optionPointers = this.options.pointers;
18069 return optionPointers === 0 || input.pointers.length === optionPointers;
18070 };
18071 /**
18072 * @private
18073 * Process the input and return the state for the recognizer
18074 * @memberof AttrRecognizer
18075 * @param {Object} input
18076 * @returns {*} State
18077 */
18078
18079
18080 _proto.process = function process(input) {
18081 var state = this.state;
18082 var eventType = input.eventType;
18083 var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
18084 var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED
18085
18086 if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
18087 return state | STATE_CANCELLED;
18088 } else if (isRecognized || isValid) {
18089 if (eventType & INPUT_END) {
18090 return state | STATE_ENDED;
18091 } else if (!(state & STATE_BEGAN)) {
18092 return STATE_BEGAN;
18093 }
18094
18095 return state | STATE_CHANGED;
18096 }
18097
18098 return STATE_FAILED;
18099 };
18100
18101 return AttrRecognizer;
18102 }(Recognizer);
18103 /**
18104 * @private
18105 * A tap is recognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
18106 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
18107 * a single tap.
18108 *
18109 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
18110 * multi-taps being recognized.
18111 * @constructor
18112 * @extends Recognizer
18113 */
18114
18115
18116 var TapRecognizer =
18117 /*#__PURE__*/
18118 function (_Recognizer) {
18119 _inheritsLoose(TapRecognizer, _Recognizer);
18120
18121 function TapRecognizer(options) {
18122 var _this;
18123
18124 if (options === void 0) {
18125 options = {};
18126 }
18127
18128 _this = _Recognizer.call(this, _extends({
18129 event: 'tap',
18130 pointers: 1,
18131 taps: 1,
18132 interval: 300,
18133 // max time between the multi-tap taps
18134 time: 250,
18135 // max time of the pointer to be down (like finger on the screen)
18136 threshold: 9,
18137 // a minimal movement is ok, but keep it low
18138 posThreshold: 10
18139 }, options)) || this; // previous time and center,
18140 // used for tap counting
18141
18142 _this.pTime = false;
18143 _this.pCenter = false;
18144 _this._timer = null;
18145 _this._input = null;
18146 _this.count = 0;
18147 return _this;
18148 }
18149
18150 var _proto = TapRecognizer.prototype;
18151
18152 _proto.getTouchAction = function getTouchAction() {
18153 return [TOUCH_ACTION_MANIPULATION];
18154 };
18155
18156 _proto.process = function process(input) {
18157 var _this2 = this;
18158
18159 var options = this.options;
18160 var validPointers = input.pointers.length === options.pointers;
18161 var validMovement = input.distance < options.threshold;
18162 var validTouchTime = input.deltaTime < options.time;
18163 this.reset();
18164
18165 if (input.eventType & INPUT_START && this.count === 0) {
18166 return this.failTimeout();
18167 } // we only allow little movement
18168 // and we've reached an end event, so a tap is possible
18169
18170
18171 if (validMovement && validTouchTime && validPointers) {
18172 if (input.eventType !== INPUT_END) {
18173 return this.failTimeout();
18174 }
18175
18176 var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
18177 var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
18178 this.pTime = input.timeStamp;
18179 this.pCenter = input.center;
18180
18181 if (!validMultiTap || !validInterval) {
18182 this.count = 1;
18183 } else {
18184 this.count += 1;
18185 }
18186
18187 this._input = input; // if tap count matches we have recognized it,
18188 // else it has began recognizing...
18189
18190 var tapCount = this.count % options.taps;
18191
18192 if (tapCount === 0) {
18193 // no failing requirements, immediately trigger the tap event
18194 // or wait as long as the multitap interval to trigger
18195 if (!this.hasRequireFailures()) {
18196 return STATE_RECOGNIZED;
18197 } else {
18198 this._timer = setTimeout(function () {
18199 _this2.state = STATE_RECOGNIZED;
18200
18201 _this2.tryEmit();
18202 }, options.interval);
18203 return STATE_BEGAN;
18204 }
18205 }
18206 }
18207
18208 return STATE_FAILED;
18209 };
18210
18211 _proto.failTimeout = function failTimeout() {
18212 var _this3 = this;
18213
18214 this._timer = setTimeout(function () {
18215 _this3.state = STATE_FAILED;
18216 }, this.options.interval);
18217 return STATE_FAILED;
18218 };
18219
18220 _proto.reset = function reset() {
18221 clearTimeout(this._timer);
18222 };
18223
18224 _proto.emit = function emit() {
18225 if (this.state === STATE_RECOGNIZED) {
18226 this._input.tapCount = this.count;
18227 this.manager.emit(this.options.event, this._input);
18228 }
18229 };
18230
18231 return TapRecognizer;
18232 }(Recognizer);
18233 /**
18234 * @private
18235 * direction cons to string
18236 * @param {constant} direction
18237 * @returns {String}
18238 */
18239
18240
18241 function directionStr(direction) {
18242 if (direction === DIRECTION_DOWN) {
18243 return 'down';
18244 } else if (direction === DIRECTION_UP) {
18245 return 'up';
18246 } else if (direction === DIRECTION_LEFT) {
18247 return 'left';
18248 } else if (direction === DIRECTION_RIGHT) {
18249 return 'right';
18250 }
18251
18252 return '';
18253 }
18254 /**
18255 * @private
18256 * Pan
18257 * Recognized when the pointer is down and moved in the allowed direction.
18258 * @constructor
18259 * @extends AttrRecognizer
18260 */
18261
18262
18263 var PanRecognizer =
18264 /*#__PURE__*/
18265 function (_AttrRecognizer) {
18266 _inheritsLoose(PanRecognizer, _AttrRecognizer);
18267
18268 function PanRecognizer(options) {
18269 var _this;
18270
18271 if (options === void 0) {
18272 options = {};
18273 }
18274
18275 _this = _AttrRecognizer.call(this, _extends({
18276 event: 'pan',
18277 threshold: 10,
18278 pointers: 1,
18279 direction: DIRECTION_ALL
18280 }, options)) || this;
18281 _this.pX = null;
18282 _this.pY = null;
18283 return _this;
18284 }
18285
18286 var _proto = PanRecognizer.prototype;
18287
18288 _proto.getTouchAction = function getTouchAction() {
18289 var direction = this.options.direction;
18290 var actions = [];
18291
18292 if (direction & DIRECTION_HORIZONTAL) {
18293 actions.push(TOUCH_ACTION_PAN_Y);
18294 }
18295
18296 if (direction & DIRECTION_VERTICAL) {
18297 actions.push(TOUCH_ACTION_PAN_X);
18298 }
18299
18300 return actions;
18301 };
18302
18303 _proto.directionTest = function directionTest(input) {
18304 var options = this.options;
18305 var hasMoved = true;
18306 var distance = input.distance;
18307 var direction = input.direction;
18308 var x = input.deltaX;
18309 var y = input.deltaY; // lock to axis?
18310
18311 if (!(direction & options.direction)) {
18312 if (options.direction & DIRECTION_HORIZONTAL) {
18313 direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
18314 hasMoved = x !== this.pX;
18315 distance = Math.abs(input.deltaX);
18316 } else {
18317 direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
18318 hasMoved = y !== this.pY;
18319 distance = Math.abs(input.deltaY);
18320 }
18321 }
18322
18323 input.direction = direction;
18324 return hasMoved && distance > options.threshold && direction & options.direction;
18325 };
18326
18327 _proto.attrTest = function attrTest(input) {
18328 return AttrRecognizer.prototype.attrTest.call(this, input) && ( // replace with a super call
18329 this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
18330 };
18331
18332 _proto.emit = function emit(input) {
18333 this.pX = input.deltaX;
18334 this.pY = input.deltaY;
18335 var direction = directionStr(input.direction);
18336
18337 if (direction) {
18338 input.additionalEvent = this.options.event + direction;
18339 }
18340
18341 _AttrRecognizer.prototype.emit.call(this, input);
18342 };
18343
18344 return PanRecognizer;
18345 }(AttrRecognizer);
18346 /**
18347 * @private
18348 * Swipe
18349 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
18350 * @constructor
18351 * @extends AttrRecognizer
18352 */
18353
18354
18355 var SwipeRecognizer =
18356 /*#__PURE__*/
18357 function (_AttrRecognizer) {
18358 _inheritsLoose(SwipeRecognizer, _AttrRecognizer);
18359
18360 function SwipeRecognizer(options) {
18361 if (options === void 0) {
18362 options = {};
18363 }
18364
18365 return _AttrRecognizer.call(this, _extends({
18366 event: 'swipe',
18367 threshold: 10,
18368 velocity: 0.3,
18369 direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
18370 pointers: 1
18371 }, options)) || this;
18372 }
18373
18374 var _proto = SwipeRecognizer.prototype;
18375
18376 _proto.getTouchAction = function getTouchAction() {
18377 return PanRecognizer.prototype.getTouchAction.call(this);
18378 };
18379
18380 _proto.attrTest = function attrTest(input) {
18381 var direction = this.options.direction;
18382 var velocity;
18383
18384 if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
18385 velocity = input.overallVelocity;
18386 } else if (direction & DIRECTION_HORIZONTAL) {
18387 velocity = input.overallVelocityX;
18388 } else if (direction & DIRECTION_VERTICAL) {
18389 velocity = input.overallVelocityY;
18390 }
18391
18392 return _AttrRecognizer.prototype.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers === this.options.pointers && abs$2(velocity) > this.options.velocity && input.eventType & INPUT_END;
18393 };
18394
18395 _proto.emit = function emit(input) {
18396 var direction = directionStr(input.offsetDirection);
18397
18398 if (direction) {
18399 this.manager.emit(this.options.event + direction, input);
18400 }
18401
18402 this.manager.emit(this.options.event, input);
18403 };
18404
18405 return SwipeRecognizer;
18406 }(AttrRecognizer);
18407 /**
18408 * @private
18409 * Pinch
18410 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
18411 * @constructor
18412 * @extends AttrRecognizer
18413 */
18414
18415
18416 var PinchRecognizer =
18417 /*#__PURE__*/
18418 function (_AttrRecognizer) {
18419 _inheritsLoose(PinchRecognizer, _AttrRecognizer);
18420
18421 function PinchRecognizer(options) {
18422 if (options === void 0) {
18423 options = {};
18424 }
18425
18426 return _AttrRecognizer.call(this, _extends({
18427 event: 'pinch',
18428 threshold: 0,
18429 pointers: 2
18430 }, options)) || this;
18431 }
18432
18433 var _proto = PinchRecognizer.prototype;
18434
18435 _proto.getTouchAction = function getTouchAction() {
18436 return [TOUCH_ACTION_NONE];
18437 };
18438
18439 _proto.attrTest = function attrTest(input) {
18440 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
18441 };
18442
18443 _proto.emit = function emit(input) {
18444 if (input.scale !== 1) {
18445 var inOut = input.scale < 1 ? 'in' : 'out';
18446 input.additionalEvent = this.options.event + inOut;
18447 }
18448
18449 _AttrRecognizer.prototype.emit.call(this, input);
18450 };
18451
18452 return PinchRecognizer;
18453 }(AttrRecognizer);
18454 /**
18455 * @private
18456 * Rotate
18457 * Recognized when two or more pointer are moving in a circular motion.
18458 * @constructor
18459 * @extends AttrRecognizer
18460 */
18461
18462
18463 var RotateRecognizer =
18464 /*#__PURE__*/
18465 function (_AttrRecognizer) {
18466 _inheritsLoose(RotateRecognizer, _AttrRecognizer);
18467
18468 function RotateRecognizer(options) {
18469 if (options === void 0) {
18470 options = {};
18471 }
18472
18473 return _AttrRecognizer.call(this, _extends({
18474 event: 'rotate',
18475 threshold: 0,
18476 pointers: 2
18477 }, options)) || this;
18478 }
18479
18480 var _proto = RotateRecognizer.prototype;
18481
18482 _proto.getTouchAction = function getTouchAction() {
18483 return [TOUCH_ACTION_NONE];
18484 };
18485
18486 _proto.attrTest = function attrTest(input) {
18487 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
18488 };
18489
18490 return RotateRecognizer;
18491 }(AttrRecognizer);
18492 /**
18493 * @private
18494 * Press
18495 * Recognized when the pointer is down for x ms without any movement.
18496 * @constructor
18497 * @extends Recognizer
18498 */
18499
18500
18501 var PressRecognizer =
18502 /*#__PURE__*/
18503 function (_Recognizer) {
18504 _inheritsLoose(PressRecognizer, _Recognizer);
18505
18506 function PressRecognizer(options) {
18507 var _this;
18508
18509 if (options === void 0) {
18510 options = {};
18511 }
18512
18513 _this = _Recognizer.call(this, _extends({
18514 event: 'press',
18515 pointers: 1,
18516 time: 251,
18517 // minimal time of the pointer to be pressed
18518 threshold: 9
18519 }, options)) || this;
18520 _this._timer = null;
18521 _this._input = null;
18522 return _this;
18523 }
18524
18525 var _proto = PressRecognizer.prototype;
18526
18527 _proto.getTouchAction = function getTouchAction() {
18528 return [TOUCH_ACTION_AUTO];
18529 };
18530
18531 _proto.process = function process(input) {
18532 var _this2 = this;
18533
18534 var options = this.options;
18535 var validPointers = input.pointers.length === options.pointers;
18536 var validMovement = input.distance < options.threshold;
18537 var validTime = input.deltaTime > options.time;
18538 this._input = input; // we only allow little movement
18539 // and we've reached an end event, so a tap is possible
18540
18541 if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
18542 this.reset();
18543 } else if (input.eventType & INPUT_START) {
18544 this.reset();
18545 this._timer = setTimeout(function () {
18546 _this2.state = STATE_RECOGNIZED;
18547
18548 _this2.tryEmit();
18549 }, options.time);
18550 } else if (input.eventType & INPUT_END) {
18551 return STATE_RECOGNIZED;
18552 }
18553
18554 return STATE_FAILED;
18555 };
18556
18557 _proto.reset = function reset() {
18558 clearTimeout(this._timer);
18559 };
18560
18561 _proto.emit = function emit(input) {
18562 if (this.state !== STATE_RECOGNIZED) {
18563 return;
18564 }
18565
18566 if (input && input.eventType & INPUT_END) {
18567 this.manager.emit(this.options.event + "up", input);
18568 } else {
18569 this._input.timeStamp = now();
18570 this.manager.emit(this.options.event, this._input);
18571 }
18572 };
18573
18574 return PressRecognizer;
18575 }(Recognizer);
18576 /**
18577 * @private
18578 * wrap a method with a deprecation warning and stack trace
18579 * @param {Function} method
18580 * @param {String} name
18581 * @param {String} message
18582 * @returns {Function} A new function wrapping the supplied method.
18583 */
18584
18585
18586 function deprecate(method, name, message) {
18587 var deprecationMessage = "DEPRECATED METHOD: " + name + "\n" + message + " AT \n";
18588 return function () {
18589 var e = new Error('get-stack-trace');
18590 var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
18591 var log = window.console && (window.console.warn || window.console.log);
18592
18593 if (log) {
18594 log.call(window.console, deprecationMessage, stack);
18595 }
18596
18597 return method.apply(this, arguments);
18598 };
18599 }
18600 /**
18601 * @private
18602 * extend object.
18603 * means that properties in dest will be overwritten by the ones in src.
18604 * @param {Object} dest
18605 * @param {Object} src
18606 * @param {Boolean} [merge=false]
18607 * @returns {Object} dest
18608 */
18609
18610
18611 var extend$1 = deprecate(function (dest, src, merge) {
18612 var keys = Object.keys(src);
18613 var i = 0;
18614
18615 while (i < keys.length) {
18616 if (!merge || merge && dest[keys[i]] === undefined) {
18617 dest[keys[i]] = src[keys[i]];
18618 }
18619
18620 i++;
18621 }
18622
18623 return dest;
18624 }, 'extend', 'Use `assign`.');
18625 /**
18626 * @private
18627 * merge the values from src in the dest.
18628 * means that properties that exist in dest will not be overwritten by src
18629 * @param {Object} dest
18630 * @param {Object} src
18631 * @returns {Object} dest
18632 */
18633
18634 var merge$1 = deprecate(function (dest, src) {
18635 return extend$1(dest, src, true);
18636 }, 'merge', 'Use `assign`.');
18637 /**
18638 * @private
18639 * simple class inheritance
18640 * @param {Function} child
18641 * @param {Function} base
18642 * @param {Object} [properties]
18643 */
18644
18645 function inherit(child, base, properties) {
18646 var baseP = base.prototype;
18647 var childP;
18648 childP = child.prototype = Object.create(baseP);
18649 childP.constructor = child;
18650 childP._super = baseP;
18651
18652 if (properties) {
18653 assign$1(childP, properties);
18654 }
18655 }
18656 /**
18657 * @private
18658 * simple function bind
18659 * @param {Function} fn
18660 * @param {Object} context
18661 * @returns {Function}
18662 */
18663
18664
18665 function bindFn(fn, context) {
18666 return function boundFn() {
18667 return fn.apply(context, arguments);
18668 };
18669 }
18670 /**
18671 * @private
18672 * Simple way to create a manager with a default set of recognizers.
18673 * @param {HTMLElement} element
18674 * @param {Object} [options]
18675 * @constructor
18676 */
18677
18678
18679 var Hammer =
18680 /*#__PURE__*/
18681 function () {
18682 var Hammer =
18683 /**
18684 * @private
18685 * @const {string}
18686 */
18687 function Hammer(element, options) {
18688 if (options === void 0) {
18689 options = {};
18690 }
18691
18692 return new Manager(element, _extends({
18693 recognizers: [// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
18694 [RotateRecognizer, {
18695 enable: false
18696 }], [PinchRecognizer, {
18697 enable: false
18698 }, ['rotate']], [SwipeRecognizer, {
18699 direction: DIRECTION_HORIZONTAL
18700 }], [PanRecognizer, {
18701 direction: DIRECTION_HORIZONTAL
18702 }, ['swipe']], [TapRecognizer], [TapRecognizer, {
18703 event: 'doubletap',
18704 taps: 2
18705 }, ['tap']], [PressRecognizer]]
18706 }, options));
18707 };
18708
18709 Hammer.VERSION = "2.0.15";
18710 Hammer.DIRECTION_ALL = DIRECTION_ALL;
18711 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
18712 Hammer.DIRECTION_LEFT = DIRECTION_LEFT;
18713 Hammer.DIRECTION_RIGHT = DIRECTION_RIGHT;
18714 Hammer.DIRECTION_UP = DIRECTION_UP;
18715 Hammer.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL;
18716 Hammer.DIRECTION_VERTICAL = DIRECTION_VERTICAL;
18717 Hammer.DIRECTION_NONE = DIRECTION_NONE;
18718 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
18719 Hammer.INPUT_START = INPUT_START;
18720 Hammer.INPUT_MOVE = INPUT_MOVE;
18721 Hammer.INPUT_END = INPUT_END;
18722 Hammer.INPUT_CANCEL = INPUT_CANCEL;
18723 Hammer.STATE_POSSIBLE = STATE_POSSIBLE;
18724 Hammer.STATE_BEGAN = STATE_BEGAN;
18725 Hammer.STATE_CHANGED = STATE_CHANGED;
18726 Hammer.STATE_ENDED = STATE_ENDED;
18727 Hammer.STATE_RECOGNIZED = STATE_RECOGNIZED;
18728 Hammer.STATE_CANCELLED = STATE_CANCELLED;
18729 Hammer.STATE_FAILED = STATE_FAILED;
18730 Hammer.Manager = Manager;
18731 Hammer.Input = Input;
18732 Hammer.TouchAction = TouchAction;
18733 Hammer.TouchInput = TouchInput;
18734 Hammer.MouseInput = MouseInput;
18735 Hammer.PointerEventInput = PointerEventInput;
18736 Hammer.TouchMouseInput = TouchMouseInput;
18737 Hammer.SingleTouchInput = SingleTouchInput;
18738 Hammer.Recognizer = Recognizer;
18739 Hammer.AttrRecognizer = AttrRecognizer;
18740 Hammer.Tap = TapRecognizer;
18741 Hammer.Pan = PanRecognizer;
18742 Hammer.Swipe = SwipeRecognizer;
18743 Hammer.Pinch = PinchRecognizer;
18744 Hammer.Rotate = RotateRecognizer;
18745 Hammer.Press = PressRecognizer;
18746 Hammer.on = addEventListeners;
18747 Hammer.off = removeEventListeners;
18748 Hammer.each = each;
18749 Hammer.merge = merge$1;
18750 Hammer.extend = extend$1;
18751 Hammer.bindFn = bindFn;
18752 Hammer.assign = assign$1;
18753 Hammer.inherit = inherit;
18754 Hammer.bindFn = bindFn;
18755 Hammer.prefixed = prefixed;
18756 Hammer.toArray = toArray$1;
18757 Hammer.inArray = inArray;
18758 Hammer.uniqueArray = uniqueArray;
18759 Hammer.splitStr = splitStr;
18760 Hammer.boolOrFn = boolOrFn;
18761 Hammer.hasParent = hasParent$1;
18762 Hammer.addEventListeners = addEventListeners;
18763 Hammer.removeEventListeners = removeEventListeners;
18764 Hammer.defaults = defaults;
18765 return Hammer;
18766 }();
18767
18768 var hammer = createCommonjsModule(function (module) {
18769 /**
18770 * Setup a mock hammer.js object, for unit testing.
18771 *
18772 * Inspiration: https://github.com/uber/deck.gl/pull/658
18773 *
18774 * @returns {{on: noop, off: noop, destroy: noop, emit: noop, get: get}}
18775 */
18776 function hammerMock() {
18777 var noop = function noop() {};
18778
18779 return {
18780 on: noop,
18781 off: noop,
18782 destroy: noop,
18783 emit: noop,
18784 get: function get(m) {
18785 //eslint-disable-line no-unused-vars
18786 return {
18787 set: noop
18788 };
18789 }
18790 };
18791 }
18792
18793 if (typeof window !== 'undefined') {
18794 var Hammer$1 = window['Hammer'] || Hammer;
18795 module.exports = Hammer$1;
18796 } else {
18797 module.exports = function () {
18798 // hammer.js is only available in a browser, not in node.js. Replacing it with a mock object.
18799 return hammerMock();
18800 };
18801 }
18802 });
18803
18804 getCjsExportFromNamespace(Activator);
18805
18806 /**
18807 * Turn an element into an clickToUse element.
18808 * When not active, the element has a transparent overlay. When the overlay is
18809 * clicked, the mode is changed to active.
18810 * When active, the element is displayed with a blue border around it, and
18811 * the interactive contents of the element can be used. When clicked outside
18812 * the element, the elements mode is changed to inactive.
18813 * @param {Element} container
18814 * @constructor Activator
18815 */
18816
18817 function Activator$1(container) {
18818 var _this = this;
18819
18820 this.active = false;
18821 this.dom = {
18822 container: container
18823 };
18824 this.dom.overlay = document.createElement('div');
18825 this.dom.overlay.className = 'vis-overlay';
18826 this.dom.container.appendChild(this.dom.overlay);
18827 this.hammer = hammer(this.dom.overlay);
18828 this.hammer.on('tap', this._onTapOverlay.bind(this)); // block all touch events (except tap)
18829
18830 var events = ['tap', 'doubletap', 'press', 'pinch', 'pan', 'panstart', 'panmove', 'panend'];
18831 events.forEach(function (event) {
18832 _this.hammer.on(event, function (event) {
18833 event.srcEvent.stopPropagation();
18834 });
18835 }); // attach a click event to the window, in order to deactivate when clicking outside the timeline
18836
18837 if (document && document.body) {
18838 this.onClick = function (event) {
18839 if (!_hasParent(event.target, container)) {
18840 _this.deactivate();
18841 }
18842 };
18843
18844 document.body.addEventListener('click', this.onClick);
18845 }
18846
18847 if (this.keycharm !== undefined) {
18848 this.keycharm.destroy();
18849 }
18850
18851 this.keycharm = keycharm(); // keycharm listener only bounded when active)
18852
18853 this.escListener = this.deactivate.bind(this);
18854 } // turn into an event emitter
18855
18856
18857 componentEmitter(Activator$1.prototype); // The currently active activator
18858
18859 Activator$1.current = null;
18860 /**
18861 * Destroy the activator. Cleans up all created DOM and event listeners
18862 */
18863
18864 Activator$1.prototype.destroy = function () {
18865 this.deactivate(); // remove dom
18866
18867 this.dom.overlay.parentNode.removeChild(this.dom.overlay); // remove global event listener
18868
18869 if (this.onClick) {
18870 document.body.removeEventListener('click', this.onClick);
18871 } // remove keycharm
18872
18873
18874 if (this.keycharm !== undefined) {
18875 this.keycharm.destroy();
18876 }
18877
18878 this.keycharm = null; // cleanup hammer instances
18879
18880 this.hammer.destroy();
18881 this.hammer = null; // FIXME: cleaning up hammer instances doesn't work (Timeline not removed from memory)
18882 };
18883 /**
18884 * Activate the element
18885 * Overlay is hidden, element is decorated with a blue shadow border
18886 */
18887
18888
18889 Activator$1.prototype.activate = function () {
18890 // we allow only one active activator at a time
18891 if (Activator$1.current) {
18892 Activator$1.current.deactivate();
18893 }
18894
18895 Activator$1.current = this;
18896 this.active = true;
18897 this.dom.overlay.style.display = 'none';
18898 util.addClassName(this.dom.container, 'vis-active');
18899 this.emit('change');
18900 this.emit('activate'); // ugly hack: bind ESC after emitting the events, as the Network rebinds all
18901 // keyboard events on a 'change' event
18902
18903 this.keycharm.bind('esc', this.escListener);
18904 };
18905 /**
18906 * Deactivate the element
18907 * Overlay is displayed on top of the element
18908 */
18909
18910
18911 Activator$1.prototype.deactivate = function () {
18912 this.active = false;
18913 this.dom.overlay.style.display = 'block';
18914 util.removeClassName(this.dom.container, 'vis-active');
18915 this.keycharm.unbind('esc', this.escListener);
18916 this.emit('change');
18917 this.emit('deactivate');
18918 };
18919 /**
18920 * Handle a tap event: activate the container
18921 * @param {Event} event The event
18922 * @private
18923 */
18924
18925
18926 Activator$1.prototype._onTapOverlay = function (event) {
18927 // activate the container
18928 this.activate();
18929 event.srcEvent.stopPropagation();
18930 };
18931 /**
18932 * Test whether the element has the requested parent element somewhere in
18933 * its chain of parent nodes.
18934 * @param {HTMLElement} element
18935 * @param {HTMLElement} parent
18936 * @returns {boolean} Returns true when the parent is found somewhere in the
18937 * chain of parent nodes.
18938 * @private
18939 */
18940
18941
18942 function _hasParent(element, parent) {
18943 while (element) {
18944 if (element === parent) {
18945 return true;
18946 }
18947
18948 element = element.parentNode;
18949 }
18950
18951 return false;
18952 }
18953
18954 var Activator_1 = Activator$1;
18955
18956 var locales = createCommonjsModule(function (module, exports) {
18957 // English
18958 exports['en'] = {
18959 edit: 'Edit',
18960 del: 'Delete selected',
18961 back: 'Back',
18962 addNode: 'Add Node',
18963 addEdge: 'Add Edge',
18964 editNode: 'Edit Node',
18965 editEdge: 'Edit Edge',
18966 addDescription: 'Click in an empty space to place a new node.',
18967 edgeDescription: 'Click on a node and drag the edge to another node to connect them.',
18968 editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.',
18969 createEdgeError: 'Cannot link edges to a cluster.',
18970 deleteClusterError: 'Clusters cannot be deleted.',
18971 editClusterError: 'Clusters cannot be edited.'
18972 };
18973 exports['en_EN'] = exports['en'];
18974 exports['en_US'] = exports['en']; // German
18975
18976 exports['de'] = {
18977 edit: 'Editieren',
18978 del: "L\xF6sche Auswahl",
18979 back: "Zur\xFCck",
18980 addNode: "Knoten hinzuf\xFCgen",
18981 addEdge: "Kante hinzuf\xFCgen",
18982 editNode: 'Knoten editieren',
18983 editEdge: 'Kante editieren',
18984 addDescription: 'Klicke auf eine freie Stelle, um einen neuen Knoten zu plazieren.',
18985 edgeDescription: 'Klicke auf einen Knoten und ziehe die Kante zu einem anderen Knoten, um diese zu verbinden.',
18986 editEdgeDescription: 'Klicke auf die Verbindungspunkte und ziehe diese auf einen Knoten, um sie zu verbinden.',
18987 createEdgeError: "Es ist nicht m\xF6glich, Kanten mit Clustern zu verbinden.",
18988 deleteClusterError: "Cluster k\xF6nnen nicht gel\xF6scht werden.",
18989 editClusterError: "Cluster k\xF6nnen nicht editiert werden."
18990 };
18991 exports['de_DE'] = exports['de']; // Spanish
18992
18993 exports['es'] = {
18994 edit: 'Editar',
18995 del: "Eliminar selecci\xF3n",
18996 back: "Atr\xE1s",
18997 addNode: "A\xF1adir nodo",
18998 addEdge: "A\xF1adir arista",
18999 editNode: 'Editar nodo',
19000 editEdge: 'Editar arista',
19001 addDescription: "Haga clic en un lugar vac\xEDo para colocar un nuevo nodo.",
19002 edgeDescription: 'Haga clic en un nodo y arrastre la arista hacia otro nodo para conectarlos.',
19003 editEdgeDescription: 'Haga clic en un punto de control y arrastrelo a un nodo para conectarlo.',
19004 createEdgeError: 'No se puede conectar una arista a un grupo.',
19005 deleteClusterError: 'No es posible eliminar grupos.',
19006 editClusterError: 'No es posible editar grupos.'
19007 };
19008 exports['es_ES'] = exports['es']; //Italiano
19009
19010 exports['it'] = {
19011 edit: 'Modifica',
19012 del: 'Cancella la selezione',
19013 back: 'Indietro',
19014 addNode: 'Aggiungi un nodo',
19015 addEdge: 'Aggiungi un vertice',
19016 editNode: 'Modifica il nodo',
19017 editEdge: 'Modifica il vertice',
19018 addDescription: 'Clicca per aggiungere un nuovo nodo',
19019 edgeDescription: 'Clicca su un nodo e trascinalo ad un altro nodo per connetterli.',
19020 editEdgeDescription: 'Clicca sui Punti di controllo e trascinali ad un nodo per connetterli.',
19021 createEdgeError: 'Non si possono collegare vertici ad un cluster',
19022 deleteClusterError: 'I cluster non possono essere cancellati',
19023 editClusterError: 'I clusters non possono essere modificati.'
19024 };
19025 exports['it_IT'] = exports['it']; // Dutch
19026
19027 exports['nl'] = {
19028 edit: 'Wijzigen',
19029 del: 'Selectie verwijderen',
19030 back: 'Terug',
19031 addNode: 'Node toevoegen',
19032 addEdge: 'Link toevoegen',
19033 editNode: 'Node wijzigen',
19034 editEdge: 'Link wijzigen',
19035 addDescription: 'Klik op een leeg gebied om een nieuwe node te maken.',
19036 edgeDescription: 'Klik op een node en sleep de link naar een andere node om ze te verbinden.',
19037 editEdgeDescription: 'Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.',
19038 createEdgeError: 'Kan geen link maken naar een cluster.',
19039 deleteClusterError: 'Clusters kunnen niet worden verwijderd.',
19040 editClusterError: 'Clusters kunnen niet worden aangepast.'
19041 };
19042 exports['nl_NL'] = exports['nl'];
19043 exports['nl_BE'] = exports['nl']; // Portuguese Brazil
19044
19045 exports['pt-br'] = {
19046 edit: 'Editar',
19047 del: 'Remover selecionado',
19048 back: 'Voltar',
19049 addNode: 'Adicionar nó',
19050 addEdge: 'Adicionar aresta',
19051 editNode: 'Editar nó',
19052 editEdge: 'Editar aresta',
19053 addDescription: 'Clique em um espaço em branco para adicionar um novo nó',
19054 edgeDescription: 'Clique em um nó e arraste a aresta até outro nó para conectá-los',
19055 editEdgeDescription: 'Clique nos pontos de controle e os arraste para um nó para conectá-los',
19056 createEdgeError: 'Não foi possível linkar arestas a um cluster.',
19057 deleteClusterError: 'Clusters não puderam ser removidos.',
19058 editClusterError: 'Clusters não puderam ser editados.'
19059 };
19060 exports['pt-BR'] = exports['pt-br'];
19061 exports['pt_BR'] = exports['pt-br'];
19062 exports['pt_br'] = exports['pt-br']; // Russian
19063
19064 exports['ru'] = {
19065 edit: 'Редактировать',
19066 del: 'Удалить выбранное',
19067 back: 'Назад',
19068 addNode: 'Добавить узел',
19069 addEdge: 'Добавить ребро',
19070 editNode: 'Редактировать узел',
19071 editEdge: 'Редактировать ребро',
19072 addDescription: 'Кликните в свободное место, чтобы добавить новый узел.',
19073 edgeDescription: 'Кликните на узел и протяните ребро к другому узлу, чтобы соединить их.',
19074 editEdgeDescription: 'Кликните на контрольные точки и перетащите их в узел, чтобы подключиться к нему.',
19075 createEdgeError: 'Невозможно соединить ребра в кластер.',
19076 deleteClusterError: 'Кластеры не могут быть удалены',
19077 editClusterError: 'Кластеры недоступны для редактирования.'
19078 };
19079 exports['ru_RU'] = exports['ru']; // Chinese
19080
19081 exports['cn'] = {
19082 edit: '编辑',
19083 del: '删除选定',
19084 back: '返回',
19085 addNode: '添加节点',
19086 addEdge: '添加连接线',
19087 editNode: '编辑节点',
19088 editEdge: '编辑连接线',
19089 addDescription: '单击空白处放置新节点。',
19090 edgeDescription: '单击某个节点并将该连接线拖动到另一个节点以连接它们。',
19091 editEdgeDescription: '单击控制节点并将它们拖到节点上连接。',
19092 createEdgeError: '无法将连接线连接到群集。',
19093 deleteClusterError: '无法删除群集。',
19094 editClusterError: '无法编辑群集。'
19095 };
19096 exports['zh_CN'] = exports['cn']; // Ukrainian
19097
19098 exports['uk'] = {
19099 edit: 'Редагувати',
19100 del: 'Видалити обране',
19101 back: 'Назад',
19102 addNode: 'Додати вузол',
19103 addEdge: 'Додати край',
19104 editNode: 'Редагувати вузол',
19105 editEdge: 'Редагувати край',
19106 addDescription: 'Kлікніть на вільне місце, щоб додати новий вузол.',
19107 edgeDescription: 'Клікніть на вузол і перетягніть край до іншого вузла, щоб їх з\'єднати.',
19108 editEdgeDescription: 'Клікніть на контрольні точки і перетягніть їх у вузол, щоб підключитися до нього.',
19109 createEdgeError: 'Не можливо об\'єднати краї в групу.',
19110 deleteClusterError: 'Групи не можуть бути видалені.',
19111 editClusterError: 'Групи недоступні для редагування.'
19112 };
19113 exports['uk_UA'] = exports['uk']; // French
19114
19115 exports['fr'] = {
19116 edit: 'Editer',
19117 del: 'Effacer la selection',
19118 back: 'Retour',
19119 addNode: 'Ajouter un noeud',
19120 addEdge: 'Ajouter un lien',
19121 editNode: 'Editer le noeud',
19122 editEdge: 'Editer le lien',
19123 addDescription: 'Cliquez dans un endroit vide pour placer un noeud.',
19124 edgeDescription: 'Cliquez sur un noeud et glissez le lien vers un autre noeud pour les connecter.',
19125 editEdgeDescription: 'Cliquez sur les points de contrôle et glissez-les pour connecter un noeud.',
19126 createEdgeError: 'Impossible de créer un lien vers un cluster.',
19127 deleteClusterError: 'Les clusters ne peuvent pas être éffacés.',
19128 editClusterError: 'Les clusters ne peuvent pas être édites.'
19129 };
19130 exports['fr_FR'] = exports['fr']; // Czech
19131
19132 exports['cs'] = {
19133 edit: 'Upravit',
19134 del: 'Smazat výběr',
19135 back: 'Zpět',
19136 addNode: 'Přidat vrchol',
19137 addEdge: 'Přidat hranu',
19138 editNode: 'Upravit vrchol',
19139 editEdge: 'Upravit hranu',
19140 addDescription: 'Kluknutím do prázdného prostoru můžete přidat nový vrchol.',
19141 edgeDescription: 'Přetažením z jednoho vrcholu do druhého můžete spojit tyto vrcholy novou hranou.',
19142 editEdgeDescription: 'Přetažením kontrolního vrcholu hrany ji můžete připojit k jinému vrcholu.',
19143 createEdgeError: 'Nelze připojit hranu ke shluku.',
19144 deleteClusterError: 'Nelze mazat shluky.',
19145 editClusterError: 'Nelze upravovat shluky.'
19146 };
19147 exports['cs_CZ'] = exports['cs'];
19148 });
19149
19150 /**
19151 * Associates a canvas to a given image, containing a number of renderings
19152 * of the image at various sizes.
19153 *
19154 * This technique is known as 'mipmapping'.
19155 *
19156 * NOTE: Images can also be of type 'data:svg+xml`. This code also works
19157 * for svg, but the mipmapping may not be necessary.
19158 *
19159 * @param {Image} image
19160 */
19161 var CachedImage =
19162 /*#__PURE__*/
19163 function () {
19164 /**
19165 * @ignore
19166 */
19167 function CachedImage() {
19168 _classCallCheck(this, CachedImage);
19169
19170 // eslint-disable-line no-unused-vars
19171 this.NUM_ITERATIONS = 4; // Number of items in the coordinates array
19172
19173 this.image = new Image();
19174 this.canvas = document.createElement('canvas');
19175 }
19176 /**
19177 * Called when the image has been successfully loaded.
19178 */
19179
19180
19181 _createClass(CachedImage, [{
19182 key: "init",
19183 value: function init() {
19184 if (this.initialized()) return;
19185 this.src = this.image.src; // For same interface with Image
19186
19187 var w = this.image.width;
19188 var h = this.image.height; // Ease external access
19189
19190 this.width = w;
19191 this.height = h;
19192 var h2 = Math.floor(h / 2);
19193 var h4 = Math.floor(h / 4);
19194 var h8 = Math.floor(h / 8);
19195 var h16 = Math.floor(h / 16);
19196 var w2 = Math.floor(w / 2);
19197 var w4 = Math.floor(w / 4);
19198 var w8 = Math.floor(w / 8);
19199 var w16 = Math.floor(w / 16); // Make canvas as small as possible
19200
19201 this.canvas.width = 3 * w4;
19202 this.canvas.height = h2; // Coordinates and sizes of images contained in the canvas
19203 // Values per row: [top x, left y, width, height]
19204
19205 this.coordinates = [[0, 0, w2, h2], [w2, 0, w4, h4], [w2, h4, w8, h8], [5 * w8, h4, w16, h16]];
19206
19207 this._fillMipMap();
19208 }
19209 /**
19210 * @return {Boolean} true if init() has been called, false otherwise.
19211 */
19212
19213 }, {
19214 key: "initialized",
19215 value: function initialized() {
19216 return this.coordinates !== undefined;
19217 }
19218 /**
19219 * Redraw main image in various sizes to the context.
19220 *
19221 * The rationale behind this is to reduce artefacts due to interpolation
19222 * at differing zoom levels.
19223 *
19224 * Source: http://stackoverflow.com/q/18761404/1223531
19225 *
19226 * This methods takes the resizing out of the drawing loop, in order to
19227 * reduce performance overhead.
19228 *
19229 * TODO: The code assumes that a 2D context can always be gotten. This is
19230 * not necessarily true! OTOH, if not true then usage of this class
19231 * is senseless.
19232 *
19233 * @private
19234 */
19235
19236 }, {
19237 key: "_fillMipMap",
19238 value: function _fillMipMap() {
19239 var ctx = this.canvas.getContext('2d'); // First zoom-level comes from the image
19240
19241 var to = this.coordinates[0];
19242 ctx.drawImage(this.image, to[0], to[1], to[2], to[3]); // The rest are copy actions internal to the canvas/context
19243
19244 for (var iterations = 1; iterations < this.NUM_ITERATIONS; iterations++) {
19245 var from = this.coordinates[iterations - 1];
19246 var _to = this.coordinates[iterations];
19247 ctx.drawImage(this.canvas, from[0], from[1], from[2], from[3], _to[0], _to[1], _to[2], _to[3]);
19248 }
19249 }
19250 /**
19251 * Draw the image, using the mipmap if necessary.
19252 *
19253 * MipMap is only used if param factor > 2; otherwise, original bitmap
19254 * is resized. This is also used to skip mipmap usage, e.g. by setting factor = 1
19255 *
19256 * Credits to 'Alex de Mulder' for original implementation.
19257 *
19258 * @param {CanvasRenderingContext2D} ctx context on which to draw zoomed image
19259 * @param {Float} factor scale factor at which to draw
19260 * @param {number} left
19261 * @param {number} top
19262 * @param {number} width
19263 * @param {number} height
19264 */
19265
19266 }, {
19267 key: "drawImageAtPosition",
19268 value: function drawImageAtPosition(ctx, factor, left, top, width, height) {
19269 if (!this.initialized()) return; //can't draw image yet not intialized
19270
19271 if (factor > 2) {
19272 // Determine which zoomed image to use
19273 factor *= 0.5;
19274 var iterations = 0;
19275
19276 while (factor > 2 && iterations < this.NUM_ITERATIONS) {
19277 factor *= 0.5;
19278 iterations += 1;
19279 }
19280
19281 if (iterations >= this.NUM_ITERATIONS) {
19282 iterations = this.NUM_ITERATIONS - 1;
19283 } //console.log("iterations: " + iterations);
19284
19285
19286 var from = this.coordinates[iterations];
19287 ctx.drawImage(this.canvas, from[0], from[1], from[2], from[3], left, top, width, height);
19288 } else {
19289 // Draw image directly
19290 ctx.drawImage(this.image, left, top, width, height);
19291 }
19292 }
19293 }]);
19294
19295 return CachedImage;
19296 }();
19297
19298 /**
19299 * This callback is a callback that accepts an Image.
19300 * @callback ImageCallback
19301 * @param {Image} image
19302 */
19303
19304 /**
19305 * This class loads images and keeps them stored.
19306 *
19307 * @param {ImageCallback} callback
19308 */
19309
19310 var Images =
19311 /*#__PURE__*/
19312 function () {
19313 /**
19314 * @param {ImageCallback} callback
19315 */
19316 function Images(callback) {
19317 _classCallCheck(this, Images);
19318
19319 this.images = {};
19320 this.imageBroken = {};
19321 this.callback = callback;
19322 }
19323 /**
19324 * @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
19325 * @param {string} brokenUrl Url the broken image to try and load
19326 * @param {Image} imageToLoadBrokenUrlOn The image object
19327 */
19328
19329
19330 _createClass(Images, [{
19331 key: "_tryloadBrokenUrl",
19332 value: function _tryloadBrokenUrl(url, brokenUrl, imageToLoadBrokenUrlOn) {
19333 //If these parameters aren't specified then exit the function because nothing constructive can be done
19334 if (url === undefined || imageToLoadBrokenUrlOn === undefined) return;
19335
19336 if (brokenUrl === undefined) {
19337 console.warn("No broken url image defined");
19338 return;
19339 } //Clear the old subscription to the error event and put a new in place that only handle errors in loading the brokenImageUrl
19340
19341
19342 imageToLoadBrokenUrlOn.image.onerror = function () {
19343 console.error("Could not load brokenImage:", brokenUrl); // cache item will contain empty image, this should be OK for default
19344 }; //Set the source of the image to the brokenUrl, this is actually what kicks off the loading of the broken image
19345
19346
19347 imageToLoadBrokenUrlOn.image.src = brokenUrl;
19348 }
19349 /**
19350 *
19351 * @param {vis.Image} imageToRedrawWith
19352 * @private
19353 */
19354
19355 }, {
19356 key: "_redrawWithImage",
19357 value: function _redrawWithImage(imageToRedrawWith) {
19358 if (this.callback) {
19359 this.callback(imageToRedrawWith);
19360 }
19361 }
19362 /**
19363 * @param {string} url Url of the image
19364 * @param {string} brokenUrl Url of an image to use if the url image is not found
19365 * @return {Image} img The image object
19366 */
19367
19368 }, {
19369 key: "load",
19370 value: function load(url, brokenUrl) {
19371 var _this = this;
19372
19373 //Try and get the image from the cache, if successful then return the cached image
19374 var cachedImage = this.images[url];
19375 if (cachedImage) return cachedImage; //Create a new image
19376
19377 var img = new CachedImage(); // Need to add to cache here, otherwise final return will spawn different copies of the same image,
19378 // Also, there will be multiple loads of the same image.
19379
19380 this.images[url] = img; //Subscribe to the event that is raised if the image loads successfully
19381
19382 img.image.onload = function () {
19383 // Properly init the cached item and then request a redraw
19384 _this._fixImageCoordinates(img.image);
19385
19386 img.init();
19387
19388 _this._redrawWithImage(img);
19389 }; //Subscribe to the event that is raised if the image fails to load
19390
19391
19392 img.image.onerror = function () {
19393 console.error("Could not load image:", url); //Try and load the image specified by the brokenUrl using
19394
19395 _this._tryloadBrokenUrl(url, brokenUrl, img);
19396 }; //Set the source of the image to the url, this is what actually kicks off the loading of the image
19397
19398
19399 img.image.src = url; //Return the new image
19400
19401 return img;
19402 }
19403 /**
19404 * IE11 fix -- thanks dponch!
19405 *
19406 * Local helper function
19407 * @param {vis.Image} imageToCache
19408 * @private
19409 */
19410
19411 }, {
19412 key: "_fixImageCoordinates",
19413 value: function _fixImageCoordinates(imageToCache) {
19414 if (imageToCache.width === 0) {
19415 document.body.appendChild(imageToCache);
19416 imageToCache.width = imageToCache.offsetWidth;
19417 imageToCache.height = imageToCache.offsetHeight;
19418 document.body.removeChild(imageToCache);
19419 }
19420 }
19421 }]);
19422
19423 return Images;
19424 }();
19425
19426 /**
19427 * This class can store groups and options specific for groups.
19428 */
19429
19430 var Groups =
19431 /*#__PURE__*/
19432 function () {
19433 /**
19434 * @ignore
19435 */
19436 function Groups() {
19437 _classCallCheck(this, Groups);
19438
19439 this.clear();
19440 this.defaultIndex = 0;
19441 this.groupsArray = [];
19442 this.groupIndex = 0;
19443 this.defaultGroups = [{
19444 border: "#2B7CE9",
19445 background: "#97C2FC",
19446 highlight: {
19447 border: "#2B7CE9",
19448 background: "#D2E5FF"
19449 },
19450 hover: {
19451 border: "#2B7CE9",
19452 background: "#D2E5FF"
19453 }
19454 }, // 0: blue
19455 {
19456 border: "#FFA500",
19457 background: "#FFFF00",
19458 highlight: {
19459 border: "#FFA500",
19460 background: "#FFFFA3"
19461 },
19462 hover: {
19463 border: "#FFA500",
19464 background: "#FFFFA3"
19465 }
19466 }, // 1: yellow
19467 {
19468 border: "#FA0A10",
19469 background: "#FB7E81",
19470 highlight: {
19471 border: "#FA0A10",
19472 background: "#FFAFB1"
19473 },
19474 hover: {
19475 border: "#FA0A10",
19476 background: "#FFAFB1"
19477 }
19478 }, // 2: red
19479 {
19480 border: "#41A906",
19481 background: "#7BE141",
19482 highlight: {
19483 border: "#41A906",
19484 background: "#A1EC76"
19485 },
19486 hover: {
19487 border: "#41A906",
19488 background: "#A1EC76"
19489 }
19490 }, // 3: green
19491 {
19492 border: "#E129F0",
19493 background: "#EB7DF4",
19494 highlight: {
19495 border: "#E129F0",
19496 background: "#F0B3F5"
19497 },
19498 hover: {
19499 border: "#E129F0",
19500 background: "#F0B3F5"
19501 }
19502 }, // 4: magenta
19503 {
19504 border: "#7C29F0",
19505 background: "#AD85E4",
19506 highlight: {
19507 border: "#7C29F0",
19508 background: "#D3BDF0"
19509 },
19510 hover: {
19511 border: "#7C29F0",
19512 background: "#D3BDF0"
19513 }
19514 }, // 5: purple
19515 {
19516 border: "#C37F00",
19517 background: "#FFA807",
19518 highlight: {
19519 border: "#C37F00",
19520 background: "#FFCA66"
19521 },
19522 hover: {
19523 border: "#C37F00",
19524 background: "#FFCA66"
19525 }
19526 }, // 6: orange
19527 {
19528 border: "#4220FB",
19529 background: "#6E6EFD",
19530 highlight: {
19531 border: "#4220FB",
19532 background: "#9B9BFD"
19533 },
19534 hover: {
19535 border: "#4220FB",
19536 background: "#9B9BFD"
19537 }
19538 }, // 7: darkblue
19539 {
19540 border: "#FD5A77",
19541 background: "#FFC0CB",
19542 highlight: {
19543 border: "#FD5A77",
19544 background: "#FFD1D9"
19545 },
19546 hover: {
19547 border: "#FD5A77",
19548 background: "#FFD1D9"
19549 }
19550 }, // 8: pink
19551 {
19552 border: "#4AD63A",
19553 background: "#C2FABC",
19554 highlight: {
19555 border: "#4AD63A",
19556 background: "#E6FFE3"
19557 },
19558 hover: {
19559 border: "#4AD63A",
19560 background: "#E6FFE3"
19561 }
19562 }, // 9: mint
19563 {
19564 border: "#990000",
19565 background: "#EE0000",
19566 highlight: {
19567 border: "#BB0000",
19568 background: "#FF3333"
19569 },
19570 hover: {
19571 border: "#BB0000",
19572 background: "#FF3333"
19573 }
19574 }, // 10:bright red
19575 {
19576 border: "#FF6000",
19577 background: "#FF6000",
19578 highlight: {
19579 border: "#FF6000",
19580 background: "#FF6000"
19581 },
19582 hover: {
19583 border: "#FF6000",
19584 background: "#FF6000"
19585 }
19586 }, // 12: real orange
19587 {
19588 border: "#97C2FC",
19589 background: "#2B7CE9",
19590 highlight: {
19591 border: "#D2E5FF",
19592 background: "#2B7CE9"
19593 },
19594 hover: {
19595 border: "#D2E5FF",
19596 background: "#2B7CE9"
19597 }
19598 }, // 13: blue
19599 {
19600 border: "#399605",
19601 background: "#255C03",
19602 highlight: {
19603 border: "#399605",
19604 background: "#255C03"
19605 },
19606 hover: {
19607 border: "#399605",
19608 background: "#255C03"
19609 }
19610 }, // 14: green
19611 {
19612 border: "#B70054",
19613 background: "#FF007E",
19614 highlight: {
19615 border: "#B70054",
19616 background: "#FF007E"
19617 },
19618 hover: {
19619 border: "#B70054",
19620 background: "#FF007E"
19621 }
19622 }, // 15: magenta
19623 {
19624 border: "#AD85E4",
19625 background: "#7C29F0",
19626 highlight: {
19627 border: "#D3BDF0",
19628 background: "#7C29F0"
19629 },
19630 hover: {
19631 border: "#D3BDF0",
19632 background: "#7C29F0"
19633 }
19634 }, // 16: purple
19635 {
19636 border: "#4557FA",
19637 background: "#000EA1",
19638 highlight: {
19639 border: "#6E6EFD",
19640 background: "#000EA1"
19641 },
19642 hover: {
19643 border: "#6E6EFD",
19644 background: "#000EA1"
19645 }
19646 }, // 17: darkblue
19647 {
19648 border: "#FFC0CB",
19649 background: "#FD5A77",
19650 highlight: {
19651 border: "#FFD1D9",
19652 background: "#FD5A77"
19653 },
19654 hover: {
19655 border: "#FFD1D9",
19656 background: "#FD5A77"
19657 }
19658 }, // 18: pink
19659 {
19660 border: "#C2FABC",
19661 background: "#74D66A",
19662 highlight: {
19663 border: "#E6FFE3",
19664 background: "#74D66A"
19665 },
19666 hover: {
19667 border: "#E6FFE3",
19668 background: "#74D66A"
19669 }
19670 }, // 19: mint
19671 {
19672 border: "#EE0000",
19673 background: "#990000",
19674 highlight: {
19675 border: "#FF3333",
19676 background: "#BB0000"
19677 },
19678 hover: {
19679 border: "#FF3333",
19680 background: "#BB0000"
19681 }
19682 } // 20:bright red
19683 ];
19684 this.options = {};
19685 this.defaultOptions = {
19686 useDefaultGroups: true
19687 };
19688 extend(this.options, this.defaultOptions);
19689 }
19690 /**
19691 *
19692 * @param {Object} options
19693 */
19694
19695
19696 _createClass(Groups, [{
19697 key: "setOptions",
19698 value: function setOptions(options) {
19699 var optionFields = ['useDefaultGroups'];
19700
19701 if (options !== undefined) {
19702 for (var groupName in options) {
19703 if (options.hasOwnProperty(groupName)) {
19704 if (optionFields.indexOf(groupName) === -1) {
19705 var group = options[groupName];
19706 this.add(groupName, group);
19707 }
19708 }
19709 }
19710 }
19711 }
19712 /**
19713 * Clear all groups
19714 */
19715
19716 }, {
19717 key: "clear",
19718 value: function clear() {
19719 this.groups = {};
19720 this.groupsArray = [];
19721 }
19722 /**
19723 * Get group options of a groupname.
19724 * If groupname is not found, a new group may be created.
19725 *
19726 * @param {*} groupname Can be a number, string, Date, etc.
19727 * @param {boolean} [shouldCreate=true] If true, create a new group
19728 * @return {Object} The found or created group
19729 */
19730
19731 }, {
19732 key: "get",
19733 value: function get(groupname) {
19734 var shouldCreate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19735 var group = this.groups[groupname];
19736
19737 if (group === undefined && shouldCreate) {
19738 if (this.options.useDefaultGroups === false && this.groupsArray.length > 0) {
19739 // create new group
19740 var index = this.groupIndex % this.groupsArray.length;
19741 this.groupIndex++;
19742 group = {};
19743 group.color = this.groups[this.groupsArray[index]];
19744 this.groups[groupname] = group;
19745 } else {
19746 // create new group
19747 var _index = this.defaultIndex % this.defaultGroups.length;
19748
19749 this.defaultIndex++;
19750 group = {};
19751 group.color = this.defaultGroups[_index];
19752 this.groups[groupname] = group;
19753 }
19754 }
19755
19756 return group;
19757 }
19758 /**
19759 * Add a custom group style
19760 * @param {string} groupName
19761 * @param {Object} style An object containing borderColor,
19762 * backgroundColor, etc.
19763 * @return {Object} group The created group object
19764 */
19765
19766 }, {
19767 key: "add",
19768 value: function add(groupName, style) {
19769 this.groups[groupName] = style;
19770 this.groupsArray.push(groupName);
19771 return style;
19772 }
19773 }]);
19774
19775 return Groups;
19776 }();
19777
19778 // `Symbol.asyncIterator` well-known symbol
19779 // https://tc39.github.io/ecma262/#sec-symbol.asynciterator
19780 defineWellKnownSymbol('asyncIterator');
19781
19782 // `Symbol.toStringTag` well-known symbol
19783 // https://tc39.github.io/ecma262/#sec-symbol.tostringtag
19784 defineWellKnownSymbol('toStringTag');
19785
19786 var $reduce$1 = arrayReduce.left;
19787
19788
19789 // `Array.prototype.reduce` method
19790 // https://tc39.github.io/ecma262/#sec-array.prototype.reduce
19791 _export({ target: 'Array', proto: true, forced: sloppyArrayMethod('reduce') }, {
19792 reduce: function reduce(callbackfn /* , initialValue */) {
19793 return $reduce$1(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
19794 }
19795 });
19796
19797 var nativeReverse = [].reverse;
19798 var test$3 = [1, 2];
19799
19800 // `Array.prototype.reverse` method
19801 // https://tc39.github.io/ecma262/#sec-array.prototype.reverse
19802 // fix for Safari 12.0 bug
19803 // https://bugs.webkit.org/show_bug.cgi?id=188794
19804 _export({ target: 'Array', proto: true, forced: String(test$3) === String(test$3.reverse()) }, {
19805 reverse: function reverse() {
19806 if (isArray(this)) this.length = this.length;
19807 return nativeReverse.call(this);
19808 }
19809 });
19810
19811 // JSON[@@toStringTag] property
19812 // https://tc39.github.io/ecma262/#sec-json-@@tostringtag
19813 setToStringTag(global_1.JSON, 'JSON', true);
19814
19815 var iterate_1 = createCommonjsModule(function (module) {
19816 var Result = function (stopped, result) {
19817 this.stopped = stopped;
19818 this.result = result;
19819 };
19820
19821 var iterate = module.exports = function (iterable, fn, that, AS_ENTRIES, IS_ITERATOR) {
19822 var boundFunction = bindContext(fn, that, AS_ENTRIES ? 2 : 1);
19823 var iterator, iterFn, index, length, result, next, step;
19824
19825 if (IS_ITERATOR) {
19826 iterator = iterable;
19827 } else {
19828 iterFn = getIteratorMethod(iterable);
19829 if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
19830 // optimisation for array iterators
19831 if (isArrayIteratorMethod(iterFn)) {
19832 for (index = 0, length = toLength(iterable.length); length > index; index++) {
19833 result = AS_ENTRIES
19834 ? boundFunction(anObject(step = iterable[index])[0], step[1])
19835 : boundFunction(iterable[index]);
19836 if (result && result instanceof Result) return result;
19837 } return new Result(false);
19838 }
19839 iterator = iterFn.call(iterable);
19840 }
19841
19842 next = iterator.next;
19843 while (!(step = next.call(iterator)).done) {
19844 result = callWithSafeIterationClosing(iterator, boundFunction, step.value, AS_ENTRIES);
19845 if (typeof result == 'object' && result && result instanceof Result) return result;
19846 } return new Result(false);
19847 };
19848
19849 iterate.stop = function (result) {
19850 return new Result(true, result);
19851 };
19852 });
19853
19854 var collection = function (CONSTRUCTOR_NAME, wrapper, common, IS_MAP, IS_WEAK) {
19855 var NativeConstructor = global_1[CONSTRUCTOR_NAME];
19856 var NativePrototype = NativeConstructor && NativeConstructor.prototype;
19857 var Constructor = NativeConstructor;
19858 var ADDER = IS_MAP ? 'set' : 'add';
19859 var exported = {};
19860
19861 var fixMethod = function (KEY) {
19862 var nativeMethod = NativePrototype[KEY];
19863 redefine(NativePrototype, KEY,
19864 KEY == 'add' ? function add(value) {
19865 nativeMethod.call(this, value === 0 ? 0 : value);
19866 return this;
19867 } : KEY == 'delete' ? function (key) {
19868 return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
19869 } : KEY == 'get' ? function get(key) {
19870 return IS_WEAK && !isObject(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key);
19871 } : KEY == 'has' ? function has(key) {
19872 return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
19873 } : function set(key, value) {
19874 nativeMethod.call(this, key === 0 ? 0 : key, value);
19875 return this;
19876 }
19877 );
19878 };
19879
19880 // eslint-disable-next-line max-len
19881 if (isForced_1(CONSTRUCTOR_NAME, typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
19882 new NativeConstructor().entries().next();
19883 })))) {
19884 // create collection constructor
19885 Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
19886 internalMetadata.REQUIRED = true;
19887 } else if (isForced_1(CONSTRUCTOR_NAME, true)) {
19888 var instance = new Constructor();
19889 // early implementations not supports chaining
19890 var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
19891 // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
19892 var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
19893 // most early implementations doesn't supports iterables, most modern - not close it correctly
19894 // eslint-disable-next-line no-new
19895 var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
19896 // for early implementations -0 and +0 not the same
19897 var BUGGY_ZERO = !IS_WEAK && fails(function () {
19898 // V8 ~ Chromium 42- fails only with 5+ elements
19899 var $instance = new NativeConstructor();
19900 var index = 5;
19901 while (index--) $instance[ADDER](index, index);
19902 return !$instance.has(-0);
19903 });
19904
19905 if (!ACCEPT_ITERABLES) {
19906 Constructor = wrapper(function (dummy, iterable) {
19907 anInstance(dummy, Constructor, CONSTRUCTOR_NAME);
19908 var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);
19909 if (iterable != undefined) iterate_1(iterable, that[ADDER], that, IS_MAP);
19910 return that;
19911 });
19912 Constructor.prototype = NativePrototype;
19913 NativePrototype.constructor = Constructor;
19914 }
19915
19916 if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
19917 fixMethod('delete');
19918 fixMethod('has');
19919 IS_MAP && fixMethod('get');
19920 }
19921
19922 if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
19923
19924 // weak collections should not contains .clear method
19925 if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
19926 }
19927
19928 exported[CONSTRUCTOR_NAME] = Constructor;
19929 _export({ global: true, forced: Constructor != NativeConstructor }, exported);
19930
19931 setToStringTag(Constructor, CONSTRUCTOR_NAME);
19932
19933 if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
19934
19935 return Constructor;
19936 };
19937
19938 var defineProperty$9 = objectDefineProperty.f;
19939
19940
19941
19942
19943
19944
19945
19946
19947 var fastKey = internalMetadata.fastKey;
19948
19949
19950 var setInternalState$4 = internalState.set;
19951 var internalStateGetterFor = internalState.getterFor;
19952
19953 var collectionStrong = {
19954 getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
19955 var C = wrapper(function (that, iterable) {
19956 anInstance(that, C, CONSTRUCTOR_NAME);
19957 setInternalState$4(that, {
19958 type: CONSTRUCTOR_NAME,
19959 index: objectCreate(null),
19960 first: undefined,
19961 last: undefined,
19962 size: 0
19963 });
19964 if (!descriptors) that.size = 0;
19965 if (iterable != undefined) iterate_1(iterable, that[ADDER], that, IS_MAP);
19966 });
19967
19968 var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);
19969
19970 var define = function (that, key, value) {
19971 var state = getInternalState(that);
19972 var entry = getEntry(that, key);
19973 var previous, index;
19974 // change existing entry
19975 if (entry) {
19976 entry.value = value;
19977 // create new entry
19978 } else {
19979 state.last = entry = {
19980 index: index = fastKey(key, true),
19981 key: key,
19982 value: value,
19983 previous: previous = state.last,
19984 next: undefined,
19985 removed: false
19986 };
19987 if (!state.first) state.first = entry;
19988 if (previous) previous.next = entry;
19989 if (descriptors) state.size++;
19990 else that.size++;
19991 // add to index
19992 if (index !== 'F') state.index[index] = entry;
19993 } return that;
19994 };
19995
19996 var getEntry = function (that, key) {
19997 var state = getInternalState(that);
19998 // fast case
19999 var index = fastKey(key);
20000 var entry;
20001 if (index !== 'F') return state.index[index];
20002 // frozen object case
20003 for (entry = state.first; entry; entry = entry.next) {
20004 if (entry.key == key) return entry;
20005 }
20006 };
20007
20008 redefineAll(C.prototype, {
20009 // 23.1.3.1 Map.prototype.clear()
20010 // 23.2.3.2 Set.prototype.clear()
20011 clear: function clear() {
20012 var that = this;
20013 var state = getInternalState(that);
20014 var data = state.index;
20015 var entry = state.first;
20016 while (entry) {
20017 entry.removed = true;
20018 if (entry.previous) entry.previous = entry.previous.next = undefined;
20019 delete data[entry.index];
20020 entry = entry.next;
20021 }
20022 state.first = state.last = undefined;
20023 if (descriptors) state.size = 0;
20024 else that.size = 0;
20025 },
20026 // 23.1.3.3 Map.prototype.delete(key)
20027 // 23.2.3.4 Set.prototype.delete(value)
20028 'delete': function (key) {
20029 var that = this;
20030 var state = getInternalState(that);
20031 var entry = getEntry(that, key);
20032 if (entry) {
20033 var next = entry.next;
20034 var prev = entry.previous;
20035 delete state.index[entry.index];
20036 entry.removed = true;
20037 if (prev) prev.next = next;
20038 if (next) next.previous = prev;
20039 if (state.first == entry) state.first = next;
20040 if (state.last == entry) state.last = prev;
20041 if (descriptors) state.size--;
20042 else that.size--;
20043 } return !!entry;
20044 },
20045 // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
20046 // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
20047 forEach: function forEach(callbackfn /* , that = undefined */) {
20048 var state = getInternalState(this);
20049 var boundFunction = bindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
20050 var entry;
20051 while (entry = entry ? entry.next : state.first) {
20052 boundFunction(entry.value, entry.key, this);
20053 // revert to the last existing entry
20054 while (entry && entry.removed) entry = entry.previous;
20055 }
20056 },
20057 // 23.1.3.7 Map.prototype.has(key)
20058 // 23.2.3.7 Set.prototype.has(value)
20059 has: function has(key) {
20060 return !!getEntry(this, key);
20061 }
20062 });
20063
20064 redefineAll(C.prototype, IS_MAP ? {
20065 // 23.1.3.6 Map.prototype.get(key)
20066 get: function get(key) {
20067 var entry = getEntry(this, key);
20068 return entry && entry.value;
20069 },
20070 // 23.1.3.9 Map.prototype.set(key, value)
20071 set: function set(key, value) {
20072 return define(this, key === 0 ? 0 : key, value);
20073 }
20074 } : {
20075 // 23.2.3.1 Set.prototype.add(value)
20076 add: function add(value) {
20077 return define(this, value = value === 0 ? 0 : value, value);
20078 }
20079 });
20080 if (descriptors) defineProperty$9(C.prototype, 'size', {
20081 get: function () {
20082 return getInternalState(this).size;
20083 }
20084 });
20085 return C;
20086 },
20087 setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) {
20088 var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator';
20089 var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME);
20090 var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME);
20091 // add .keys, .values, .entries, [@@iterator]
20092 // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
20093 defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) {
20094 setInternalState$4(this, {
20095 type: ITERATOR_NAME,
20096 target: iterated,
20097 state: getInternalCollectionState(iterated),
20098 kind: kind,
20099 last: undefined
20100 });
20101 }, function () {
20102 var state = getInternalIteratorState(this);
20103 var kind = state.kind;
20104 var entry = state.last;
20105 // revert to the last existing entry
20106 while (entry && entry.removed) entry = entry.previous;
20107 // get next entry
20108 if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) {
20109 // or finish the iteration
20110 state.target = undefined;
20111 return { value: undefined, done: true };
20112 }
20113 // return step by kind
20114 if (kind == 'keys') return { value: entry.key, done: false };
20115 if (kind == 'values') return { value: entry.value, done: false };
20116 return { value: [entry.key, entry.value], done: false };
20117 }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
20118
20119 // add [@@species], 23.1.2.2, 23.2.2.2
20120 setSpecies(CONSTRUCTOR_NAME);
20121 }
20122 };
20123
20124 // `Map` constructor
20125 // https://tc39.github.io/ecma262/#sec-map-objects
20126 var es_map = collection('Map', function (get) {
20127 return function Map() { return get(this, arguments.length ? arguments[0] : undefined); };
20128 }, collectionStrong, true);
20129
20130 // Math[@@toStringTag] property
20131 // https://tc39.github.io/ecma262/#sec-math-@@tostringtag
20132 setToStringTag(Math, 'Math', true);
20133
20134 var nativePromiseConstructor = global_1.Promise;
20135
20136 var location = global_1.location;
20137 var set$2 = global_1.setImmediate;
20138 var clear = global_1.clearImmediate;
20139 var process$1 = global_1.process;
20140 var MessageChannel = global_1.MessageChannel;
20141 var Dispatch = global_1.Dispatch;
20142 var counter = 0;
20143 var queue = {};
20144 var ONREADYSTATECHANGE = 'onreadystatechange';
20145 var defer, channel, port;
20146
20147 var run = function (id) {
20148 // eslint-disable-next-line no-prototype-builtins
20149 if (queue.hasOwnProperty(id)) {
20150 var fn = queue[id];
20151 delete queue[id];
20152 fn();
20153 }
20154 };
20155
20156 var runner = function (id) {
20157 return function () {
20158 run(id);
20159 };
20160 };
20161
20162 var listener = function (event) {
20163 run(event.data);
20164 };
20165
20166 var post = function (id) {
20167 // old engines have not location.origin
20168 global_1.postMessage(id + '', location.protocol + '//' + location.host);
20169 };
20170
20171 // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
20172 if (!set$2 || !clear) {
20173 set$2 = function setImmediate(fn) {
20174 var args = [];
20175 var i = 1;
20176 while (arguments.length > i) args.push(arguments[i++]);
20177 queue[++counter] = function () {
20178 // eslint-disable-next-line no-new-func
20179 (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
20180 };
20181 defer(counter);
20182 return counter;
20183 };
20184 clear = function clearImmediate(id) {
20185 delete queue[id];
20186 };
20187 // Node.js 0.8-
20188 if (classofRaw(process$1) == 'process') {
20189 defer = function (id) {
20190 process$1.nextTick(runner(id));
20191 };
20192 // Sphere (JS game engine) Dispatch API
20193 } else if (Dispatch && Dispatch.now) {
20194 defer = function (id) {
20195 Dispatch.now(runner(id));
20196 };
20197 // Browsers with MessageChannel, includes WebWorkers
20198 // except iOS - https://github.com/zloirock/core-js/issues/624
20199 } else if (MessageChannel && !/(iphone|ipod|ipad).*applewebkit/i.test(userAgent)) {
20200 channel = new MessageChannel();
20201 port = channel.port2;
20202 channel.port1.onmessage = listener;
20203 defer = bindContext(port.postMessage, port, 1);
20204 // Browsers with postMessage, skip WebWorkers
20205 // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
20206 } else if (global_1.addEventListener && typeof postMessage == 'function' && !global_1.importScripts && !fails(post)) {
20207 defer = post;
20208 global_1.addEventListener('message', listener, false);
20209 // IE8-
20210 } else if (ONREADYSTATECHANGE in documentCreateElement('script')) {
20211 defer = function (id) {
20212 html.appendChild(documentCreateElement('script'))[ONREADYSTATECHANGE] = function () {
20213 html.removeChild(this);
20214 run(id);
20215 };
20216 };
20217 // Rest old browsers
20218 } else {
20219 defer = function (id) {
20220 setTimeout(runner(id), 0);
20221 };
20222 }
20223 }
20224
20225 var task = {
20226 set: set$2,
20227 clear: clear
20228 };
20229
20230 var getOwnPropertyDescriptor$3 = objectGetOwnPropertyDescriptor.f;
20231
20232 var macrotask = task.set;
20233
20234
20235 var MutationObserver = global_1.MutationObserver || global_1.WebKitMutationObserver;
20236 var process$2 = global_1.process;
20237 var Promise$1 = global_1.Promise;
20238 var IS_NODE = classofRaw(process$2) == 'process';
20239 // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask`
20240 var queueMicrotaskDescriptor = getOwnPropertyDescriptor$3(global_1, 'queueMicrotask');
20241 var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value;
20242
20243 var flush, head, last, notify, toggle, node, promise, then;
20244
20245 // modern engines have queueMicrotask method
20246 if (!queueMicrotask) {
20247 flush = function () {
20248 var parent, fn;
20249 if (IS_NODE && (parent = process$2.domain)) parent.exit();
20250 while (head) {
20251 fn = head.fn;
20252 head = head.next;
20253 try {
20254 fn();
20255 } catch (error) {
20256 if (head) notify();
20257 else last = undefined;
20258 throw error;
20259 }
20260 } last = undefined;
20261 if (parent) parent.enter();
20262 };
20263
20264 // Node.js
20265 if (IS_NODE) {
20266 notify = function () {
20267 process$2.nextTick(flush);
20268 };
20269 // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339
20270 } else if (MutationObserver && !/(iphone|ipod|ipad).*applewebkit/i.test(userAgent)) {
20271 toggle = true;
20272 node = document.createTextNode('');
20273 new MutationObserver(flush).observe(node, { characterData: true });
20274 notify = function () {
20275 node.data = toggle = !toggle;
20276 };
20277 // environments with maybe non-completely correct, but existent Promise
20278 } else if (Promise$1 && Promise$1.resolve) {
20279 // Promise.resolve without an argument throws an error in LG WebOS 2
20280 promise = Promise$1.resolve(undefined);
20281 then = promise.then;
20282 notify = function () {
20283 then.call(promise, flush);
20284 };
20285 // for other environments - macrotask based on:
20286 // - setImmediate
20287 // - MessageChannel
20288 // - window.postMessag
20289 // - onreadystatechange
20290 // - setTimeout
20291 } else {
20292 notify = function () {
20293 // strange IE + webpack dev server bug - use .call(global)
20294 macrotask.call(global_1, flush);
20295 };
20296 }
20297 }
20298
20299 var microtask = queueMicrotask || function (fn) {
20300 var task = { fn: fn, next: undefined };
20301 if (last) last.next = task;
20302 if (!head) {
20303 head = task;
20304 notify();
20305 } last = task;
20306 };
20307
20308 var PromiseCapability = function (C) {
20309 var resolve, reject;
20310 this.promise = new C(function ($$resolve, $$reject) {
20311 if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
20312 resolve = $$resolve;
20313 reject = $$reject;
20314 });
20315 this.resolve = aFunction$1(resolve);
20316 this.reject = aFunction$1(reject);
20317 };
20318
20319 // 25.4.1.5 NewPromiseCapability(C)
20320 var f$8 = function (C) {
20321 return new PromiseCapability(C);
20322 };
20323
20324 var newPromiseCapability = {
20325 f: f$8
20326 };
20327
20328 var promiseResolve = function (C, x) {
20329 anObject(C);
20330 if (isObject(x) && x.constructor === C) return x;
20331 var promiseCapability = newPromiseCapability.f(C);
20332 var resolve = promiseCapability.resolve;
20333 resolve(x);
20334 return promiseCapability.promise;
20335 };
20336
20337 var hostReportErrors = function (a, b) {
20338 var console = global_1.console;
20339 if (console && console.error) {
20340 arguments.length === 1 ? console.error(a) : console.error(a, b);
20341 }
20342 };
20343
20344 var perform = function (exec) {
20345 try {
20346 return { error: false, value: exec() };
20347 } catch (error) {
20348 return { error: true, value: error };
20349 }
20350 };
20351
20352 var task$1 = task.set;
20353
20354
20355
20356
20357
20358
20359
20360
20361
20362
20363 var SPECIES$7 = wellKnownSymbol('species');
20364 var PROMISE = 'Promise';
20365 var getInternalState$4 = internalState.get;
20366 var setInternalState$5 = internalState.set;
20367 var getInternalPromiseState = internalState.getterFor(PROMISE);
20368 var PromiseConstructor = nativePromiseConstructor;
20369 var TypeError$1 = global_1.TypeError;
20370 var document$3 = global_1.document;
20371 var process$3 = global_1.process;
20372 var $fetch = getBuiltIn('fetch');
20373 var newPromiseCapability$1 = newPromiseCapability.f;
20374 var newGenericPromiseCapability = newPromiseCapability$1;
20375 var IS_NODE$1 = classofRaw(process$3) == 'process';
20376 var DISPATCH_EVENT = !!(document$3 && document$3.createEvent && global_1.dispatchEvent);
20377 var UNHANDLED_REJECTION = 'unhandledrejection';
20378 var REJECTION_HANDLED = 'rejectionhandled';
20379 var PENDING = 0;
20380 var FULFILLED = 1;
20381 var REJECTED = 2;
20382 var HANDLED = 1;
20383 var UNHANDLED = 2;
20384 var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen;
20385
20386 var FORCED$b = isForced_1(PROMISE, function () {
20387 // correct subclassing with @@species support
20388 var promise = PromiseConstructor.resolve(1);
20389 var empty = function () { /* empty */ };
20390 var FakePromise = (promise.constructor = {})[SPECIES$7] = function (exec) {
20391 exec(empty, empty);
20392 };
20393 // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
20394 return !((IS_NODE$1 || typeof PromiseRejectionEvent == 'function')
20395 && (!isPure || promise['finally'])
20396 && promise.then(empty) instanceof FakePromise
20397 // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
20398 // https://bugs.chromium.org/p/chromium/issues/detail?id=830565
20399 // we can't detect it synchronously, so just check versions
20400 && v8Version !== 66);
20401 });
20402
20403 var INCORRECT_ITERATION$1 = FORCED$b || !checkCorrectnessOfIteration(function (iterable) {
20404 PromiseConstructor.all(iterable)['catch'](function () { /* empty */ });
20405 });
20406
20407 // helpers
20408 var isThenable = function (it) {
20409 var then;
20410 return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
20411 };
20412
20413 var notify$1 = function (promise, state, isReject) {
20414 if (state.notified) return;
20415 state.notified = true;
20416 var chain = state.reactions;
20417 microtask(function () {
20418 var value = state.value;
20419 var ok = state.state == FULFILLED;
20420 var index = 0;
20421 // variable length - can't use forEach
20422 while (chain.length > index) {
20423 var reaction = chain[index++];
20424 var handler = ok ? reaction.ok : reaction.fail;
20425 var resolve = reaction.resolve;
20426 var reject = reaction.reject;
20427 var domain = reaction.domain;
20428 var result, then, exited;
20429 try {
20430 if (handler) {
20431 if (!ok) {
20432 if (state.rejection === UNHANDLED) onHandleUnhandled(promise, state);
20433 state.rejection = HANDLED;
20434 }
20435 if (handler === true) result = value;
20436 else {
20437 if (domain) domain.enter();
20438 result = handler(value); // can throw
20439 if (domain) {
20440 domain.exit();
20441 exited = true;
20442 }
20443 }
20444 if (result === reaction.promise) {
20445 reject(TypeError$1('Promise-chain cycle'));
20446 } else if (then = isThenable(result)) {
20447 then.call(result, resolve, reject);
20448 } else resolve(result);
20449 } else reject(value);
20450 } catch (error) {
20451 if (domain && !exited) domain.exit();
20452 reject(error);
20453 }
20454 }
20455 state.reactions = [];
20456 state.notified = false;
20457 if (isReject && !state.rejection) onUnhandled(promise, state);
20458 });
20459 };
20460
20461 var dispatchEvent = function (name, promise, reason) {
20462 var event, handler;
20463 if (DISPATCH_EVENT) {
20464 event = document$3.createEvent('Event');
20465 event.promise = promise;
20466 event.reason = reason;
20467 event.initEvent(name, false, true);
20468 global_1.dispatchEvent(event);
20469 } else event = { promise: promise, reason: reason };
20470 if (handler = global_1['on' + name]) handler(event);
20471 else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
20472 };
20473
20474 var onUnhandled = function (promise, state) {
20475 task$1.call(global_1, function () {
20476 var value = state.value;
20477 var IS_UNHANDLED = isUnhandled(state);
20478 var result;
20479 if (IS_UNHANDLED) {
20480 result = perform(function () {
20481 if (IS_NODE$1) {
20482 process$3.emit('unhandledRejection', value, promise);
20483 } else dispatchEvent(UNHANDLED_REJECTION, promise, value);
20484 });
20485 // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
20486 state.rejection = IS_NODE$1 || isUnhandled(state) ? UNHANDLED : HANDLED;
20487 if (result.error) throw result.value;
20488 }
20489 });
20490 };
20491
20492 var isUnhandled = function (state) {
20493 return state.rejection !== HANDLED && !state.parent;
20494 };
20495
20496 var onHandleUnhandled = function (promise, state) {
20497 task$1.call(global_1, function () {
20498 if (IS_NODE$1) {
20499 process$3.emit('rejectionHandled', promise);
20500 } else dispatchEvent(REJECTION_HANDLED, promise, state.value);
20501 });
20502 };
20503
20504 var bind = function (fn, promise, state, unwrap) {
20505 return function (value) {
20506 fn(promise, state, value, unwrap);
20507 };
20508 };
20509
20510 var internalReject = function (promise, state, value, unwrap) {
20511 if (state.done) return;
20512 state.done = true;
20513 if (unwrap) state = unwrap;
20514 state.value = value;
20515 state.state = REJECTED;
20516 notify$1(promise, state, true);
20517 };
20518
20519 var internalResolve = function (promise, state, value, unwrap) {
20520 if (state.done) return;
20521 state.done = true;
20522 if (unwrap) state = unwrap;
20523 try {
20524 if (promise === value) throw TypeError$1("Promise can't be resolved itself");
20525 var then = isThenable(value);
20526 if (then) {
20527 microtask(function () {
20528 var wrapper = { done: false };
20529 try {
20530 then.call(value,
20531 bind(internalResolve, promise, wrapper, state),
20532 bind(internalReject, promise, wrapper, state)
20533 );
20534 } catch (error) {
20535 internalReject(promise, wrapper, error, state);
20536 }
20537 });
20538 } else {
20539 state.value = value;
20540 state.state = FULFILLED;
20541 notify$1(promise, state, false);
20542 }
20543 } catch (error) {
20544 internalReject(promise, { done: false }, error, state);
20545 }
20546 };
20547
20548 // constructor polyfill
20549 if (FORCED$b) {
20550 // 25.4.3.1 Promise(executor)
20551 PromiseConstructor = function Promise(executor) {
20552 anInstance(this, PromiseConstructor, PROMISE);
20553 aFunction$1(executor);
20554 Internal.call(this);
20555 var state = getInternalState$4(this);
20556 try {
20557 executor(bind(internalResolve, this, state), bind(internalReject, this, state));
20558 } catch (error) {
20559 internalReject(this, state, error);
20560 }
20561 };
20562 // eslint-disable-next-line no-unused-vars
20563 Internal = function Promise(executor) {
20564 setInternalState$5(this, {
20565 type: PROMISE,
20566 done: false,
20567 notified: false,
20568 parent: false,
20569 reactions: [],
20570 rejection: false,
20571 state: PENDING,
20572 value: undefined
20573 });
20574 };
20575 Internal.prototype = redefineAll(PromiseConstructor.prototype, {
20576 // `Promise.prototype.then` method
20577 // https://tc39.github.io/ecma262/#sec-promise.prototype.then
20578 then: function then(onFulfilled, onRejected) {
20579 var state = getInternalPromiseState(this);
20580 var reaction = newPromiseCapability$1(speciesConstructor(this, PromiseConstructor));
20581 reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
20582 reaction.fail = typeof onRejected == 'function' && onRejected;
20583 reaction.domain = IS_NODE$1 ? process$3.domain : undefined;
20584 state.parent = true;
20585 state.reactions.push(reaction);
20586 if (state.state != PENDING) notify$1(this, state, false);
20587 return reaction.promise;
20588 },
20589 // `Promise.prototype.catch` method
20590 // https://tc39.github.io/ecma262/#sec-promise.prototype.catch
20591 'catch': function (onRejected) {
20592 return this.then(undefined, onRejected);
20593 }
20594 });
20595 OwnPromiseCapability = function () {
20596 var promise = new Internal();
20597 var state = getInternalState$4(promise);
20598 this.promise = promise;
20599 this.resolve = bind(internalResolve, promise, state);
20600 this.reject = bind(internalReject, promise, state);
20601 };
20602 newPromiseCapability.f = newPromiseCapability$1 = function (C) {
20603 return C === PromiseConstructor || C === PromiseWrapper
20604 ? new OwnPromiseCapability(C)
20605 : newGenericPromiseCapability(C);
20606 };
20607
20608 if ( typeof nativePromiseConstructor == 'function') {
20609 nativeThen = nativePromiseConstructor.prototype.then;
20610
20611 // wrap native Promise#then for native async functions
20612 redefine(nativePromiseConstructor.prototype, 'then', function then(onFulfilled, onRejected) {
20613 var that = this;
20614 return new PromiseConstructor(function (resolve, reject) {
20615 nativeThen.call(that, resolve, reject);
20616 }).then(onFulfilled, onRejected);
20617 // https://github.com/zloirock/core-js/issues/640
20618 }, { unsafe: true });
20619
20620 // wrap fetch result
20621 if (typeof $fetch == 'function') _export({ global: true, enumerable: true, forced: true }, {
20622 // eslint-disable-next-line no-unused-vars
20623 fetch: function fetch(input /* , init */) {
20624 return promiseResolve(PromiseConstructor, $fetch.apply(global_1, arguments));
20625 }
20626 });
20627 }
20628 }
20629
20630 _export({ global: true, wrap: true, forced: FORCED$b }, {
20631 Promise: PromiseConstructor
20632 });
20633
20634 setToStringTag(PromiseConstructor, PROMISE, false);
20635 setSpecies(PROMISE);
20636
20637 PromiseWrapper = getBuiltIn(PROMISE);
20638
20639 // statics
20640 _export({ target: PROMISE, stat: true, forced: FORCED$b }, {
20641 // `Promise.reject` method
20642 // https://tc39.github.io/ecma262/#sec-promise.reject
20643 reject: function reject(r) {
20644 var capability = newPromiseCapability$1(this);
20645 capability.reject.call(undefined, r);
20646 return capability.promise;
20647 }
20648 });
20649
20650 _export({ target: PROMISE, stat: true, forced: FORCED$b }, {
20651 // `Promise.resolve` method
20652 // https://tc39.github.io/ecma262/#sec-promise.resolve
20653 resolve: function resolve(x) {
20654 return promiseResolve( this, x);
20655 }
20656 });
20657
20658 _export({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION$1 }, {
20659 // `Promise.all` method
20660 // https://tc39.github.io/ecma262/#sec-promise.all
20661 all: function all(iterable) {
20662 var C = this;
20663 var capability = newPromiseCapability$1(C);
20664 var resolve = capability.resolve;
20665 var reject = capability.reject;
20666 var result = perform(function () {
20667 var $promiseResolve = aFunction$1(C.resolve);
20668 var values = [];
20669 var counter = 0;
20670 var remaining = 1;
20671 iterate_1(iterable, function (promise) {
20672 var index = counter++;
20673 var alreadyCalled = false;
20674 values.push(undefined);
20675 remaining++;
20676 $promiseResolve.call(C, promise).then(function (value) {
20677 if (alreadyCalled) return;
20678 alreadyCalled = true;
20679 values[index] = value;
20680 --remaining || resolve(values);
20681 }, reject);
20682 });
20683 --remaining || resolve(values);
20684 });
20685 if (result.error) reject(result.value);
20686 return capability.promise;
20687 },
20688 // `Promise.race` method
20689 // https://tc39.github.io/ecma262/#sec-promise.race
20690 race: function race(iterable) {
20691 var C = this;
20692 var capability = newPromiseCapability$1(C);
20693 var reject = capability.reject;
20694 var result = perform(function () {
20695 var $promiseResolve = aFunction$1(C.resolve);
20696 iterate_1(iterable, function (promise) {
20697 $promiseResolve.call(C, promise).then(capability.resolve, reject);
20698 });
20699 });
20700 if (result.error) reject(result.value);
20701 return capability.promise;
20702 }
20703 });
20704
20705 // `Set` constructor
20706 // https://tc39.github.io/ecma262/#sec-set-objects
20707 var es_set = collection('Set', function (get) {
20708 return function Set() { return get(this, arguments.length ? arguments[0] : undefined); };
20709 }, collectionStrong);
20710
20711 /**
20712 * vis-data - data
20713 * http://visjs.org/
20714 *
20715 * Manage unstructured data using DataSet. Add, update, and remove data, and listen for changes in the data.
20716 *
20717 * @version 6.2.1
20718 * @date 2019-09-13T21:24:53Z
20719 *
20720 * @copyright (c) 2011-2017 Almende B.V, http://almende.com
20721 * @copyright (c) 2018-2019 visjs contributors, https://github.com/visjs
20722 *
20723 * @license
20724 * vis.js is dual licensed under both
20725 *
20726 * 1. The Apache 2.0 License
20727 * http://www.apache.org/licenses/LICENSE-2.0
20728 *
20729 * and
20730 *
20731 * 2. The MIT License
20732 * http://opensource.org/licenses/MIT
20733 *
20734 * vis.js may be distributed under either license.
20735 */
20736 function createCommonjsModule$2(fn, module) {
20737 return module = {
20738 exports: {}
20739 }, fn(module, module.exports), module.exports;
20740 }
20741
20742 var runtime_1 = createCommonjsModule$2(function (module) {
20743 /**
20744 * Copyright (c) 2014-present, Facebook, Inc.
20745 *
20746 * This source code is licensed under the MIT license found in the
20747 * LICENSE file in the root directory of this source tree.
20748 */
20749 var runtime = function (exports) {
20750 var Op = Object.prototype;
20751 var hasOwn = Op.hasOwnProperty;
20752 var undefined$1; // More compressible than void 0.
20753
20754 var $Symbol = typeof Symbol === "function" ? Symbol : {};
20755 var iteratorSymbol = $Symbol.iterator || "@@iterator";
20756 var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
20757 var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
20758
20759 function wrap(innerFn, outerFn, self, tryLocsList) {
20760 // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
20761 var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
20762 var generator = Object.create(protoGenerator.prototype);
20763 var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
20764 // .throw, and .return methods.
20765
20766 generator._invoke = makeInvokeMethod(innerFn, self, context);
20767 return generator;
20768 }
20769
20770 exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
20771 // record like context.tryEntries[i].completion. This interface could
20772 // have been (and was previously) designed to take a closure to be
20773 // invoked without arguments, but in all the cases we care about we
20774 // already have an existing method we want to call, so there's no need
20775 // to create a new function object. We can even get away with assuming
20776 // the method takes exactly one argument, since that happens to be true
20777 // in every case, so we don't have to touch the arguments object. The
20778 // only additional allocation required is the completion record, which
20779 // has a stable shape and so hopefully should be cheap to allocate.
20780
20781 function tryCatch(fn, obj, arg) {
20782 try {
20783 return {
20784 type: "normal",
20785 arg: fn.call(obj, arg)
20786 };
20787 } catch (err) {
20788 return {
20789 type: "throw",
20790 arg: err
20791 };
20792 }
20793 }
20794
20795 var GenStateSuspendedStart = "suspendedStart";
20796 var GenStateSuspendedYield = "suspendedYield";
20797 var GenStateExecuting = "executing";
20798 var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
20799 // breaking out of the dispatch switch statement.
20800
20801 var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
20802 // .constructor.prototype properties for functions that return Generator
20803 // objects. For full spec compliance, you may wish to configure your
20804 // minifier not to mangle the names of these two functions.
20805
20806 function Generator() {}
20807
20808 function GeneratorFunction() {}
20809
20810 function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
20811 // don't natively support it.
20812
20813
20814 var IteratorPrototype = {};
20815
20816 IteratorPrototype[iteratorSymbol] = function () {
20817 return this;
20818 };
20819
20820 var getProto = Object.getPrototypeOf;
20821 var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
20822
20823 if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
20824 // This environment has a native %IteratorPrototype%; use it instead
20825 // of the polyfill.
20826 IteratorPrototype = NativeIteratorPrototype;
20827 }
20828
20829 var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
20830 GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
20831 GeneratorFunctionPrototype.constructor = GeneratorFunction;
20832 GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; // Helper for defining the .next, .throw, and .return methods of the
20833 // Iterator interface in terms of a single ._invoke method.
20834
20835 function defineIteratorMethods(prototype) {
20836 ["next", "throw", "return"].forEach(function (method) {
20837 prototype[method] = function (arg) {
20838 return this._invoke(method, arg);
20839 };
20840 });
20841 }
20842
20843 exports.isGeneratorFunction = function (genFun) {
20844 var ctor = typeof genFun === "function" && genFun.constructor;
20845 return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
20846 // do is to check its .name property.
20847 (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
20848 };
20849
20850 exports.mark = function (genFun) {
20851 if (Object.setPrototypeOf) {
20852 Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
20853 } else {
20854 genFun.__proto__ = GeneratorFunctionPrototype;
20855
20856 if (!(toStringTagSymbol in genFun)) {
20857 genFun[toStringTagSymbol] = "GeneratorFunction";
20858 }
20859 }
20860
20861 genFun.prototype = Object.create(Gp);
20862 return genFun;
20863 }; // Within the body of any async function, `await x` is transformed to
20864 // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
20865 // `hasOwn.call(value, "__await")` to determine if the yielded value is
20866 // meant to be awaited.
20867
20868
20869 exports.awrap = function (arg) {
20870 return {
20871 __await: arg
20872 };
20873 };
20874
20875 function AsyncIterator(generator) {
20876 function invoke(method, arg, resolve, reject) {
20877 var record = tryCatch(generator[method], generator, arg);
20878
20879 if (record.type === "throw") {
20880 reject(record.arg);
20881 } else {
20882 var result = record.arg;
20883 var value = result.value;
20884
20885 if (value && _typeof(value) === "object" && hasOwn.call(value, "__await")) {
20886 return Promise.resolve(value.__await).then(function (value) {
20887 invoke("next", value, resolve, reject);
20888 }, function (err) {
20889 invoke("throw", err, resolve, reject);
20890 });
20891 }
20892
20893 return Promise.resolve(value).then(function (unwrapped) {
20894 // When a yielded Promise is resolved, its final value becomes
20895 // the .value of the Promise<{value,done}> result for the
20896 // current iteration.
20897 result.value = unwrapped;
20898 resolve(result);
20899 }, function (error) {
20900 // If a rejected Promise was yielded, throw the rejection back
20901 // into the async generator function so it can be handled there.
20902 return invoke("throw", error, resolve, reject);
20903 });
20904 }
20905 }
20906
20907 var previousPromise;
20908
20909 function enqueue(method, arg) {
20910 function callInvokeWithMethodAndArg() {
20911 return new Promise(function (resolve, reject) {
20912 invoke(method, arg, resolve, reject);
20913 });
20914 }
20915
20916 return previousPromise = // If enqueue has been called before, then we want to wait until
20917 // all previous Promises have been resolved before calling invoke,
20918 // so that results are always delivered in the correct order. If
20919 // enqueue has not been called before, then it is important to
20920 // call invoke immediately, without waiting on a callback to fire,
20921 // so that the async generator function has the opportunity to do
20922 // any necessary setup in a predictable way. This predictability
20923 // is why the Promise constructor synchronously invokes its
20924 // executor callback, and why async functions synchronously
20925 // execute code before the first await. Since we implement simple
20926 // async functions in terms of async generators, it is especially
20927 // important to get this right, even though it requires care.
20928 previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
20929 // invocations of the iterator.
20930 callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
20931 } // Define the unified helper method that is used to implement .next,
20932 // .throw, and .return (see defineIteratorMethods).
20933
20934
20935 this._invoke = enqueue;
20936 }
20937
20938 defineIteratorMethods(AsyncIterator.prototype);
20939
20940 AsyncIterator.prototype[asyncIteratorSymbol] = function () {
20941 return this;
20942 };
20943
20944 exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
20945 // AsyncIterator objects; they just return a Promise for the value of
20946 // the final result produced by the iterator.
20947
20948 exports.async = function (innerFn, outerFn, self, tryLocsList) {
20949 var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList));
20950 return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
20951 : iter.next().then(function (result) {
20952 return result.done ? result.value : iter.next();
20953 });
20954 };
20955
20956 function makeInvokeMethod(innerFn, self, context) {
20957 var state = GenStateSuspendedStart;
20958 return function invoke(method, arg) {
20959 if (state === GenStateExecuting) {
20960 throw new Error("Generator is already running");
20961 }
20962
20963 if (state === GenStateCompleted) {
20964 if (method === "throw") {
20965 throw arg;
20966 } // Be forgiving, per 25.3.3.3.3 of the spec:
20967 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
20968
20969
20970 return doneResult();
20971 }
20972
20973 context.method = method;
20974 context.arg = arg;
20975
20976 while (true) {
20977 var delegate = context.delegate;
20978
20979 if (delegate) {
20980 var delegateResult = maybeInvokeDelegate(delegate, context);
20981
20982 if (delegateResult) {
20983 if (delegateResult === ContinueSentinel) continue;
20984 return delegateResult;
20985 }
20986 }
20987
20988 if (context.method === "next") {
20989 // Setting context._sent for legacy support of Babel's
20990 // function.sent implementation.
20991 context.sent = context._sent = context.arg;
20992 } else if (context.method === "throw") {
20993 if (state === GenStateSuspendedStart) {
20994 state = GenStateCompleted;
20995 throw context.arg;
20996 }
20997
20998 context.dispatchException(context.arg);
20999 } else if (context.method === "return") {
21000 context.abrupt("return", context.arg);
21001 }
21002
21003 state = GenStateExecuting;
21004 var record = tryCatch(innerFn, self, context);
21005
21006 if (record.type === "normal") {
21007 // If an exception is thrown from innerFn, we leave state ===
21008 // GenStateExecuting and loop back for another invocation.
21009 state = context.done ? GenStateCompleted : GenStateSuspendedYield;
21010
21011 if (record.arg === ContinueSentinel) {
21012 continue;
21013 }
21014
21015 return {
21016 value: record.arg,
21017 done: context.done
21018 };
21019 } else if (record.type === "throw") {
21020 state = GenStateCompleted; // Dispatch the exception by looping back around to the
21021 // context.dispatchException(context.arg) call above.
21022
21023 context.method = "throw";
21024 context.arg = record.arg;
21025 }
21026 }
21027 };
21028 } // Call delegate.iterator[context.method](context.arg) and handle the
21029 // result, either by returning a { value, done } result from the
21030 // delegate iterator, or by modifying context.method and context.arg,
21031 // setting context.delegate to null, and returning the ContinueSentinel.
21032
21033
21034 function maybeInvokeDelegate(delegate, context) {
21035 var method = delegate.iterator[context.method];
21036
21037 if (method === undefined$1) {
21038 // A .throw or .return when the delegate iterator has no .throw
21039 // method always terminates the yield* loop.
21040 context.delegate = null;
21041
21042 if (context.method === "throw") {
21043 // Note: ["return"] must be used for ES3 parsing compatibility.
21044 if (delegate.iterator["return"]) {
21045 // If the delegate iterator has a return method, give it a
21046 // chance to clean up.
21047 context.method = "return";
21048 context.arg = undefined$1;
21049 maybeInvokeDelegate(delegate, context);
21050
21051 if (context.method === "throw") {
21052 // If maybeInvokeDelegate(context) changed context.method from
21053 // "return" to "throw", let that override the TypeError below.
21054 return ContinueSentinel;
21055 }
21056 }
21057
21058 context.method = "throw";
21059 context.arg = new TypeError("The iterator does not provide a 'throw' method");
21060 }
21061
21062 return ContinueSentinel;
21063 }
21064
21065 var record = tryCatch(method, delegate.iterator, context.arg);
21066
21067 if (record.type === "throw") {
21068 context.method = "throw";
21069 context.arg = record.arg;
21070 context.delegate = null;
21071 return ContinueSentinel;
21072 }
21073
21074 var info = record.arg;
21075
21076 if (!info) {
21077 context.method = "throw";
21078 context.arg = new TypeError("iterator result is not an object");
21079 context.delegate = null;
21080 return ContinueSentinel;
21081 }
21082
21083 if (info.done) {
21084 // Assign the result of the finished delegate to the temporary
21085 // variable specified by delegate.resultName (see delegateYield).
21086 context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
21087
21088 context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
21089 // exception, let the outer generator proceed normally. If
21090 // context.method was "next", forget context.arg since it has been
21091 // "consumed" by the delegate iterator. If context.method was
21092 // "return", allow the original .return call to continue in the
21093 // outer generator.
21094
21095 if (context.method !== "return") {
21096 context.method = "next";
21097 context.arg = undefined$1;
21098 }
21099 } else {
21100 // Re-yield the result returned by the delegate method.
21101 return info;
21102 } // The delegate iterator is finished, so forget it and continue with
21103 // the outer generator.
21104
21105
21106 context.delegate = null;
21107 return ContinueSentinel;
21108 } // Define Generator.prototype.{next,throw,return} in terms of the
21109 // unified ._invoke helper method.
21110
21111
21112 defineIteratorMethods(Gp);
21113 Gp[toStringTagSymbol] = "Generator"; // A Generator should always return itself as the iterator object when the
21114 // @@iterator function is called on it. Some browsers' implementations of the
21115 // iterator prototype chain incorrectly implement this, causing the Generator
21116 // object to not be returned from this call. This ensures that doesn't happen.
21117 // See https://github.com/facebook/regenerator/issues/274 for more details.
21118
21119 Gp[iteratorSymbol] = function () {
21120 return this;
21121 };
21122
21123 Gp.toString = function () {
21124 return "[object Generator]";
21125 };
21126
21127 function pushTryEntry(locs) {
21128 var entry = {
21129 tryLoc: locs[0]
21130 };
21131
21132 if (1 in locs) {
21133 entry.catchLoc = locs[1];
21134 }
21135
21136 if (2 in locs) {
21137 entry.finallyLoc = locs[2];
21138 entry.afterLoc = locs[3];
21139 }
21140
21141 this.tryEntries.push(entry);
21142 }
21143
21144 function resetTryEntry(entry) {
21145 var record = entry.completion || {};
21146 record.type = "normal";
21147 delete record.arg;
21148 entry.completion = record;
21149 }
21150
21151 function Context(tryLocsList) {
21152 // The root entry object (effectively a try statement without a catch
21153 // or a finally block) gives us a place to store values thrown from
21154 // locations where there is no enclosing try statement.
21155 this.tryEntries = [{
21156 tryLoc: "root"
21157 }];
21158 tryLocsList.forEach(pushTryEntry, this);
21159 this.reset(true);
21160 }
21161
21162 exports.keys = function (object) {
21163 var keys = [];
21164
21165 for (var key in object) {
21166 keys.push(key);
21167 }
21168
21169 keys.reverse(); // Rather than returning an object with a next method, we keep
21170 // things simple and return the next function itself.
21171
21172 return function next() {
21173 while (keys.length) {
21174 var key = keys.pop();
21175
21176 if (key in object) {
21177 next.value = key;
21178 next.done = false;
21179 return next;
21180 }
21181 } // To avoid creating an additional object, we just hang the .value
21182 // and .done properties off the next function object itself. This
21183 // also ensures that the minifier will not anonymize the function.
21184
21185
21186 next.done = true;
21187 return next;
21188 };
21189 };
21190
21191 function values(iterable) {
21192 if (iterable) {
21193 var iteratorMethod = iterable[iteratorSymbol];
21194
21195 if (iteratorMethod) {
21196 return iteratorMethod.call(iterable);
21197 }
21198
21199 if (typeof iterable.next === "function") {
21200 return iterable;
21201 }
21202
21203 if (!isNaN(iterable.length)) {
21204 var i = -1,
21205 next = function next() {
21206 while (++i < iterable.length) {
21207 if (hasOwn.call(iterable, i)) {
21208 next.value = iterable[i];
21209 next.done = false;
21210 return next;
21211 }
21212 }
21213
21214 next.value = undefined$1;
21215 next.done = true;
21216 return next;
21217 };
21218
21219 return next.next = next;
21220 }
21221 } // Return an iterator with no values.
21222
21223
21224 return {
21225 next: doneResult
21226 };
21227 }
21228
21229 exports.values = values;
21230
21231 function doneResult() {
21232 return {
21233 value: undefined$1,
21234 done: true
21235 };
21236 }
21237
21238 Context.prototype = {
21239 constructor: Context,
21240 reset: function reset(skipTempReset) {
21241 this.prev = 0;
21242 this.next = 0; // Resetting context._sent for legacy support of Babel's
21243 // function.sent implementation.
21244
21245 this.sent = this._sent = undefined$1;
21246 this.done = false;
21247 this.delegate = null;
21248 this.method = "next";
21249 this.arg = undefined$1;
21250 this.tryEntries.forEach(resetTryEntry);
21251
21252 if (!skipTempReset) {
21253 for (var name in this) {
21254 // Not sure about the optimal order of these conditions:
21255 if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
21256 this[name] = undefined$1;
21257 }
21258 }
21259 }
21260 },
21261 stop: function stop() {
21262 this.done = true;
21263 var rootEntry = this.tryEntries[0];
21264 var rootRecord = rootEntry.completion;
21265
21266 if (rootRecord.type === "throw") {
21267 throw rootRecord.arg;
21268 }
21269
21270 return this.rval;
21271 },
21272 dispatchException: function dispatchException(exception) {
21273 if (this.done) {
21274 throw exception;
21275 }
21276
21277 var context = this;
21278
21279 function handle(loc, caught) {
21280 record.type = "throw";
21281 record.arg = exception;
21282 context.next = loc;
21283
21284 if (caught) {
21285 // If the dispatched exception was caught by a catch block,
21286 // then let that catch block handle the exception normally.
21287 context.method = "next";
21288 context.arg = undefined$1;
21289 }
21290
21291 return !!caught;
21292 }
21293
21294 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
21295 var entry = this.tryEntries[i];
21296 var record = entry.completion;
21297
21298 if (entry.tryLoc === "root") {
21299 // Exception thrown outside of any try block that could handle
21300 // it, so set the completion value of the entire function to
21301 // throw the exception.
21302 return handle("end");
21303 }
21304
21305 if (entry.tryLoc <= this.prev) {
21306 var hasCatch = hasOwn.call(entry, "catchLoc");
21307 var hasFinally = hasOwn.call(entry, "finallyLoc");
21308
21309 if (hasCatch && hasFinally) {
21310 if (this.prev < entry.catchLoc) {
21311 return handle(entry.catchLoc, true);
21312 } else if (this.prev < entry.finallyLoc) {
21313 return handle(entry.finallyLoc);
21314 }
21315 } else if (hasCatch) {
21316 if (this.prev < entry.catchLoc) {
21317 return handle(entry.catchLoc, true);
21318 }
21319 } else if (hasFinally) {
21320 if (this.prev < entry.finallyLoc) {
21321 return handle(entry.finallyLoc);
21322 }
21323 } else {
21324 throw new Error("try statement without catch or finally");
21325 }
21326 }
21327 }
21328 },
21329 abrupt: function abrupt(type, arg) {
21330 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
21331 var entry = this.tryEntries[i];
21332
21333 if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
21334 var finallyEntry = entry;
21335 break;
21336 }
21337 }
21338
21339 if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
21340 // Ignore the finally entry if control is not jumping to a
21341 // location outside the try/catch block.
21342 finallyEntry = null;
21343 }
21344
21345 var record = finallyEntry ? finallyEntry.completion : {};
21346 record.type = type;
21347 record.arg = arg;
21348
21349 if (finallyEntry) {
21350 this.method = "next";
21351 this.next = finallyEntry.finallyLoc;
21352 return ContinueSentinel;
21353 }
21354
21355 return this.complete(record);
21356 },
21357 complete: function complete(record, afterLoc) {
21358 if (record.type === "throw") {
21359 throw record.arg;
21360 }
21361
21362 if (record.type === "break" || record.type === "continue") {
21363 this.next = record.arg;
21364 } else if (record.type === "return") {
21365 this.rval = this.arg = record.arg;
21366 this.method = "return";
21367 this.next = "end";
21368 } else if (record.type === "normal" && afterLoc) {
21369 this.next = afterLoc;
21370 }
21371
21372 return ContinueSentinel;
21373 },
21374 finish: function finish(finallyLoc) {
21375 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
21376 var entry = this.tryEntries[i];
21377
21378 if (entry.finallyLoc === finallyLoc) {
21379 this.complete(entry.completion, entry.afterLoc);
21380 resetTryEntry(entry);
21381 return ContinueSentinel;
21382 }
21383 }
21384 },
21385 "catch": function _catch(tryLoc) {
21386 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
21387 var entry = this.tryEntries[i];
21388
21389 if (entry.tryLoc === tryLoc) {
21390 var record = entry.completion;
21391
21392 if (record.type === "throw") {
21393 var thrown = record.arg;
21394 resetTryEntry(entry);
21395 }
21396
21397 return thrown;
21398 }
21399 } // The context.catch method must only be called with a location
21400 // argument that corresponds to a known catch block.
21401
21402
21403 throw new Error("illegal catch attempt");
21404 },
21405 delegateYield: function delegateYield(iterable, resultName, nextLoc) {
21406 this.delegate = {
21407 iterator: values(iterable),
21408 resultName: resultName,
21409 nextLoc: nextLoc
21410 };
21411
21412 if (this.method === "next") {
21413 // Deliberately forget the last sent value so that we don't
21414 // accidentally pass it on to the delegate.
21415 this.arg = undefined$1;
21416 }
21417
21418 return ContinueSentinel;
21419 }
21420 }; // Regardless of whether this script is executing as a CommonJS module
21421 // or not, return the runtime object so that we can declare the variable
21422 // regeneratorRuntime in the outer scope, which allows this module to be
21423 // injected easily by `bin/regenerator --include-runtime script.js`.
21424
21425 return exports;
21426 }( // If this script is executing as a CommonJS module, use module.exports
21427 // as the regeneratorRuntime namespace. Otherwise create a new empty
21428 // object. Either way, the resulting object will be used to initialize
21429 // the regeneratorRuntime variable at the top of this file.
21430 module.exports);
21431
21432 try {
21433 regeneratorRuntime = runtime;
21434 } catch (accidentalStrictMode) {
21435 // This module should not be running in strict mode, so the above
21436 // assignment should always work unless something is misconfigured. Just
21437 // in case runtime.js accidentally runs in strict mode, we can escape
21438 // strict mode using a global Function call. This could conceivably fail
21439 // if a Content Security Policy forbids using Function, but in that case
21440 // the proper solution is to fix the accidental strict mode problem. If
21441 // you've misconfigured your bundler to force strict mode and applied a
21442 // CSP to forbid Function, and you're not willing to fix either of those
21443 // problems, please detail your unique predicament in a GitHub issue.
21444 Function("r", "regeneratorRuntime = r")(runtime);
21445 }
21446 });
21447 var regenerator = runtime_1;
21448
21449 function _defineProperty$2(obj, key, value) {
21450 if (key in obj) {
21451 Object.defineProperty(obj, key, {
21452 value: value,
21453 enumerable: true,
21454 configurable: true,
21455 writable: true
21456 });
21457 } else {
21458 obj[key] = value;
21459 }
21460
21461 return obj;
21462 }
21463
21464 var defineProperty$a = _defineProperty$2;
21465
21466 function _arrayWithoutHoles$1(arr) {
21467 if (Array.isArray(arr)) {
21468 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
21469 arr2[i] = arr[i];
21470 }
21471
21472 return arr2;
21473 }
21474 }
21475
21476 var arrayWithoutHoles = _arrayWithoutHoles$1;
21477
21478 function _iterableToArray$1(iter) {
21479 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
21480 }
21481
21482 var iterableToArray = _iterableToArray$1;
21483
21484 function _nonIterableSpread$1() {
21485 throw new TypeError("Invalid attempt to spread non-iterable instance");
21486 }
21487
21488 var nonIterableSpread = _nonIterableSpread$1;
21489
21490 function _toConsumableArray$1(arr) {
21491 return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
21492 }
21493
21494 var toConsumableArray = _toConsumableArray$1;
21495
21496 var _typeof_1 = createCommonjsModule$2(function (module) {
21497 function _typeof2(obj) {
21498 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
21499 _typeof2 = function _typeof2(obj) {
21500 return _typeof(obj);
21501 };
21502 } else {
21503 _typeof2 = function _typeof2(obj) {
21504 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
21505 };
21506 }
21507
21508 return _typeof2(obj);
21509 }
21510
21511 function _typeof$1(obj) {
21512 if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
21513 module.exports = _typeof$1 = function _typeof(obj) {
21514 return _typeof2(obj);
21515 };
21516 } else {
21517 module.exports = _typeof$1 = function _typeof(obj) {
21518 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
21519 };
21520 }
21521
21522 return _typeof$1(obj);
21523 }
21524
21525 module.exports = _typeof$1;
21526 });
21527
21528 function _classCallCheck$1(instance, Constructor) {
21529 if (!(instance instanceof Constructor)) {
21530 throw new TypeError("Cannot call a class as a function");
21531 }
21532 }
21533
21534 var classCallCheck = _classCallCheck$1;
21535
21536 function _defineProperties$1(target, props) {
21537 for (var i = 0; i < props.length; i++) {
21538 var descriptor = props[i];
21539 descriptor.enumerable = descriptor.enumerable || false;
21540 descriptor.configurable = true;
21541 if ("value" in descriptor) descriptor.writable = true;
21542 Object.defineProperty(target, descriptor.key, descriptor);
21543 }
21544 }
21545
21546 function _createClass$1(Constructor, protoProps, staticProps) {
21547 if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
21548 if (staticProps) _defineProperties$1(Constructor, staticProps);
21549 return Constructor;
21550 }
21551
21552 var createClass = _createClass$1;
21553
21554 function _assertThisInitialized$2(self) {
21555 if (self === void 0) {
21556 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
21557 }
21558
21559 return self;
21560 }
21561
21562 var assertThisInitialized = _assertThisInitialized$2;
21563
21564 function _possibleConstructorReturn$1(self, call) {
21565 if (call && (_typeof_1(call) === "object" || typeof call === "function")) {
21566 return call;
21567 }
21568
21569 return assertThisInitialized(self);
21570 }
21571
21572 var possibleConstructorReturn = _possibleConstructorReturn$1;
21573 var getPrototypeOf = createCommonjsModule$2(function (module) {
21574 function _getPrototypeOf(o) {
21575 module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
21576 return o.__proto__ || Object.getPrototypeOf(o);
21577 };
21578 return _getPrototypeOf(o);
21579 }
21580
21581 module.exports = _getPrototypeOf;
21582 });
21583 var setPrototypeOf$1 = createCommonjsModule$2(function (module) {
21584 function _setPrototypeOf(o, p) {
21585 module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
21586 o.__proto__ = p;
21587 return o;
21588 };
21589
21590 return _setPrototypeOf(o, p);
21591 }
21592
21593 module.exports = _setPrototypeOf;
21594 });
21595
21596 function _inherits$1(subClass, superClass) {
21597 if (typeof superClass !== "function" && superClass !== null) {
21598 throw new TypeError("Super expression must either be null or a function");
21599 }
21600
21601 subClass.prototype = Object.create(superClass && superClass.prototype, {
21602 constructor: {
21603 value: subClass,
21604 writable: true,
21605 configurable: true
21606 }
21607 });
21608 if (superClass) setPrototypeOf$1(subClass, superClass);
21609 }
21610
21611 var inherits = _inherits$1; // Maps for number <-> hex string conversion
21612
21613 var byteToHex$2 = [];
21614
21615 for (var i$2 = 0; i$2 < 256; i$2++) {
21616 byteToHex$2[i$2] = (i$2 + 0x100).toString(16).substr(1);
21617 }
21618 /**
21619 * Represent binary UUID into it's string representation.
21620 *
21621 * @param buf - Buffer containing UUID bytes.
21622 * @param offset - Offset from the start of the buffer where the UUID is saved (not needed if the buffer starts with the UUID).
21623 *
21624 * @returns String representation of the UUID.
21625 */
21626
21627
21628 function stringifyUUID$1(buf, offset) {
21629 var i = offset || 0;
21630 var bth = byteToHex$2;
21631 return bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + '-' + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]] + bth[buf[i++]];
21632 }
21633 /**
21634 * Generate 16 random bytes to be used as a base for UUID.
21635 *
21636 * @ignore
21637 */
21638
21639
21640 var random$1 = function () {
21641 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
21642 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
21643 // Moderately fast, high quality
21644 var _rnds8 = new Uint8Array(16);
21645
21646 return function whatwgRNG() {
21647 crypto.getRandomValues(_rnds8);
21648 return _rnds8;
21649 };
21650 } // Math.random()-based (RNG)
21651 //
21652 // If all else fails, use Math.random().
21653 // It's fast, but is of unspecified quality.
21654
21655
21656 var _rnds = new Array(16);
21657
21658 return function () {
21659 for (var i = 0, r; i < 16; i++) {
21660 if ((i & 0x03) === 0) {
21661 r = Math.random() * 0x100000000;
21662 }
21663
21664 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
21665 }
21666
21667 return _rnds;
21668 }; // uuid.js
21669 //
21670 // Copyright (c) 2010-2012 Robert Kieffer
21671 // MIT License - http://opensource.org/licenses/mit-license.php
21672 // Unique ID creation requires a high quality random # generator. We feature
21673 // detect to determine the best RNG source, normalizing to a function that
21674 // returns 128-bits of randomness, since that's what's usually required
21675 // return require('./rng');
21676 }();
21677
21678 var byteToHex$1$1 = [];
21679
21680 for (var i$1$2 = 0; i$1$2 < 256; i$1$2++) {
21681 byteToHex$1$1[i$1$2] = (i$1$2 + 0x100).toString(16).substr(1);
21682 } // **`v1()` - Generate time-based UUID**
21683 //
21684 // Inspired by https://github.com/LiosK/UUID.js
21685 // and http://docs.python.org/library/uuid.html
21686 // random #'s we need to init node and clockseq
21687
21688
21689 var seedBytes$1 = random$1(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
21690
21691 var defaultNodeId$1 = [seedBytes$1[0] | 0x01, seedBytes$1[1], seedBytes$1[2], seedBytes$1[3], seedBytes$1[4], seedBytes$1[5]]; // Per 4.2.2, randomize (14 bit) clockseq
21692
21693 var defaultClockseq$1 = (seedBytes$1[6] << 8 | seedBytes$1[7]) & 0x3fff; // Previous uuid creation time
21694
21695 /**
21696 * UUIDv4 options.
21697 */
21698
21699 /**
21700 * Generate UUIDv4
21701 *
21702 * @param options - Options to be used instead of default generated values.
21703 * String 'binary' is a shorthand for uuid4({}, new Array(16)).
21704 * @param buf - If present the buffer will be filled with the generated UUID.
21705 * @param offset - Offset of the UUID from the start of the buffer.
21706 *
21707 * @returns UUIDv4
21708 */
21709
21710 function uuid4$1() {
21711 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21712 var buf = arguments.length > 1 ? arguments[1] : undefined;
21713 var offset = arguments.length > 2 ? arguments[2] : undefined; // Deprecated - 'format' argument, as supported in v1.2
21714
21715 var i = buf && offset || 0;
21716
21717 if (typeof options === 'string') {
21718 buf = options === 'binary' ? new Array(16) : undefined;
21719 options = {};
21720 }
21721
21722 var rnds = options.random || (options.rng || random$1)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
21723
21724 rnds[6] = rnds[6] & 0x0f | 0x40;
21725 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
21726
21727 if (buf) {
21728 for (var ii = 0; ii < 16; ii++) {
21729 buf[i + ii] = rnds[ii];
21730 }
21731 }
21732
21733 return buf || stringifyUUID$1(rnds);
21734 } // Rollup will complain about mixing default and named exports in UMD build,
21735
21736
21737 function _typeof$2(obj) {
21738 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
21739 _typeof$2 = function _typeof$1(obj) {
21740 return _typeof(obj);
21741 };
21742 } else {
21743 _typeof$2 = function _typeof$1(obj) {
21744 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
21745 };
21746 }
21747
21748 return _typeof$2(obj);
21749 }
21750
21751 var commonjsGlobal$2 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
21752
21753 function commonjsRequire$1() {
21754 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
21755 }
21756
21757 function createCommonjsModule$1$1(fn, module) {
21758 return module = {
21759 exports: {}
21760 }, fn(module, module.exports), module.exports;
21761 }
21762
21763 var moment$1 = createCommonjsModule$1$1(function (module, exports) {
21764 (function (global, factory) {
21765 module.exports = factory();
21766 })(commonjsGlobal$2, function () {
21767 var hookCallback;
21768
21769 function hooks() {
21770 return hookCallback.apply(null, arguments);
21771 } // This is done to register the method called with moment()
21772 // without creating circular dependencies.
21773
21774
21775 function setHookCallback(callback) {
21776 hookCallback = callback;
21777 }
21778
21779 function isArray(input) {
21780 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
21781 }
21782
21783 function isObject(input) {
21784 // IE8 will treat undefined and null as object if it wasn't for
21785 // input != null
21786 return input != null && Object.prototype.toString.call(input) === '[object Object]';
21787 }
21788
21789 function isObjectEmpty(obj) {
21790 if (Object.getOwnPropertyNames) {
21791 return Object.getOwnPropertyNames(obj).length === 0;
21792 } else {
21793 var k;
21794
21795 for (k in obj) {
21796 if (obj.hasOwnProperty(k)) {
21797 return false;
21798 }
21799 }
21800
21801 return true;
21802 }
21803 }
21804
21805 function isUndefined(input) {
21806 return input === void 0;
21807 }
21808
21809 function isNumber(input) {
21810 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
21811 }
21812
21813 function isDate(input) {
21814 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
21815 }
21816
21817 function map(arr, fn) {
21818 var res = [],
21819 i;
21820
21821 for (i = 0; i < arr.length; ++i) {
21822 res.push(fn(arr[i], i));
21823 }
21824
21825 return res;
21826 }
21827
21828 function hasOwnProp(a, b) {
21829 return Object.prototype.hasOwnProperty.call(a, b);
21830 }
21831
21832 function extend(a, b) {
21833 for (var i in b) {
21834 if (hasOwnProp(b, i)) {
21835 a[i] = b[i];
21836 }
21837 }
21838
21839 if (hasOwnProp(b, 'toString')) {
21840 a.toString = b.toString;
21841 }
21842
21843 if (hasOwnProp(b, 'valueOf')) {
21844 a.valueOf = b.valueOf;
21845 }
21846
21847 return a;
21848 }
21849
21850 function createUTC(input, format, locale, strict) {
21851 return createLocalOrUTC(input, format, locale, strict, true).utc();
21852 }
21853
21854 function defaultParsingFlags() {
21855 // We need to deep clone this object.
21856 return {
21857 empty: false,
21858 unusedTokens: [],
21859 unusedInput: [],
21860 overflow: -2,
21861 charsLeftOver: 0,
21862 nullInput: false,
21863 invalidMonth: null,
21864 invalidFormat: false,
21865 userInvalidated: false,
21866 iso: false,
21867 parsedDateParts: [],
21868 meridiem: null,
21869 rfc2822: false,
21870 weekdayMismatch: false
21871 };
21872 }
21873
21874 function getParsingFlags(m) {
21875 if (m._pf == null) {
21876 m._pf = defaultParsingFlags();
21877 }
21878
21879 return m._pf;
21880 }
21881
21882 var some;
21883
21884 if (Array.prototype.some) {
21885 some = Array.prototype.some;
21886 } else {
21887 some = function some(fun) {
21888 var t = Object(this);
21889 var len = t.length >>> 0;
21890
21891 for (var i = 0; i < len; i++) {
21892 if (i in t && fun.call(this, t[i], i, t)) {
21893 return true;
21894 }
21895 }
21896
21897 return false;
21898 };
21899 }
21900
21901 function isValid(m) {
21902 if (m._isValid == null) {
21903 var flags = getParsingFlags(m);
21904 var parsedParts = some.call(flags.parsedDateParts, function (i) {
21905 return i != null;
21906 });
21907 var isNowValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || flags.meridiem && parsedParts);
21908
21909 if (m._strict) {
21910 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
21911 }
21912
21913 if (Object.isFrozen == null || !Object.isFrozen(m)) {
21914 m._isValid = isNowValid;
21915 } else {
21916 return isNowValid;
21917 }
21918 }
21919
21920 return m._isValid;
21921 }
21922
21923 function createInvalid(flags) {
21924 var m = createUTC(NaN);
21925
21926 if (flags != null) {
21927 extend(getParsingFlags(m), flags);
21928 } else {
21929 getParsingFlags(m).userInvalidated = true;
21930 }
21931
21932 return m;
21933 } // Plugins that add properties should also add the key here (null value),
21934 // so we can properly clone ourselves.
21935
21936
21937 var momentProperties = hooks.momentProperties = [];
21938
21939 function copyConfig(to, from) {
21940 var i, prop, val;
21941
21942 if (!isUndefined(from._isAMomentObject)) {
21943 to._isAMomentObject = from._isAMomentObject;
21944 }
21945
21946 if (!isUndefined(from._i)) {
21947 to._i = from._i;
21948 }
21949
21950 if (!isUndefined(from._f)) {
21951 to._f = from._f;
21952 }
21953
21954 if (!isUndefined(from._l)) {
21955 to._l = from._l;
21956 }
21957
21958 if (!isUndefined(from._strict)) {
21959 to._strict = from._strict;
21960 }
21961
21962 if (!isUndefined(from._tzm)) {
21963 to._tzm = from._tzm;
21964 }
21965
21966 if (!isUndefined(from._isUTC)) {
21967 to._isUTC = from._isUTC;
21968 }
21969
21970 if (!isUndefined(from._offset)) {
21971 to._offset = from._offset;
21972 }
21973
21974 if (!isUndefined(from._pf)) {
21975 to._pf = getParsingFlags(from);
21976 }
21977
21978 if (!isUndefined(from._locale)) {
21979 to._locale = from._locale;
21980 }
21981
21982 if (momentProperties.length > 0) {
21983 for (i = 0; i < momentProperties.length; i++) {
21984 prop = momentProperties[i];
21985 val = from[prop];
21986
21987 if (!isUndefined(val)) {
21988 to[prop] = val;
21989 }
21990 }
21991 }
21992
21993 return to;
21994 }
21995
21996 var updateInProgress = false; // Moment prototype object
21997
21998 function Moment(config) {
21999 copyConfig(this, config);
22000 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
22001
22002 if (!this.isValid()) {
22003 this._d = new Date(NaN);
22004 } // Prevent infinite loop in case updateOffset creates new moment
22005 // objects.
22006
22007
22008 if (updateInProgress === false) {
22009 updateInProgress = true;
22010 hooks.updateOffset(this);
22011 updateInProgress = false;
22012 }
22013 }
22014
22015 function isMoment(obj) {
22016 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
22017 }
22018
22019 function absFloor(number) {
22020 if (number < 0) {
22021 // -0 -> 0
22022 return Math.ceil(number) || 0;
22023 } else {
22024 return Math.floor(number);
22025 }
22026 }
22027
22028 function toInt(argumentForCoercion) {
22029 var coercedNumber = +argumentForCoercion,
22030 value = 0;
22031
22032 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
22033 value = absFloor(coercedNumber);
22034 }
22035
22036 return value;
22037 } // compare two arrays, return the number of differences
22038
22039
22040 function compareArrays(array1, array2, dontConvert) {
22041 var len = Math.min(array1.length, array2.length),
22042 lengthDiff = Math.abs(array1.length - array2.length),
22043 diffs = 0,
22044 i;
22045
22046 for (i = 0; i < len; i++) {
22047 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
22048 diffs++;
22049 }
22050 }
22051
22052 return diffs + lengthDiff;
22053 }
22054
22055 function warn(msg) {
22056 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
22057 console.warn('Deprecation warning: ' + msg);
22058 }
22059 }
22060
22061 function deprecate(msg, fn) {
22062 var firstTime = true;
22063 return extend(function () {
22064 if (hooks.deprecationHandler != null) {
22065 hooks.deprecationHandler(null, msg);
22066 }
22067
22068 if (firstTime) {
22069 var args = [];
22070 var arg;
22071
22072 for (var i = 0; i < arguments.length; i++) {
22073 arg = '';
22074
22075 if (_typeof(arguments[i]) === 'object') {
22076 arg += '\n[' + i + '] ';
22077
22078 for (var key in arguments[0]) {
22079 arg += key + ': ' + arguments[0][key] + ', ';
22080 }
22081
22082 arg = arg.slice(0, -2); // Remove trailing comma and space
22083 } else {
22084 arg = arguments[i];
22085 }
22086
22087 args.push(arg);
22088 }
22089
22090 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
22091 firstTime = false;
22092 }
22093
22094 return fn.apply(this, arguments);
22095 }, fn);
22096 }
22097
22098 var deprecations = {};
22099
22100 function deprecateSimple(name, msg) {
22101 if (hooks.deprecationHandler != null) {
22102 hooks.deprecationHandler(name, msg);
22103 }
22104
22105 if (!deprecations[name]) {
22106 warn(msg);
22107 deprecations[name] = true;
22108 }
22109 }
22110
22111 hooks.suppressDeprecationWarnings = false;
22112 hooks.deprecationHandler = null;
22113
22114 function isFunction(input) {
22115 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
22116 }
22117
22118 function set(config) {
22119 var prop, i;
22120
22121 for (i in config) {
22122 prop = config[i];
22123
22124 if (isFunction(prop)) {
22125 this[i] = prop;
22126 } else {
22127 this['_' + i] = prop;
22128 }
22129 }
22130
22131 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
22132 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
22133 // TODO: Remove "ordinalParse" fallback in next major release.
22134
22135 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
22136 }
22137
22138 function mergeConfigs(parentConfig, childConfig) {
22139 var res = extend({}, parentConfig),
22140 prop;
22141
22142 for (prop in childConfig) {
22143 if (hasOwnProp(childConfig, prop)) {
22144 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
22145 res[prop] = {};
22146 extend(res[prop], parentConfig[prop]);
22147 extend(res[prop], childConfig[prop]);
22148 } else if (childConfig[prop] != null) {
22149 res[prop] = childConfig[prop];
22150 } else {
22151 delete res[prop];
22152 }
22153 }
22154 }
22155
22156 for (prop in parentConfig) {
22157 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
22158 // make sure changes to properties don't modify parent config
22159 res[prop] = extend({}, res[prop]);
22160 }
22161 }
22162
22163 return res;
22164 }
22165
22166 function Locale(config) {
22167 if (config != null) {
22168 this.set(config);
22169 }
22170 }
22171
22172 var keys;
22173
22174 if (Object.keys) {
22175 keys = Object.keys;
22176 } else {
22177 keys = function keys(obj) {
22178 var i,
22179 res = [];
22180
22181 for (i in obj) {
22182 if (hasOwnProp(obj, i)) {
22183 res.push(i);
22184 }
22185 }
22186
22187 return res;
22188 };
22189 }
22190
22191 var defaultCalendar = {
22192 sameDay: '[Today at] LT',
22193 nextDay: '[Tomorrow at] LT',
22194 nextWeek: 'dddd [at] LT',
22195 lastDay: '[Yesterday at] LT',
22196 lastWeek: '[Last] dddd [at] LT',
22197 sameElse: 'L'
22198 };
22199
22200 function calendar(key, mom, now) {
22201 var output = this._calendar[key] || this._calendar['sameElse'];
22202 return isFunction(output) ? output.call(mom, now) : output;
22203 }
22204
22205 var defaultLongDateFormat = {
22206 LTS: 'h:mm:ss A',
22207 LT: 'h:mm A',
22208 L: 'MM/DD/YYYY',
22209 LL: 'MMMM D, YYYY',
22210 LLL: 'MMMM D, YYYY h:mm A',
22211 LLLL: 'dddd, MMMM D, YYYY h:mm A'
22212 };
22213
22214 function longDateFormat(key) {
22215 var format = this._longDateFormat[key],
22216 formatUpper = this._longDateFormat[key.toUpperCase()];
22217
22218 if (format || !formatUpper) {
22219 return format;
22220 }
22221
22222 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
22223 return val.slice(1);
22224 });
22225 return this._longDateFormat[key];
22226 }
22227
22228 var defaultInvalidDate = 'Invalid date';
22229
22230 function invalidDate() {
22231 return this._invalidDate;
22232 }
22233
22234 var defaultOrdinal = '%d';
22235 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
22236
22237 function ordinal(number) {
22238 return this._ordinal.replace('%d', number);
22239 }
22240
22241 var defaultRelativeTime = {
22242 future: 'in %s',
22243 past: '%s ago',
22244 s: 'a few seconds',
22245 ss: '%d seconds',
22246 m: 'a minute',
22247 mm: '%d minutes',
22248 h: 'an hour',
22249 hh: '%d hours',
22250 d: 'a day',
22251 dd: '%d days',
22252 M: 'a month',
22253 MM: '%d months',
22254 y: 'a year',
22255 yy: '%d years'
22256 };
22257
22258 function relativeTime(number, withoutSuffix, string, isFuture) {
22259 var output = this._relativeTime[string];
22260 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
22261 }
22262
22263 function pastFuture(diff, output) {
22264 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
22265 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
22266 }
22267
22268 var aliases = {};
22269
22270 function addUnitAlias(unit, shorthand) {
22271 var lowerCase = unit.toLowerCase();
22272 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
22273 }
22274
22275 function normalizeUnits(units) {
22276 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
22277 }
22278
22279 function normalizeObjectUnits(inputObject) {
22280 var normalizedInput = {},
22281 normalizedProp,
22282 prop;
22283
22284 for (prop in inputObject) {
22285 if (hasOwnProp(inputObject, prop)) {
22286 normalizedProp = normalizeUnits(prop);
22287
22288 if (normalizedProp) {
22289 normalizedInput[normalizedProp] = inputObject[prop];
22290 }
22291 }
22292 }
22293
22294 return normalizedInput;
22295 }
22296
22297 var priorities = {};
22298
22299 function addUnitPriority(unit, priority) {
22300 priorities[unit] = priority;
22301 }
22302
22303 function getPrioritizedUnits(unitsObj) {
22304 var units = [];
22305
22306 for (var u in unitsObj) {
22307 units.push({
22308 unit: u,
22309 priority: priorities[u]
22310 });
22311 }
22312
22313 units.sort(function (a, b) {
22314 return a.priority - b.priority;
22315 });
22316 return units;
22317 }
22318
22319 function zeroFill(number, targetLength, forceSign) {
22320 var absNumber = '' + Math.abs(number),
22321 zerosToFill = targetLength - absNumber.length,
22322 sign = number >= 0;
22323 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
22324 }
22325
22326 var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
22327 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
22328 var formatFunctions = {};
22329 var formatTokenFunctions = {}; // token: 'M'
22330 // padded: ['MM', 2]
22331 // ordinal: 'Mo'
22332 // callback: function () { this.month() + 1 }
22333
22334 function addFormatToken(token, padded, ordinal, callback) {
22335 var func = callback;
22336
22337 if (typeof callback === 'string') {
22338 func = function func() {
22339 return this[callback]();
22340 };
22341 }
22342
22343 if (token) {
22344 formatTokenFunctions[token] = func;
22345 }
22346
22347 if (padded) {
22348 formatTokenFunctions[padded[0]] = function () {
22349 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
22350 };
22351 }
22352
22353 if (ordinal) {
22354 formatTokenFunctions[ordinal] = function () {
22355 return this.localeData().ordinal(func.apply(this, arguments), token);
22356 };
22357 }
22358 }
22359
22360 function removeFormattingTokens(input) {
22361 if (input.match(/\[[\s\S]/)) {
22362 return input.replace(/^\[|\]$/g, '');
22363 }
22364
22365 return input.replace(/\\/g, '');
22366 }
22367
22368 function makeFormatFunction(format) {
22369 var array = format.match(formattingTokens),
22370 i,
22371 length;
22372
22373 for (i = 0, length = array.length; i < length; i++) {
22374 if (formatTokenFunctions[array[i]]) {
22375 array[i] = formatTokenFunctions[array[i]];
22376 } else {
22377 array[i] = removeFormattingTokens(array[i]);
22378 }
22379 }
22380
22381 return function (mom) {
22382 var output = '',
22383 i;
22384
22385 for (i = 0; i < length; i++) {
22386 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
22387 }
22388
22389 return output;
22390 };
22391 } // format date using native date object
22392
22393
22394 function formatMoment(m, format) {
22395 if (!m.isValid()) {
22396 return m.localeData().invalidDate();
22397 }
22398
22399 format = expandFormat(format, m.localeData());
22400 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
22401 return formatFunctions[format](m);
22402 }
22403
22404 function expandFormat(format, locale) {
22405 var i = 5;
22406
22407 function replaceLongDateFormatTokens(input) {
22408 return locale.longDateFormat(input) || input;
22409 }
22410
22411 localFormattingTokens.lastIndex = 0;
22412
22413 while (i >= 0 && localFormattingTokens.test(format)) {
22414 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
22415 localFormattingTokens.lastIndex = 0;
22416 i -= 1;
22417 }
22418
22419 return format;
22420 }
22421
22422 var match1 = /\d/; // 0 - 9
22423
22424 var match2 = /\d\d/; // 00 - 99
22425
22426 var match3 = /\d{3}/; // 000 - 999
22427
22428 var match4 = /\d{4}/; // 0000 - 9999
22429
22430 var match6 = /[+-]?\d{6}/; // -999999 - 999999
22431
22432 var match1to2 = /\d\d?/; // 0 - 99
22433
22434 var match3to4 = /\d\d\d\d?/; // 999 - 9999
22435
22436 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
22437
22438 var match1to3 = /\d{1,3}/; // 0 - 999
22439
22440 var match1to4 = /\d{1,4}/; // 0 - 9999
22441
22442 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
22443
22444 var matchUnsigned = /\d+/; // 0 - inf
22445
22446 var matchSigned = /[+-]?\d+/; // -inf - inf
22447
22448 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
22449
22450 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
22451
22452 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
22453 // any word (or two) characters or numbers including two/three word month in arabic.
22454 // includes scottish gaelic two word and hyphenated months
22455
22456 var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
22457 var regexes = {};
22458
22459 function addRegexToken(token, regex, strictRegex) {
22460 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
22461 return isStrict && strictRegex ? strictRegex : regex;
22462 };
22463 }
22464
22465 function getParseRegexForToken(token, config) {
22466 if (!hasOwnProp(regexes, token)) {
22467 return new RegExp(unescapeFormat(token));
22468 }
22469
22470 return regexes[token](config._strict, config._locale);
22471 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
22472
22473
22474 function unescapeFormat(s) {
22475 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
22476 return p1 || p2 || p3 || p4;
22477 }));
22478 }
22479
22480 function regexEscape(s) {
22481 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
22482 }
22483
22484 var tokens = {};
22485
22486 function addParseToken(token, callback) {
22487 var i,
22488 func = callback;
22489
22490 if (typeof token === 'string') {
22491 token = [token];
22492 }
22493
22494 if (isNumber(callback)) {
22495 func = function func(input, array) {
22496 array[callback] = toInt(input);
22497 };
22498 }
22499
22500 for (i = 0; i < token.length; i++) {
22501 tokens[token[i]] = func;
22502 }
22503 }
22504
22505 function addWeekParseToken(token, callback) {
22506 addParseToken(token, function (input, array, config, token) {
22507 config._w = config._w || {};
22508 callback(input, config._w, config, token);
22509 });
22510 }
22511
22512 function addTimeToArrayFromToken(token, input, config) {
22513 if (input != null && hasOwnProp(tokens, token)) {
22514 tokens[token](input, config._a, config, token);
22515 }
22516 }
22517
22518 var YEAR = 0;
22519 var MONTH = 1;
22520 var DATE = 2;
22521 var HOUR = 3;
22522 var MINUTE = 4;
22523 var SECOND = 5;
22524 var MILLISECOND = 6;
22525 var WEEK = 7;
22526 var WEEKDAY = 8; // FORMATTING
22527
22528 addFormatToken('Y', 0, 0, function () {
22529 var y = this.year();
22530 return y <= 9999 ? '' + y : '+' + y;
22531 });
22532 addFormatToken(0, ['YY', 2], 0, function () {
22533 return this.year() % 100;
22534 });
22535 addFormatToken(0, ['YYYY', 4], 0, 'year');
22536 addFormatToken(0, ['YYYYY', 5], 0, 'year');
22537 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
22538
22539 addUnitAlias('year', 'y'); // PRIORITIES
22540
22541 addUnitPriority('year', 1); // PARSING
22542
22543 addRegexToken('Y', matchSigned);
22544 addRegexToken('YY', match1to2, match2);
22545 addRegexToken('YYYY', match1to4, match4);
22546 addRegexToken('YYYYY', match1to6, match6);
22547 addRegexToken('YYYYYY', match1to6, match6);
22548 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
22549 addParseToken('YYYY', function (input, array) {
22550 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
22551 });
22552 addParseToken('YY', function (input, array) {
22553 array[YEAR] = hooks.parseTwoDigitYear(input);
22554 });
22555 addParseToken('Y', function (input, array) {
22556 array[YEAR] = parseInt(input, 10);
22557 }); // HELPERS
22558
22559 function daysInYear(year) {
22560 return isLeapYear(year) ? 366 : 365;
22561 }
22562
22563 function isLeapYear(year) {
22564 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
22565 } // HOOKS
22566
22567
22568 hooks.parseTwoDigitYear = function (input) {
22569 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
22570 }; // MOMENTS
22571
22572
22573 var getSetYear = makeGetSet('FullYear', true);
22574
22575 function getIsLeapYear() {
22576 return isLeapYear(this.year());
22577 }
22578
22579 function makeGetSet(unit, keepTime) {
22580 return function (value) {
22581 if (value != null) {
22582 set$1(this, unit, value);
22583 hooks.updateOffset(this, keepTime);
22584 return this;
22585 } else {
22586 return get(this, unit);
22587 }
22588 };
22589 }
22590
22591 function get(mom, unit) {
22592 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
22593 }
22594
22595 function set$1(mom, unit, value) {
22596 if (mom.isValid() && !isNaN(value)) {
22597 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
22598 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
22599 } else {
22600 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
22601 }
22602 }
22603 } // MOMENTS
22604
22605
22606 function stringGet(units) {
22607 units = normalizeUnits(units);
22608
22609 if (isFunction(this[units])) {
22610 return this[units]();
22611 }
22612
22613 return this;
22614 }
22615
22616 function stringSet(units, value) {
22617 if (_typeof(units) === 'object') {
22618 units = normalizeObjectUnits(units);
22619 var prioritized = getPrioritizedUnits(units);
22620
22621 for (var i = 0; i < prioritized.length; i++) {
22622 this[prioritized[i].unit](units[prioritized[i].unit]);
22623 }
22624 } else {
22625 units = normalizeUnits(units);
22626
22627 if (isFunction(this[units])) {
22628 return this[units](value);
22629 }
22630 }
22631
22632 return this;
22633 }
22634
22635 function mod(n, x) {
22636 return (n % x + x) % x;
22637 }
22638
22639 var indexOf;
22640
22641 if (Array.prototype.indexOf) {
22642 indexOf = Array.prototype.indexOf;
22643 } else {
22644 indexOf = function indexOf(o) {
22645 // I know
22646 var i;
22647
22648 for (i = 0; i < this.length; ++i) {
22649 if (this[i] === o) {
22650 return i;
22651 }
22652 }
22653
22654 return -1;
22655 };
22656 }
22657
22658 function daysInMonth(year, month) {
22659 if (isNaN(year) || isNaN(month)) {
22660 return NaN;
22661 }
22662
22663 var modMonth = mod(month, 12);
22664 year += (month - modMonth) / 12;
22665 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
22666 } // FORMATTING
22667
22668
22669 addFormatToken('M', ['MM', 2], 'Mo', function () {
22670 return this.month() + 1;
22671 });
22672 addFormatToken('MMM', 0, 0, function (format) {
22673 return this.localeData().monthsShort(this, format);
22674 });
22675 addFormatToken('MMMM', 0, 0, function (format) {
22676 return this.localeData().months(this, format);
22677 }); // ALIASES
22678
22679 addUnitAlias('month', 'M'); // PRIORITY
22680
22681 addUnitPriority('month', 8); // PARSING
22682
22683 addRegexToken('M', match1to2);
22684 addRegexToken('MM', match1to2, match2);
22685 addRegexToken('MMM', function (isStrict, locale) {
22686 return locale.monthsShortRegex(isStrict);
22687 });
22688 addRegexToken('MMMM', function (isStrict, locale) {
22689 return locale.monthsRegex(isStrict);
22690 });
22691 addParseToken(['M', 'MM'], function (input, array) {
22692 array[MONTH] = toInt(input) - 1;
22693 });
22694 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
22695 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
22696
22697
22698 if (month != null) {
22699 array[MONTH] = month;
22700 } else {
22701 getParsingFlags(config).invalidMonth = input;
22702 }
22703 }); // LOCALES
22704
22705 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
22706 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
22707
22708 function localeMonths(m, format) {
22709 if (!m) {
22710 return isArray(this._months) ? this._months : this._months['standalone'];
22711 }
22712
22713 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
22714 }
22715
22716 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
22717
22718 function localeMonthsShort(m, format) {
22719 if (!m) {
22720 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
22721 }
22722
22723 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
22724 }
22725
22726 function handleStrictParse(monthName, format, strict) {
22727 var i,
22728 ii,
22729 mom,
22730 llc = monthName.toLocaleLowerCase();
22731
22732 if (!this._monthsParse) {
22733 // this is not used
22734 this._monthsParse = [];
22735 this._longMonthsParse = [];
22736 this._shortMonthsParse = [];
22737
22738 for (i = 0; i < 12; ++i) {
22739 mom = createUTC([2000, i]);
22740 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
22741 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
22742 }
22743 }
22744
22745 if (strict) {
22746 if (format === 'MMM') {
22747 ii = indexOf.call(this._shortMonthsParse, llc);
22748 return ii !== -1 ? ii : null;
22749 } else {
22750 ii = indexOf.call(this._longMonthsParse, llc);
22751 return ii !== -1 ? ii : null;
22752 }
22753 } else {
22754 if (format === 'MMM') {
22755 ii = indexOf.call(this._shortMonthsParse, llc);
22756
22757 if (ii !== -1) {
22758 return ii;
22759 }
22760
22761 ii = indexOf.call(this._longMonthsParse, llc);
22762 return ii !== -1 ? ii : null;
22763 } else {
22764 ii = indexOf.call(this._longMonthsParse, llc);
22765
22766 if (ii !== -1) {
22767 return ii;
22768 }
22769
22770 ii = indexOf.call(this._shortMonthsParse, llc);
22771 return ii !== -1 ? ii : null;
22772 }
22773 }
22774 }
22775
22776 function localeMonthsParse(monthName, format, strict) {
22777 var i, mom, regex;
22778
22779 if (this._monthsParseExact) {
22780 return handleStrictParse.call(this, monthName, format, strict);
22781 }
22782
22783 if (!this._monthsParse) {
22784 this._monthsParse = [];
22785 this._longMonthsParse = [];
22786 this._shortMonthsParse = [];
22787 } // TODO: add sorting
22788 // Sorting makes sure if one month (or abbr) is a prefix of another
22789 // see sorting in computeMonthsParse
22790
22791
22792 for (i = 0; i < 12; i++) {
22793 // make the regex if we don't have it already
22794 mom = createUTC([2000, i]);
22795
22796 if (strict && !this._longMonthsParse[i]) {
22797 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
22798 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
22799 }
22800
22801 if (!strict && !this._monthsParse[i]) {
22802 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
22803 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
22804 } // test the regex
22805
22806
22807 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
22808 return i;
22809 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
22810 return i;
22811 } else if (!strict && this._monthsParse[i].test(monthName)) {
22812 return i;
22813 }
22814 }
22815 } // MOMENTS
22816
22817
22818 function setMonth(mom, value) {
22819 var dayOfMonth;
22820
22821 if (!mom.isValid()) {
22822 // No op
22823 return mom;
22824 }
22825
22826 if (typeof value === 'string') {
22827 if (/^\d+$/.test(value)) {
22828 value = toInt(value);
22829 } else {
22830 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
22831
22832 if (!isNumber(value)) {
22833 return mom;
22834 }
22835 }
22836 }
22837
22838 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
22839
22840 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
22841
22842 return mom;
22843 }
22844
22845 function getSetMonth(value) {
22846 if (value != null) {
22847 setMonth(this, value);
22848 hooks.updateOffset(this, true);
22849 return this;
22850 } else {
22851 return get(this, 'Month');
22852 }
22853 }
22854
22855 function getDaysInMonth() {
22856 return daysInMonth(this.year(), this.month());
22857 }
22858
22859 var defaultMonthsShortRegex = matchWord;
22860
22861 function monthsShortRegex(isStrict) {
22862 if (this._monthsParseExact) {
22863 if (!hasOwnProp(this, '_monthsRegex')) {
22864 computeMonthsParse.call(this);
22865 }
22866
22867 if (isStrict) {
22868 return this._monthsShortStrictRegex;
22869 } else {
22870 return this._monthsShortRegex;
22871 }
22872 } else {
22873 if (!hasOwnProp(this, '_monthsShortRegex')) {
22874 this._monthsShortRegex = defaultMonthsShortRegex;
22875 }
22876
22877 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
22878 }
22879 }
22880
22881 var defaultMonthsRegex = matchWord;
22882
22883 function monthsRegex(isStrict) {
22884 if (this._monthsParseExact) {
22885 if (!hasOwnProp(this, '_monthsRegex')) {
22886 computeMonthsParse.call(this);
22887 }
22888
22889 if (isStrict) {
22890 return this._monthsStrictRegex;
22891 } else {
22892 return this._monthsRegex;
22893 }
22894 } else {
22895 if (!hasOwnProp(this, '_monthsRegex')) {
22896 this._monthsRegex = defaultMonthsRegex;
22897 }
22898
22899 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
22900 }
22901 }
22902
22903 function computeMonthsParse() {
22904 function cmpLenRev(a, b) {
22905 return b.length - a.length;
22906 }
22907
22908 var shortPieces = [],
22909 longPieces = [],
22910 mixedPieces = [],
22911 i,
22912 mom;
22913
22914 for (i = 0; i < 12; i++) {
22915 // make the regex if we don't have it already
22916 mom = createUTC([2000, i]);
22917 shortPieces.push(this.monthsShort(mom, ''));
22918 longPieces.push(this.months(mom, ''));
22919 mixedPieces.push(this.months(mom, ''));
22920 mixedPieces.push(this.monthsShort(mom, ''));
22921 } // Sorting makes sure if one month (or abbr) is a prefix of another it
22922 // will match the longer piece.
22923
22924
22925 shortPieces.sort(cmpLenRev);
22926 longPieces.sort(cmpLenRev);
22927 mixedPieces.sort(cmpLenRev);
22928
22929 for (i = 0; i < 12; i++) {
22930 shortPieces[i] = regexEscape(shortPieces[i]);
22931 longPieces[i] = regexEscape(longPieces[i]);
22932 }
22933
22934 for (i = 0; i < 24; i++) {
22935 mixedPieces[i] = regexEscape(mixedPieces[i]);
22936 }
22937
22938 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
22939 this._monthsShortRegex = this._monthsRegex;
22940 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
22941 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
22942 }
22943
22944 function createDate(y, m, d, h, M, s, ms) {
22945 // can't just apply() to create a date:
22946 // https://stackoverflow.com/q/181348
22947 var date; // the date constructor remaps years 0-99 to 1900-1999
22948
22949 if (y < 100 && y >= 0) {
22950 // preserve leap years using a full 400 year cycle, then reset
22951 date = new Date(y + 400, m, d, h, M, s, ms);
22952
22953 if (isFinite(date.getFullYear())) {
22954 date.setFullYear(y);
22955 }
22956 } else {
22957 date = new Date(y, m, d, h, M, s, ms);
22958 }
22959
22960 return date;
22961 }
22962
22963 function createUTCDate(y) {
22964 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
22965
22966 if (y < 100 && y >= 0) {
22967 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
22968
22969 args[0] = y + 400;
22970 date = new Date(Date.UTC.apply(null, args));
22971
22972 if (isFinite(date.getUTCFullYear())) {
22973 date.setUTCFullYear(y);
22974 }
22975 } else {
22976 date = new Date(Date.UTC.apply(null, arguments));
22977 }
22978
22979 return date;
22980 } // start-of-first-week - start-of-year
22981
22982
22983 function firstWeekOffset(year, dow, doy) {
22984 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
22985 fwd = 7 + dow - doy,
22986 // first-week day local weekday -- which local weekday is fwd
22987 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
22988 return -fwdlw + fwd - 1;
22989 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
22990
22991
22992 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
22993 var localWeekday = (7 + weekday - dow) % 7,
22994 weekOffset = firstWeekOffset(year, dow, doy),
22995 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
22996 resYear,
22997 resDayOfYear;
22998
22999 if (dayOfYear <= 0) {
23000 resYear = year - 1;
23001 resDayOfYear = daysInYear(resYear) + dayOfYear;
23002 } else if (dayOfYear > daysInYear(year)) {
23003 resYear = year + 1;
23004 resDayOfYear = dayOfYear - daysInYear(year);
23005 } else {
23006 resYear = year;
23007 resDayOfYear = dayOfYear;
23008 }
23009
23010 return {
23011 year: resYear,
23012 dayOfYear: resDayOfYear
23013 };
23014 }
23015
23016 function weekOfYear(mom, dow, doy) {
23017 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
23018 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
23019 resWeek,
23020 resYear;
23021
23022 if (week < 1) {
23023 resYear = mom.year() - 1;
23024 resWeek = week + weeksInYear(resYear, dow, doy);
23025 } else if (week > weeksInYear(mom.year(), dow, doy)) {
23026 resWeek = week - weeksInYear(mom.year(), dow, doy);
23027 resYear = mom.year() + 1;
23028 } else {
23029 resYear = mom.year();
23030 resWeek = week;
23031 }
23032
23033 return {
23034 week: resWeek,
23035 year: resYear
23036 };
23037 }
23038
23039 function weeksInYear(year, dow, doy) {
23040 var weekOffset = firstWeekOffset(year, dow, doy),
23041 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
23042 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
23043 } // FORMATTING
23044
23045
23046 addFormatToken('w', ['ww', 2], 'wo', 'week');
23047 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
23048
23049 addUnitAlias('week', 'w');
23050 addUnitAlias('isoWeek', 'W'); // PRIORITIES
23051
23052 addUnitPriority('week', 5);
23053 addUnitPriority('isoWeek', 5); // PARSING
23054
23055 addRegexToken('w', match1to2);
23056 addRegexToken('ww', match1to2, match2);
23057 addRegexToken('W', match1to2);
23058 addRegexToken('WW', match1to2, match2);
23059 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
23060 week[token.substr(0, 1)] = toInt(input);
23061 }); // HELPERS
23062 // LOCALES
23063
23064 function localeWeek(mom) {
23065 return weekOfYear(mom, this._week.dow, this._week.doy).week;
23066 }
23067
23068 var defaultLocaleWeek = {
23069 dow: 0,
23070 // Sunday is the first day of the week.
23071 doy: 6 // The week that contains Jan 6th is the first week of the year.
23072
23073 };
23074
23075 function localeFirstDayOfWeek() {
23076 return this._week.dow;
23077 }
23078
23079 function localeFirstDayOfYear() {
23080 return this._week.doy;
23081 } // MOMENTS
23082
23083
23084 function getSetWeek(input) {
23085 var week = this.localeData().week(this);
23086 return input == null ? week : this.add((input - week) * 7, 'd');
23087 }
23088
23089 function getSetISOWeek(input) {
23090 var week = weekOfYear(this, 1, 4).week;
23091 return input == null ? week : this.add((input - week) * 7, 'd');
23092 } // FORMATTING
23093
23094
23095 addFormatToken('d', 0, 'do', 'day');
23096 addFormatToken('dd', 0, 0, function (format) {
23097 return this.localeData().weekdaysMin(this, format);
23098 });
23099 addFormatToken('ddd', 0, 0, function (format) {
23100 return this.localeData().weekdaysShort(this, format);
23101 });
23102 addFormatToken('dddd', 0, 0, function (format) {
23103 return this.localeData().weekdays(this, format);
23104 });
23105 addFormatToken('e', 0, 0, 'weekday');
23106 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
23107
23108 addUnitAlias('day', 'd');
23109 addUnitAlias('weekday', 'e');
23110 addUnitAlias('isoWeekday', 'E'); // PRIORITY
23111
23112 addUnitPriority('day', 11);
23113 addUnitPriority('weekday', 11);
23114 addUnitPriority('isoWeekday', 11); // PARSING
23115
23116 addRegexToken('d', match1to2);
23117 addRegexToken('e', match1to2);
23118 addRegexToken('E', match1to2);
23119 addRegexToken('dd', function (isStrict, locale) {
23120 return locale.weekdaysMinRegex(isStrict);
23121 });
23122 addRegexToken('ddd', function (isStrict, locale) {
23123 return locale.weekdaysShortRegex(isStrict);
23124 });
23125 addRegexToken('dddd', function (isStrict, locale) {
23126 return locale.weekdaysRegex(isStrict);
23127 });
23128 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
23129 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
23130
23131
23132 if (weekday != null) {
23133 week.d = weekday;
23134 } else {
23135 getParsingFlags(config).invalidWeekday = input;
23136 }
23137 });
23138 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
23139 week[token] = toInt(input);
23140 }); // HELPERS
23141
23142 function parseWeekday(input, locale) {
23143 if (typeof input !== 'string') {
23144 return input;
23145 }
23146
23147 if (!isNaN(input)) {
23148 return parseInt(input, 10);
23149 }
23150
23151 input = locale.weekdaysParse(input);
23152
23153 if (typeof input === 'number') {
23154 return input;
23155 }
23156
23157 return null;
23158 }
23159
23160 function parseIsoWeekday(input, locale) {
23161 if (typeof input === 'string') {
23162 return locale.weekdaysParse(input) % 7 || 7;
23163 }
23164
23165 return isNaN(input) ? null : input;
23166 } // LOCALES
23167
23168
23169 function shiftWeekdays(ws, n) {
23170 return ws.slice(n, 7).concat(ws.slice(0, n));
23171 }
23172
23173 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
23174
23175 function localeWeekdays(m, format) {
23176 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
23177 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
23178 }
23179
23180 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
23181
23182 function localeWeekdaysShort(m) {
23183 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
23184 }
23185
23186 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
23187
23188 function localeWeekdaysMin(m) {
23189 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
23190 }
23191
23192 function handleStrictParse$1(weekdayName, format, strict) {
23193 var i,
23194 ii,
23195 mom,
23196 llc = weekdayName.toLocaleLowerCase();
23197
23198 if (!this._weekdaysParse) {
23199 this._weekdaysParse = [];
23200 this._shortWeekdaysParse = [];
23201 this._minWeekdaysParse = [];
23202
23203 for (i = 0; i < 7; ++i) {
23204 mom = createUTC([2000, 1]).day(i);
23205 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
23206 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
23207 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
23208 }
23209 }
23210
23211 if (strict) {
23212 if (format === 'dddd') {
23213 ii = indexOf.call(this._weekdaysParse, llc);
23214 return ii !== -1 ? ii : null;
23215 } else if (format === 'ddd') {
23216 ii = indexOf.call(this._shortWeekdaysParse, llc);
23217 return ii !== -1 ? ii : null;
23218 } else {
23219 ii = indexOf.call(this._minWeekdaysParse, llc);
23220 return ii !== -1 ? ii : null;
23221 }
23222 } else {
23223 if (format === 'dddd') {
23224 ii = indexOf.call(this._weekdaysParse, llc);
23225
23226 if (ii !== -1) {
23227 return ii;
23228 }
23229
23230 ii = indexOf.call(this._shortWeekdaysParse, llc);
23231
23232 if (ii !== -1) {
23233 return ii;
23234 }
23235
23236 ii = indexOf.call(this._minWeekdaysParse, llc);
23237 return ii !== -1 ? ii : null;
23238 } else if (format === 'ddd') {
23239 ii = indexOf.call(this._shortWeekdaysParse, llc);
23240
23241 if (ii !== -1) {
23242 return ii;
23243 }
23244
23245 ii = indexOf.call(this._weekdaysParse, llc);
23246
23247 if (ii !== -1) {
23248 return ii;
23249 }
23250
23251 ii = indexOf.call(this._minWeekdaysParse, llc);
23252 return ii !== -1 ? ii : null;
23253 } else {
23254 ii = indexOf.call(this._minWeekdaysParse, llc);
23255
23256 if (ii !== -1) {
23257 return ii;
23258 }
23259
23260 ii = indexOf.call(this._weekdaysParse, llc);
23261
23262 if (ii !== -1) {
23263 return ii;
23264 }
23265
23266 ii = indexOf.call(this._shortWeekdaysParse, llc);
23267 return ii !== -1 ? ii : null;
23268 }
23269 }
23270 }
23271
23272 function localeWeekdaysParse(weekdayName, format, strict) {
23273 var i, mom, regex;
23274
23275 if (this._weekdaysParseExact) {
23276 return handleStrictParse$1.call(this, weekdayName, format, strict);
23277 }
23278
23279 if (!this._weekdaysParse) {
23280 this._weekdaysParse = [];
23281 this._minWeekdaysParse = [];
23282 this._shortWeekdaysParse = [];
23283 this._fullWeekdaysParse = [];
23284 }
23285
23286 for (i = 0; i < 7; i++) {
23287 // make the regex if we don't have it already
23288 mom = createUTC([2000, 1]).day(i);
23289
23290 if (strict && !this._fullWeekdaysParse[i]) {
23291 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
23292 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
23293 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
23294 }
23295
23296 if (!this._weekdaysParse[i]) {
23297 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
23298 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
23299 } // test the regex
23300
23301
23302 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
23303 return i;
23304 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
23305 return i;
23306 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
23307 return i;
23308 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
23309 return i;
23310 }
23311 }
23312 } // MOMENTS
23313
23314
23315 function getSetDayOfWeek(input) {
23316 if (!this.isValid()) {
23317 return input != null ? this : NaN;
23318 }
23319
23320 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
23321
23322 if (input != null) {
23323 input = parseWeekday(input, this.localeData());
23324 return this.add(input - day, 'd');
23325 } else {
23326 return day;
23327 }
23328 }
23329
23330 function getSetLocaleDayOfWeek(input) {
23331 if (!this.isValid()) {
23332 return input != null ? this : NaN;
23333 }
23334
23335 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
23336 return input == null ? weekday : this.add(input - weekday, 'd');
23337 }
23338
23339 function getSetISODayOfWeek(input) {
23340 if (!this.isValid()) {
23341 return input != null ? this : NaN;
23342 } // behaves the same as moment#day except
23343 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
23344 // as a setter, sunday should belong to the previous week.
23345
23346
23347 if (input != null) {
23348 var weekday = parseIsoWeekday(input, this.localeData());
23349 return this.day(this.day() % 7 ? weekday : weekday - 7);
23350 } else {
23351 return this.day() || 7;
23352 }
23353 }
23354
23355 var defaultWeekdaysRegex = matchWord;
23356
23357 function weekdaysRegex(isStrict) {
23358 if (this._weekdaysParseExact) {
23359 if (!hasOwnProp(this, '_weekdaysRegex')) {
23360 computeWeekdaysParse.call(this);
23361 }
23362
23363 if (isStrict) {
23364 return this._weekdaysStrictRegex;
23365 } else {
23366 return this._weekdaysRegex;
23367 }
23368 } else {
23369 if (!hasOwnProp(this, '_weekdaysRegex')) {
23370 this._weekdaysRegex = defaultWeekdaysRegex;
23371 }
23372
23373 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
23374 }
23375 }
23376
23377 var defaultWeekdaysShortRegex = matchWord;
23378
23379 function weekdaysShortRegex(isStrict) {
23380 if (this._weekdaysParseExact) {
23381 if (!hasOwnProp(this, '_weekdaysRegex')) {
23382 computeWeekdaysParse.call(this);
23383 }
23384
23385 if (isStrict) {
23386 return this._weekdaysShortStrictRegex;
23387 } else {
23388 return this._weekdaysShortRegex;
23389 }
23390 } else {
23391 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
23392 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
23393 }
23394
23395 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
23396 }
23397 }
23398
23399 var defaultWeekdaysMinRegex = matchWord;
23400
23401 function weekdaysMinRegex(isStrict) {
23402 if (this._weekdaysParseExact) {
23403 if (!hasOwnProp(this, '_weekdaysRegex')) {
23404 computeWeekdaysParse.call(this);
23405 }
23406
23407 if (isStrict) {
23408 return this._weekdaysMinStrictRegex;
23409 } else {
23410 return this._weekdaysMinRegex;
23411 }
23412 } else {
23413 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
23414 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
23415 }
23416
23417 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
23418 }
23419 }
23420
23421 function computeWeekdaysParse() {
23422 function cmpLenRev(a, b) {
23423 return b.length - a.length;
23424 }
23425
23426 var minPieces = [],
23427 shortPieces = [],
23428 longPieces = [],
23429 mixedPieces = [],
23430 i,
23431 mom,
23432 minp,
23433 shortp,
23434 longp;
23435
23436 for (i = 0; i < 7; i++) {
23437 // make the regex if we don't have it already
23438 mom = createUTC([2000, 1]).day(i);
23439 minp = this.weekdaysMin(mom, '');
23440 shortp = this.weekdaysShort(mom, '');
23441 longp = this.weekdays(mom, '');
23442 minPieces.push(minp);
23443 shortPieces.push(shortp);
23444 longPieces.push(longp);
23445 mixedPieces.push(minp);
23446 mixedPieces.push(shortp);
23447 mixedPieces.push(longp);
23448 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
23449 // will match the longer piece.
23450
23451
23452 minPieces.sort(cmpLenRev);
23453 shortPieces.sort(cmpLenRev);
23454 longPieces.sort(cmpLenRev);
23455 mixedPieces.sort(cmpLenRev);
23456
23457 for (i = 0; i < 7; i++) {
23458 shortPieces[i] = regexEscape(shortPieces[i]);
23459 longPieces[i] = regexEscape(longPieces[i]);
23460 mixedPieces[i] = regexEscape(mixedPieces[i]);
23461 }
23462
23463 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
23464 this._weekdaysShortRegex = this._weekdaysRegex;
23465 this._weekdaysMinRegex = this._weekdaysRegex;
23466 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
23467 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
23468 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
23469 } // FORMATTING
23470
23471
23472 function hFormat() {
23473 return this.hours() % 12 || 12;
23474 }
23475
23476 function kFormat() {
23477 return this.hours() || 24;
23478 }
23479
23480 addFormatToken('H', ['HH', 2], 0, 'hour');
23481 addFormatToken('h', ['hh', 2], 0, hFormat);
23482 addFormatToken('k', ['kk', 2], 0, kFormat);
23483 addFormatToken('hmm', 0, 0, function () {
23484 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
23485 });
23486 addFormatToken('hmmss', 0, 0, function () {
23487 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
23488 });
23489 addFormatToken('Hmm', 0, 0, function () {
23490 return '' + this.hours() + zeroFill(this.minutes(), 2);
23491 });
23492 addFormatToken('Hmmss', 0, 0, function () {
23493 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
23494 });
23495
23496 function meridiem(token, lowercase) {
23497 addFormatToken(token, 0, 0, function () {
23498 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
23499 });
23500 }
23501
23502 meridiem('a', true);
23503 meridiem('A', false); // ALIASES
23504
23505 addUnitAlias('hour', 'h'); // PRIORITY
23506
23507 addUnitPriority('hour', 13); // PARSING
23508
23509 function matchMeridiem(isStrict, locale) {
23510 return locale._meridiemParse;
23511 }
23512
23513 addRegexToken('a', matchMeridiem);
23514 addRegexToken('A', matchMeridiem);
23515 addRegexToken('H', match1to2);
23516 addRegexToken('h', match1to2);
23517 addRegexToken('k', match1to2);
23518 addRegexToken('HH', match1to2, match2);
23519 addRegexToken('hh', match1to2, match2);
23520 addRegexToken('kk', match1to2, match2);
23521 addRegexToken('hmm', match3to4);
23522 addRegexToken('hmmss', match5to6);
23523 addRegexToken('Hmm', match3to4);
23524 addRegexToken('Hmmss', match5to6);
23525 addParseToken(['H', 'HH'], HOUR);
23526 addParseToken(['k', 'kk'], function (input, array, config) {
23527 var kInput = toInt(input);
23528 array[HOUR] = kInput === 24 ? 0 : kInput;
23529 });
23530 addParseToken(['a', 'A'], function (input, array, config) {
23531 config._isPm = config._locale.isPM(input);
23532 config._meridiem = input;
23533 });
23534 addParseToken(['h', 'hh'], function (input, array, config) {
23535 array[HOUR] = toInt(input);
23536 getParsingFlags(config).bigHour = true;
23537 });
23538 addParseToken('hmm', function (input, array, config) {
23539 var pos = input.length - 2;
23540 array[HOUR] = toInt(input.substr(0, pos));
23541 array[MINUTE] = toInt(input.substr(pos));
23542 getParsingFlags(config).bigHour = true;
23543 });
23544 addParseToken('hmmss', function (input, array, config) {
23545 var pos1 = input.length - 4;
23546 var pos2 = input.length - 2;
23547 array[HOUR] = toInt(input.substr(0, pos1));
23548 array[MINUTE] = toInt(input.substr(pos1, 2));
23549 array[SECOND] = toInt(input.substr(pos2));
23550 getParsingFlags(config).bigHour = true;
23551 });
23552 addParseToken('Hmm', function (input, array, config) {
23553 var pos = input.length - 2;
23554 array[HOUR] = toInt(input.substr(0, pos));
23555 array[MINUTE] = toInt(input.substr(pos));
23556 });
23557 addParseToken('Hmmss', function (input, array, config) {
23558 var pos1 = input.length - 4;
23559 var pos2 = input.length - 2;
23560 array[HOUR] = toInt(input.substr(0, pos1));
23561 array[MINUTE] = toInt(input.substr(pos1, 2));
23562 array[SECOND] = toInt(input.substr(pos2));
23563 }); // LOCALES
23564
23565 function localeIsPM(input) {
23566 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
23567 // Using charAt should be more compatible.
23568 return (input + '').toLowerCase().charAt(0) === 'p';
23569 }
23570
23571 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
23572
23573 function localeMeridiem(hours, minutes, isLower) {
23574 if (hours > 11) {
23575 return isLower ? 'pm' : 'PM';
23576 } else {
23577 return isLower ? 'am' : 'AM';
23578 }
23579 } // MOMENTS
23580 // Setting the hour should keep the time, because the user explicitly
23581 // specified which hour they want. So trying to maintain the same hour (in
23582 // a new timezone) makes sense. Adding/subtracting hours does not follow
23583 // this rule.
23584
23585
23586 var getSetHour = makeGetSet('Hours', true);
23587 var baseConfig = {
23588 calendar: defaultCalendar,
23589 longDateFormat: defaultLongDateFormat,
23590 invalidDate: defaultInvalidDate,
23591 ordinal: defaultOrdinal,
23592 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
23593 relativeTime: defaultRelativeTime,
23594 months: defaultLocaleMonths,
23595 monthsShort: defaultLocaleMonthsShort,
23596 week: defaultLocaleWeek,
23597 weekdays: defaultLocaleWeekdays,
23598 weekdaysMin: defaultLocaleWeekdaysMin,
23599 weekdaysShort: defaultLocaleWeekdaysShort,
23600 meridiemParse: defaultLocaleMeridiemParse
23601 }; // internal storage for locale config files
23602
23603 var locales = {};
23604 var localeFamilies = {};
23605 var globalLocale;
23606
23607 function normalizeLocale(key) {
23608 return key ? key.toLowerCase().replace('_', '-') : key;
23609 } // pick the locale from the array
23610 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
23611 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
23612
23613
23614 function chooseLocale(names) {
23615 var i = 0,
23616 j,
23617 next,
23618 locale,
23619 split;
23620
23621 while (i < names.length) {
23622 split = normalizeLocale(names[i]).split('-');
23623 j = split.length;
23624 next = normalizeLocale(names[i + 1]);
23625 next = next ? next.split('-') : null;
23626
23627 while (j > 0) {
23628 locale = loadLocale(split.slice(0, j).join('-'));
23629
23630 if (locale) {
23631 return locale;
23632 }
23633
23634 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
23635 //the next array item is better than a shallower substring of this one
23636 break;
23637 }
23638
23639 j--;
23640 }
23641
23642 i++;
23643 }
23644
23645 return globalLocale;
23646 }
23647
23648 function loadLocale(name) {
23649 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
23650
23651 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
23652 try {
23653 oldLocale = globalLocale._abbr;
23654 var aliasedRequire = commonjsRequire$1;
23655 aliasedRequire('./locale/' + name);
23656 getSetGlobalLocale(oldLocale);
23657 } catch (e) {}
23658 }
23659
23660 return locales[name];
23661 } // This function will load locale and then set the global locale. If
23662 // no arguments are passed in, it will simply return the current global
23663 // locale key.
23664
23665
23666 function getSetGlobalLocale(key, values) {
23667 var data;
23668
23669 if (key) {
23670 if (isUndefined(values)) {
23671 data = getLocale(key);
23672 } else {
23673 data = defineLocale(key, values);
23674 }
23675
23676 if (data) {
23677 // moment.duration._locale = moment._locale = data;
23678 globalLocale = data;
23679 } else {
23680 if (typeof console !== 'undefined' && console.warn) {
23681 //warn user if arguments are passed but the locale could not be set
23682 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
23683 }
23684 }
23685 }
23686
23687 return globalLocale._abbr;
23688 }
23689
23690 function defineLocale(name, config) {
23691 if (config !== null) {
23692 var locale,
23693 parentConfig = baseConfig;
23694 config.abbr = name;
23695
23696 if (locales[name] != null) {
23697 deprecateSimple('defineLocaleOverride', 'use moment.updateLocale(localeName, config) to change ' + 'an existing locale. moment.defineLocale(localeName, ' + 'config) should only be used for creating a new locale ' + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
23698 parentConfig = locales[name]._config;
23699 } else if (config.parentLocale != null) {
23700 if (locales[config.parentLocale] != null) {
23701 parentConfig = locales[config.parentLocale]._config;
23702 } else {
23703 locale = loadLocale(config.parentLocale);
23704
23705 if (locale != null) {
23706 parentConfig = locale._config;
23707 } else {
23708 if (!localeFamilies[config.parentLocale]) {
23709 localeFamilies[config.parentLocale] = [];
23710 }
23711
23712 localeFamilies[config.parentLocale].push({
23713 name: name,
23714 config: config
23715 });
23716 return null;
23717 }
23718 }
23719 }
23720
23721 locales[name] = new Locale(mergeConfigs(parentConfig, config));
23722
23723 if (localeFamilies[name]) {
23724 localeFamilies[name].forEach(function (x) {
23725 defineLocale(x.name, x.config);
23726 });
23727 } // backwards compat for now: also set the locale
23728 // make sure we set the locale AFTER all child locales have been
23729 // created, so we won't end up with the child locale set.
23730
23731
23732 getSetGlobalLocale(name);
23733 return locales[name];
23734 } else {
23735 // useful for testing
23736 delete locales[name];
23737 return null;
23738 }
23739 }
23740
23741 function updateLocale(name, config) {
23742 if (config != null) {
23743 var locale,
23744 tmpLocale,
23745 parentConfig = baseConfig; // MERGE
23746
23747 tmpLocale = loadLocale(name);
23748
23749 if (tmpLocale != null) {
23750 parentConfig = tmpLocale._config;
23751 }
23752
23753 config = mergeConfigs(parentConfig, config);
23754 locale = new Locale(config);
23755 locale.parentLocale = locales[name];
23756 locales[name] = locale; // backwards compat for now: also set the locale
23757
23758 getSetGlobalLocale(name);
23759 } else {
23760 // pass null for config to unupdate, useful for tests
23761 if (locales[name] != null) {
23762 if (locales[name].parentLocale != null) {
23763 locales[name] = locales[name].parentLocale;
23764 } else if (locales[name] != null) {
23765 delete locales[name];
23766 }
23767 }
23768 }
23769
23770 return locales[name];
23771 } // returns locale data
23772
23773
23774 function getLocale(key) {
23775 var locale;
23776
23777 if (key && key._locale && key._locale._abbr) {
23778 key = key._locale._abbr;
23779 }
23780
23781 if (!key) {
23782 return globalLocale;
23783 }
23784
23785 if (!isArray(key)) {
23786 //short-circuit everything else
23787 locale = loadLocale(key);
23788
23789 if (locale) {
23790 return locale;
23791 }
23792
23793 key = [key];
23794 }
23795
23796 return chooseLocale(key);
23797 }
23798
23799 function listLocales() {
23800 return keys(locales);
23801 }
23802
23803 function checkOverflow(m) {
23804 var overflow;
23805 var a = m._a;
23806
23807 if (a && getParsingFlags(m).overflow === -2) {
23808 overflow = a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : a[HOUR] < 0 || a[HOUR] > 24 || a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0) ? HOUR : a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : -1;
23809
23810 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
23811 overflow = DATE;
23812 }
23813
23814 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
23815 overflow = WEEK;
23816 }
23817
23818 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
23819 overflow = WEEKDAY;
23820 }
23821
23822 getParsingFlags(m).overflow = overflow;
23823 }
23824
23825 return m;
23826 } // Pick the first defined of two or three arguments.
23827
23828
23829 function defaults(a, b, c) {
23830 if (a != null) {
23831 return a;
23832 }
23833
23834 if (b != null) {
23835 return b;
23836 }
23837
23838 return c;
23839 }
23840
23841 function currentDateArray(config) {
23842 // hooks is actually the exported moment object
23843 var nowValue = new Date(hooks.now());
23844
23845 if (config._useUTC) {
23846 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
23847 }
23848
23849 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
23850 } // convert an array to a date.
23851 // the array should mirror the parameters below
23852 // note: all values past the year are optional and will default to the lowest possible value.
23853 // [year, month, day , hour, minute, second, millisecond]
23854
23855
23856 function configFromArray(config) {
23857 var i,
23858 date,
23859 input = [],
23860 currentDate,
23861 expectedWeekday,
23862 yearToUse;
23863
23864 if (config._d) {
23865 return;
23866 }
23867
23868 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
23869
23870 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
23871 dayOfYearFromWeekInfo(config);
23872 } //if the day of the year is set, figure out what it is
23873
23874
23875 if (config._dayOfYear != null) {
23876 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
23877
23878 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
23879 getParsingFlags(config)._overflowDayOfYear = true;
23880 }
23881
23882 date = createUTCDate(yearToUse, 0, config._dayOfYear);
23883 config._a[MONTH] = date.getUTCMonth();
23884 config._a[DATE] = date.getUTCDate();
23885 } // Default to current date.
23886 // * if no year, month, day of month are given, default to today
23887 // * if day of month is given, default month and year
23888 // * if month is given, default only year
23889 // * if year is given, don't default anything
23890
23891
23892 for (i = 0; i < 3 && config._a[i] == null; ++i) {
23893 config._a[i] = input[i] = currentDate[i];
23894 } // Zero out whatever was not defaulted, including time
23895
23896
23897 for (; i < 7; i++) {
23898 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
23899 } // Check for 24:00:00.000
23900
23901
23902 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
23903 config._nextDay = true;
23904 config._a[HOUR] = 0;
23905 }
23906
23907 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
23908 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
23909 // with parseZone.
23910
23911 if (config._tzm != null) {
23912 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
23913 }
23914
23915 if (config._nextDay) {
23916 config._a[HOUR] = 24;
23917 } // check for mismatching day of week
23918
23919
23920 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
23921 getParsingFlags(config).weekdayMismatch = true;
23922 }
23923 }
23924
23925 function dayOfYearFromWeekInfo(config) {
23926 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
23927 w = config._w;
23928
23929 if (w.GG != null || w.W != null || w.E != null) {
23930 dow = 1;
23931 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
23932 // how we interpret now (local, utc, fixed offset). So create
23933 // a now version of current config (take local/utc/offset flags, and
23934 // create now).
23935
23936 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
23937 week = defaults(w.W, 1);
23938 weekday = defaults(w.E, 1);
23939
23940 if (weekday < 1 || weekday > 7) {
23941 weekdayOverflow = true;
23942 }
23943 } else {
23944 dow = config._locale._week.dow;
23945 doy = config._locale._week.doy;
23946 var curWeek = weekOfYear(createLocal(), dow, doy);
23947 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
23948
23949 week = defaults(w.w, curWeek.week);
23950
23951 if (w.d != null) {
23952 // weekday -- low day numbers are considered next week
23953 weekday = w.d;
23954
23955 if (weekday < 0 || weekday > 6) {
23956 weekdayOverflow = true;
23957 }
23958 } else if (w.e != null) {
23959 // local weekday -- counting starts from beginning of week
23960 weekday = w.e + dow;
23961
23962 if (w.e < 0 || w.e > 6) {
23963 weekdayOverflow = true;
23964 }
23965 } else {
23966 // default to beginning of week
23967 weekday = dow;
23968 }
23969 }
23970
23971 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
23972 getParsingFlags(config)._overflowWeeks = true;
23973 } else if (weekdayOverflow != null) {
23974 getParsingFlags(config)._overflowWeekday = true;
23975 } else {
23976 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
23977 config._a[YEAR] = temp.year;
23978 config._dayOfYear = temp.dayOfYear;
23979 }
23980 } // iso 8601 regex
23981 // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
23982
23983
23984 var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
23985 var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
23986 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
23987 var isoDates = [['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], ['GGGG-[W]WW', /\d{4}-W\d\d/, false], ['YYYY-DDD', /\d{4}-\d{3}/], ['YYYY-MM', /\d{4}-\d\d/, false], ['YYYYYYMMDD', /[+-]\d{10}/], ['YYYYMMDD', /\d{8}/], // YYYYMM is NOT allowed by the standard
23988 ['GGGG[W]WWE', /\d{4}W\d{3}/], ['GGGG[W]WW', /\d{4}W\d{2}/, false], ['YYYYDDD', /\d{7}/]]; // iso time formats and regexes
23989
23990 var isoTimes = [['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], ['HH:mm:ss', /\d\d:\d\d:\d\d/], ['HH:mm', /\d\d:\d\d/], ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], ['HHmmss', /\d\d\d\d\d\d/], ['HHmm', /\d\d\d\d/], ['HH', /\d\d/]];
23991 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
23992
23993 function configFromISO(config) {
23994 var i,
23995 l,
23996 string = config._i,
23997 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
23998 allowTime,
23999 dateFormat,
24000 timeFormat,
24001 tzFormat;
24002
24003 if (match) {
24004 getParsingFlags(config).iso = true;
24005
24006 for (i = 0, l = isoDates.length; i < l; i++) {
24007 if (isoDates[i][1].exec(match[1])) {
24008 dateFormat = isoDates[i][0];
24009 allowTime = isoDates[i][2] !== false;
24010 break;
24011 }
24012 }
24013
24014 if (dateFormat == null) {
24015 config._isValid = false;
24016 return;
24017 }
24018
24019 if (match[3]) {
24020 for (i = 0, l = isoTimes.length; i < l; i++) {
24021 if (isoTimes[i][1].exec(match[3])) {
24022 // match[2] should be 'T' or space
24023 timeFormat = (match[2] || ' ') + isoTimes[i][0];
24024 break;
24025 }
24026 }
24027
24028 if (timeFormat == null) {
24029 config._isValid = false;
24030 return;
24031 }
24032 }
24033
24034 if (!allowTime && timeFormat != null) {
24035 config._isValid = false;
24036 return;
24037 }
24038
24039 if (match[4]) {
24040 if (tzRegex.exec(match[4])) {
24041 tzFormat = 'Z';
24042 } else {
24043 config._isValid = false;
24044 return;
24045 }
24046 }
24047
24048 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
24049 configFromStringAndFormat(config);
24050 } else {
24051 config._isValid = false;
24052 }
24053 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
24054
24055
24056 var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
24057
24058 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
24059 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
24060
24061 if (secondStr) {
24062 result.push(parseInt(secondStr, 10));
24063 }
24064
24065 return result;
24066 }
24067
24068 function untruncateYear(yearStr) {
24069 var year = parseInt(yearStr, 10);
24070
24071 if (year <= 49) {
24072 return 2000 + year;
24073 } else if (year <= 999) {
24074 return 1900 + year;
24075 }
24076
24077 return year;
24078 }
24079
24080 function preprocessRFC2822(s) {
24081 // Remove comments and folding whitespace and replace multiple-spaces with a single space
24082 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
24083 }
24084
24085 function checkWeekday(weekdayStr, parsedInput, config) {
24086 if (weekdayStr) {
24087 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
24088 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
24089 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
24090
24091 if (weekdayProvided !== weekdayActual) {
24092 getParsingFlags(config).weekdayMismatch = true;
24093 config._isValid = false;
24094 return false;
24095 }
24096 }
24097
24098 return true;
24099 }
24100
24101 var obsOffsets = {
24102 UT: 0,
24103 GMT: 0,
24104 EDT: -4 * 60,
24105 EST: -5 * 60,
24106 CDT: -5 * 60,
24107 CST: -6 * 60,
24108 MDT: -6 * 60,
24109 MST: -7 * 60,
24110 PDT: -7 * 60,
24111 PST: -8 * 60
24112 };
24113
24114 function calculateOffset(obsOffset, militaryOffset, numOffset) {
24115 if (obsOffset) {
24116 return obsOffsets[obsOffset];
24117 } else if (militaryOffset) {
24118 // the only allowed military tz is Z
24119 return 0;
24120 } else {
24121 var hm = parseInt(numOffset, 10);
24122 var m = hm % 100,
24123 h = (hm - m) / 100;
24124 return h * 60 + m;
24125 }
24126 } // date and time from ref 2822 format
24127
24128
24129 function configFromRFC2822(config) {
24130 var match = rfc2822.exec(preprocessRFC2822(config._i));
24131
24132 if (match) {
24133 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
24134
24135 if (!checkWeekday(match[1], parsedArray, config)) {
24136 return;
24137 }
24138
24139 config._a = parsedArray;
24140 config._tzm = calculateOffset(match[8], match[9], match[10]);
24141 config._d = createUTCDate.apply(null, config._a);
24142
24143 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
24144
24145 getParsingFlags(config).rfc2822 = true;
24146 } else {
24147 config._isValid = false;
24148 }
24149 } // date from iso format or fallback
24150
24151
24152 function configFromString(config) {
24153 var matched = aspNetJsonRegex.exec(config._i);
24154
24155 if (matched !== null) {
24156 config._d = new Date(+matched[1]);
24157 return;
24158 }
24159
24160 configFromISO(config);
24161
24162 if (config._isValid === false) {
24163 delete config._isValid;
24164 } else {
24165 return;
24166 }
24167
24168 configFromRFC2822(config);
24169
24170 if (config._isValid === false) {
24171 delete config._isValid;
24172 } else {
24173 return;
24174 } // Final attempt, use Input Fallback
24175
24176
24177 hooks.createFromInputFallback(config);
24178 }
24179
24180 hooks.createFromInputFallback = deprecate('value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 'discouraged and will be removed in an upcoming major release. Please refer to ' + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', function (config) {
24181 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
24182 }); // constant that refers to the ISO standard
24183
24184 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
24185
24186
24187 hooks.RFC_2822 = function () {}; // date from string and format string
24188
24189
24190 function configFromStringAndFormat(config) {
24191 // TODO: Move this to another part of the creation flow to prevent circular deps
24192 if (config._f === hooks.ISO_8601) {
24193 configFromISO(config);
24194 return;
24195 }
24196
24197 if (config._f === hooks.RFC_2822) {
24198 configFromRFC2822(config);
24199 return;
24200 }
24201
24202 config._a = [];
24203 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
24204
24205 var string = '' + config._i,
24206 i,
24207 parsedInput,
24208 tokens,
24209 token,
24210 skipped,
24211 stringLength = string.length,
24212 totalParsedInputLength = 0;
24213 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
24214
24215 for (i = 0; i < tokens.length; i++) {
24216 token = tokens[i];
24217 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
24218 // 'regex', getParseRegexForToken(token, config));
24219
24220 if (parsedInput) {
24221 skipped = string.substr(0, string.indexOf(parsedInput));
24222
24223 if (skipped.length > 0) {
24224 getParsingFlags(config).unusedInput.push(skipped);
24225 }
24226
24227 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
24228 totalParsedInputLength += parsedInput.length;
24229 } // don't parse if it's not a known token
24230
24231
24232 if (formatTokenFunctions[token]) {
24233 if (parsedInput) {
24234 getParsingFlags(config).empty = false;
24235 } else {
24236 getParsingFlags(config).unusedTokens.push(token);
24237 }
24238
24239 addTimeToArrayFromToken(token, parsedInput, config);
24240 } else if (config._strict && !parsedInput) {
24241 getParsingFlags(config).unusedTokens.push(token);
24242 }
24243 } // add remaining unparsed input length to the string
24244
24245
24246 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
24247
24248 if (string.length > 0) {
24249 getParsingFlags(config).unusedInput.push(string);
24250 } // clear _12h flag if hour is <= 12
24251
24252
24253 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
24254 getParsingFlags(config).bigHour = undefined;
24255 }
24256
24257 getParsingFlags(config).parsedDateParts = config._a.slice(0);
24258 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
24259
24260 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
24261 configFromArray(config);
24262 checkOverflow(config);
24263 }
24264
24265 function meridiemFixWrap(locale, hour, meridiem) {
24266 var isPm;
24267
24268 if (meridiem == null) {
24269 // nothing to do
24270 return hour;
24271 }
24272
24273 if (locale.meridiemHour != null) {
24274 return locale.meridiemHour(hour, meridiem);
24275 } else if (locale.isPM != null) {
24276 // Fallback
24277 isPm = locale.isPM(meridiem);
24278
24279 if (isPm && hour < 12) {
24280 hour += 12;
24281 }
24282
24283 if (!isPm && hour === 12) {
24284 hour = 0;
24285 }
24286
24287 return hour;
24288 } else {
24289 // this is not supposed to happen
24290 return hour;
24291 }
24292 } // date from string and array of format strings
24293
24294
24295 function configFromStringAndArray(config) {
24296 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
24297
24298 if (config._f.length === 0) {
24299 getParsingFlags(config).invalidFormat = true;
24300 config._d = new Date(NaN);
24301 return;
24302 }
24303
24304 for (i = 0; i < config._f.length; i++) {
24305 currentScore = 0;
24306 tempConfig = copyConfig({}, config);
24307
24308 if (config._useUTC != null) {
24309 tempConfig._useUTC = config._useUTC;
24310 }
24311
24312 tempConfig._f = config._f[i];
24313 configFromStringAndFormat(tempConfig);
24314
24315 if (!isValid(tempConfig)) {
24316 continue;
24317 } // if there is any input that was not parsed add a penalty for that format
24318
24319
24320 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
24321
24322 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
24323 getParsingFlags(tempConfig).score = currentScore;
24324
24325 if (scoreToBeat == null || currentScore < scoreToBeat) {
24326 scoreToBeat = currentScore;
24327 bestMoment = tempConfig;
24328 }
24329 }
24330
24331 extend(config, bestMoment || tempConfig);
24332 }
24333
24334 function configFromObject(config) {
24335 if (config._d) {
24336 return;
24337 }
24338
24339 var i = normalizeObjectUnits(config._i);
24340 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
24341 return obj && parseInt(obj, 10);
24342 });
24343 configFromArray(config);
24344 }
24345
24346 function createFromConfig(config) {
24347 var res = new Moment(checkOverflow(prepareConfig(config)));
24348
24349 if (res._nextDay) {
24350 // Adding is smart enough around DST
24351 res.add(1, 'd');
24352 res._nextDay = undefined;
24353 }
24354
24355 return res;
24356 }
24357
24358 function prepareConfig(config) {
24359 var input = config._i,
24360 format = config._f;
24361 config._locale = config._locale || getLocale(config._l);
24362
24363 if (input === null || format === undefined && input === '') {
24364 return createInvalid({
24365 nullInput: true
24366 });
24367 }
24368
24369 if (typeof input === 'string') {
24370 config._i = input = config._locale.preparse(input);
24371 }
24372
24373 if (isMoment(input)) {
24374 return new Moment(checkOverflow(input));
24375 } else if (isDate(input)) {
24376 config._d = input;
24377 } else if (isArray(format)) {
24378 configFromStringAndArray(config);
24379 } else if (format) {
24380 configFromStringAndFormat(config);
24381 } else {
24382 configFromInput(config);
24383 }
24384
24385 if (!isValid(config)) {
24386 config._d = null;
24387 }
24388
24389 return config;
24390 }
24391
24392 function configFromInput(config) {
24393 var input = config._i;
24394
24395 if (isUndefined(input)) {
24396 config._d = new Date(hooks.now());
24397 } else if (isDate(input)) {
24398 config._d = new Date(input.valueOf());
24399 } else if (typeof input === 'string') {
24400 configFromString(config);
24401 } else if (isArray(input)) {
24402 config._a = map(input.slice(0), function (obj) {
24403 return parseInt(obj, 10);
24404 });
24405 configFromArray(config);
24406 } else if (isObject(input)) {
24407 configFromObject(config);
24408 } else if (isNumber(input)) {
24409 // from milliseconds
24410 config._d = new Date(input);
24411 } else {
24412 hooks.createFromInputFallback(config);
24413 }
24414 }
24415
24416 function createLocalOrUTC(input, format, locale, strict, isUTC) {
24417 var c = {};
24418
24419 if (locale === true || locale === false) {
24420 strict = locale;
24421 locale = undefined;
24422 }
24423
24424 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
24425 input = undefined;
24426 } // object construction must be done this way.
24427 // https://github.com/moment/moment/issues/1423
24428
24429
24430 c._isAMomentObject = true;
24431 c._useUTC = c._isUTC = isUTC;
24432 c._l = locale;
24433 c._i = input;
24434 c._f = format;
24435 c._strict = strict;
24436 return createFromConfig(c);
24437 }
24438
24439 function createLocal(input, format, locale, strict) {
24440 return createLocalOrUTC(input, format, locale, strict, false);
24441 }
24442
24443 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
24444 var other = createLocal.apply(null, arguments);
24445
24446 if (this.isValid() && other.isValid()) {
24447 return other < this ? this : other;
24448 } else {
24449 return createInvalid();
24450 }
24451 });
24452 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
24453 var other = createLocal.apply(null, arguments);
24454
24455 if (this.isValid() && other.isValid()) {
24456 return other > this ? this : other;
24457 } else {
24458 return createInvalid();
24459 }
24460 }); // Pick a moment m from moments so that m[fn](other) is true for all
24461 // other. This relies on the function fn to be transitive.
24462 //
24463 // moments should either be an array of moment objects or an array, whose
24464 // first element is an array of moment objects.
24465
24466 function pickBy(fn, moments) {
24467 var res, i;
24468
24469 if (moments.length === 1 && isArray(moments[0])) {
24470 moments = moments[0];
24471 }
24472
24473 if (!moments.length) {
24474 return createLocal();
24475 }
24476
24477 res = moments[0];
24478
24479 for (i = 1; i < moments.length; ++i) {
24480 if (!moments[i].isValid() || moments[i][fn](res)) {
24481 res = moments[i];
24482 }
24483 }
24484
24485 return res;
24486 } // TODO: Use [].sort instead?
24487
24488
24489 function min() {
24490 var args = [].slice.call(arguments, 0);
24491 return pickBy('isBefore', args);
24492 }
24493
24494 function max() {
24495 var args = [].slice.call(arguments, 0);
24496 return pickBy('isAfter', args);
24497 }
24498
24499 var now = function now() {
24500 return Date.now ? Date.now() : +new Date();
24501 };
24502
24503 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
24504
24505 function isDurationValid(m) {
24506 for (var key in m) {
24507 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
24508 return false;
24509 }
24510 }
24511
24512 var unitHasDecimal = false;
24513
24514 for (var i = 0; i < ordering.length; ++i) {
24515 if (m[ordering[i]]) {
24516 if (unitHasDecimal) {
24517 return false; // only allow non-integers for smallest unit
24518 }
24519
24520 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
24521 unitHasDecimal = true;
24522 }
24523 }
24524 }
24525
24526 return true;
24527 }
24528
24529 function isValid$1() {
24530 return this._isValid;
24531 }
24532
24533 function createInvalid$1() {
24534 return createDuration(NaN);
24535 }
24536
24537 function Duration(duration) {
24538 var normalizedInput = normalizeObjectUnits(duration),
24539 years = normalizedInput.year || 0,
24540 quarters = normalizedInput.quarter || 0,
24541 months = normalizedInput.month || 0,
24542 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
24543 days = normalizedInput.day || 0,
24544 hours = normalizedInput.hour || 0,
24545 minutes = normalizedInput.minute || 0,
24546 seconds = normalizedInput.second || 0,
24547 milliseconds = normalizedInput.millisecond || 0;
24548 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
24549
24550 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
24551 minutes * 6e4 + // 1000 * 60
24552 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
24553 // Because of dateAddRemove treats 24 hours as different from a
24554 // day when working around DST, we need to store them separately
24555
24556 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
24557 // which months you are are talking about, so we have to store
24558 // it separately.
24559
24560 this._months = +months + quarters * 3 + years * 12;
24561 this._data = {};
24562 this._locale = getLocale();
24563
24564 this._bubble();
24565 }
24566
24567 function isDuration(obj) {
24568 return obj instanceof Duration;
24569 }
24570
24571 function absRound(number) {
24572 if (number < 0) {
24573 return Math.round(-1 * number) * -1;
24574 } else {
24575 return Math.round(number);
24576 }
24577 } // FORMATTING
24578
24579
24580 function offset(token, separator) {
24581 addFormatToken(token, 0, 0, function () {
24582 var offset = this.utcOffset();
24583 var sign = '+';
24584
24585 if (offset < 0) {
24586 offset = -offset;
24587 sign = '-';
24588 }
24589
24590 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
24591 });
24592 }
24593
24594 offset('Z', ':');
24595 offset('ZZ', ''); // PARSING
24596
24597 addRegexToken('Z', matchShortOffset);
24598 addRegexToken('ZZ', matchShortOffset);
24599 addParseToken(['Z', 'ZZ'], function (input, array, config) {
24600 config._useUTC = true;
24601 config._tzm = offsetFromString(matchShortOffset, input);
24602 }); // HELPERS
24603 // timezone chunker
24604 // '+10:00' > ['10', '00']
24605 // '-1530' > ['-15', '30']
24606
24607 var chunkOffset = /([\+\-]|\d\d)/gi;
24608
24609 function offsetFromString(matcher, string) {
24610 var matches = (string || '').match(matcher);
24611
24612 if (matches === null) {
24613 return null;
24614 }
24615
24616 var chunk = matches[matches.length - 1] || [];
24617 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
24618 var minutes = +(parts[1] * 60) + toInt(parts[2]);
24619 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
24620 } // Return a moment from input, that is local/utc/zone equivalent to model.
24621
24622
24623 function cloneWithOffset(input, model) {
24624 var res, diff;
24625
24626 if (model._isUTC) {
24627 res = model.clone();
24628 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
24629
24630 res._d.setTime(res._d.valueOf() + diff);
24631
24632 hooks.updateOffset(res, false);
24633 return res;
24634 } else {
24635 return createLocal(input).local();
24636 }
24637 }
24638
24639 function getDateOffset(m) {
24640 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
24641 // https://github.com/moment/moment/pull/1871
24642 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
24643 } // HOOKS
24644 // This function will be called whenever a moment is mutated.
24645 // It is intended to keep the offset in sync with the timezone.
24646
24647
24648 hooks.updateOffset = function () {}; // MOMENTS
24649 // keepLocalTime = true means only change the timezone, without
24650 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
24651 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
24652 // +0200, so we adjust the time as needed, to be valid.
24653 //
24654 // Keeping the time actually adds/subtracts (one hour)
24655 // from the actual represented time. That is why we call updateOffset
24656 // a second time. In case it wants us to change the offset again
24657 // _changeInProgress == true case, then we have to adjust, because
24658 // there is no such time in the given timezone.
24659
24660
24661 function getSetOffset(input, keepLocalTime, keepMinutes) {
24662 var offset = this._offset || 0,
24663 localAdjust;
24664
24665 if (!this.isValid()) {
24666 return input != null ? this : NaN;
24667 }
24668
24669 if (input != null) {
24670 if (typeof input === 'string') {
24671 input = offsetFromString(matchShortOffset, input);
24672
24673 if (input === null) {
24674 return this;
24675 }
24676 } else if (Math.abs(input) < 16 && !keepMinutes) {
24677 input = input * 60;
24678 }
24679
24680 if (!this._isUTC && keepLocalTime) {
24681 localAdjust = getDateOffset(this);
24682 }
24683
24684 this._offset = input;
24685 this._isUTC = true;
24686
24687 if (localAdjust != null) {
24688 this.add(localAdjust, 'm');
24689 }
24690
24691 if (offset !== input) {
24692 if (!keepLocalTime || this._changeInProgress) {
24693 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
24694 } else if (!this._changeInProgress) {
24695 this._changeInProgress = true;
24696 hooks.updateOffset(this, true);
24697 this._changeInProgress = null;
24698 }
24699 }
24700
24701 return this;
24702 } else {
24703 return this._isUTC ? offset : getDateOffset(this);
24704 }
24705 }
24706
24707 function getSetZone(input, keepLocalTime) {
24708 if (input != null) {
24709 if (typeof input !== 'string') {
24710 input = -input;
24711 }
24712
24713 this.utcOffset(input, keepLocalTime);
24714 return this;
24715 } else {
24716 return -this.utcOffset();
24717 }
24718 }
24719
24720 function setOffsetToUTC(keepLocalTime) {
24721 return this.utcOffset(0, keepLocalTime);
24722 }
24723
24724 function setOffsetToLocal(keepLocalTime) {
24725 if (this._isUTC) {
24726 this.utcOffset(0, keepLocalTime);
24727 this._isUTC = false;
24728
24729 if (keepLocalTime) {
24730 this.subtract(getDateOffset(this), 'm');
24731 }
24732 }
24733
24734 return this;
24735 }
24736
24737 function setOffsetToParsedOffset() {
24738 if (this._tzm != null) {
24739 this.utcOffset(this._tzm, false, true);
24740 } else if (typeof this._i === 'string') {
24741 var tZone = offsetFromString(matchOffset, this._i);
24742
24743 if (tZone != null) {
24744 this.utcOffset(tZone);
24745 } else {
24746 this.utcOffset(0, true);
24747 }
24748 }
24749
24750 return this;
24751 }
24752
24753 function hasAlignedHourOffset(input) {
24754 if (!this.isValid()) {
24755 return false;
24756 }
24757
24758 input = input ? createLocal(input).utcOffset() : 0;
24759 return (this.utcOffset() - input) % 60 === 0;
24760 }
24761
24762 function isDaylightSavingTime() {
24763 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
24764 }
24765
24766 function isDaylightSavingTimeShifted() {
24767 if (!isUndefined(this._isDSTShifted)) {
24768 return this._isDSTShifted;
24769 }
24770
24771 var c = {};
24772 copyConfig(c, this);
24773 c = prepareConfig(c);
24774
24775 if (c._a) {
24776 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
24777 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
24778 } else {
24779 this._isDSTShifted = false;
24780 }
24781
24782 return this._isDSTShifted;
24783 }
24784
24785 function isLocal() {
24786 return this.isValid() ? !this._isUTC : false;
24787 }
24788
24789 function isUtcOffset() {
24790 return this.isValid() ? this._isUTC : false;
24791 }
24792
24793 function isUtc() {
24794 return this.isValid() ? this._isUTC && this._offset === 0 : false;
24795 } // ASP.NET json date format regex
24796
24797
24798 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
24799 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
24800 // and further modified to allow for strings containing both week and day
24801
24802 var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
24803
24804 function createDuration(input, key) {
24805 var duration = input,
24806 // matching against regexp is expensive, do it on demand
24807 match = null,
24808 sign,
24809 ret,
24810 diffRes;
24811
24812 if (isDuration(input)) {
24813 duration = {
24814 ms: input._milliseconds,
24815 d: input._days,
24816 M: input._months
24817 };
24818 } else if (isNumber(input)) {
24819 duration = {};
24820
24821 if (key) {
24822 duration[key] = input;
24823 } else {
24824 duration.milliseconds = input;
24825 }
24826 } else if (!!(match = aspNetRegex.exec(input))) {
24827 sign = match[1] === '-' ? -1 : 1;
24828 duration = {
24829 y: 0,
24830 d: toInt(match[DATE]) * sign,
24831 h: toInt(match[HOUR]) * sign,
24832 m: toInt(match[MINUTE]) * sign,
24833 s: toInt(match[SECOND]) * sign,
24834 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
24835
24836 };
24837 } else if (!!(match = isoRegex.exec(input))) {
24838 sign = match[1] === '-' ? -1 : 1;
24839 duration = {
24840 y: parseIso(match[2], sign),
24841 M: parseIso(match[3], sign),
24842 w: parseIso(match[4], sign),
24843 d: parseIso(match[5], sign),
24844 h: parseIso(match[6], sign),
24845 m: parseIso(match[7], sign),
24846 s: parseIso(match[8], sign)
24847 };
24848 } else if (duration == null) {
24849 // checks for null or undefined
24850 duration = {};
24851 } else if (_typeof(duration) === 'object' && ('from' in duration || 'to' in duration)) {
24852 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
24853 duration = {};
24854 duration.ms = diffRes.milliseconds;
24855 duration.M = diffRes.months;
24856 }
24857
24858 ret = new Duration(duration);
24859
24860 if (isDuration(input) && hasOwnProp(input, '_locale')) {
24861 ret._locale = input._locale;
24862 }
24863
24864 return ret;
24865 }
24866
24867 createDuration.fn = Duration.prototype;
24868 createDuration.invalid = createInvalid$1;
24869
24870 function parseIso(inp, sign) {
24871 // We'd normally use ~~inp for this, but unfortunately it also
24872 // converts floats to ints.
24873 // inp may be undefined, so careful calling replace on it.
24874 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
24875
24876 return (isNaN(res) ? 0 : res) * sign;
24877 }
24878
24879 function positiveMomentsDifference(base, other) {
24880 var res = {};
24881 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
24882
24883 if (base.clone().add(res.months, 'M').isAfter(other)) {
24884 --res.months;
24885 }
24886
24887 res.milliseconds = +other - +base.clone().add(res.months, 'M');
24888 return res;
24889 }
24890
24891 function momentsDifference(base, other) {
24892 var res;
24893
24894 if (!(base.isValid() && other.isValid())) {
24895 return {
24896 milliseconds: 0,
24897 months: 0
24898 };
24899 }
24900
24901 other = cloneWithOffset(other, base);
24902
24903 if (base.isBefore(other)) {
24904 res = positiveMomentsDifference(base, other);
24905 } else {
24906 res = positiveMomentsDifference(other, base);
24907 res.milliseconds = -res.milliseconds;
24908 res.months = -res.months;
24909 }
24910
24911 return res;
24912 } // TODO: remove 'name' arg after deprecation is removed
24913
24914
24915 function createAdder(direction, name) {
24916 return function (val, period) {
24917 var dur, tmp; //invert the arguments, but complain about it
24918
24919 if (period !== null && !isNaN(+period)) {
24920 deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
24921 tmp = val;
24922 val = period;
24923 period = tmp;
24924 }
24925
24926 val = typeof val === 'string' ? +val : val;
24927 dur = createDuration(val, period);
24928 addSubtract(this, dur, direction);
24929 return this;
24930 };
24931 }
24932
24933 function addSubtract(mom, duration, isAdding, updateOffset) {
24934 var milliseconds = duration._milliseconds,
24935 days = absRound(duration._days),
24936 months = absRound(duration._months);
24937
24938 if (!mom.isValid()) {
24939 // No op
24940 return;
24941 }
24942
24943 updateOffset = updateOffset == null ? true : updateOffset;
24944
24945 if (months) {
24946 setMonth(mom, get(mom, 'Month') + months * isAdding);
24947 }
24948
24949 if (days) {
24950 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
24951 }
24952
24953 if (milliseconds) {
24954 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
24955 }
24956
24957 if (updateOffset) {
24958 hooks.updateOffset(mom, days || months);
24959 }
24960 }
24961
24962 var add = createAdder(1, 'add');
24963 var subtract = createAdder(-1, 'subtract');
24964
24965 function getCalendarFormat(myMoment, now) {
24966 var diff = myMoment.diff(now, 'days', true);
24967 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
24968 }
24969
24970 function calendar$1(time, formats) {
24971 // We want to compare the start of today, vs this.
24972 // Getting start-of-today depends on whether we're local/utc/offset or not.
24973 var now = time || createLocal(),
24974 sod = cloneWithOffset(now, this).startOf('day'),
24975 format = hooks.calendarFormat(this, sod) || 'sameElse';
24976 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
24977 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
24978 }
24979
24980 function clone() {
24981 return new Moment(this);
24982 }
24983
24984 function isAfter(input, units) {
24985 var localInput = isMoment(input) ? input : createLocal(input);
24986
24987 if (!(this.isValid() && localInput.isValid())) {
24988 return false;
24989 }
24990
24991 units = normalizeUnits(units) || 'millisecond';
24992
24993 if (units === 'millisecond') {
24994 return this.valueOf() > localInput.valueOf();
24995 } else {
24996 return localInput.valueOf() < this.clone().startOf(units).valueOf();
24997 }
24998 }
24999
25000 function isBefore(input, units) {
25001 var localInput = isMoment(input) ? input : createLocal(input);
25002
25003 if (!(this.isValid() && localInput.isValid())) {
25004 return false;
25005 }
25006
25007 units = normalizeUnits(units) || 'millisecond';
25008
25009 if (units === 'millisecond') {
25010 return this.valueOf() < localInput.valueOf();
25011 } else {
25012 return this.clone().endOf(units).valueOf() < localInput.valueOf();
25013 }
25014 }
25015
25016 function isBetween(from, to, units, inclusivity) {
25017 var localFrom = isMoment(from) ? from : createLocal(from),
25018 localTo = isMoment(to) ? to : createLocal(to);
25019
25020 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
25021 return false;
25022 }
25023
25024 inclusivity = inclusivity || '()';
25025 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
25026 }
25027
25028 function isSame(input, units) {
25029 var localInput = isMoment(input) ? input : createLocal(input),
25030 inputMs;
25031
25032 if (!(this.isValid() && localInput.isValid())) {
25033 return false;
25034 }
25035
25036 units = normalizeUnits(units) || 'millisecond';
25037
25038 if (units === 'millisecond') {
25039 return this.valueOf() === localInput.valueOf();
25040 } else {
25041 inputMs = localInput.valueOf();
25042 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
25043 }
25044 }
25045
25046 function isSameOrAfter(input, units) {
25047 return this.isSame(input, units) || this.isAfter(input, units);
25048 }
25049
25050 function isSameOrBefore(input, units) {
25051 return this.isSame(input, units) || this.isBefore(input, units);
25052 }
25053
25054 function diff(input, units, asFloat) {
25055 var that, zoneDelta, output;
25056
25057 if (!this.isValid()) {
25058 return NaN;
25059 }
25060
25061 that = cloneWithOffset(input, this);
25062
25063 if (!that.isValid()) {
25064 return NaN;
25065 }
25066
25067 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
25068 units = normalizeUnits(units);
25069
25070 switch (units) {
25071 case 'year':
25072 output = monthDiff(this, that) / 12;
25073 break;
25074
25075 case 'month':
25076 output = monthDiff(this, that);
25077 break;
25078
25079 case 'quarter':
25080 output = monthDiff(this, that) / 3;
25081 break;
25082
25083 case 'second':
25084 output = (this - that) / 1e3;
25085 break;
25086 // 1000
25087
25088 case 'minute':
25089 output = (this - that) / 6e4;
25090 break;
25091 // 1000 * 60
25092
25093 case 'hour':
25094 output = (this - that) / 36e5;
25095 break;
25096 // 1000 * 60 * 60
25097
25098 case 'day':
25099 output = (this - that - zoneDelta) / 864e5;
25100 break;
25101 // 1000 * 60 * 60 * 24, negate dst
25102
25103 case 'week':
25104 output = (this - that - zoneDelta) / 6048e5;
25105 break;
25106 // 1000 * 60 * 60 * 24 * 7, negate dst
25107
25108 default:
25109 output = this - that;
25110 }
25111
25112 return asFloat ? output : absFloor(output);
25113 }
25114
25115 function monthDiff(a, b) {
25116 // difference in months
25117 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
25118 // b is in (anchor - 1 month, anchor + 1 month)
25119 anchor = a.clone().add(wholeMonthDiff, 'months'),
25120 anchor2,
25121 adjust;
25122
25123 if (b - anchor < 0) {
25124 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
25125
25126 adjust = (b - anchor) / (anchor - anchor2);
25127 } else {
25128 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
25129
25130 adjust = (b - anchor) / (anchor2 - anchor);
25131 } //check for negative zero, return zero if negative zero
25132
25133
25134 return -(wholeMonthDiff + adjust) || 0;
25135 }
25136
25137 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
25138 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
25139
25140 function toString() {
25141 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
25142 }
25143
25144 function toISOString(keepOffset) {
25145 if (!this.isValid()) {
25146 return null;
25147 }
25148
25149 var utc = keepOffset !== true;
25150 var m = utc ? this.clone().utc() : this;
25151
25152 if (m.year() < 0 || m.year() > 9999) {
25153 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
25154 }
25155
25156 if (isFunction(Date.prototype.toISOString)) {
25157 // native implementation is ~50x faster, use it when we can
25158 if (utc) {
25159 return this.toDate().toISOString();
25160 } else {
25161 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
25162 }
25163 }
25164
25165 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
25166 }
25167 /**
25168 * Return a human readable representation of a moment that can
25169 * also be evaluated to get a new moment which is the same
25170 *
25171 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
25172 */
25173
25174
25175 function inspect() {
25176 if (!this.isValid()) {
25177 return 'moment.invalid(/* ' + this._i + ' */)';
25178 }
25179
25180 var func = 'moment';
25181 var zone = '';
25182
25183 if (!this.isLocal()) {
25184 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
25185 zone = 'Z';
25186 }
25187
25188 var prefix = '[' + func + '("]';
25189 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
25190 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
25191 var suffix = zone + '[")]';
25192 return this.format(prefix + year + datetime + suffix);
25193 }
25194
25195 function format(inputString) {
25196 if (!inputString) {
25197 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
25198 }
25199
25200 var output = formatMoment(this, inputString);
25201 return this.localeData().postformat(output);
25202 }
25203
25204 function from(time, withoutSuffix) {
25205 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
25206 return createDuration({
25207 to: this,
25208 from: time
25209 }).locale(this.locale()).humanize(!withoutSuffix);
25210 } else {
25211 return this.localeData().invalidDate();
25212 }
25213 }
25214
25215 function fromNow(withoutSuffix) {
25216 return this.from(createLocal(), withoutSuffix);
25217 }
25218
25219 function to(time, withoutSuffix) {
25220 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
25221 return createDuration({
25222 from: this,
25223 to: time
25224 }).locale(this.locale()).humanize(!withoutSuffix);
25225 } else {
25226 return this.localeData().invalidDate();
25227 }
25228 }
25229
25230 function toNow(withoutSuffix) {
25231 return this.to(createLocal(), withoutSuffix);
25232 } // If passed a locale key, it will set the locale for this
25233 // instance. Otherwise, it will return the locale configuration
25234 // variables for this instance.
25235
25236
25237 function locale(key) {
25238 var newLocaleData;
25239
25240 if (key === undefined) {
25241 return this._locale._abbr;
25242 } else {
25243 newLocaleData = getLocale(key);
25244
25245 if (newLocaleData != null) {
25246 this._locale = newLocaleData;
25247 }
25248
25249 return this;
25250 }
25251 }
25252
25253 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
25254 if (key === undefined) {
25255 return this.localeData();
25256 } else {
25257 return this.locale(key);
25258 }
25259 });
25260
25261 function localeData() {
25262 return this._locale;
25263 }
25264
25265 var MS_PER_SECOND = 1000;
25266 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
25267 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
25268 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
25269
25270 function mod$1(dividend, divisor) {
25271 return (dividend % divisor + divisor) % divisor;
25272 }
25273
25274 function localStartOfDate(y, m, d) {
25275 // the date constructor remaps years 0-99 to 1900-1999
25276 if (y < 100 && y >= 0) {
25277 // preserve leap years using a full 400 year cycle, then reset
25278 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
25279 } else {
25280 return new Date(y, m, d).valueOf();
25281 }
25282 }
25283
25284 function utcStartOfDate(y, m, d) {
25285 // Date.UTC remaps years 0-99 to 1900-1999
25286 if (y < 100 && y >= 0) {
25287 // preserve leap years using a full 400 year cycle, then reset
25288 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
25289 } else {
25290 return Date.UTC(y, m, d);
25291 }
25292 }
25293
25294 function startOf(units) {
25295 var time;
25296 units = normalizeUnits(units);
25297
25298 if (units === undefined || units === 'millisecond' || !this.isValid()) {
25299 return this;
25300 }
25301
25302 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
25303
25304 switch (units) {
25305 case 'year':
25306 time = startOfDate(this.year(), 0, 1);
25307 break;
25308
25309 case 'quarter':
25310 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
25311 break;
25312
25313 case 'month':
25314 time = startOfDate(this.year(), this.month(), 1);
25315 break;
25316
25317 case 'week':
25318 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
25319 break;
25320
25321 case 'isoWeek':
25322 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
25323 break;
25324
25325 case 'day':
25326 case 'date':
25327 time = startOfDate(this.year(), this.month(), this.date());
25328 break;
25329
25330 case 'hour':
25331 time = this._d.valueOf();
25332 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
25333 break;
25334
25335 case 'minute':
25336 time = this._d.valueOf();
25337 time -= mod$1(time, MS_PER_MINUTE);
25338 break;
25339
25340 case 'second':
25341 time = this._d.valueOf();
25342 time -= mod$1(time, MS_PER_SECOND);
25343 break;
25344 }
25345
25346 this._d.setTime(time);
25347
25348 hooks.updateOffset(this, true);
25349 return this;
25350 }
25351
25352 function endOf(units) {
25353 var time;
25354 units = normalizeUnits(units);
25355
25356 if (units === undefined || units === 'millisecond' || !this.isValid()) {
25357 return this;
25358 }
25359
25360 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
25361
25362 switch (units) {
25363 case 'year':
25364 time = startOfDate(this.year() + 1, 0, 1) - 1;
25365 break;
25366
25367 case 'quarter':
25368 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
25369 break;
25370
25371 case 'month':
25372 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
25373 break;
25374
25375 case 'week':
25376 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
25377 break;
25378
25379 case 'isoWeek':
25380 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
25381 break;
25382
25383 case 'day':
25384 case 'date':
25385 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
25386 break;
25387
25388 case 'hour':
25389 time = this._d.valueOf();
25390 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
25391 break;
25392
25393 case 'minute':
25394 time = this._d.valueOf();
25395 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
25396 break;
25397
25398 case 'second':
25399 time = this._d.valueOf();
25400 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
25401 break;
25402 }
25403
25404 this._d.setTime(time);
25405
25406 hooks.updateOffset(this, true);
25407 return this;
25408 }
25409
25410 function valueOf() {
25411 return this._d.valueOf() - (this._offset || 0) * 60000;
25412 }
25413
25414 function unix() {
25415 return Math.floor(this.valueOf() / 1000);
25416 }
25417
25418 function toDate() {
25419 return new Date(this.valueOf());
25420 }
25421
25422 function toArray() {
25423 var m = this;
25424 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
25425 }
25426
25427 function toObject() {
25428 var m = this;
25429 return {
25430 years: m.year(),
25431 months: m.month(),
25432 date: m.date(),
25433 hours: m.hours(),
25434 minutes: m.minutes(),
25435 seconds: m.seconds(),
25436 milliseconds: m.milliseconds()
25437 };
25438 }
25439
25440 function toJSON() {
25441 // new Date(NaN).toJSON() === null
25442 return this.isValid() ? this.toISOString() : null;
25443 }
25444
25445 function isValid$2() {
25446 return isValid(this);
25447 }
25448
25449 function parsingFlags() {
25450 return extend({}, getParsingFlags(this));
25451 }
25452
25453 function invalidAt() {
25454 return getParsingFlags(this).overflow;
25455 }
25456
25457 function creationData() {
25458 return {
25459 input: this._i,
25460 format: this._f,
25461 locale: this._locale,
25462 isUTC: this._isUTC,
25463 strict: this._strict
25464 };
25465 } // FORMATTING
25466
25467
25468 addFormatToken(0, ['gg', 2], 0, function () {
25469 return this.weekYear() % 100;
25470 });
25471 addFormatToken(0, ['GG', 2], 0, function () {
25472 return this.isoWeekYear() % 100;
25473 });
25474
25475 function addWeekYearFormatToken(token, getter) {
25476 addFormatToken(0, [token, token.length], 0, getter);
25477 }
25478
25479 addWeekYearFormatToken('gggg', 'weekYear');
25480 addWeekYearFormatToken('ggggg', 'weekYear');
25481 addWeekYearFormatToken('GGGG', 'isoWeekYear');
25482 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
25483
25484 addUnitAlias('weekYear', 'gg');
25485 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
25486
25487 addUnitPriority('weekYear', 1);
25488 addUnitPriority('isoWeekYear', 1); // PARSING
25489
25490 addRegexToken('G', matchSigned);
25491 addRegexToken('g', matchSigned);
25492 addRegexToken('GG', match1to2, match2);
25493 addRegexToken('gg', match1to2, match2);
25494 addRegexToken('GGGG', match1to4, match4);
25495 addRegexToken('gggg', match1to4, match4);
25496 addRegexToken('GGGGG', match1to6, match6);
25497 addRegexToken('ggggg', match1to6, match6);
25498 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
25499 week[token.substr(0, 2)] = toInt(input);
25500 });
25501 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
25502 week[token] = hooks.parseTwoDigitYear(input);
25503 }); // MOMENTS
25504
25505 function getSetWeekYear(input) {
25506 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
25507 }
25508
25509 function getSetISOWeekYear(input) {
25510 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
25511 }
25512
25513 function getISOWeeksInYear() {
25514 return weeksInYear(this.year(), 1, 4);
25515 }
25516
25517 function getWeeksInYear() {
25518 var weekInfo = this.localeData()._week;
25519
25520 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
25521 }
25522
25523 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
25524 var weeksTarget;
25525
25526 if (input == null) {
25527 return weekOfYear(this, dow, doy).year;
25528 } else {
25529 weeksTarget = weeksInYear(input, dow, doy);
25530
25531 if (week > weeksTarget) {
25532 week = weeksTarget;
25533 }
25534
25535 return setWeekAll.call(this, input, week, weekday, dow, doy);
25536 }
25537 }
25538
25539 function setWeekAll(weekYear, week, weekday, dow, doy) {
25540 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
25541 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
25542 this.year(date.getUTCFullYear());
25543 this.month(date.getUTCMonth());
25544 this.date(date.getUTCDate());
25545 return this;
25546 } // FORMATTING
25547
25548
25549 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
25550
25551 addUnitAlias('quarter', 'Q'); // PRIORITY
25552
25553 addUnitPriority('quarter', 7); // PARSING
25554
25555 addRegexToken('Q', match1);
25556 addParseToken('Q', function (input, array) {
25557 array[MONTH] = (toInt(input) - 1) * 3;
25558 }); // MOMENTS
25559
25560 function getSetQuarter(input) {
25561 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
25562 } // FORMATTING
25563
25564
25565 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
25566
25567 addUnitAlias('date', 'D'); // PRIORITY
25568
25569 addUnitPriority('date', 9); // PARSING
25570
25571 addRegexToken('D', match1to2);
25572 addRegexToken('DD', match1to2, match2);
25573 addRegexToken('Do', function (isStrict, locale) {
25574 // TODO: Remove "ordinalParse" fallback in next major release.
25575 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
25576 });
25577 addParseToken(['D', 'DD'], DATE);
25578 addParseToken('Do', function (input, array) {
25579 array[DATE] = toInt(input.match(match1to2)[0]);
25580 }); // MOMENTS
25581
25582 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
25583
25584 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
25585
25586 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
25587
25588 addUnitPriority('dayOfYear', 4); // PARSING
25589
25590 addRegexToken('DDD', match1to3);
25591 addRegexToken('DDDD', match3);
25592 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
25593 config._dayOfYear = toInt(input);
25594 }); // HELPERS
25595 // MOMENTS
25596
25597 function getSetDayOfYear(input) {
25598 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
25599 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
25600 } // FORMATTING
25601
25602
25603 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
25604
25605 addUnitAlias('minute', 'm'); // PRIORITY
25606
25607 addUnitPriority('minute', 14); // PARSING
25608
25609 addRegexToken('m', match1to2);
25610 addRegexToken('mm', match1to2, match2);
25611 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
25612
25613 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
25614
25615 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
25616
25617 addUnitAlias('second', 's'); // PRIORITY
25618
25619 addUnitPriority('second', 15); // PARSING
25620
25621 addRegexToken('s', match1to2);
25622 addRegexToken('ss', match1to2, match2);
25623 addParseToken(['s', 'ss'], SECOND); // MOMENTS
25624
25625 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
25626
25627 addFormatToken('S', 0, 0, function () {
25628 return ~~(this.millisecond() / 100);
25629 });
25630 addFormatToken(0, ['SS', 2], 0, function () {
25631 return ~~(this.millisecond() / 10);
25632 });
25633 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
25634 addFormatToken(0, ['SSSS', 4], 0, function () {
25635 return this.millisecond() * 10;
25636 });
25637 addFormatToken(0, ['SSSSS', 5], 0, function () {
25638 return this.millisecond() * 100;
25639 });
25640 addFormatToken(0, ['SSSSSS', 6], 0, function () {
25641 return this.millisecond() * 1000;
25642 });
25643 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
25644 return this.millisecond() * 10000;
25645 });
25646 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
25647 return this.millisecond() * 100000;
25648 });
25649 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
25650 return this.millisecond() * 1000000;
25651 }); // ALIASES
25652
25653 addUnitAlias('millisecond', 'ms'); // PRIORITY
25654
25655 addUnitPriority('millisecond', 16); // PARSING
25656
25657 addRegexToken('S', match1to3, match1);
25658 addRegexToken('SS', match1to3, match2);
25659 addRegexToken('SSS', match1to3, match3);
25660 var token;
25661
25662 for (token = 'SSSS'; token.length <= 9; token += 'S') {
25663 addRegexToken(token, matchUnsigned);
25664 }
25665
25666 function parseMs(input, array) {
25667 array[MILLISECOND] = toInt(('0.' + input) * 1000);
25668 }
25669
25670 for (token = 'S'; token.length <= 9; token += 'S') {
25671 addParseToken(token, parseMs);
25672 } // MOMENTS
25673
25674
25675 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
25676
25677 addFormatToken('z', 0, 0, 'zoneAbbr');
25678 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
25679
25680 function getZoneAbbr() {
25681 return this._isUTC ? 'UTC' : '';
25682 }
25683
25684 function getZoneName() {
25685 return this._isUTC ? 'Coordinated Universal Time' : '';
25686 }
25687
25688 var proto = Moment.prototype;
25689 proto.add = add;
25690 proto.calendar = calendar$1;
25691 proto.clone = clone;
25692 proto.diff = diff;
25693 proto.endOf = endOf;
25694 proto.format = format;
25695 proto.from = from;
25696 proto.fromNow = fromNow;
25697 proto.to = to;
25698 proto.toNow = toNow;
25699 proto.get = stringGet;
25700 proto.invalidAt = invalidAt;
25701 proto.isAfter = isAfter;
25702 proto.isBefore = isBefore;
25703 proto.isBetween = isBetween;
25704 proto.isSame = isSame;
25705 proto.isSameOrAfter = isSameOrAfter;
25706 proto.isSameOrBefore = isSameOrBefore;
25707 proto.isValid = isValid$2;
25708 proto.lang = lang;
25709 proto.locale = locale;
25710 proto.localeData = localeData;
25711 proto.max = prototypeMax;
25712 proto.min = prototypeMin;
25713 proto.parsingFlags = parsingFlags;
25714 proto.set = stringSet;
25715 proto.startOf = startOf;
25716 proto.subtract = subtract;
25717 proto.toArray = toArray;
25718 proto.toObject = toObject;
25719 proto.toDate = toDate;
25720 proto.toISOString = toISOString;
25721 proto.inspect = inspect;
25722 proto.toJSON = toJSON;
25723 proto.toString = toString;
25724 proto.unix = unix;
25725 proto.valueOf = valueOf;
25726 proto.creationData = creationData;
25727 proto.year = getSetYear;
25728 proto.isLeapYear = getIsLeapYear;
25729 proto.weekYear = getSetWeekYear;
25730 proto.isoWeekYear = getSetISOWeekYear;
25731 proto.quarter = proto.quarters = getSetQuarter;
25732 proto.month = getSetMonth;
25733 proto.daysInMonth = getDaysInMonth;
25734 proto.week = proto.weeks = getSetWeek;
25735 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
25736 proto.weeksInYear = getWeeksInYear;
25737 proto.isoWeeksInYear = getISOWeeksInYear;
25738 proto.date = getSetDayOfMonth;
25739 proto.day = proto.days = getSetDayOfWeek;
25740 proto.weekday = getSetLocaleDayOfWeek;
25741 proto.isoWeekday = getSetISODayOfWeek;
25742 proto.dayOfYear = getSetDayOfYear;
25743 proto.hour = proto.hours = getSetHour;
25744 proto.minute = proto.minutes = getSetMinute;
25745 proto.second = proto.seconds = getSetSecond;
25746 proto.millisecond = proto.milliseconds = getSetMillisecond;
25747 proto.utcOffset = getSetOffset;
25748 proto.utc = setOffsetToUTC;
25749 proto.local = setOffsetToLocal;
25750 proto.parseZone = setOffsetToParsedOffset;
25751 proto.hasAlignedHourOffset = hasAlignedHourOffset;
25752 proto.isDST = isDaylightSavingTime;
25753 proto.isLocal = isLocal;
25754 proto.isUtcOffset = isUtcOffset;
25755 proto.isUtc = isUtc;
25756 proto.isUTC = isUtc;
25757 proto.zoneAbbr = getZoneAbbr;
25758 proto.zoneName = getZoneName;
25759 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
25760 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
25761 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
25762 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
25763 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
25764
25765 function createUnix(input) {
25766 return createLocal(input * 1000);
25767 }
25768
25769 function createInZone() {
25770 return createLocal.apply(null, arguments).parseZone();
25771 }
25772
25773 function preParsePostFormat(string) {
25774 return string;
25775 }
25776
25777 var proto$1 = Locale.prototype;
25778 proto$1.calendar = calendar;
25779 proto$1.longDateFormat = longDateFormat;
25780 proto$1.invalidDate = invalidDate;
25781 proto$1.ordinal = ordinal;
25782 proto$1.preparse = preParsePostFormat;
25783 proto$1.postformat = preParsePostFormat;
25784 proto$1.relativeTime = relativeTime;
25785 proto$1.pastFuture = pastFuture;
25786 proto$1.set = set;
25787 proto$1.months = localeMonths;
25788 proto$1.monthsShort = localeMonthsShort;
25789 proto$1.monthsParse = localeMonthsParse;
25790 proto$1.monthsRegex = monthsRegex;
25791 proto$1.monthsShortRegex = monthsShortRegex;
25792 proto$1.week = localeWeek;
25793 proto$1.firstDayOfYear = localeFirstDayOfYear;
25794 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
25795 proto$1.weekdays = localeWeekdays;
25796 proto$1.weekdaysMin = localeWeekdaysMin;
25797 proto$1.weekdaysShort = localeWeekdaysShort;
25798 proto$1.weekdaysParse = localeWeekdaysParse;
25799 proto$1.weekdaysRegex = weekdaysRegex;
25800 proto$1.weekdaysShortRegex = weekdaysShortRegex;
25801 proto$1.weekdaysMinRegex = weekdaysMinRegex;
25802 proto$1.isPM = localeIsPM;
25803 proto$1.meridiem = localeMeridiem;
25804
25805 function get$1(format, index, field, setter) {
25806 var locale = getLocale();
25807 var utc = createUTC().set(setter, index);
25808 return locale[field](utc, format);
25809 }
25810
25811 function listMonthsImpl(format, index, field) {
25812 if (isNumber(format)) {
25813 index = format;
25814 format = undefined;
25815 }
25816
25817 format = format || '';
25818
25819 if (index != null) {
25820 return get$1(format, index, field, 'month');
25821 }
25822
25823 var i;
25824 var out = [];
25825
25826 for (i = 0; i < 12; i++) {
25827 out[i] = get$1(format, i, field, 'month');
25828 }
25829
25830 return out;
25831 } // ()
25832 // (5)
25833 // (fmt, 5)
25834 // (fmt)
25835 // (true)
25836 // (true, 5)
25837 // (true, fmt, 5)
25838 // (true, fmt)
25839
25840
25841 function listWeekdaysImpl(localeSorted, format, index, field) {
25842 if (typeof localeSorted === 'boolean') {
25843 if (isNumber(format)) {
25844 index = format;
25845 format = undefined;
25846 }
25847
25848 format = format || '';
25849 } else {
25850 format = localeSorted;
25851 index = format;
25852 localeSorted = false;
25853
25854 if (isNumber(format)) {
25855 index = format;
25856 format = undefined;
25857 }
25858
25859 format = format || '';
25860 }
25861
25862 var locale = getLocale(),
25863 shift = localeSorted ? locale._week.dow : 0;
25864
25865 if (index != null) {
25866 return get$1(format, (index + shift) % 7, field, 'day');
25867 }
25868
25869 var i;
25870 var out = [];
25871
25872 for (i = 0; i < 7; i++) {
25873 out[i] = get$1(format, (i + shift) % 7, field, 'day');
25874 }
25875
25876 return out;
25877 }
25878
25879 function listMonths(format, index) {
25880 return listMonthsImpl(format, index, 'months');
25881 }
25882
25883 function listMonthsShort(format, index) {
25884 return listMonthsImpl(format, index, 'monthsShort');
25885 }
25886
25887 function listWeekdays(localeSorted, format, index) {
25888 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
25889 }
25890
25891 function listWeekdaysShort(localeSorted, format, index) {
25892 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
25893 }
25894
25895 function listWeekdaysMin(localeSorted, format, index) {
25896 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
25897 }
25898
25899 getSetGlobalLocale('en', {
25900 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
25901 ordinal: function ordinal(number) {
25902 var b = number % 10,
25903 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
25904 return number + output;
25905 }
25906 }); // Side effect imports
25907
25908 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
25909 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
25910 var mathAbs = Math.abs;
25911
25912 function abs() {
25913 var data = this._data;
25914 this._milliseconds = mathAbs(this._milliseconds);
25915 this._days = mathAbs(this._days);
25916 this._months = mathAbs(this._months);
25917 data.milliseconds = mathAbs(data.milliseconds);
25918 data.seconds = mathAbs(data.seconds);
25919 data.minutes = mathAbs(data.minutes);
25920 data.hours = mathAbs(data.hours);
25921 data.months = mathAbs(data.months);
25922 data.years = mathAbs(data.years);
25923 return this;
25924 }
25925
25926 function addSubtract$1(duration, input, value, direction) {
25927 var other = createDuration(input, value);
25928 duration._milliseconds += direction * other._milliseconds;
25929 duration._days += direction * other._days;
25930 duration._months += direction * other._months;
25931 return duration._bubble();
25932 } // supports only 2.0-style add(1, 's') or add(duration)
25933
25934
25935 function add$1(input, value) {
25936 return addSubtract$1(this, input, value, 1);
25937 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
25938
25939
25940 function subtract$1(input, value) {
25941 return addSubtract$1(this, input, value, -1);
25942 }
25943
25944 function absCeil(number) {
25945 if (number < 0) {
25946 return Math.floor(number);
25947 } else {
25948 return Math.ceil(number);
25949 }
25950 }
25951
25952 function bubble() {
25953 var milliseconds = this._milliseconds;
25954 var days = this._days;
25955 var months = this._months;
25956 var data = this._data;
25957 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
25958 // check: https://github.com/moment/moment/issues/2166
25959
25960 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
25961 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
25962 days = 0;
25963 months = 0;
25964 } // The following code bubbles up values, see the tests for
25965 // examples of what that means.
25966
25967
25968 data.milliseconds = milliseconds % 1000;
25969 seconds = absFloor(milliseconds / 1000);
25970 data.seconds = seconds % 60;
25971 minutes = absFloor(seconds / 60);
25972 data.minutes = minutes % 60;
25973 hours = absFloor(minutes / 60);
25974 data.hours = hours % 24;
25975 days += absFloor(hours / 24); // convert days to months
25976
25977 monthsFromDays = absFloor(daysToMonths(days));
25978 months += monthsFromDays;
25979 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
25980
25981 years = absFloor(months / 12);
25982 months %= 12;
25983 data.days = days;
25984 data.months = months;
25985 data.years = years;
25986 return this;
25987 }
25988
25989 function daysToMonths(days) {
25990 // 400 years have 146097 days (taking into account leap year rules)
25991 // 400 years have 12 months === 4800
25992 return days * 4800 / 146097;
25993 }
25994
25995 function monthsToDays(months) {
25996 // the reverse of daysToMonths
25997 return months * 146097 / 4800;
25998 }
25999
26000 function as(units) {
26001 if (!this.isValid()) {
26002 return NaN;
26003 }
26004
26005 var days;
26006 var months;
26007 var milliseconds = this._milliseconds;
26008 units = normalizeUnits(units);
26009
26010 if (units === 'month' || units === 'quarter' || units === 'year') {
26011 days = this._days + milliseconds / 864e5;
26012 months = this._months + daysToMonths(days);
26013
26014 switch (units) {
26015 case 'month':
26016 return months;
26017
26018 case 'quarter':
26019 return months / 3;
26020
26021 case 'year':
26022 return months / 12;
26023 }
26024 } else {
26025 // handle milliseconds separately because of floating point math errors (issue #1867)
26026 days = this._days + Math.round(monthsToDays(this._months));
26027
26028 switch (units) {
26029 case 'week':
26030 return days / 7 + milliseconds / 6048e5;
26031
26032 case 'day':
26033 return days + milliseconds / 864e5;
26034
26035 case 'hour':
26036 return days * 24 + milliseconds / 36e5;
26037
26038 case 'minute':
26039 return days * 1440 + milliseconds / 6e4;
26040
26041 case 'second':
26042 return days * 86400 + milliseconds / 1000;
26043 // Math.floor prevents floating point math errors here
26044
26045 case 'millisecond':
26046 return Math.floor(days * 864e5) + milliseconds;
26047
26048 default:
26049 throw new Error('Unknown unit ' + units);
26050 }
26051 }
26052 } // TODO: Use this.as('ms')?
26053
26054
26055 function valueOf$1() {
26056 if (!this.isValid()) {
26057 return NaN;
26058 }
26059
26060 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
26061 }
26062
26063 function makeAs(alias) {
26064 return function () {
26065 return this.as(alias);
26066 };
26067 }
26068
26069 var asMilliseconds = makeAs('ms');
26070 var asSeconds = makeAs('s');
26071 var asMinutes = makeAs('m');
26072 var asHours = makeAs('h');
26073 var asDays = makeAs('d');
26074 var asWeeks = makeAs('w');
26075 var asMonths = makeAs('M');
26076 var asQuarters = makeAs('Q');
26077 var asYears = makeAs('y');
26078
26079 function clone$1() {
26080 return createDuration(this);
26081 }
26082
26083 function get$2(units) {
26084 units = normalizeUnits(units);
26085 return this.isValid() ? this[units + 's']() : NaN;
26086 }
26087
26088 function makeGetter(name) {
26089 return function () {
26090 return this.isValid() ? this._data[name] : NaN;
26091 };
26092 }
26093
26094 var milliseconds = makeGetter('milliseconds');
26095 var seconds = makeGetter('seconds');
26096 var minutes = makeGetter('minutes');
26097 var hours = makeGetter('hours');
26098 var days = makeGetter('days');
26099 var months = makeGetter('months');
26100 var years = makeGetter('years');
26101
26102 function weeks() {
26103 return absFloor(this.days() / 7);
26104 }
26105
26106 var round = Math.round;
26107 var thresholds = {
26108 ss: 44,
26109 // a few seconds to seconds
26110 s: 45,
26111 // seconds to minute
26112 m: 45,
26113 // minutes to hour
26114 h: 22,
26115 // hours to day
26116 d: 26,
26117 // days to month
26118 M: 11 // months to year
26119
26120 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
26121
26122 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
26123 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
26124 }
26125
26126 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
26127 var duration = createDuration(posNegDuration).abs();
26128 var seconds = round(duration.as('s'));
26129 var minutes = round(duration.as('m'));
26130 var hours = round(duration.as('h'));
26131 var days = round(duration.as('d'));
26132 var months = round(duration.as('M'));
26133 var years = round(duration.as('y'));
26134 var a = seconds <= thresholds.ss && ['s', seconds] || seconds < thresholds.s && ['ss', seconds] || minutes <= 1 && ['m'] || minutes < thresholds.m && ['mm', minutes] || hours <= 1 && ['h'] || hours < thresholds.h && ['hh', hours] || days <= 1 && ['d'] || days < thresholds.d && ['dd', days] || months <= 1 && ['M'] || months < thresholds.M && ['MM', months] || years <= 1 && ['y'] || ['yy', years];
26135 a[2] = withoutSuffix;
26136 a[3] = +posNegDuration > 0;
26137 a[4] = locale;
26138 return substituteTimeAgo.apply(null, a);
26139 } // This function allows you to set the rounding function for relative time strings
26140
26141
26142 function getSetRelativeTimeRounding(roundingFunction) {
26143 if (roundingFunction === undefined) {
26144 return round;
26145 }
26146
26147 if (typeof roundingFunction === 'function') {
26148 round = roundingFunction;
26149 return true;
26150 }
26151
26152 return false;
26153 } // This function allows you to set a threshold for relative time strings
26154
26155
26156 function getSetRelativeTimeThreshold(threshold, limit) {
26157 if (thresholds[threshold] === undefined) {
26158 return false;
26159 }
26160
26161 if (limit === undefined) {
26162 return thresholds[threshold];
26163 }
26164
26165 thresholds[threshold] = limit;
26166
26167 if (threshold === 's') {
26168 thresholds.ss = limit - 1;
26169 }
26170
26171 return true;
26172 }
26173
26174 function humanize(withSuffix) {
26175 if (!this.isValid()) {
26176 return this.localeData().invalidDate();
26177 }
26178
26179 var locale = this.localeData();
26180 var output = relativeTime$1(this, !withSuffix, locale);
26181
26182 if (withSuffix) {
26183 output = locale.pastFuture(+this, output);
26184 }
26185
26186 return locale.postformat(output);
26187 }
26188
26189 var abs$1 = Math.abs;
26190
26191 function sign(x) {
26192 return (x > 0) - (x < 0) || +x;
26193 }
26194
26195 function toISOString$1() {
26196 // for ISO strings we do not use the normal bubbling rules:
26197 // * milliseconds bubble up until they become hours
26198 // * days do not bubble at all
26199 // * months bubble up until they become years
26200 // This is because there is no context-free conversion between hours and days
26201 // (think of clock changes)
26202 // and also not between days and months (28-31 days per month)
26203 if (!this.isValid()) {
26204 return this.localeData().invalidDate();
26205 }
26206
26207 var seconds = abs$1(this._milliseconds) / 1000;
26208 var days = abs$1(this._days);
26209 var months = abs$1(this._months);
26210 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
26211
26212 minutes = absFloor(seconds / 60);
26213 hours = absFloor(minutes / 60);
26214 seconds %= 60;
26215 minutes %= 60; // 12 months -> 1 year
26216
26217 years = absFloor(months / 12);
26218 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
26219
26220 var Y = years;
26221 var M = months;
26222 var D = days;
26223 var h = hours;
26224 var m = minutes;
26225 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
26226 var total = this.asSeconds();
26227
26228 if (!total) {
26229 // this is the same as C#'s (Noda) and python (isodate)...
26230 // but not other JS (goog.date)
26231 return 'P0D';
26232 }
26233
26234 var totalSign = total < 0 ? '-' : '';
26235 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
26236 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
26237 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
26238 return totalSign + 'P' + (Y ? ymSign + Y + 'Y' : '') + (M ? ymSign + M + 'M' : '') + (D ? daysSign + D + 'D' : '') + (h || m || s ? 'T' : '') + (h ? hmsSign + h + 'H' : '') + (m ? hmsSign + m + 'M' : '') + (s ? hmsSign + s + 'S' : '');
26239 }
26240
26241 var proto$2 = Duration.prototype;
26242 proto$2.isValid = isValid$1;
26243 proto$2.abs = abs;
26244 proto$2.add = add$1;
26245 proto$2.subtract = subtract$1;
26246 proto$2.as = as;
26247 proto$2.asMilliseconds = asMilliseconds;
26248 proto$2.asSeconds = asSeconds;
26249 proto$2.asMinutes = asMinutes;
26250 proto$2.asHours = asHours;
26251 proto$2.asDays = asDays;
26252 proto$2.asWeeks = asWeeks;
26253 proto$2.asMonths = asMonths;
26254 proto$2.asQuarters = asQuarters;
26255 proto$2.asYears = asYears;
26256 proto$2.valueOf = valueOf$1;
26257 proto$2._bubble = bubble;
26258 proto$2.clone = clone$1;
26259 proto$2.get = get$2;
26260 proto$2.milliseconds = milliseconds;
26261 proto$2.seconds = seconds;
26262 proto$2.minutes = minutes;
26263 proto$2.hours = hours;
26264 proto$2.days = days;
26265 proto$2.weeks = weeks;
26266 proto$2.months = months;
26267 proto$2.years = years;
26268 proto$2.humanize = humanize;
26269 proto$2.toISOString = toISOString$1;
26270 proto$2.toString = toISOString$1;
26271 proto$2.toJSON = toISOString$1;
26272 proto$2.locale = locale;
26273 proto$2.localeData = localeData;
26274 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
26275 proto$2.lang = lang; // Side effect imports
26276 // FORMATTING
26277
26278 addFormatToken('X', 0, 0, 'unix');
26279 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
26280
26281 addRegexToken('x', matchSigned);
26282 addRegexToken('X', matchTimestamp);
26283 addParseToken('X', function (input, array, config) {
26284 config._d = new Date(parseFloat(input, 10) * 1000);
26285 });
26286 addParseToken('x', function (input, array, config) {
26287 config._d = new Date(toInt(input));
26288 }); // Side effect imports
26289
26290 hooks.version = '2.24.0';
26291 setHookCallback(createLocal);
26292 hooks.fn = proto;
26293 hooks.min = min;
26294 hooks.max = max;
26295 hooks.now = now;
26296 hooks.utc = createUTC;
26297 hooks.unix = createUnix;
26298 hooks.months = listMonths;
26299 hooks.isDate = isDate;
26300 hooks.locale = getSetGlobalLocale;
26301 hooks.invalid = createInvalid;
26302 hooks.duration = createDuration;
26303 hooks.isMoment = isMoment;
26304 hooks.weekdays = listWeekdays;
26305 hooks.parseZone = createInZone;
26306 hooks.localeData = getLocale;
26307 hooks.isDuration = isDuration;
26308 hooks.monthsShort = listMonthsShort;
26309 hooks.weekdaysMin = listWeekdaysMin;
26310 hooks.defineLocale = defineLocale;
26311 hooks.updateLocale = updateLocale;
26312 hooks.locales = listLocales;
26313 hooks.weekdaysShort = listWeekdaysShort;
26314 hooks.normalizeUnits = normalizeUnits;
26315 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
26316 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
26317 hooks.calendarFormat = getCalendarFormat;
26318 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
26319
26320 hooks.HTML5_FMT = {
26321 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
26322 // <input type="datetime-local" />
26323 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
26324 // <input type="datetime-local" step="1" />
26325 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
26326 // <input type="datetime-local" step="0.001" />
26327 DATE: 'YYYY-MM-DD',
26328 // <input type="date" />
26329 TIME: 'HH:mm',
26330 // <input type="time" />
26331 TIME_SECONDS: 'HH:mm:ss',
26332 // <input type="time" step="1" />
26333 TIME_MS: 'HH:mm:ss.SSS',
26334 // <input type="time" step="0.001" />
26335 WEEK: 'GGGG-[W]WW',
26336 // <input type="week" />
26337 MONTH: 'YYYY-MM' // <input type="month" />
26338
26339 };
26340 return hooks;
26341 });
26342 }); // Maps for number <-> hex string conversion
26343
26344 var byteToHex$2$1 = [];
26345
26346 for (var i$2$1 = 0; i$2$1 < 256; i$2$1++) {
26347 byteToHex$2$1[i$2$1] = (i$2$1 + 0x100).toString(16).substr(1);
26348 }
26349 /**
26350 * Generate 16 random bytes to be used as a base for UUID.
26351 *
26352 * @ignore
26353 */
26354
26355
26356 var random$1$1 = function () {
26357 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
26358 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
26359 // Moderately fast, high quality
26360 var _rnds8 = new Uint8Array(16);
26361
26362 return function whatwgRNG() {
26363 crypto.getRandomValues(_rnds8);
26364 return _rnds8;
26365 };
26366 } // Math.random()-based (RNG)
26367 //
26368 // If all else fails, use Math.random().
26369 // It's fast, but is of unspecified quality.
26370
26371
26372 var _rnds = new Array(16);
26373
26374 return function () {
26375 for (var i = 0, r; i < 16; i++) {
26376 if ((i & 0x03) === 0) {
26377 r = Math.random() * 0x100000000;
26378 }
26379
26380 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
26381 }
26382
26383 return _rnds;
26384 }; // uuid.js
26385 //
26386 // Copyright (c) 2010-2012 Robert Kieffer
26387 // MIT License - http://opensource.org/licenses/mit-license.php
26388 // Unique ID creation requires a high quality random # generator. We feature
26389 // detect to determine the best RNG source, normalizing to a function that
26390 // returns 128-bits of randomness, since that's what's usually required
26391 // return require('./rng');
26392 }();
26393
26394 var byteToHex$1$1$1 = [];
26395
26396 for (var i$1$1$1 = 0; i$1$1$1 < 256; i$1$1$1++) {
26397 byteToHex$1$1$1[i$1$1$1] = (i$1$1$1 + 0x100).toString(16).substr(1);
26398 } // **`v1()` - Generate time-based UUID**
26399 //
26400 // Inspired by https://github.com/LiosK/UUID.js
26401 // and http://docs.python.org/library/uuid.html
26402 // random #'s we need to init node and clockseq
26403
26404
26405 var seedBytes$1$1 = random$1$1(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
26406
26407 var defaultNodeId$1$1 = [seedBytes$1$1[0] | 0x01, seedBytes$1$1[1], seedBytes$1$1[2], seedBytes$1$1[3], seedBytes$1$1[4], seedBytes$1$1[5]]; // Per 4.2.2, randomize (14 bit) clockseq
26408
26409 var defaultClockseq$1$1 = (seedBytes$1$1[6] << 8 | seedBytes$1$1[7]) & 0x3fff; // Previous uuid creation time
26410 // for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
26411 // code from http://momentjs.com/
26412
26413 var ASPDateRegex$1 = /^\/?Date\((-?\d+)/i; // Hex color
26414
26415 /**
26416 * Hue, Saturation, Value.
26417 */
26418
26419 /**
26420 * Test whether given object is a number
26421 *
26422 * @param value - Input value of unknown type.
26423 *
26424 * @returns True if number, false otherwise.
26425 */
26426
26427 function isNumber$1(value) {
26428 return value instanceof Number || typeof value === 'number';
26429 }
26430 /**
26431 * Test whether given object is a string
26432 *
26433 * @param value - Input value of unknown type.
26434 *
26435 * @returns True if string, false otherwise.
26436 */
26437
26438
26439 function isString$1(value) {
26440 return value instanceof String || typeof value === 'string';
26441 }
26442 /**
26443 * Test whether given object is a Moment date.
26444 * @TODO: This is basically a workaround, if Moment was imported property it wouldn't necessary as moment.isMoment is a TS type guard.
26445 *
26446 * @param value - Input value of unknown type.
26447 *
26448 * @returns True if Moment instance, false otherwise.
26449 */
26450
26451
26452 function isMoment$1(value) {
26453 return moment$1.isMoment(value);
26454 }
26455 /**
26456 * Copy property from b to a if property present in a.
26457 * If property in b explicitly set to null, delete it if `allowDeletion` set.
26458 *
26459 * Internal helper routine, should not be exported. Not added to `exports` for that reason.
26460 *
26461 * @param a - Target object.
26462 * @param b - Source object.
26463 * @param prop - Name of property to copy from b to a.
26464 * @param allowDeletion if true, delete property in a if explicitly set to null in b
26465 */
26466
26467
26468 function copyOrDelete$1(a, b, prop, allowDeletion) {
26469 var doDeletion = false;
26470
26471 if (allowDeletion === true) {
26472 doDeletion = b[prop] === null && a[prop] !== undefined;
26473 }
26474
26475 if (doDeletion) {
26476 delete a[prop];
26477 } else {
26478 a[prop] = b[prop]; // Remember, this is a reference copy!
26479 }
26480 }
26481 /**
26482 * Deep extend an object a with the properties of object b
26483 *
26484 * @param a - Target object.
26485 * @param b - Source object.
26486 * @param protoExtend - If true, the prototype values will also be extended
26487 * (ie. the options objects that inherit from others will also get the inherited options).
26488 * @param allowDeletion - If true, the values of fields that are null will be deleted.
26489 *
26490 * @returns Argument a.
26491 */
26492
26493
26494 function deepExtend$1(a, b) {
26495 var protoExtend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
26496 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
26497
26498 for (var prop in b) {
26499 if (Object.prototype.hasOwnProperty.call(b, prop) || protoExtend === true) {
26500 if (b[prop] && b[prop].constructor === Object) {
26501 if (a[prop] === undefined) {
26502 a[prop] = {};
26503 }
26504
26505 if (a[prop].constructor === Object) {
26506 deepExtend$1(a[prop], b[prop], protoExtend); // NOTE: allowDeletion not propagated!
26507 } else {
26508 copyOrDelete$1(a, b, prop, allowDeletion);
26509 }
26510 } else if (Array.isArray(b[prop])) {
26511 a[prop] = [];
26512
26513 for (var i = 0; i < b[prop].length; i++) {
26514 a[prop].push(b[prop][i]);
26515 }
26516 } else {
26517 copyOrDelete$1(a, b, prop, allowDeletion);
26518 }
26519 }
26520 }
26521
26522 return a;
26523 }
26524 /**
26525 * Convert an object into another type
26526 *
26527 * @param object - Value of unknown type.
26528 * @param type - Name of the desired type.
26529 *
26530 * @returns Object in the desired type.
26531 * @throws Error
26532 */
26533
26534
26535 function convert$1(object, type) {
26536 var match;
26537
26538 if (object === undefined) {
26539 return undefined;
26540 }
26541
26542 if (object === null) {
26543 return null;
26544 }
26545
26546 if (!type) {
26547 return object;
26548 }
26549
26550 if (!(typeof type === 'string') && !(type instanceof String)) {
26551 throw new Error('Type must be a string');
26552 } //noinspection FallthroughInSwitchStatementJS
26553
26554
26555 switch (type) {
26556 case 'boolean':
26557 case 'Boolean':
26558 return Boolean(object);
26559
26560 case 'number':
26561 case 'Number':
26562 if (isString$1(object) && !isNaN(Date.parse(object))) {
26563 return moment$1(object).valueOf();
26564 } else {
26565 // @TODO: I don't think that Number and String constructors are a good idea.
26566 // This could also fail if the object doesn't have valueOf method or if it's redefined.
26567 // For example: Object.create(null) or { valueOf: 7 }.
26568 return Number(object.valueOf());
26569 }
26570
26571 case 'string':
26572 case 'String':
26573 return String(object);
26574
26575 case 'Date':
26576 if (isNumber$1(object)) {
26577 return new Date(object);
26578 }
26579
26580 if (object instanceof Date) {
26581 return new Date(object.valueOf());
26582 } else if (isMoment$1(object)) {
26583 return new Date(object.valueOf());
26584 }
26585
26586 if (isString$1(object)) {
26587 match = ASPDateRegex$1.exec(object);
26588
26589 if (match) {
26590 // object is an ASP date
26591 return new Date(Number(match[1])); // parse number
26592 } else {
26593 return moment$1(new Date(object)).toDate(); // parse string
26594 }
26595 } else {
26596 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type Date');
26597 }
26598
26599 case 'Moment':
26600 if (isNumber$1(object)) {
26601 return moment$1(object);
26602 }
26603
26604 if (object instanceof Date) {
26605 return moment$1(object.valueOf());
26606 } else if (isMoment$1(object)) {
26607 return moment$1(object);
26608 }
26609
26610 if (isString$1(object)) {
26611 match = ASPDateRegex$1.exec(object);
26612
26613 if (match) {
26614 // object is an ASP date
26615 return moment$1(Number(match[1])); // parse number
26616 } else {
26617 return moment$1(object); // parse string
26618 }
26619 } else {
26620 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type Date');
26621 }
26622
26623 case 'ISODate':
26624 if (isNumber$1(object)) {
26625 return new Date(object);
26626 } else if (object instanceof Date) {
26627 return object.toISOString();
26628 } else if (isMoment$1(object)) {
26629 return object.toDate().toISOString();
26630 } else if (isString$1(object)) {
26631 match = ASPDateRegex$1.exec(object);
26632
26633 if (match) {
26634 // object is an ASP date
26635 return new Date(Number(match[1])).toISOString(); // parse number
26636 } else {
26637 return moment$1(object).format(); // ISO 8601
26638 }
26639 } else {
26640 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type ISODate');
26641 }
26642
26643 case 'ASPDate':
26644 if (isNumber$1(object)) {
26645 return '/Date(' + object + ')/';
26646 } else if (object instanceof Date) {
26647 return '/Date(' + object.valueOf() + ')/';
26648 } else if (isString$1(object)) {
26649 match = ASPDateRegex$1.exec(object);
26650
26651 var _value;
26652
26653 if (match) {
26654 // object is an ASP date
26655 _value = new Date(Number(match[1])).valueOf(); // parse number
26656 } else {
26657 _value = new Date(object).valueOf(); // parse string
26658 }
26659
26660 return '/Date(' + _value + ')/';
26661 } else {
26662 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type ASPDate');
26663 }
26664
26665 default:
26666 var never = type;
26667 throw new Error("Unknown type ".concat(never));
26668 }
26669 }
26670 /**
26671 * Get the type of an object, for example exports.getType([]) returns 'Array'
26672 *
26673 * @param object - Input value of unknown type.
26674 *
26675 * @returns Detected type.
26676 */
26677
26678
26679 function getType$1(object) {
26680 var type = _typeof$2(object);
26681
26682 if (type === 'object') {
26683 if (object === null) {
26684 return 'null';
26685 }
26686
26687 if (object instanceof Boolean) {
26688 return 'Boolean';
26689 }
26690
26691 if (object instanceof Number) {
26692 return 'Number';
26693 }
26694
26695 if (object instanceof String) {
26696 return 'String';
26697 }
26698
26699 if (Array.isArray(object)) {
26700 return 'Array';
26701 }
26702
26703 if (object instanceof Date) {
26704 return 'Date';
26705 }
26706
26707 return 'Object';
26708 }
26709
26710 if (type === 'number') {
26711 return 'Number';
26712 }
26713
26714 if (type === 'boolean') {
26715 return 'Boolean';
26716 }
26717
26718 if (type === 'string') {
26719 return 'String';
26720 }
26721
26722 if (type === undefined) {
26723 return 'undefined';
26724 }
26725
26726 return type;
26727 }
26728 /**
26729 * Determine whether a value can be used as an id.
26730 *
26731 * @param value - Input value of unknown type.
26732 *
26733 * @returns True if the value is valid id, false otherwise.
26734 */
26735
26736
26737 function isId(value) {
26738 return typeof value === "string" || typeof value === "number";
26739 }
26740 /* eslint @typescript-eslint/member-ordering: ["error", { "classes": ["field", "constructor", "method"] }] */
26741
26742 /**
26743 * A queue.
26744 *
26745 * @typeParam T - The type of method names to be replaced by queued versions.
26746 */
26747
26748
26749 var Queue =
26750 /*#__PURE__*/
26751 function () {
26752 /**
26753 * Construct a new Queue.
26754 *
26755 * @param options - Queue configuration.
26756 */
26757 function Queue(options) {
26758 classCallCheck(this, Queue);
26759 this._queue = [];
26760 this._timeout = null;
26761 this._extended = null; // options
26762
26763 this.delay = null;
26764 this.max = Infinity;
26765 this.setOptions(options);
26766 }
26767 /**
26768 * Update the configuration of the queue.
26769 *
26770 * @param options - Queue configuration.
26771 */
26772
26773
26774 createClass(Queue, [{
26775 key: "setOptions",
26776 value: function setOptions(options) {
26777 if (options && typeof options.delay !== "undefined") {
26778 this.delay = options.delay;
26779 }
26780
26781 if (options && typeof options.max !== "undefined") {
26782 this.max = options.max;
26783 }
26784
26785 this._flushIfNeeded();
26786 }
26787 /**
26788 * Extend an object with queuing functionality.
26789 * The object will be extended with a function flush, and the methods provided in options.replace will be replaced with queued ones.
26790 *
26791 * @param object - The object to be extended.
26792 * @param options - Additional options.
26793 *
26794 * @returns The created queue.
26795 */
26796
26797 }, {
26798 key: "destroy",
26799
26800 /**
26801 * Destroy the queue. The queue will first flush all queued actions, and in case it has extended an object, will restore the original object.
26802 */
26803 value: function destroy() {
26804 this.flush();
26805
26806 if (this._extended) {
26807 var object = this._extended.object;
26808 var methods = this._extended.methods;
26809
26810 for (var i = 0; i < methods.length; i++) {
26811 var method = methods[i];
26812
26813 if (method.original) {
26814 // @TODO: better solution?
26815 object[method.name] = method.original;
26816 } else {
26817 // @TODO: better solution?
26818 delete object[method.name];
26819 }
26820 }
26821
26822 this._extended = null;
26823 }
26824 }
26825 /**
26826 * Replace a method on an object with a queued version.
26827 *
26828 * @param object - Object having the method.
26829 * @param method - The method name.
26830 */
26831
26832 }, {
26833 key: "replace",
26834 value: function replace(object, method) {
26835 /* eslint-disable-next-line @typescript-eslint/no-this-alias */
26836 var me = this;
26837 var original = object[method];
26838
26839 if (!original) {
26840 throw new Error("Method " + method + " undefined");
26841 }
26842
26843 object[method] = function () {
26844 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
26845 args[_key] = arguments[_key];
26846 } // add this call to the queue
26847
26848
26849 me.queue({
26850 args: args,
26851 fn: original,
26852 context: this
26853 });
26854 };
26855 }
26856 /**
26857 * Queue a call.
26858 *
26859 * @param entry - The function or entry to be queued.
26860 */
26861
26862 }, {
26863 key: "queue",
26864 value: function queue(entry) {
26865 if (typeof entry === "function") {
26866 this._queue.push({
26867 fn: entry
26868 });
26869 } else {
26870 this._queue.push(entry);
26871 }
26872
26873 this._flushIfNeeded();
26874 }
26875 /**
26876 * Check whether the queue needs to be flushed.
26877 */
26878
26879 }, {
26880 key: "_flushIfNeeded",
26881 value: function _flushIfNeeded() {
26882 var _this = this; // flush when the maximum is exceeded.
26883
26884
26885 if (this._queue.length > this.max) {
26886 this.flush();
26887 } // flush after a period of inactivity when a delay is configured
26888
26889
26890 if (this._timeout != null) {
26891 clearTimeout(this._timeout);
26892 this._timeout = null;
26893 }
26894
26895 if (this.queue.length > 0 && typeof this.delay === "number") {
26896 this._timeout = setTimeout(function () {
26897 _this.flush();
26898 }, this.delay);
26899 }
26900 }
26901 /**
26902 * Flush all queued calls
26903 */
26904
26905 }, {
26906 key: "flush",
26907 value: function flush() {
26908 this._queue.splice(0).forEach(function (entry) {
26909 entry.fn.apply(entry.context || entry.fn, entry.args || []);
26910 });
26911 }
26912 }], [{
26913 key: "extend",
26914 value: function extend(object, options) {
26915 var queue = new Queue(options);
26916
26917 if (object.flush !== undefined) {
26918 throw new Error("Target object already has a property flush");
26919 }
26920
26921 object.flush = function () {
26922 queue.flush();
26923 };
26924
26925 var methods = [{
26926 name: "flush",
26927 original: undefined
26928 }];
26929
26930 if (options && options.replace) {
26931 for (var i = 0; i < options.replace.length; i++) {
26932 var name = options.replace[i];
26933 methods.push({
26934 name: name,
26935 // @TODO: better solution?
26936 original: object[name]
26937 }); // @TODO: better solution?
26938
26939 queue.replace(object, name);
26940 }
26941 }
26942
26943 queue._extended = {
26944 object: object,
26945 methods: methods
26946 };
26947 return queue;
26948 }
26949 }]);
26950 return Queue;
26951 }();
26952 /* eslint-disable @typescript-eslint/member-ordering */
26953
26954 /**
26955 * [[DataSet]] code that can be reused in [[DataView]] or other similar implementations of [[DataInterface]].
26956 *
26957 * @typeParam Item - Item type that may or may not have an id.
26958 * @typeParam IdProp - Name of the property that contains the id.
26959 */
26960
26961
26962 var DataSetPart =
26963 /*#__PURE__*/
26964 function () {
26965 function DataSetPart() {
26966 classCallCheck(this, DataSetPart);
26967 this._subscribers = {
26968 "*": [],
26969 add: [],
26970 remove: [],
26971 update: []
26972 };
26973 /**
26974 * @deprecated Use on instead (PS: DataView.subscribe === DataView.on).
26975 */
26976
26977 this.subscribe = DataSetPart.prototype.on;
26978 /**
26979 * @deprecated Use off instead (PS: DataView.unsubscribe === DataView.off).
26980 */
26981
26982 this.unsubscribe = DataSetPart.prototype.off;
26983 }
26984 /**
26985 * Trigger an event
26986 *
26987 * @param event - Event name.
26988 * @param payload - Event payload.
26989 * @param senderId - Id of the sender.
26990 */
26991
26992
26993 createClass(DataSetPart, [{
26994 key: "_trigger",
26995 value: function _trigger(event, payload, senderId) {
26996 if (event === "*") {
26997 throw new Error("Cannot trigger event *");
26998 }
26999
27000 [].concat(toConsumableArray(this._subscribers[event]), toConsumableArray(this._subscribers["*"])).forEach(function (subscriber) {
27001 subscriber(event, payload, senderId != null ? senderId : null);
27002 });
27003 }
27004 /**
27005 * Subscribe to an event, add an event listener.
27006 *
27007 * @remarks Non-function callbacks are ignored.
27008 *
27009 * @param event - Event name.
27010 * @param callback - Callback method.
27011 */
27012
27013 }, {
27014 key: "on",
27015 value: function on(event, callback) {
27016 if (typeof callback === "function") {
27017 this._subscribers[event].push(callback);
27018 } // @TODO: Maybe throw for invalid callbacks?
27019
27020 }
27021 /**
27022 * Unsubscribe from an event, remove an event listener.
27023 *
27024 * @remarks If the same callback was subscribed more than once **all** occurences will be removed.
27025 *
27026 * @param event - Event name.
27027 * @param callback - Callback method.
27028 */
27029
27030 }, {
27031 key: "off",
27032 value: function off(event, callback) {
27033 this._subscribers[event] = this._subscribers[event].filter(function (subscriber) {
27034 return subscriber !== callback;
27035 });
27036 }
27037 }]);
27038 return DataSetPart;
27039 }();
27040
27041 function _arrayWithHoles$1(arr) {
27042 if (Array.isArray(arr)) return arr;
27043 }
27044
27045 var arrayWithHoles = _arrayWithHoles$1;
27046
27047 function _iterableToArrayLimit$1(arr, i) {
27048 var _arr = [];
27049 var _n = true;
27050 var _d = false;
27051 var _e = undefined;
27052
27053 try {
27054 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
27055 _arr.push(_s.value);
27056
27057 if (i && _arr.length === i) break;
27058 }
27059 } catch (err) {
27060 _d = true;
27061 _e = err;
27062 } finally {
27063 try {
27064 if (!_n && _i["return"] != null) _i["return"]();
27065 } finally {
27066 if (_d) throw _e;
27067 }
27068 }
27069
27070 return _arr;
27071 }
27072
27073 var iterableToArrayLimit = _iterableToArrayLimit$1;
27074
27075 function _nonIterableRest$1() {
27076 throw new TypeError("Invalid attempt to destructure non-iterable instance");
27077 }
27078
27079 var nonIterableRest = _nonIterableRest$1;
27080
27081 function _slicedToArray$1(arr, i) {
27082 return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
27083 }
27084
27085 var slicedToArray = _slicedToArray$1;
27086 /**
27087 * Data stream
27088 *
27089 * @remarks
27090 * [[DataStream]] offers an always up to date stream of items from a [[DataSet]] or [[DataView]].
27091 * 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.
27092 * Multiple invocations of for example [[toItemArray]] may yield different results (if the data source like for example [[DataSet]] gets modified).
27093 *
27094 * @typeparam Item - The item type this stream is going to work with.
27095 */
27096
27097 var DataStream =
27098 /*#__PURE__*/
27099 function () {
27100 /**
27101 * Create a new data stream.
27102 *
27103 * @param _pairs - The id, item pairs.
27104 */
27105 function DataStream(_pairs) {
27106 classCallCheck(this, DataStream);
27107 this._pairs = _pairs;
27108 }
27109 /**
27110 * Return an iterable of key, value pairs for every entry in the stream.
27111 */
27112
27113
27114 createClass(DataStream, [{
27115 key: Symbol.iterator,
27116 value:
27117 /*#__PURE__*/
27118 regenerator.mark(function value() {
27119 var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step$value, id, item;
27120
27121 return regenerator.wrap(function value$(_context) {
27122 while (1) {
27123 switch (_context.prev = _context.next) {
27124 case 0:
27125 _iteratorNormalCompletion = true;
27126 _didIteratorError = false;
27127 _iteratorError = undefined;
27128 _context.prev = 3;
27129 _iterator = this._pairs[Symbol.iterator]();
27130
27131 case 5:
27132 if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
27133 _context.next = 12;
27134 break;
27135 }
27136
27137 _step$value = slicedToArray(_step.value, 2), id = _step$value[0], item = _step$value[1];
27138 _context.next = 9;
27139 return [id, item];
27140
27141 case 9:
27142 _iteratorNormalCompletion = true;
27143 _context.next = 5;
27144 break;
27145
27146 case 12:
27147 _context.next = 18;
27148 break;
27149
27150 case 14:
27151 _context.prev = 14;
27152 _context.t0 = _context["catch"](3);
27153 _didIteratorError = true;
27154 _iteratorError = _context.t0;
27155
27156 case 18:
27157 _context.prev = 18;
27158 _context.prev = 19;
27159
27160 if (!_iteratorNormalCompletion && _iterator.return != null) {
27161 _iterator.return();
27162 }
27163
27164 case 21:
27165 _context.prev = 21;
27166
27167 if (!_didIteratorError) {
27168 _context.next = 24;
27169 break;
27170 }
27171
27172 throw _iteratorError;
27173
27174 case 24:
27175 return _context.finish(21);
27176
27177 case 25:
27178 return _context.finish(18);
27179
27180 case 26:
27181 case "end":
27182 return _context.stop();
27183 }
27184 }
27185 }, value, this, [[3, 14, 18, 26], [19,, 21, 25]]);
27186 })
27187 /**
27188 * Return an iterable of key, value pairs for every entry in the stream.
27189 */
27190
27191 }, {
27192 key: "entries",
27193 value:
27194 /*#__PURE__*/
27195 regenerator.mark(function entries() {
27196 var _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, _step2$value, id, item;
27197
27198 return regenerator.wrap(function entries$(_context2) {
27199 while (1) {
27200 switch (_context2.prev = _context2.next) {
27201 case 0:
27202 _iteratorNormalCompletion2 = true;
27203 _didIteratorError2 = false;
27204 _iteratorError2 = undefined;
27205 _context2.prev = 3;
27206 _iterator2 = this._pairs[Symbol.iterator]();
27207
27208 case 5:
27209 if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
27210 _context2.next = 12;
27211 break;
27212 }
27213
27214 _step2$value = slicedToArray(_step2.value, 2), id = _step2$value[0], item = _step2$value[1];
27215 _context2.next = 9;
27216 return [id, item];
27217
27218 case 9:
27219 _iteratorNormalCompletion2 = true;
27220 _context2.next = 5;
27221 break;
27222
27223 case 12:
27224 _context2.next = 18;
27225 break;
27226
27227 case 14:
27228 _context2.prev = 14;
27229 _context2.t0 = _context2["catch"](3);
27230 _didIteratorError2 = true;
27231 _iteratorError2 = _context2.t0;
27232
27233 case 18:
27234 _context2.prev = 18;
27235 _context2.prev = 19;
27236
27237 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
27238 _iterator2.return();
27239 }
27240
27241 case 21:
27242 _context2.prev = 21;
27243
27244 if (!_didIteratorError2) {
27245 _context2.next = 24;
27246 break;
27247 }
27248
27249 throw _iteratorError2;
27250
27251 case 24:
27252 return _context2.finish(21);
27253
27254 case 25:
27255 return _context2.finish(18);
27256
27257 case 26:
27258 case "end":
27259 return _context2.stop();
27260 }
27261 }
27262 }, entries, this, [[3, 14, 18, 26], [19,, 21, 25]]);
27263 })
27264 /**
27265 * Return an iterable of keys in the stream.
27266 */
27267
27268 }, {
27269 key: "keys",
27270 value:
27271 /*#__PURE__*/
27272 regenerator.mark(function keys() {
27273 var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, _step3$value, id;
27274
27275 return regenerator.wrap(function keys$(_context3) {
27276 while (1) {
27277 switch (_context3.prev = _context3.next) {
27278 case 0:
27279 _iteratorNormalCompletion3 = true;
27280 _didIteratorError3 = false;
27281 _iteratorError3 = undefined;
27282 _context3.prev = 3;
27283 _iterator3 = this._pairs[Symbol.iterator]();
27284
27285 case 5:
27286 if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
27287 _context3.next = 12;
27288 break;
27289 }
27290
27291 _step3$value = slicedToArray(_step3.value, 1), id = _step3$value[0];
27292 _context3.next = 9;
27293 return id;
27294
27295 case 9:
27296 _iteratorNormalCompletion3 = true;
27297 _context3.next = 5;
27298 break;
27299
27300 case 12:
27301 _context3.next = 18;
27302 break;
27303
27304 case 14:
27305 _context3.prev = 14;
27306 _context3.t0 = _context3["catch"](3);
27307 _didIteratorError3 = true;
27308 _iteratorError3 = _context3.t0;
27309
27310 case 18:
27311 _context3.prev = 18;
27312 _context3.prev = 19;
27313
27314 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
27315 _iterator3.return();
27316 }
27317
27318 case 21:
27319 _context3.prev = 21;
27320
27321 if (!_didIteratorError3) {
27322 _context3.next = 24;
27323 break;
27324 }
27325
27326 throw _iteratorError3;
27327
27328 case 24:
27329 return _context3.finish(21);
27330
27331 case 25:
27332 return _context3.finish(18);
27333
27334 case 26:
27335 case "end":
27336 return _context3.stop();
27337 }
27338 }
27339 }, keys, this, [[3, 14, 18, 26], [19,, 21, 25]]);
27340 })
27341 /**
27342 * Return an iterable of values in the stream.
27343 */
27344
27345 }, {
27346 key: "values",
27347 value:
27348 /*#__PURE__*/
27349 regenerator.mark(function values() {
27350 var _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, _step4$value, item;
27351
27352 return regenerator.wrap(function values$(_context4) {
27353 while (1) {
27354 switch (_context4.prev = _context4.next) {
27355 case 0:
27356 _iteratorNormalCompletion4 = true;
27357 _didIteratorError4 = false;
27358 _iteratorError4 = undefined;
27359 _context4.prev = 3;
27360 _iterator4 = this._pairs[Symbol.iterator]();
27361
27362 case 5:
27363 if (_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done) {
27364 _context4.next = 12;
27365 break;
27366 }
27367
27368 _step4$value = slicedToArray(_step4.value, 2), item = _step4$value[1];
27369 _context4.next = 9;
27370 return item;
27371
27372 case 9:
27373 _iteratorNormalCompletion4 = true;
27374 _context4.next = 5;
27375 break;
27376
27377 case 12:
27378 _context4.next = 18;
27379 break;
27380
27381 case 14:
27382 _context4.prev = 14;
27383 _context4.t0 = _context4["catch"](3);
27384 _didIteratorError4 = true;
27385 _iteratorError4 = _context4.t0;
27386
27387 case 18:
27388 _context4.prev = 18;
27389 _context4.prev = 19;
27390
27391 if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
27392 _iterator4.return();
27393 }
27394
27395 case 21:
27396 _context4.prev = 21;
27397
27398 if (!_didIteratorError4) {
27399 _context4.next = 24;
27400 break;
27401 }
27402
27403 throw _iteratorError4;
27404
27405 case 24:
27406 return _context4.finish(21);
27407
27408 case 25:
27409 return _context4.finish(18);
27410
27411 case 26:
27412 case "end":
27413 return _context4.stop();
27414 }
27415 }
27416 }, values, this, [[3, 14, 18, 26], [19,, 21, 25]]);
27417 })
27418 /**
27419 * Return an array containing all the ids in this stream.
27420 *
27421 * @remarks
27422 * The array may contain duplicities.
27423 *
27424 * @returns The array with all ids from this stream.
27425 */
27426
27427 }, {
27428 key: "toIdArray",
27429 value: function toIdArray() {
27430 return toConsumableArray(this._pairs).map(function (pair) {
27431 return pair[0];
27432 });
27433 }
27434 /**
27435 * Return an array containing all the items in this stream.
27436 *
27437 * @remarks
27438 * The array may contain duplicities.
27439 *
27440 * @returns The array with all items from this stream.
27441 */
27442
27443 }, {
27444 key: "toItemArray",
27445 value: function toItemArray() {
27446 return toConsumableArray(this._pairs).map(function (pair) {
27447 return pair[1];
27448 });
27449 }
27450 /**
27451 * Return an array containing all the entries in this stream.
27452 *
27453 * @remarks
27454 * The array may contain duplicities.
27455 *
27456 * @returns The array with all entries from this stream.
27457 */
27458
27459 }, {
27460 key: "toEntryArray",
27461 value: function toEntryArray() {
27462 return toConsumableArray(this._pairs);
27463 }
27464 /**
27465 * Return an object map containing all the items in this stream accessible by ids.
27466 *
27467 * @remarks
27468 * In case of duplicate ids (coerced to string so `7 == '7'`) the last encoutered appears in the returned object.
27469 *
27470 * @returns The object map of all id → item pairs from this stream.
27471 */
27472
27473 }, {
27474 key: "toObjectMap",
27475 value: function toObjectMap() {
27476 var map = Object.create(null);
27477 var _iteratorNormalCompletion5 = true;
27478 var _didIteratorError5 = false;
27479 var _iteratorError5 = undefined;
27480
27481 try {
27482 for (var _iterator5 = this._pairs[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
27483 var _step5$value = slicedToArray(_step5.value, 2),
27484 id = _step5$value[0],
27485 item = _step5$value[1];
27486
27487 map[id] = item;
27488 }
27489 } catch (err) {
27490 _didIteratorError5 = true;
27491 _iteratorError5 = err;
27492 } finally {
27493 try {
27494 if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
27495 _iterator5.return();
27496 }
27497 } finally {
27498 if (_didIteratorError5) {
27499 throw _iteratorError5;
27500 }
27501 }
27502 }
27503
27504 return map;
27505 }
27506 /**
27507 * Return a map containing all the items in this stream accessible by ids.
27508 *
27509 * @returns The map of all id → item pairs from this stream.
27510 */
27511
27512 }, {
27513 key: "toMap",
27514 value: function toMap() {
27515 return new Map(this._pairs);
27516 }
27517 /**
27518 * Return a set containing all the (unique) ids in this stream.
27519 *
27520 * @returns The set of all ids from this stream.
27521 */
27522
27523 }, {
27524 key: "toIdSet",
27525 value: function toIdSet() {
27526 return new Set(this.toIdArray());
27527 }
27528 /**
27529 * Return a set containing all the (unique) items in this stream.
27530 *
27531 * @returns The set of all items from this stream.
27532 */
27533
27534 }, {
27535 key: "toItemSet",
27536 value: function toItemSet() {
27537 return new Set(this.toItemArray());
27538 }
27539 /**
27540 * Cache the items from this stream.
27541 *
27542 * @remarks
27543 * This method allows for items to be fetched immediatelly and used (possibly multiple times) later.
27544 * It can also be used to optimize performance as [[DataStream]] would otherwise reevaluate everything upon each iteration.
27545 *
27546 * ## Example
27547 * ```javascript
27548 * const ds = new DataSet([…])
27549 *
27550 * const cachedStream = ds.stream()
27551 * .filter(…)
27552 * .sort(…)
27553 * .map(…)
27554 * .cached(…) // Data are fetched, processed and cached here.
27555 *
27556 * ds.clear()
27557 * chachedStream // Still has all the items.
27558 * ```
27559 *
27560 * @returns A new [[DataStream]] with cached items (detached from the original [[DataSet]]).
27561 */
27562
27563 }, {
27564 key: "cache",
27565 value: function cache() {
27566 return new DataStream(toConsumableArray(this._pairs));
27567 }
27568 /**
27569 * Get the distinct values of given property.
27570 *
27571 * @param callback - The function that picks and possibly converts the property.
27572 *
27573 * @typeparam T - The type of the distinct value.
27574 *
27575 * @returns A set of all distinct properties.
27576 */
27577
27578 }, {
27579 key: "distinct",
27580 value: function distinct(callback) {
27581 var set = new Set();
27582 var _iteratorNormalCompletion6 = true;
27583 var _didIteratorError6 = false;
27584 var _iteratorError6 = undefined;
27585
27586 try {
27587 for (var _iterator6 = this._pairs[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
27588 var _step6$value = slicedToArray(_step6.value, 2),
27589 id = _step6$value[0],
27590 item = _step6$value[1];
27591
27592 set.add(callback(item, id));
27593 }
27594 } catch (err) {
27595 _didIteratorError6 = true;
27596 _iteratorError6 = err;
27597 } finally {
27598 try {
27599 if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
27600 _iterator6.return();
27601 }
27602 } finally {
27603 if (_didIteratorError6) {
27604 throw _iteratorError6;
27605 }
27606 }
27607 }
27608
27609 return set;
27610 }
27611 /**
27612 * Filter the items of the stream.
27613 *
27614 * @param callback - The function that decides whether an item will be included.
27615 *
27616 * @returns A new data stream with the filtered items.
27617 */
27618
27619 }, {
27620 key: "filter",
27621 value: function filter(callback) {
27622 var pairs = this._pairs;
27623 return new DataStream(defineProperty$a({}, Symbol.iterator,
27624 /*#__PURE__*/
27625 regenerator.mark(function _callee() {
27626 var _iteratorNormalCompletion7, _didIteratorError7, _iteratorError7, _iterator7, _step7, _step7$value, id, item;
27627
27628 return regenerator.wrap(function _callee$(_context5) {
27629 while (1) {
27630 switch (_context5.prev = _context5.next) {
27631 case 0:
27632 _iteratorNormalCompletion7 = true;
27633 _didIteratorError7 = false;
27634 _iteratorError7 = undefined;
27635 _context5.prev = 3;
27636 _iterator7 = pairs[Symbol.iterator]();
27637
27638 case 5:
27639 if (_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done) {
27640 _context5.next = 13;
27641 break;
27642 }
27643
27644 _step7$value = slicedToArray(_step7.value, 2), id = _step7$value[0], item = _step7$value[1];
27645
27646 if (!callback(item, id)) {
27647 _context5.next = 10;
27648 break;
27649 }
27650
27651 _context5.next = 10;
27652 return [id, item];
27653
27654 case 10:
27655 _iteratorNormalCompletion7 = true;
27656 _context5.next = 5;
27657 break;
27658
27659 case 13:
27660 _context5.next = 19;
27661 break;
27662
27663 case 15:
27664 _context5.prev = 15;
27665 _context5.t0 = _context5["catch"](3);
27666 _didIteratorError7 = true;
27667 _iteratorError7 = _context5.t0;
27668
27669 case 19:
27670 _context5.prev = 19;
27671 _context5.prev = 20;
27672
27673 if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
27674 _iterator7.return();
27675 }
27676
27677 case 22:
27678 _context5.prev = 22;
27679
27680 if (!_didIteratorError7) {
27681 _context5.next = 25;
27682 break;
27683 }
27684
27685 throw _iteratorError7;
27686
27687 case 25:
27688 return _context5.finish(22);
27689
27690 case 26:
27691 return _context5.finish(19);
27692
27693 case 27:
27694 case "end":
27695 return _context5.stop();
27696 }
27697 }
27698 }, _callee, null, [[3, 15, 19, 27], [20,, 22, 26]]);
27699 })));
27700 }
27701 /**
27702 * Execute a callback for each item of the stream.
27703 *
27704 * @param callback - The function that will be invoked for each item.
27705 */
27706
27707 }, {
27708 key: "forEach",
27709 value: function forEach(callback) {
27710 var _iteratorNormalCompletion8 = true;
27711 var _didIteratorError8 = false;
27712 var _iteratorError8 = undefined;
27713
27714 try {
27715 for (var _iterator8 = this._pairs[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
27716 var _step8$value = slicedToArray(_step8.value, 2),
27717 id = _step8$value[0],
27718 item = _step8$value[1];
27719
27720 callback(item, id);
27721 }
27722 } catch (err) {
27723 _didIteratorError8 = true;
27724 _iteratorError8 = err;
27725 } finally {
27726 try {
27727 if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
27728 _iterator8.return();
27729 }
27730 } finally {
27731 if (_didIteratorError8) {
27732 throw _iteratorError8;
27733 }
27734 }
27735 }
27736 }
27737 /**
27738 * Map the items into a different type.
27739 *
27740 * @param callback - The function that does the conversion.
27741 *
27742 * @typeparam Mapped - The type of the item after mapping.
27743 *
27744 * @returns A new data stream with the mapped items.
27745 */
27746
27747 }, {
27748 key: "map",
27749 value: function map(callback) {
27750 var pairs = this._pairs;
27751 return new DataStream(defineProperty$a({}, Symbol.iterator,
27752 /*#__PURE__*/
27753 regenerator.mark(function _callee2() {
27754 var _iteratorNormalCompletion9, _didIteratorError9, _iteratorError9, _iterator9, _step9, _step9$value, id, item;
27755
27756 return regenerator.wrap(function _callee2$(_context6) {
27757 while (1) {
27758 switch (_context6.prev = _context6.next) {
27759 case 0:
27760 _iteratorNormalCompletion9 = true;
27761 _didIteratorError9 = false;
27762 _iteratorError9 = undefined;
27763 _context6.prev = 3;
27764 _iterator9 = pairs[Symbol.iterator]();
27765
27766 case 5:
27767 if (_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done) {
27768 _context6.next = 12;
27769 break;
27770 }
27771
27772 _step9$value = slicedToArray(_step9.value, 2), id = _step9$value[0], item = _step9$value[1];
27773 _context6.next = 9;
27774 return [id, callback(item, id)];
27775
27776 case 9:
27777 _iteratorNormalCompletion9 = true;
27778 _context6.next = 5;
27779 break;
27780
27781 case 12:
27782 _context6.next = 18;
27783 break;
27784
27785 case 14:
27786 _context6.prev = 14;
27787 _context6.t0 = _context6["catch"](3);
27788 _didIteratorError9 = true;
27789 _iteratorError9 = _context6.t0;
27790
27791 case 18:
27792 _context6.prev = 18;
27793 _context6.prev = 19;
27794
27795 if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
27796 _iterator9.return();
27797 }
27798
27799 case 21:
27800 _context6.prev = 21;
27801
27802 if (!_didIteratorError9) {
27803 _context6.next = 24;
27804 break;
27805 }
27806
27807 throw _iteratorError9;
27808
27809 case 24:
27810 return _context6.finish(21);
27811
27812 case 25:
27813 return _context6.finish(18);
27814
27815 case 26:
27816 case "end":
27817 return _context6.stop();
27818 }
27819 }
27820 }, _callee2, null, [[3, 14, 18, 26], [19,, 21, 25]]);
27821 })));
27822 }
27823 /**
27824 * Get the item with the maximum value of given property.
27825 *
27826 * @param callback - The function that picks and possibly converts the property.
27827 *
27828 * @returns The item with the maximum if found otherwise null.
27829 */
27830
27831 }, {
27832 key: "max",
27833 value: function max(callback) {
27834 var iter = this._pairs[Symbol.iterator]();
27835
27836 var curr = iter.next();
27837
27838 if (curr.done) {
27839 return null;
27840 }
27841
27842 var maxItem = curr.value[1];
27843 var maxValue = callback(curr.value[1], curr.value[0]);
27844
27845 while (!(curr = iter.next()).done) {
27846 var _curr$value = slicedToArray(curr.value, 2),
27847 id = _curr$value[0],
27848 item = _curr$value[1];
27849
27850 var _value = callback(item, id);
27851
27852 if (_value > maxValue) {
27853 maxValue = _value;
27854 maxItem = item;
27855 }
27856 }
27857
27858 return maxItem;
27859 }
27860 /**
27861 * Get the item with the minimum value of given property.
27862 *
27863 * @param callback - The function that picks and possibly converts the property.
27864 *
27865 * @returns The item with the minimum if found otherwise null.
27866 */
27867
27868 }, {
27869 key: "min",
27870 value: function min(callback) {
27871 var iter = this._pairs[Symbol.iterator]();
27872
27873 var curr = iter.next();
27874
27875 if (curr.done) {
27876 return null;
27877 }
27878
27879 var minItem = curr.value[1];
27880 var minValue = callback(curr.value[1], curr.value[0]);
27881
27882 while (!(curr = iter.next()).done) {
27883 var _curr$value2 = slicedToArray(curr.value, 2),
27884 id = _curr$value2[0],
27885 item = _curr$value2[1];
27886
27887 var _value2 = callback(item, id);
27888
27889 if (_value2 < minValue) {
27890 minValue = _value2;
27891 minItem = item;
27892 }
27893 }
27894
27895 return minItem;
27896 }
27897 /**
27898 * Reduce the items into a single value.
27899 *
27900 * @param callback - The function that does the reduction.
27901 * @param accumulator - The initial value of the accumulator.
27902 *
27903 * @typeparam T - The type of the accumulated value.
27904 *
27905 * @returns The reduced value.
27906 */
27907
27908 }, {
27909 key: "reduce",
27910 value: function reduce(callback, accumulator) {
27911 var _iteratorNormalCompletion10 = true;
27912 var _didIteratorError10 = false;
27913 var _iteratorError10 = undefined;
27914
27915 try {
27916 for (var _iterator10 = this._pairs[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
27917 var _step10$value = slicedToArray(_step10.value, 2),
27918 id = _step10$value[0],
27919 item = _step10$value[1];
27920
27921 accumulator = callback(accumulator, item, id);
27922 }
27923 } catch (err) {
27924 _didIteratorError10 = true;
27925 _iteratorError10 = err;
27926 } finally {
27927 try {
27928 if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
27929 _iterator10.return();
27930 }
27931 } finally {
27932 if (_didIteratorError10) {
27933 throw _iteratorError10;
27934 }
27935 }
27936 }
27937
27938 return accumulator;
27939 }
27940 /**
27941 * Sort the items.
27942 *
27943 * @param callback - Item comparator.
27944 *
27945 * @returns A new stream with sorted items.
27946 */
27947
27948 }, {
27949 key: "sort",
27950 value: function sort(callback) {
27951 var _this = this;
27952
27953 return new DataStream(defineProperty$a({}, Symbol.iterator, function () {
27954 return toConsumableArray(_this._pairs).sort(function (_ref3, _ref4) {
27955 var _ref5 = slicedToArray(_ref3, 2),
27956 idA = _ref5[0],
27957 itemA = _ref5[1];
27958
27959 var _ref6 = slicedToArray(_ref4, 2),
27960 idB = _ref6[0],
27961 itemB = _ref6[1];
27962
27963 return callback(itemA, itemB, idA, idB);
27964 })[Symbol.iterator]();
27965 }));
27966 }
27967 }]);
27968 return DataStream;
27969 }();
27970
27971 function ownKeys$3(object, enumerableOnly) {
27972 var keys = Object.keys(object);
27973
27974 if (Object.getOwnPropertySymbols) {
27975 keys.push.apply(keys, Object.getOwnPropertySymbols(object));
27976 }
27977
27978 if (enumerableOnly) keys = keys.filter(function (sym) {
27979 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
27980 });
27981 return keys;
27982 }
27983
27984 function _objectSpread(target) {
27985 for (var i = 1; i < arguments.length; i++) {
27986 var source = arguments[i] != null ? arguments[i] : {};
27987
27988 if (i % 2) {
27989 ownKeys$3(source, true).forEach(function (key) {
27990 defineProperty$a(target, key, source[key]);
27991 });
27992 } else if (Object.getOwnPropertyDescriptors) {
27993 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
27994 } else {
27995 ownKeys$3(source).forEach(function (key) {
27996 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
27997 });
27998 }
27999 }
28000
28001 return target;
28002 }
28003 /**
28004 * # DataSet
28005 *
28006 * Vis.js comes with a flexible DataSet, which can be used to hold and manipulate unstructured data and listen for changes in the data. The DataSet is key/value based. Data items can be added, updated and removed from the DataSet, and one can subscribe to changes in the DataSet. The data in the DataSet can be filtered and ordered, and fields (like dates) can be converted to a specific type. Data can be normalized when appending it to the DataSet as well.
28007 *
28008 * ## Example
28009 *
28010 * The following example shows how to use a DataSet.
28011 *
28012 * ```javascript
28013 * // create a DataSet
28014 * var options = {};
28015 * var data = new vis.DataSet(options);
28016 *
28017 * // add items
28018 * // note that the data items can contain different properties and data formats
28019 * data.add([
28020 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
28021 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
28022 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
28023 * {id: 4, text: 'item 4'}
28024 * ]);
28025 *
28026 * // subscribe to any change in the DataSet
28027 * data.on('*', function (event, properties, senderId) {
28028 * console.log('event', event, properties);
28029 * });
28030 *
28031 * // update an existing item
28032 * data.update({id: 2, group: 1});
28033 *
28034 * // remove an item
28035 * data.remove(4);
28036 *
28037 * // get all ids
28038 * var ids = data.getIds();
28039 * console.log('ids', ids);
28040 *
28041 * // get a specific item
28042 * var item1 = data.get(1);
28043 * console.log('item1', item1);
28044 *
28045 * // retrieve a filtered subset of the data
28046 * var items = data.get({
28047 * filter: function (item) {
28048 * return item.group == 1;
28049 * }
28050 * });
28051 * console.log('filtered items', items);
28052 *
28053 * // retrieve formatted items
28054 * var items = data.get({
28055 * fields: ['id', 'date'],
28056 * type: {
28057 * date: 'ISODate'
28058 * }
28059 * });
28060 * console.log('formatted items', items);
28061 * ```
28062 *
28063 * @typeParam Item - Item type that may or may not have an id.
28064 * @typeParam IdProp - Name of the property that contains the id.
28065 */
28066
28067
28068 var DataSet =
28069 /*#__PURE__*/
28070 function (_DataSetPart) {
28071 inherits(DataSet, _DataSetPart);
28072 /**
28073 * Construct a new DataSet.
28074 *
28075 * @param data - Initial data or options.
28076 * @param options - Options (type error if data is also options).
28077 */
28078
28079 function DataSet(data, options) {
28080 var _this;
28081
28082 classCallCheck(this, DataSet);
28083 _this = possibleConstructorReturn(this, getPrototypeOf(DataSet).call(this)); // correctly read optional arguments
28084
28085 if (data && !Array.isArray(data)) {
28086 options = data;
28087 data = [];
28088 }
28089
28090 _this._options = options || {};
28091 _this._data = new Map(); // map with data indexed by id
28092
28093 _this.length = 0; // number of items in the DataSet
28094
28095 _this._idProp = _this._options.fieldId || "id"; // name of the field containing id
28096
28097 _this._type = {}; // internal field types (NOTE: this can differ from this._options.type)
28098 // all variants of a Date are internally stored as Date, so we can convert
28099 // from everything to everything (also from ISODate to Number for example)
28100
28101 if (_this._options.type) {
28102 var fields = Object.keys(_this._options.type);
28103
28104 for (var i = 0, len = fields.length; i < len; i++) {
28105 var field = fields[i];
28106 var value = _this._options.type[field];
28107
28108 if (value == "Date" || value == "ISODate" || value == "ASPDate") {
28109 _this._type[field] = "Date";
28110 } else {
28111 _this._type[field] = value;
28112 }
28113 }
28114 } // add initial data when provided
28115
28116
28117 if (data && data.length) {
28118 _this.add(data);
28119 }
28120
28121 _this.setOptions(options);
28122
28123 return _this;
28124 }
28125 /**
28126 * Set new options.
28127 *
28128 * @param options - The new options.
28129 */
28130
28131
28132 createClass(DataSet, [{
28133 key: "setOptions",
28134 value: function setOptions(options) {
28135 if (options && options.queue !== undefined) {
28136 if (options.queue === false) {
28137 // delete queue if loaded
28138 if (this._queue) {
28139 this._queue.destroy();
28140
28141 delete this._queue;
28142 }
28143 } else {
28144 // create queue and update its options
28145 if (!this._queue) {
28146 this._queue = Queue.extend(this, {
28147 replace: ["add", "update", "remove"]
28148 });
28149 }
28150
28151 if (options.queue && _typeof_1(options.queue) === "object") {
28152 this._queue.setOptions(options.queue);
28153 }
28154 }
28155 }
28156 }
28157 /**
28158 * Add a data item or an array with items.
28159 *
28160 * 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.
28161 *
28162 * ## Example
28163 *
28164 * ```javascript
28165 * // create a DataSet
28166 * const data = new vis.DataSet()
28167 *
28168 * // add items
28169 * const ids = data.add([
28170 * { id: 1, text: 'item 1' },
28171 * { id: 2, text: 'item 2' },
28172 * { text: 'item without an id' }
28173 * ])
28174 *
28175 * console.log(ids) // [1, 2, '<UUIDv4>']
28176 * ```
28177 *
28178 * @param data - Items to be added (ids will be generated if missing).
28179 * @param senderId - Sender id.
28180 *
28181 * @returns addedIds - Array with the ids (generated if not present) of the added items.
28182 *
28183 * @throws When an item with the same id as any of the added items already exists.
28184 */
28185
28186 }, {
28187 key: "add",
28188 value: function add(data, senderId) {
28189 var _this2 = this;
28190
28191 var addedIds = [];
28192 var id;
28193
28194 if (Array.isArray(data)) {
28195 // Array
28196 var idsToAdd = data.map(function (d) {
28197 return d[_this2._idProp];
28198 });
28199
28200 if (idsToAdd.some(function (id) {
28201 return _this2._data.has(id);
28202 })) {
28203 throw new Error("A duplicate id was found in the parameter array.");
28204 }
28205
28206 for (var i = 0, len = data.length; i < len; i++) {
28207 id = this._addItem(data[i]);
28208 addedIds.push(id);
28209 }
28210 } else if (data && _typeof_1(data) === "object") {
28211 // Single item
28212 id = this._addItem(data);
28213 addedIds.push(id);
28214 } else {
28215 throw new Error("Unknown dataType");
28216 }
28217
28218 if (addedIds.length) {
28219 this._trigger("add", {
28220 items: addedIds
28221 }, senderId);
28222 }
28223
28224 return addedIds;
28225 }
28226 /**
28227 * Update existing items. When an item does not exist, it will be created.
28228 *
28229 * @remarks
28230 * The provided properties will be merged in the existing item. When an item does not exist, it will be created.
28231 *
28232 * 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.
28233 *
28234 * ## Example
28235 *
28236 * ```javascript
28237 * // create a DataSet
28238 * const data = new vis.DataSet([
28239 * { id: 1, text: 'item 1' },
28240 * { id: 2, text: 'item 2' },
28241 * { id: 3, text: 'item 3' }
28242 * ])
28243 *
28244 * // update items
28245 * const ids = data.update([
28246 * { id: 2, text: 'item 2 (updated)' },
28247 * { id: 4, text: 'item 4 (new)' }
28248 * ])
28249 *
28250 * console.log(ids) // [2, 4]
28251 * ```
28252 *
28253 * ## Warning for TypeScript users
28254 * This method may introduce partial items into the data set. Use add or updateOnly instead for better type safety.
28255 *
28256 * @param data - Items to be updated (if the id is already present) or added (if the id is missing).
28257 * @param senderId - Sender id.
28258 *
28259 * @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.
28260 *
28261 * @throws When the supplied data is neither an item nor an array of items.
28262 */
28263
28264 }, {
28265 key: "update",
28266 value: function update(data, senderId) {
28267 var _this3 = this;
28268
28269 var addedIds = [];
28270 var updatedIds = [];
28271 var oldData = [];
28272 var updatedData = [];
28273 var idProp = this._idProp;
28274
28275 var addOrUpdate = function addOrUpdate(item) {
28276 var origId = item[idProp];
28277
28278 if (origId != null && _this3._data.has(origId)) {
28279 var fullItem = item; // it has an id, therefore it is a fullitem
28280
28281 var oldItem = Object.assign({}, _this3._data.get(origId)); // update item
28282
28283 var id = _this3._updateItem(fullItem);
28284
28285 updatedIds.push(id);
28286 updatedData.push(fullItem);
28287 oldData.push(oldItem);
28288 } else {
28289 // add new item
28290 var _id = _this3._addItem(item);
28291
28292 addedIds.push(_id);
28293 }
28294 };
28295
28296 if (Array.isArray(data)) {
28297 // Array
28298 for (var i = 0, len = data.length; i < len; i++) {
28299 if (data[i] && _typeof_1(data[i]) === "object") {
28300 addOrUpdate(data[i]);
28301 } else {
28302 console.warn("Ignoring input item, which is not an object at index " + i);
28303 }
28304 }
28305 } else if (data && _typeof_1(data) === "object") {
28306 // Single item
28307 addOrUpdate(data);
28308 } else {
28309 throw new Error("Unknown dataType");
28310 }
28311
28312 if (addedIds.length) {
28313 this._trigger("add", {
28314 items: addedIds
28315 }, senderId);
28316 }
28317
28318 if (updatedIds.length) {
28319 var props = {
28320 items: updatedIds,
28321 oldData: oldData,
28322 data: updatedData
28323 }; // TODO: remove deprecated property 'data' some day
28324 //Object.defineProperty(props, 'data', {
28325 // 'get': (function() {
28326 // 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');
28327 // return updatedData;
28328 // }).bind(this)
28329 //});
28330
28331 this._trigger("update", props, senderId);
28332 }
28333
28334 return addedIds.concat(updatedIds);
28335 }
28336 /**
28337 * Update existing items. When an item does not exist, an error will be thrown.
28338 *
28339 * @remarks
28340 * The provided properties will be deeply merged into the existing item.
28341 * 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.
28342 *
28343 * After the items are updated, the DataSet will trigger an event `update`.
28344 * When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
28345 *
28346 * ## Example
28347 *
28348 * ```javascript
28349 * // create a DataSet
28350 * const data = new vis.DataSet([
28351 * { id: 1, text: 'item 1' },
28352 * { id: 2, text: 'item 2' },
28353 * { id: 3, text: 'item 3' },
28354 * ])
28355 *
28356 * // update items
28357 * const ids = data.update([
28358 * { id: 2, text: 'item 2 (updated)' }, // works
28359 * // { id: 4, text: 'item 4 (new)' }, // would throw
28360 * // { text: 'item 4 (new)' }, // would also throw
28361 * ])
28362 *
28363 * console.log(ids) // [2]
28364 * ```
28365 *
28366 * @param data - Updates (the id and optionally other props) to the items in this data set.
28367 * @param senderId - Sender id.
28368 *
28369 * @returns updatedIds - The ids of the updated items.
28370 *
28371 * @throws When the supplied data is neither an item nor an array of items, when the ids are missing.
28372 */
28373
28374 }, {
28375 key: "updateOnly",
28376 value: function updateOnly(data, senderId) {
28377 var _this4 = this;
28378
28379 if (!Array.isArray(data)) {
28380 data = [data];
28381 }
28382
28383 var updateEventData = data.map(function (update) {
28384 var oldData = _this4._data.get(update[_this4._idProp]);
28385
28386 if (oldData == null) {
28387 throw new Error("Updating non-existent items is not allowed.");
28388 }
28389
28390 return {
28391 oldData: oldData,
28392 update: update
28393 };
28394 }).map(function (_ref) {
28395 var oldData = _ref.oldData,
28396 update = _ref.update;
28397 var id = oldData[_this4._idProp];
28398 var updatedData = deepExtend$1(deepExtend$1({}, oldData), update);
28399
28400 _this4._data.set(id, updatedData);
28401
28402 return {
28403 id: id,
28404 oldData: oldData,
28405 updatedData: updatedData
28406 };
28407 });
28408
28409 if (updateEventData.length) {
28410 var props = {
28411 items: updateEventData.map(function (value) {
28412 return value.id;
28413 }),
28414 oldData: updateEventData.map(function (value) {
28415 return value.oldData;
28416 }),
28417 data: updateEventData.map(function (value) {
28418 return value.updatedData;
28419 })
28420 }; // TODO: remove deprecated property 'data' some day
28421 //Object.defineProperty(props, 'data', {
28422 // 'get': (function() {
28423 // 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');
28424 // return updatedData;
28425 // }).bind(this)
28426 //});
28427
28428 this._trigger("update", props, senderId);
28429
28430 return props.items;
28431 } else {
28432 return [];
28433 }
28434 }
28435 /** @inheritdoc */
28436
28437 }, {
28438 key: "get",
28439 value: function get(first, second) {
28440 // @TODO: Woudn't it be better to split this into multiple methods?
28441 // parse the arguments
28442 var id = undefined;
28443 var ids = undefined;
28444 var options = undefined;
28445
28446 if (isId(first)) {
28447 // get(id [, options])
28448 id = first;
28449 options = second;
28450 } else if (Array.isArray(first)) {
28451 // get(ids [, options])
28452 ids = first;
28453 options = second;
28454 } else {
28455 // get([, options])
28456 options = first;
28457 } // determine the return type
28458
28459
28460 var returnType = options && options.returnType === "Object" ? "Object" : "Array"; // @TODO: WTF is this? Or am I missing something?
28461 // var returnType
28462 // if (options && options.returnType) {
28463 // var allowedValues = ['Array', 'Object']
28464 // returnType =
28465 // allowedValues.indexOf(options.returnType) == -1
28466 // ? 'Array'
28467 // : options.returnType
28468 // } else {
28469 // returnType = 'Array'
28470 // }
28471 // build options
28472
28473 var type = options && options.type || this._options.type;
28474 var filter = options && options.filter;
28475 var items = [];
28476 var item = null;
28477 var itemIds = null;
28478 var itemId = null; // convert items
28479
28480 if (id != null) {
28481 // return a single item
28482 item = this._getItem(id, type);
28483
28484 if (item && filter && !filter(item)) {
28485 item = null;
28486 }
28487 } else if (ids != null) {
28488 // return a subset of items
28489 for (var i = 0, len = ids.length; i < len; i++) {
28490 item = this._getItem(ids[i], type);
28491
28492 if (item != null && (!filter || filter(item))) {
28493 items.push(item);
28494 }
28495 }
28496 } else {
28497 // return all items
28498 itemIds = toConsumableArray(this._data.keys());
28499
28500 for (var _i = 0, _len = itemIds.length; _i < _len; _i++) {
28501 itemId = itemIds[_i];
28502 item = this._getItem(itemId, type);
28503
28504 if (item != null && (!filter || filter(item))) {
28505 items.push(item);
28506 }
28507 }
28508 } // order the results
28509
28510
28511 if (options && options.order && id == undefined) {
28512 this._sort(items, options.order);
28513 } // filter fields of the items
28514
28515
28516 if (options && options.fields) {
28517 var fields = options.fields;
28518
28519 if (id != undefined && item != null) {
28520 item = this._filterFields(item, fields);
28521 } else {
28522 for (var _i2 = 0, _len2 = items.length; _i2 < _len2; _i2++) {
28523 items[_i2] = this._filterFields(items[_i2], fields);
28524 }
28525 }
28526 } // return the results
28527
28528
28529 if (returnType == "Object") {
28530 var result = {};
28531
28532 for (var _i3 = 0, _len3 = items.length; _i3 < _len3; _i3++) {
28533 var resultant = items[_i3]; // @TODO: Shoudn't this be this._fieldId?
28534 // result[resultant.id] = resultant
28535
28536 var _id2 = resultant[this._idProp];
28537 result[_id2] = resultant;
28538 }
28539
28540 return result;
28541 } else {
28542 if (id != null) {
28543 // a single item
28544 return item;
28545 } else {
28546 // just return our array
28547 return items;
28548 }
28549 }
28550 }
28551 /** @inheritdoc */
28552
28553 }, {
28554 key: "getIds",
28555 value: function getIds(options) {
28556 var data = this._data;
28557 var filter = options && options.filter;
28558 var order = options && options.order;
28559 var type = options && options.type || this._options.type;
28560 var itemIds = toConsumableArray(data.keys());
28561 var ids = [];
28562 var item;
28563 var items;
28564
28565 if (filter) {
28566 // get filtered items
28567 if (order) {
28568 // create ordered list
28569 items = [];
28570
28571 for (var i = 0, len = itemIds.length; i < len; i++) {
28572 var id = itemIds[i];
28573 item = this._getItem(id, type);
28574
28575 if (filter(item)) {
28576 items.push(item);
28577 }
28578 }
28579
28580 this._sort(items, order);
28581
28582 for (var _i4 = 0, _len4 = items.length; _i4 < _len4; _i4++) {
28583 ids.push(items[_i4][this._idProp]);
28584 }
28585 } else {
28586 // create unordered list
28587 for (var _i5 = 0, _len5 = itemIds.length; _i5 < _len5; _i5++) {
28588 var _id3 = itemIds[_i5];
28589 item = this._getItem(_id3, type);
28590
28591 if (filter(item)) {
28592 ids.push(item[this._idProp]);
28593 }
28594 }
28595 }
28596 } else {
28597 // get all items
28598 if (order) {
28599 // create an ordered list
28600 items = [];
28601
28602 for (var _i6 = 0, _len6 = itemIds.length; _i6 < _len6; _i6++) {
28603 var _id4 = itemIds[_i6];
28604 items.push(data.get(_id4));
28605 }
28606
28607 this._sort(items, order);
28608
28609 for (var _i7 = 0, _len7 = items.length; _i7 < _len7; _i7++) {
28610 ids.push(items[_i7][this._idProp]);
28611 }
28612 } else {
28613 // create unordered list
28614 for (var _i8 = 0, _len8 = itemIds.length; _i8 < _len8; _i8++) {
28615 var _id5 = itemIds[_i8];
28616 item = data.get(_id5);
28617 ids.push(item[this._idProp]);
28618 }
28619 }
28620 }
28621
28622 return ids;
28623 }
28624 /** @inheritdoc */
28625
28626 }, {
28627 key: "getDataSet",
28628 value: function getDataSet() {
28629 return this;
28630 }
28631 /** @inheritdoc */
28632
28633 }, {
28634 key: "forEach",
28635 value: function forEach(callback, options) {
28636 var filter = options && options.filter;
28637 var type = options && options.type || this._options.type;
28638 var data = this._data;
28639 var itemIds = toConsumableArray(data.keys());
28640
28641 if (options && options.order) {
28642 // execute forEach on ordered list
28643 var items = this.get(options);
28644
28645 for (var i = 0, len = items.length; i < len; i++) {
28646 var item = items[i];
28647 var id = item[this._idProp];
28648 callback(item, id);
28649 }
28650 } else {
28651 // unordered
28652 for (var _i9 = 0, _len9 = itemIds.length; _i9 < _len9; _i9++) {
28653 var _id6 = itemIds[_i9];
28654
28655 var _item = this._getItem(_id6, type);
28656
28657 if (!filter || filter(_item)) {
28658 callback(_item, _id6);
28659 }
28660 }
28661 }
28662 }
28663 /** @inheritdoc */
28664
28665 }, {
28666 key: "map",
28667 value: function map(callback, options) {
28668 var filter = options && options.filter;
28669 var type = options && options.type || this._options.type;
28670 var mappedItems = [];
28671 var data = this._data;
28672 var itemIds = toConsumableArray(data.keys()); // convert and filter items
28673
28674 for (var i = 0, len = itemIds.length; i < len; i++) {
28675 var id = itemIds[i];
28676
28677 var item = this._getItem(id, type);
28678
28679 if (!filter || filter(item)) {
28680 mappedItems.push(callback(item, id));
28681 }
28682 } // order items
28683
28684
28685 if (options && options.order) {
28686 this._sort(mappedItems, options.order);
28687 }
28688
28689 return mappedItems;
28690 }
28691 /**
28692 * Filter the fields of an item.
28693 *
28694 * @param item - The item whose fields should be filtered.
28695 * @param fields - The names of the fields that will be kept.
28696 *
28697 * @typeParam K - Field name type.
28698 *
28699 * @returns The item without any additional fields.
28700 */
28701
28702 }, {
28703 key: "_filterFields",
28704 value: function _filterFields(item, fields) {
28705 if (!item) {
28706 // item is null
28707 return item;
28708 }
28709
28710 return (Array.isArray(fields) ? // Use the supplied array
28711 fields : // Use the keys of the supplied object
28712 Object.keys(fields)).reduce(function (filteredItem, field) {
28713 filteredItem[field] = item[field];
28714 return filteredItem;
28715 }, {});
28716 }
28717 /**
28718 * Sort the provided array with items.
28719 *
28720 * @param items - Items to be sorted in place.
28721 * @param order - A field name or custom sort function.
28722 *
28723 * @typeParam T - The type of the items in the items array.
28724 */
28725
28726 }, {
28727 key: "_sort",
28728 value: function _sort(items, order) {
28729 if (typeof order === "string") {
28730 // order by provided field name
28731 var name = order; // field name
28732
28733 items.sort(function (a, b) {
28734 // @TODO: How to treat missing properties?
28735 var av = a[name];
28736 var bv = b[name];
28737 return av > bv ? 1 : av < bv ? -1 : 0;
28738 });
28739 } else if (typeof order === "function") {
28740 // order by sort function
28741 items.sort(order);
28742 } else {
28743 // TODO: extend order by an Object {field:string, direction:string}
28744 // where direction can be 'asc' or 'desc'
28745 throw new TypeError("Order must be a function or a string");
28746 }
28747 }
28748 /**
28749 * Remove an item or multiple items by “reference” (only the id is used) or by id.
28750 *
28751 * 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.
28752 *
28753 * 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.
28754 *
28755 * ## Example
28756 * ```javascript
28757 * // create a DataSet
28758 * const data = new vis.DataSet([
28759 * { id: 1, text: 'item 1' },
28760 * { id: 2, text: 'item 2' },
28761 * { id: 3, text: 'item 3' }
28762 * ])
28763 *
28764 * // remove items
28765 * const ids = data.remove([2, { id: 3 }, 4])
28766 *
28767 * console.log(ids) // [2, 3]
28768 * ```
28769 *
28770 * @param id - One or more items or ids of items to be removed.
28771 * @param senderId - Sender id.
28772 *
28773 * @returns The ids of the removed items.
28774 */
28775
28776 }, {
28777 key: "remove",
28778 value: function remove(id, senderId) {
28779 var removedIds = [];
28780 var removedItems = []; // force everything to be an array for simplicity
28781
28782 var ids = Array.isArray(id) ? id : [id];
28783
28784 for (var i = 0, len = ids.length; i < len; i++) {
28785 var item = this._remove(ids[i]);
28786
28787 if (item) {
28788 var itemId = item[this._idProp];
28789
28790 if (itemId != null) {
28791 removedIds.push(itemId);
28792 removedItems.push(item);
28793 }
28794 }
28795 }
28796
28797 if (removedIds.length) {
28798 this._trigger("remove", {
28799 items: removedIds,
28800 oldData: removedItems
28801 }, senderId);
28802 }
28803
28804 return removedIds;
28805 }
28806 /**
28807 * Remove an item by its id or reference.
28808 *
28809 * @param id - Id of an item or the item itself.
28810 *
28811 * @returns The removed item if removed, null otherwise.
28812 */
28813
28814 }, {
28815 key: "_remove",
28816 value: function _remove(id) {
28817 // @TODO: It origianlly returned the item although the docs say id.
28818 // The code expects the item, so probably an error in the docs.
28819 var ident; // confirm the id to use based on the args type
28820
28821 if (isId(id)) {
28822 ident = id;
28823 } else if (id && _typeof_1(id) === "object") {
28824 ident = id[this._idProp]; // look for the identifier field using ._idProp
28825 } // do the removing if the item is found
28826
28827
28828 if (ident != null && this._data.has(ident)) {
28829 var item = this._data.get(ident) || null;
28830
28831 this._data.delete(ident);
28832
28833 --this.length;
28834 return item;
28835 }
28836
28837 return null;
28838 }
28839 /**
28840 * Clear the entire data set.
28841 *
28842 * 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.
28843 *
28844 * @param senderId - Sender id.
28845 *
28846 * @returns removedIds - The ids of all removed items.
28847 */
28848
28849 }, {
28850 key: "clear",
28851 value: function clear(senderId) {
28852 var ids = toConsumableArray(this._data.keys());
28853 var items = [];
28854
28855 for (var i = 0, len = ids.length; i < len; i++) {
28856 items.push(this._data.get(ids[i]));
28857 }
28858
28859 this._data.clear();
28860
28861 this.length = 0;
28862
28863 this._trigger("remove", {
28864 items: ids,
28865 oldData: items
28866 }, senderId);
28867
28868 return ids;
28869 }
28870 /**
28871 * Find the item with maximum value of a specified field.
28872 *
28873 * @param field - Name of the property that should be searched for max value.
28874 *
28875 * @returns Item containing max value, or null if no items.
28876 */
28877
28878 }, {
28879 key: "max",
28880 value: function max(field) {
28881 var max = null;
28882 var maxField = null;
28883 var _iteratorNormalCompletion = true;
28884 var _didIteratorError = false;
28885 var _iteratorError = undefined;
28886
28887 try {
28888 for (var _iterator = this._data.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
28889 var item = _step.value;
28890 var itemField = item[field];
28891
28892 if (typeof itemField === "number" && (maxField == null || itemField > maxField)) {
28893 max = item;
28894 maxField = itemField;
28895 }
28896 }
28897 } catch (err) {
28898 _didIteratorError = true;
28899 _iteratorError = err;
28900 } finally {
28901 try {
28902 if (!_iteratorNormalCompletion && _iterator.return != null) {
28903 _iterator.return();
28904 }
28905 } finally {
28906 if (_didIteratorError) {
28907 throw _iteratorError;
28908 }
28909 }
28910 }
28911
28912 return max || null;
28913 }
28914 /**
28915 * Find the item with minimum value of a specified field.
28916 *
28917 * @param field - Name of the property that should be searched for min value.
28918 *
28919 * @returns Item containing min value, or null if no items.
28920 */
28921
28922 }, {
28923 key: "min",
28924 value: function min(field) {
28925 var min = null;
28926 var minField = null;
28927 var _iteratorNormalCompletion2 = true;
28928 var _didIteratorError2 = false;
28929 var _iteratorError2 = undefined;
28930
28931 try {
28932 for (var _iterator2 = this._data.values()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
28933 var item = _step2.value;
28934 var itemField = item[field];
28935
28936 if (typeof itemField === "number" && (minField == null || itemField < minField)) {
28937 min = item;
28938 minField = itemField;
28939 }
28940 }
28941 } catch (err) {
28942 _didIteratorError2 = true;
28943 _iteratorError2 = err;
28944 } finally {
28945 try {
28946 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
28947 _iterator2.return();
28948 }
28949 } finally {
28950 if (_didIteratorError2) {
28951 throw _iteratorError2;
28952 }
28953 }
28954 }
28955
28956 return min || null;
28957 }
28958 /**
28959 * Find all distinct values of a specified field
28960 *
28961 * @param prop - The property name whose distinct values should be returned.
28962 *
28963 * @returns Unordered array containing all distinct values. Items without specified property are ignored.
28964 */
28965
28966 }, {
28967 key: "distinct",
28968 value: function distinct(prop) {
28969 var data = this._data;
28970 var itemIds = toConsumableArray(data.keys());
28971 var values = [];
28972 var fieldType = this._options.type && this._options.type[prop] || null;
28973 var count = 0;
28974
28975 for (var i = 0, len = itemIds.length; i < len; i++) {
28976 var id = itemIds[i];
28977 var item = data.get(id);
28978 var value = item[prop];
28979 var exists = false;
28980
28981 for (var j = 0; j < count; j++) {
28982 if (values[j] == value) {
28983 exists = true;
28984 break;
28985 }
28986 }
28987
28988 if (!exists && value !== undefined) {
28989 values[count] = value;
28990 count++;
28991 }
28992 }
28993
28994 if (fieldType) {
28995 for (var _i10 = 0, _len10 = values.length; _i10 < _len10; _i10++) {
28996 values[_i10] = convert$1(values[_i10], fieldType);
28997 }
28998 }
28999
29000 return values;
29001 }
29002 /**
29003 * Add a single item. Will fail when an item with the same id already exists.
29004 *
29005 * @param item - A new item to be added.
29006 *
29007 * @returns Added item's id. An id is generated when it is not present in the item.
29008 */
29009
29010 }, {
29011 key: "_addItem",
29012 value: function _addItem(item) {
29013 var id = item[this._idProp];
29014
29015 if (id != null) {
29016 // check whether this id is already taken
29017 if (this._data.has(id)) {
29018 // item already exists
29019 throw new Error("Cannot add item: item with id " + id + " already exists");
29020 }
29021 } else {
29022 // generate an id
29023 id = uuid4$1();
29024 item[this._idProp] = id;
29025 }
29026
29027 var d = {};
29028 var fields = Object.keys(item);
29029
29030 for (var i = 0, len = fields.length; i < len; i++) {
29031 var field = fields[i];
29032 var fieldType = this._type[field]; // type may be undefined
29033
29034 d[field] = convert$1(item[field], fieldType);
29035 }
29036
29037 this._data.set(id, d);
29038
29039 ++this.length;
29040 return id;
29041 }
29042 /**
29043 * Get an item. Fields can be converted to a specific type
29044 *
29045 * @param id - Id of the requested item.
29046 * @param types - Property name to type name object map of type converstions.
29047 *
29048 * @returns The item, optionally after type conversion.
29049 */
29050
29051 }, {
29052 key: "_getItem",
29053 value: function _getItem(id, types) {
29054 // @TODO: I have no idea how to type this.
29055 // get the item from the dataset
29056 var raw = this._data.get(id);
29057
29058 if (!raw) {
29059 return null;
29060 } // convert the items field types
29061
29062
29063 var converted;
29064 var fields = Object.keys(raw);
29065
29066 if (types) {
29067 converted = {};
29068
29069 for (var i = 0, len = fields.length; i < len; i++) {
29070 var field = fields[i];
29071 var value = raw[field];
29072 converted[field] = convert$1(value, types[field]);
29073 }
29074 } else {
29075 // no field types specified, no converting needed
29076 converted = _objectSpread({}, raw);
29077 }
29078
29079 if (converted[this._idProp] == null) {
29080 converted[this._idProp] = raw.id;
29081 }
29082
29083 return converted;
29084 }
29085 /**
29086 * Update a single item: merge with existing item.
29087 * Will fail when the item has no id, or when there does not exist an item with the same id.
29088 *
29089 * @param item - The new item
29090 *
29091 * @returns The id of the updated item.
29092 */
29093
29094 }, {
29095 key: "_updateItem",
29096 value: function _updateItem(item) {
29097 var id = item[this._idProp];
29098
29099 if (id == null) {
29100 throw new Error("Cannot update item: item has no id (item: " + JSON.stringify(item) + ")");
29101 }
29102
29103 var d = this._data.get(id);
29104
29105 if (!d) {
29106 // item doesn't exist
29107 throw new Error("Cannot update item: no item with id " + id + " found");
29108 } // merge with current item
29109
29110
29111 var fields = Object.keys(item);
29112
29113 for (var i = 0, len = fields.length; i < len; i++) {
29114 var field = fields[i];
29115 var fieldType = this._type[field]; // type may be undefined
29116
29117 d[field] = convert$1(item[field], fieldType);
29118 }
29119
29120 return id;
29121 }
29122 /** @inheritdoc */
29123
29124 }, {
29125 key: "stream",
29126 value: function stream(ids) {
29127 if (ids) {
29128 var data = this._data;
29129 return new DataStream(defineProperty$a({}, Symbol.iterator,
29130 /*#__PURE__*/
29131 regenerator.mark(function _callee() {
29132 var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, id, item;
29133
29134 return regenerator.wrap(function _callee$(_context) {
29135 while (1) {
29136 switch (_context.prev = _context.next) {
29137 case 0:
29138 _iteratorNormalCompletion3 = true;
29139 _didIteratorError3 = false;
29140 _iteratorError3 = undefined;
29141 _context.prev = 3;
29142 _iterator3 = ids[Symbol.iterator]();
29143
29144 case 5:
29145 if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
29146 _context.next = 14;
29147 break;
29148 }
29149
29150 id = _step3.value;
29151 item = data.get(id);
29152
29153 if (!(item != null)) {
29154 _context.next = 11;
29155 break;
29156 }
29157
29158 _context.next = 11;
29159 return [id, item];
29160
29161 case 11:
29162 _iteratorNormalCompletion3 = true;
29163 _context.next = 5;
29164 break;
29165
29166 case 14:
29167 _context.next = 20;
29168 break;
29169
29170 case 16:
29171 _context.prev = 16;
29172 _context.t0 = _context["catch"](3);
29173 _didIteratorError3 = true;
29174 _iteratorError3 = _context.t0;
29175
29176 case 20:
29177 _context.prev = 20;
29178 _context.prev = 21;
29179
29180 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
29181 _iterator3.return();
29182 }
29183
29184 case 23:
29185 _context.prev = 23;
29186
29187 if (!_didIteratorError3) {
29188 _context.next = 26;
29189 break;
29190 }
29191
29192 throw _iteratorError3;
29193
29194 case 26:
29195 return _context.finish(23);
29196
29197 case 27:
29198 return _context.finish(20);
29199
29200 case 28:
29201 case "end":
29202 return _context.stop();
29203 }
29204 }
29205 }, _callee, null, [[3, 16, 20, 28], [21,, 23, 27]]);
29206 })));
29207 } else {
29208 return new DataStream(defineProperty$a({}, Symbol.iterator, this._data.entries.bind(this._data)));
29209 }
29210 }
29211 }]);
29212 return DataSet;
29213 }(DataSetPart);
29214 /**
29215 * DataView
29216 *
29217 * 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.
29218 *
29219 * ## Example
29220 * ```javascript
29221 * // create a DataSet
29222 * var data = new vis.DataSet();
29223 * data.add([
29224 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
29225 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
29226 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
29227 * {id: 4, text: 'item 4'}
29228 * ]);
29229 *
29230 * // create a DataView
29231 * // the view will only contain items having a property group with value 1,
29232 * // and will only output fields id, text, and date.
29233 * var view = new vis.DataView(data, {
29234 * filter: function (item) {
29235 * return (item.group == 1);
29236 * },
29237 * fields: ['id', 'text', 'date']
29238 * });
29239 *
29240 * // subscribe to any change in the DataView
29241 * view.on('*', function (event, properties, senderId) {
29242 * console.log('event', event, properties);
29243 * });
29244 *
29245 * // update an item in the data set
29246 * data.update({id: 2, group: 1});
29247 *
29248 * // get all ids in the view
29249 * var ids = view.getIds();
29250 * console.log('ids', ids); // will output [1, 2]
29251 *
29252 * // get all items in the view
29253 * var items = view.get();
29254 * ```
29255 *
29256 * @typeParam Item - Item type that may or may not have an id.
29257 * @typeParam IdProp - Name of the property that contains the id.
29258 */
29259
29260
29261 var DataView$2 =
29262 /*#__PURE__*/
29263 function (_DataSetPart) {
29264 inherits(DataView, _DataSetPart);
29265 /**
29266 * Create a DataView.
29267 *
29268 * @param data - The instance containing data (directly or indirectly).
29269 * @param options - Options to configure this data view.
29270 */
29271
29272 function DataView(data, options) {
29273 var _this;
29274
29275 classCallCheck(this, DataView);
29276 _this = possibleConstructorReturn(this, getPrototypeOf(DataView).call(this));
29277 /** @inheritdoc */
29278
29279 _this.length = 0;
29280 _this._ids = new Set(); // ids of the items currently in memory (just contains a boolean true)
29281
29282 _this._options = options || {};
29283 _this._listener = _this._onEvent.bind(assertThisInitialized(_this));
29284
29285 _this.setData(data);
29286
29287 return _this;
29288 } // TODO: implement a function .config() to dynamically update things like configured filter
29289 // and trigger changes accordingly
29290
29291 /**
29292 * Set a data source for the view.
29293 *
29294 * @param data - The instance containing data (directly or indirectly).
29295 */
29296
29297
29298 createClass(DataView, [{
29299 key: "setData",
29300 value: function setData(data) {
29301 if (this._data) {
29302 // unsubscribe from current dataset
29303 if (this._data.off) {
29304 this._data.off("*", this._listener);
29305 } // trigger a remove of all items in memory
29306
29307
29308 var ids = this._data.getIds({
29309 filter: this._options.filter
29310 });
29311
29312 var items = this._data.get(ids);
29313
29314 this._ids.clear();
29315
29316 this.length = 0;
29317
29318 this._trigger("remove", {
29319 items: ids,
29320 oldData: items
29321 });
29322 }
29323
29324 if (data != null) {
29325 this._data = data; // trigger an add of all added items
29326
29327 var _ids = this._data.getIds({
29328 filter: this._options.filter
29329 });
29330
29331 for (var i = 0, len = _ids.length; i < len; i++) {
29332 var id = _ids[i];
29333
29334 this._ids.add(id);
29335 }
29336
29337 this.length = _ids.length;
29338
29339 this._trigger("add", {
29340 items: _ids
29341 });
29342 } else {
29343 this._data = new DataSet();
29344 } // subscribe to new dataset
29345
29346
29347 if (this._data.on) {
29348 this._data.on("*", this._listener);
29349 }
29350 }
29351 /**
29352 * Refresh the DataView.
29353 * Useful when the DataView has a filter function containing a variable parameter.
29354 */
29355
29356 }, {
29357 key: "refresh",
29358 value: function refresh() {
29359 var ids = this._data.getIds({
29360 filter: this._options.filter
29361 });
29362
29363 var oldIds = toConsumableArray(this._ids);
29364 var newIds = {};
29365 var addedIds = [];
29366 var removedIds = [];
29367 var removedItems = []; // check for additions
29368
29369 for (var i = 0, len = ids.length; i < len; i++) {
29370 var id = ids[i];
29371 newIds[id] = true;
29372
29373 if (!this._ids.has(id)) {
29374 addedIds.push(id);
29375
29376 this._ids.add(id);
29377 }
29378 } // check for removals
29379
29380
29381 for (var _i = 0, _len = oldIds.length; _i < _len; _i++) {
29382 var _id = oldIds[_i];
29383
29384 var item = this._data.get(_id);
29385
29386 if (item == null) {
29387 // @TODO: Investigate.
29388 // Doesn't happen during tests or examples.
29389 // Is it really impossible or could it eventually happen?
29390 // How to handle it if it does? The types guarantee non-nullable items.
29391 console.error("If you see this, report it please.");
29392 } else if (!newIds[_id]) {
29393 removedIds.push(_id);
29394 removedItems.push(item);
29395
29396 this._ids.delete(_id);
29397 }
29398 }
29399
29400 this.length += addedIds.length - removedIds.length; // trigger events
29401
29402 if (addedIds.length) {
29403 this._trigger("add", {
29404 items: addedIds
29405 });
29406 }
29407
29408 if (removedIds.length) {
29409 this._trigger("remove", {
29410 items: removedIds,
29411 oldData: removedItems
29412 });
29413 }
29414 }
29415 /** @inheritdoc */
29416
29417 }, {
29418 key: "get",
29419 value: function get(first, second) {
29420 if (this._data == null) {
29421 return null;
29422 } // parse the arguments
29423
29424
29425 var ids = null;
29426 var options;
29427
29428 if (isId(first) || Array.isArray(first)) {
29429 ids = first;
29430 options = second;
29431 } else {
29432 options = first;
29433 } // extend the options with the default options and provided options
29434
29435
29436 var viewOptions = Object.assign({}, this._options, options); // create a combined filter method when needed
29437
29438 var thisFilter = this._options.filter;
29439 var optionsFilter = options && options.filter;
29440
29441 if (thisFilter && optionsFilter) {
29442 viewOptions.filter = function (item) {
29443 return thisFilter(item) && optionsFilter(item);
29444 };
29445 }
29446
29447 if (ids == null) {
29448 return this._data.get(viewOptions);
29449 } else {
29450 return this._data.get(ids, viewOptions);
29451 }
29452 }
29453 /** @inheritdoc */
29454
29455 }, {
29456 key: "getIds",
29457 value: function getIds(options) {
29458 if (this._data.length) {
29459 var defaultFilter = this._options.filter;
29460 var optionsFilter = options != null ? options.filter : null;
29461 var filter;
29462
29463 if (optionsFilter) {
29464 if (defaultFilter) {
29465 filter = function filter(item) {
29466 return defaultFilter(item) && optionsFilter(item);
29467 };
29468 } else {
29469 filter = optionsFilter;
29470 }
29471 } else {
29472 filter = defaultFilter;
29473 }
29474
29475 return this._data.getIds({
29476 filter: filter,
29477 order: options && options.order
29478 });
29479 } else {
29480 return [];
29481 }
29482 }
29483 /** @inheritdoc */
29484
29485 }, {
29486 key: "forEach",
29487 value: function forEach(callback, options) {
29488 if (this._data) {
29489 var defaultFilter = this._options.filter;
29490 var optionsFilter = options && options.filter;
29491 var filter;
29492
29493 if (optionsFilter) {
29494 if (defaultFilter) {
29495 filter = function filter(item) {
29496 return defaultFilter(item) && optionsFilter(item);
29497 };
29498 } else {
29499 filter = optionsFilter;
29500 }
29501 } else {
29502 filter = defaultFilter;
29503 }
29504
29505 this._data.forEach(callback, {
29506 filter: filter,
29507 order: options && options.order
29508 });
29509 }
29510 }
29511 /** @inheritdoc */
29512
29513 }, {
29514 key: "map",
29515 value: function map(callback, options) {
29516 if (this._data) {
29517 var defaultFilter = this._options.filter;
29518 var optionsFilter = options && options.filter;
29519 var filter;
29520
29521 if (optionsFilter) {
29522 if (defaultFilter) {
29523 filter = function filter(item) {
29524 return defaultFilter(item) && optionsFilter(item);
29525 };
29526 } else {
29527 filter = optionsFilter;
29528 }
29529 } else {
29530 filter = defaultFilter;
29531 }
29532
29533 return this._data.map(callback, {
29534 filter: filter,
29535 order: options && options.order
29536 });
29537 } else {
29538 return [];
29539 }
29540 }
29541 /** @inheritdoc */
29542
29543 }, {
29544 key: "getDataSet",
29545 value: function getDataSet() {
29546 return this._data.getDataSet();
29547 }
29548 /** @inheritdoc */
29549
29550 }, {
29551 key: "stream",
29552 value: function stream(ids) {
29553 return this._data.stream(ids || defineProperty$a({}, Symbol.iterator, this._ids.keys.bind(this._ids)));
29554 }
29555 /**
29556 * 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.
29557 *
29558 * @param event - The name of the event.
29559 * @param params - Parameters of the event.
29560 * @param senderId - Id supplied by the sender.
29561 */
29562
29563 }, {
29564 key: "_onEvent",
29565 value: function _onEvent(event, params, senderId) {
29566 if (!params || !params.items || !this._data) {
29567 return;
29568 }
29569
29570 var ids = params.items;
29571 var addedIds = [];
29572 var updatedIds = [];
29573 var removedIds = [];
29574 var oldItems = [];
29575 var updatedItems = [];
29576 var removedItems = [];
29577
29578 switch (event) {
29579 case "add":
29580 // filter the ids of the added items
29581 for (var i = 0, len = ids.length; i < len; i++) {
29582 var id = ids[i];
29583 var item = this.get(id);
29584
29585 if (item) {
29586 this._ids.add(id);
29587
29588 addedIds.push(id);
29589 }
29590 }
29591
29592 break;
29593
29594 case "update":
29595 // determine the event from the views viewpoint: an updated
29596 // item can be added, updated, or removed from this view.
29597 for (var _i2 = 0, _len2 = ids.length; _i2 < _len2; _i2++) {
29598 var _id2 = ids[_i2];
29599
29600 var _item = this.get(_id2);
29601
29602 if (_item) {
29603 if (this._ids.has(_id2)) {
29604 updatedIds.push(_id2);
29605 updatedItems.push(params.data[_i2]);
29606 oldItems.push(params.oldData[_i2]);
29607 } else {
29608 this._ids.add(_id2);
29609
29610 addedIds.push(_id2);
29611 }
29612 } else {
29613 if (this._ids.has(_id2)) {
29614 this._ids.delete(_id2);
29615
29616 removedIds.push(_id2);
29617 removedItems.push(params.oldData[_i2]);
29618 }
29619 }
29620 }
29621
29622 break;
29623
29624 case "remove":
29625 // filter the ids of the removed items
29626 for (var _i3 = 0, _len3 = ids.length; _i3 < _len3; _i3++) {
29627 var _id3 = ids[_i3];
29628
29629 if (this._ids.has(_id3)) {
29630 this._ids.delete(_id3);
29631
29632 removedIds.push(_id3);
29633 removedItems.push(params.oldData[_i3]);
29634 }
29635 }
29636
29637 break;
29638 }
29639
29640 this.length += addedIds.length - removedIds.length;
29641
29642 if (addedIds.length) {
29643 this._trigger("add", {
29644 items: addedIds
29645 }, senderId);
29646 }
29647
29648 if (updatedIds.length) {
29649 this._trigger("update", {
29650 items: updatedIds,
29651 oldData: oldItems,
29652 data: updatedItems
29653 }, senderId);
29654 }
29655
29656 if (removedIds.length) {
29657 this._trigger("remove", {
29658 items: removedIds,
29659 oldData: removedItems
29660 }, senderId);
29661 }
29662 }
29663 }]);
29664 return DataView;
29665 }(DataSetPart);
29666
29667 var index$2 = {
29668 DataSet: DataSet,
29669 DataView: DataView$2,
29670 Queue: Queue
29671 };
29672
29673 var esm$1 = /*#__PURE__*/Object.freeze({
29674 __proto__: null,
29675 'default': index$2,
29676 DataSet: DataSet,
29677 DataStream: DataStream,
29678 DataView: DataView$2,
29679 Queue: Queue
29680 });
29681
29682 /**
29683 * Helper functions for components
29684 * @class
29685 */
29686
29687 var ComponentUtil =
29688 /*#__PURE__*/
29689 function () {
29690 function ComponentUtil() {
29691 _classCallCheck(this, ComponentUtil);
29692 }
29693
29694 _createClass(ComponentUtil, null, [{
29695 key: "choosify",
29696
29697 /**
29698 * Determine values to use for (sub)options of 'chosen'.
29699 *
29700 * This option is either a boolean or an object whose values should be examined further.
29701 * The relevant structures are:
29702 *
29703 * - chosen: <boolean value>
29704 * - chosen: { subOption: <boolean or function> }
29705 *
29706 * Where subOption is 'node', 'edge' or 'label'.
29707 *
29708 * The intention of this method appears to be to set a specific priority to the options;
29709 * Since most properties are either bridged or merged into the local options objects, there
29710 * is not much point in handling them separately.
29711 * TODO: examine if 'most' in previous sentence can be replaced with 'all'. In that case, we
29712 * should be able to get rid of this method.
29713 *
29714 * @param {string} subOption option within object 'chosen' to consider; either 'node', 'edge' or 'label'
29715 * @param {Object} pile array of options objects to consider
29716 *
29717 * @return {boolean|function} value for passed subOption of 'chosen' to use
29718 */
29719 value: function choosify(subOption, pile) {
29720 // allowed values for subOption
29721 var allowed = ['node', 'edge', 'label'];
29722 var value = true;
29723 var chosen = topMost(pile, 'chosen');
29724
29725 if (typeof chosen === 'boolean') {
29726 value = chosen;
29727 } else if (_typeof(chosen) === 'object') {
29728 if (allowed.indexOf(subOption) === -1) {
29729 throw new Error('choosify: subOption \'' + subOption + '\' should be one of ' + "'" + allowed.join("', '") + "'");
29730 }
29731
29732 var chosenEdge = topMost(pile, ['chosen', subOption]);
29733
29734 if (typeof chosenEdge === 'boolean' || typeof chosenEdge === 'function') {
29735 value = chosenEdge;
29736 }
29737 }
29738
29739 return value;
29740 }
29741 /**
29742 * Check if the point falls within the given rectangle.
29743 *
29744 * @param {rect} rect
29745 * @param {point} point
29746 * @param {rotationPoint} [rotationPoint] if specified, the rotation that applies to the rectangle.
29747 * @returns {boolean} true if point within rectangle, false otherwise
29748 * @static
29749 */
29750
29751 }, {
29752 key: "pointInRect",
29753 value: function pointInRect(rect, point, rotationPoint) {
29754 if (rect.width <= 0 || rect.height <= 0) {
29755 return false; // early out
29756 }
29757
29758 if (rotationPoint !== undefined) {
29759 // Rotate the point the same amount as the rectangle
29760 var tmp = {
29761 x: point.x - rotationPoint.x,
29762 y: point.y - rotationPoint.y
29763 };
29764
29765 if (rotationPoint.angle !== 0) {
29766 // In order to get the coordinates the same, you need to
29767 // rotate in the reverse direction
29768 var angle = -rotationPoint.angle;
29769 var tmp2 = {
29770 x: Math.cos(angle) * tmp.x - Math.sin(angle) * tmp.y,
29771 y: Math.sin(angle) * tmp.x + Math.cos(angle) * tmp.y
29772 };
29773 point = tmp2;
29774 } else {
29775 point = tmp;
29776 } // Note that if a rotation is specified, the rectangle coordinates
29777 // are **not* the full canvas coordinates. They are relative to the
29778 // rotationPoint. Hence, the point coordinates need not be translated
29779 // back in this case.
29780
29781 }
29782
29783 var right = rect.x + rect.width;
29784 var bottom = rect.y + rect.width;
29785 return rect.left < point.x && right > point.x && rect.top < point.y && bottom > point.y;
29786 }
29787 /**
29788 * Check if given value is acceptable as a label text.
29789 *
29790 * @param {*} text value to check; can be anything at this point
29791 * @returns {boolean} true if valid label value, false otherwise
29792 */
29793
29794 }, {
29795 key: "isValidLabel",
29796 value: function isValidLabel(text) {
29797 // Note that this is quite strict: types that *might* be converted to string are disallowed
29798 return typeof text === 'string' && text !== '';
29799 }
29800 }]);
29801
29802 return ComponentUtil;
29803 }();
29804
29805 // `String.prototype.bold` method
29806 // https://tc39.github.io/ecma262/#sec-string.prototype.bold
29807 _export({ target: 'String', proto: true, forced: forcedStringHtmlMethod('bold') }, {
29808 bold: function bold() {
29809 return createHtml(this, 'b', '', '');
29810 }
29811 });
29812
29813 /**
29814 * Callback to determine text dimensions, using the parent label settings.
29815 * @callback MeasureText
29816 * @param {text} text
29817 * @param {text} mod
29818 * @return {Object} { width, values} width in pixels and font attributes
29819 */
29820
29821 /**
29822 * Helper class for Label which collects results of splitting labels into lines and blocks.
29823 *
29824 * @private
29825 */
29826 var LabelAccumulator =
29827 /*#__PURE__*/
29828 function () {
29829 /**
29830 * @param {MeasureText} measureText
29831 */
29832 function LabelAccumulator(measureText) {
29833 _classCallCheck(this, LabelAccumulator);
29834
29835 this.measureText = measureText;
29836 this.current = 0;
29837 this.width = 0;
29838 this.height = 0;
29839 this.lines = [];
29840 }
29841 /**
29842 * Append given text to the given line.
29843 *
29844 * @param {number} l index of line to add to
29845 * @param {string} text string to append to line
29846 * @param {'bold'|'ital'|'boldital'|'mono'|'normal'} [mod='normal']
29847 * @private
29848 */
29849
29850
29851 _createClass(LabelAccumulator, [{
29852 key: "_add",
29853 value: function _add(l, text) {
29854 var mod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'normal';
29855
29856 if (this.lines[l] === undefined) {
29857 this.lines[l] = {
29858 width: 0,
29859 height: 0,
29860 blocks: []
29861 };
29862 } // We still need to set a block for undefined and empty texts, hence return at this point
29863 // This is necessary because we don't know at this point if we're at the
29864 // start of an empty line or not.
29865 // To compensate, empty blocks are removed in `finalize()`.
29866 //
29867 // Empty strings should still have a height
29868
29869
29870 var tmpText = text;
29871 if (text === undefined || text === "") tmpText = " "; // Determine width and get the font properties
29872
29873 var result = this.measureText(tmpText, mod);
29874 var block = Object.assign({}, result.values);
29875 block.text = text;
29876 block.width = result.width;
29877 block.mod = mod;
29878
29879 if (text === undefined || text === "") {
29880 block.width = 0;
29881 }
29882
29883 this.lines[l].blocks.push(block); // Update the line width. We need this for determining if a string goes over max width
29884
29885 this.lines[l].width += block.width;
29886 }
29887 /**
29888 * Returns the width in pixels of the current line.
29889 *
29890 * @returns {number}
29891 */
29892
29893 }, {
29894 key: "curWidth",
29895 value: function curWidth() {
29896 var line = this.lines[this.current];
29897 if (line === undefined) return 0;
29898 return line.width;
29899 }
29900 /**
29901 * Add text in block to current line
29902 *
29903 * @param {string} text
29904 * @param {'bold'|'ital'|'boldital'|'mono'|'normal'} [mod='normal']
29905 */
29906
29907 }, {
29908 key: "append",
29909 value: function append(text) {
29910 var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'normal';
29911
29912 this._add(this.current, text, mod);
29913 }
29914 /**
29915 * Add text in block to current line and start a new line
29916 *
29917 * @param {string} text
29918 * @param {'bold'|'ital'|'boldital'|'mono'|'normal'} [mod='normal']
29919 */
29920
29921 }, {
29922 key: "newLine",
29923 value: function newLine(text) {
29924 var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'normal';
29925
29926 this._add(this.current, text, mod);
29927
29928 this.current++;
29929 }
29930 /**
29931 * Determine and set the heights of all the lines currently contained in this instance
29932 *
29933 * Note that width has already been set.
29934 *
29935 * @private
29936 */
29937
29938 }, {
29939 key: "determineLineHeights",
29940 value: function determineLineHeights() {
29941 for (var k = 0; k < this.lines.length; k++) {
29942 var line = this.lines[k]; // Looking for max height of blocks in line
29943
29944 var height = 0;
29945
29946 if (line.blocks !== undefined) {
29947 // Can happen if text contains e.g. '\n '
29948 for (var l = 0; l < line.blocks.length; l++) {
29949 var block = line.blocks[l];
29950
29951 if (height < block.height) {
29952 height = block.height;
29953 }
29954 }
29955 }
29956
29957 line.height = height;
29958 }
29959 }
29960 /**
29961 * Determine the full size of the label text, as determined by current lines and blocks
29962 *
29963 * @private
29964 */
29965
29966 }, {
29967 key: "determineLabelSize",
29968 value: function determineLabelSize() {
29969 var width = 0;
29970 var height = 0;
29971
29972 for (var k = 0; k < this.lines.length; k++) {
29973 var line = this.lines[k];
29974
29975 if (line.width > width) {
29976 width = line.width;
29977 }
29978
29979 height += line.height;
29980 }
29981
29982 this.width = width;
29983 this.height = height;
29984 }
29985 /**
29986 * Remove all empty blocks and empty lines we don't need
29987 *
29988 * This must be done after the width/height determination,
29989 * so that these are set properly for processing here.
29990 *
29991 * @returns {Array<Line>} Lines with empty blocks (and some empty lines) removed
29992 * @private
29993 */
29994
29995 }, {
29996 key: "removeEmptyBlocks",
29997 value: function removeEmptyBlocks() {
29998 var tmpLines = [];
29999
30000 for (var k = 0; k < this.lines.length; k++) {
30001 var line = this.lines[k]; // Note: an empty line in between text has width zero but is still relevant to layout.
30002 // So we can't use width for testing empty line here
30003
30004 if (line.blocks.length === 0) continue; // Discard final empty line always
30005
30006 if (k === this.lines.length - 1) {
30007 if (line.width === 0) continue;
30008 }
30009
30010 var tmpLine = {};
30011 Object.assign(tmpLine, line);
30012 tmpLine.blocks = [];
30013 var firstEmptyBlock = void 0;
30014 var tmpBlocks = [];
30015
30016 for (var l = 0; l < line.blocks.length; l++) {
30017 var block = line.blocks[l];
30018
30019 if (block.width !== 0) {
30020 tmpBlocks.push(block);
30021 } else {
30022 if (firstEmptyBlock === undefined) {
30023 firstEmptyBlock = block;
30024 }
30025 }
30026 } // Ensure that there is *some* text present
30027
30028
30029 if (tmpBlocks.length === 0 && firstEmptyBlock !== undefined) {
30030 tmpBlocks.push(firstEmptyBlock);
30031 }
30032
30033 tmpLine.blocks = tmpBlocks;
30034 tmpLines.push(tmpLine);
30035 }
30036
30037 return tmpLines;
30038 }
30039 /**
30040 * Set the sizes for all lines and the whole thing.
30041 *
30042 * @returns {{width: (number|*), height: (number|*), lines: Array}}
30043 */
30044
30045 }, {
30046 key: "finalize",
30047 value: function finalize() {
30048 //console.log(JSON.stringify(this.lines, null, 2));
30049 this.determineLineHeights();
30050 this.determineLabelSize();
30051 var tmpLines = this.removeEmptyBlocks(); // Return a simple hash object for further processing.
30052
30053 return {
30054 width: this.width,
30055 height: this.height,
30056 lines: tmpLines
30057 };
30058 }
30059 }]);
30060
30061 return LabelAccumulator;
30062 }();
30063
30064 var tagPattern = {
30065 // HTML
30066 '<b>': /<b>/,
30067 '<i>': /<i>/,
30068 '<code>': /<code>/,
30069 '</b>': /<\/b>/,
30070 '</i>': /<\/i>/,
30071 '</code>': /<\/code>/,
30072 // Markdown
30073 '*': /\*/,
30074 // bold
30075 '_': /\_/,
30076 // ital
30077 '`': /`/,
30078 // mono
30079 'afterBold': /[^\*]/,
30080 'afterItal': /[^_]/,
30081 'afterMono': /[^`]/
30082 };
30083 /**
30084 * Internal helper class for parsing the markup tags for HTML and Markdown.
30085 *
30086 * NOTE: Sequences of tabs and spaces are reduced to single space.
30087 * Scan usage of `this.spacing` within method
30088 */
30089
30090 var MarkupAccumulator =
30091 /*#__PURE__*/
30092 function () {
30093 /**
30094 * Create an instance
30095 *
30096 * @param {string} text text to parse for markup
30097 */
30098 function MarkupAccumulator(text) {
30099 _classCallCheck(this, MarkupAccumulator);
30100
30101 this.text = text;
30102 this.bold = false;
30103 this.ital = false;
30104 this.mono = false;
30105 this.spacing = false;
30106 this.position = 0;
30107 this.buffer = "";
30108 this.modStack = [];
30109 this.blocks = [];
30110 }
30111 /**
30112 * Return the mod label currently on the top of the stack
30113 *
30114 * @returns {string} label of topmost mod
30115 * @private
30116 */
30117
30118
30119 _createClass(MarkupAccumulator, [{
30120 key: "mod",
30121 value: function mod() {
30122 return this.modStack.length === 0 ? 'normal' : this.modStack[0];
30123 }
30124 /**
30125 * Return the mod label currently active
30126 *
30127 * @returns {string} label of active mod
30128 * @private
30129 */
30130
30131 }, {
30132 key: "modName",
30133 value: function modName() {
30134 if (this.modStack.length === 0) return 'normal';else if (this.modStack[0] === 'mono') return 'mono';else {
30135 if (this.bold && this.ital) {
30136 return 'boldital';
30137 } else if (this.bold) {
30138 return 'bold';
30139 } else if (this.ital) {
30140 return 'ital';
30141 }
30142 }
30143 }
30144 /**
30145 * @private
30146 */
30147
30148 }, {
30149 key: "emitBlock",
30150 value: function emitBlock() {
30151 if (this.spacing) {
30152 this.add(" ");
30153 this.spacing = false;
30154 }
30155
30156 if (this.buffer.length > 0) {
30157 this.blocks.push({
30158 text: this.buffer,
30159 mod: this.modName()
30160 });
30161 this.buffer = "";
30162 }
30163 }
30164 /**
30165 * Output text to buffer
30166 *
30167 * @param {string} text text to add
30168 * @private
30169 */
30170
30171 }, {
30172 key: "add",
30173 value: function add(text) {
30174 if (text === " ") {
30175 this.spacing = true;
30176 }
30177
30178 if (this.spacing) {
30179 this.buffer += " ";
30180 this.spacing = false;
30181 }
30182
30183 if (text != " ") {
30184 this.buffer += text;
30185 }
30186 }
30187 /**
30188 * Handle parsing of whitespace
30189 *
30190 * @param {string} ch the character to check
30191 * @returns {boolean} true if the character was processed as whitespace, false otherwise
30192 */
30193
30194 }, {
30195 key: "parseWS",
30196 value: function parseWS(ch) {
30197 if (/[ \t]/.test(ch)) {
30198 if (!this.mono) {
30199 this.spacing = true;
30200 } else {
30201 this.add(ch);
30202 }
30203
30204 return true;
30205 }
30206
30207 return false;
30208 }
30209 /**
30210 * @param {string} tagName label for block type to set
30211 * @private
30212 */
30213
30214 }, {
30215 key: "setTag",
30216 value: function setTag(tagName) {
30217 this.emitBlock();
30218 this[tagName] = true;
30219 this.modStack.unshift(tagName);
30220 }
30221 /**
30222 * @param {string} tagName label for block type to unset
30223 * @private
30224 */
30225
30226 }, {
30227 key: "unsetTag",
30228 value: function unsetTag(tagName) {
30229 this.emitBlock();
30230 this[tagName] = false;
30231 this.modStack.shift();
30232 }
30233 /**
30234 * @param {string} tagName label for block type we are currently processing
30235 * @param {string|RegExp} tag string to match in text
30236 * @returns {boolean} true if the tag was processed, false otherwise
30237 */
30238
30239 }, {
30240 key: "parseStartTag",
30241 value: function parseStartTag(tagName, tag) {
30242 // Note: if 'mono' passed as tagName, there is a double check here. This is OK
30243 if (!this.mono && !this[tagName] && this.match(tag)) {
30244 this.setTag(tagName);
30245 return true;
30246 }
30247
30248 return false;
30249 }
30250 /**
30251 * @param {string|RegExp} tag
30252 * @param {number} [advance=true] if set, advance current position in text
30253 * @returns {boolean} true if match at given position, false otherwise
30254 * @private
30255 */
30256
30257 }, {
30258 key: "match",
30259 value: function match(tag) {
30260 var advance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
30261
30262 var _this$prepareRegExp = this.prepareRegExp(tag),
30263 _this$prepareRegExp2 = _slicedToArray(_this$prepareRegExp, 2),
30264 regExp = _this$prepareRegExp2[0],
30265 length = _this$prepareRegExp2[1];
30266
30267 var matched = regExp.test(this.text.substr(this.position, length));
30268
30269 if (matched && advance) {
30270 this.position += length - 1;
30271 }
30272
30273 return matched;
30274 }
30275 /**
30276 * @param {string} tagName label for block type we are currently processing
30277 * @param {string|RegExp} tag string to match in text
30278 * @param {RegExp} [nextTag] regular expression to match for characters *following* the current tag
30279 * @returns {boolean} true if the tag was processed, false otherwise
30280 */
30281
30282 }, {
30283 key: "parseEndTag",
30284 value: function parseEndTag(tagName, tag, nextTag) {
30285 var checkTag = this.mod() === tagName;
30286
30287 if (tagName === 'mono') {
30288 // special handling for 'mono'
30289 checkTag = checkTag && this.mono;
30290 } else {
30291 checkTag = checkTag && !this.mono;
30292 }
30293
30294 if (checkTag && this.match(tag)) {
30295 if (nextTag !== undefined) {
30296 // Purpose of the following match is to prevent a direct unset/set of a given tag
30297 // E.g. '*bold **still bold*' => '*bold still bold*'
30298 if (this.position === this.text.length - 1 || this.match(nextTag, false)) {
30299 this.unsetTag(tagName);
30300 }
30301 } else {
30302 this.unsetTag(tagName);
30303 }
30304
30305 return true;
30306 }
30307
30308 return false;
30309 }
30310 /**
30311 * @param {string|RegExp} tag string to match in text
30312 * @param {value} value string to replace tag with, if found at current position
30313 * @returns {boolean} true if the tag was processed, false otherwise
30314 */
30315
30316 }, {
30317 key: "replace",
30318 value: function replace(tag, value) {
30319 if (this.match(tag)) {
30320 this.add(value);
30321 this.position += length - 1;
30322 return true;
30323 }
30324
30325 return false;
30326 }
30327 /**
30328 * Create a regular expression for the tag if it isn't already one.
30329 *
30330 * The return value is an array `[RegExp, number]`, with exactly two value, where:
30331 * - RegExp is the regular expression to use
30332 * - number is the lenth of the input string to match
30333 *
30334 * @param {string|RegExp} tag string to match in text
30335 * @returns {Array} regular expression to use and length of input string to match
30336 * @private
30337 */
30338
30339 }, {
30340 key: "prepareRegExp",
30341 value: function prepareRegExp(tag) {
30342 var length;
30343 var regExp;
30344
30345 if (tag instanceof RegExp) {
30346 regExp = tag;
30347 length = 1; // ASSUMPTION: regexp only tests one character
30348 } else {
30349 // use prepared regexp if present
30350 var prepared = tagPattern[tag];
30351
30352 if (prepared !== undefined) {
30353 regExp = prepared;
30354 } else {
30355 regExp = new RegExp(tag);
30356 }
30357
30358 length = tag.length;
30359 }
30360
30361 return [regExp, length];
30362 }
30363 }]);
30364
30365 return MarkupAccumulator;
30366 }();
30367 /**
30368 * Helper class for Label which explodes the label text into lines and blocks within lines
30369 *
30370 * @private
30371 */
30372
30373
30374 var LabelSplitter =
30375 /*#__PURE__*/
30376 function () {
30377 /**
30378 * @param {CanvasRenderingContext2D} ctx Canvas rendering context
30379 * @param {Label} parent reference to the Label instance using current instance
30380 * @param {boolean} selected
30381 * @param {boolean} hover
30382 */
30383 function LabelSplitter(ctx, parent, selected, hover) {
30384 var _this = this;
30385
30386 _classCallCheck(this, LabelSplitter);
30387
30388 this.ctx = ctx;
30389 this.parent = parent;
30390 this.selected = selected;
30391 this.hover = hover;
30392 /**
30393 * Callback to determine text width; passed to LabelAccumulator instance
30394 *
30395 * @param {String} text string to determine width of
30396 * @param {String} mod font type to use for this text
30397 * @return {Object} { width, values} width in pixels and font attributes
30398 */
30399
30400 var textWidth = function textWidth(text, mod) {
30401 if (text === undefined) return 0; // TODO: This can be done more efficiently with caching
30402 // This will set the ctx.font correctly, depending on selected/hover and mod - so that ctx.measureText() will be accurate.
30403
30404 var values = _this.parent.getFormattingValues(ctx, selected, hover, mod);
30405
30406 var width = 0;
30407
30408 if (text !== '') {
30409 var measure = _this.ctx.measureText(text);
30410
30411 width = measure.width;
30412 }
30413
30414 return {
30415 width: width,
30416 values: values
30417 };
30418 };
30419
30420 this.lines = new LabelAccumulator(textWidth);
30421 }
30422 /**
30423 * Split passed text of a label into lines and blocks.
30424 *
30425 * # NOTE
30426 *
30427 * The handling of spacing is option dependent:
30428 *
30429 * - if `font.multi : false`, all spaces are retained
30430 * - if `font.multi : true`, every sequence of spaces is compressed to a single space
30431 *
30432 * This might not be the best way to do it, but this is as it has been working till now.
30433 * In order not to break existing functionality, for the time being this behaviour will
30434 * be retained in any code changes.
30435 *
30436 * @param {string} text text to split
30437 * @returns {Array<line>}
30438 */
30439
30440
30441 _createClass(LabelSplitter, [{
30442 key: "process",
30443 value: function process(text) {
30444 if (!ComponentUtil.isValidLabel(text)) {
30445 return this.lines.finalize();
30446 }
30447
30448 var font = this.parent.fontOptions; // Normalize the end-of-line's to a single representation - order important
30449
30450 text = text.replace(/\r\n/g, '\n'); // Dos EOL's
30451
30452 text = text.replace(/\r/g, '\n'); // Mac EOL's
30453 // Note that at this point, there can be no \r's in the text.
30454 // This is used later on splitStringIntoLines() to split multifont texts.
30455
30456 var nlLines = String(text).split('\n');
30457 var lineCount = nlLines.length;
30458
30459 if (font.multi) {
30460 // Multi-font case: styling tags active
30461 for (var i = 0; i < lineCount; i++) {
30462 var blocks = this.splitBlocks(nlLines[i], font.multi); // Post: Sequences of tabs and spaces are reduced to single space
30463
30464 if (blocks === undefined) continue;
30465
30466 if (blocks.length === 0) {
30467 this.lines.newLine("");
30468 continue;
30469 }
30470
30471 if (font.maxWdt > 0) {
30472 // widthConstraint.maximum defined
30473 //console.log('Running widthConstraint multi, max: ' + this.fontOptions.maxWdt);
30474 for (var j = 0; j < blocks.length; j++) {
30475 var mod = blocks[j].mod;
30476 var _text = blocks[j].text;
30477 this.splitStringIntoLines(_text, mod, true);
30478 }
30479 } else {
30480 // widthConstraint.maximum NOT defined
30481 for (var _j = 0; _j < blocks.length; _j++) {
30482 var _mod = blocks[_j].mod;
30483 var _text2 = blocks[_j].text;
30484 this.lines.append(_text2, _mod);
30485 }
30486 }
30487
30488 this.lines.newLine();
30489 }
30490 } else {
30491 // Single-font case
30492 if (font.maxWdt > 0) {
30493 // widthConstraint.maximum defined
30494 // console.log('Running widthConstraint normal, max: ' + this.fontOptions.maxWdt);
30495 for (var _i = 0; _i < lineCount; _i++) {
30496 this.splitStringIntoLines(nlLines[_i]);
30497 }
30498 } else {
30499 // widthConstraint.maximum NOT defined
30500 for (var _i2 = 0; _i2 < lineCount; _i2++) {
30501 this.lines.newLine(nlLines[_i2]);
30502 }
30503 }
30504 }
30505
30506 return this.lines.finalize();
30507 }
30508 /**
30509 * normalize the markup system
30510 *
30511 * @param {boolean|'md'|'markdown'|'html'} markupSystem
30512 * @returns {string}
30513 */
30514
30515 }, {
30516 key: "decodeMarkupSystem",
30517 value: function decodeMarkupSystem(markupSystem) {
30518 var system = 'none';
30519
30520 if (markupSystem === 'markdown' || markupSystem === 'md') {
30521 system = 'markdown';
30522 } else if (markupSystem === true || markupSystem === 'html') {
30523 system = 'html';
30524 }
30525
30526 return system;
30527 }
30528 /**
30529 *
30530 * @param {string} text
30531 * @returns {Array}
30532 */
30533
30534 }, {
30535 key: "splitHtmlBlocks",
30536 value: function splitHtmlBlocks(text) {
30537 var s = new MarkupAccumulator(text);
30538
30539 var parseEntities = function parseEntities(ch) {
30540 if (/&/.test(ch)) {
30541 var parsed = s.replace(s.text, '&lt;', '<') || s.replace(s.text, '&amp;', '&');
30542
30543 if (!parsed) {
30544 s.add("&");
30545 }
30546
30547 return true;
30548 }
30549
30550 return false;
30551 };
30552
30553 while (s.position < s.text.length) {
30554 var ch = s.text.charAt(s.position);
30555 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);
30556
30557 if (!parsed) {
30558 s.add(ch);
30559 }
30560
30561 s.position++;
30562 }
30563
30564 s.emitBlock();
30565 return s.blocks;
30566 }
30567 /**
30568 *
30569 * @param {string} text
30570 * @returns {Array}
30571 */
30572
30573 }, {
30574 key: "splitMarkdownBlocks",
30575 value: function splitMarkdownBlocks(text) {
30576 var _this2 = this;
30577
30578 var s = new MarkupAccumulator(text);
30579 var beginable = true;
30580
30581 var parseOverride = function parseOverride(ch) {
30582 if (/\\/.test(ch)) {
30583 if (s.position < _this2.text.length + 1) {
30584 s.position++;
30585 ch = _this2.text.charAt(s.position);
30586
30587 if (/ \t/.test(ch)) {
30588 s.spacing = true;
30589 } else {
30590 s.add(ch);
30591 beginable = false;
30592 }
30593 }
30594
30595 return true;
30596 }
30597
30598 return false;
30599 };
30600
30601 while (s.position < s.text.length) {
30602 var ch = s.text.charAt(s.position);
30603 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');
30604
30605 if (!parsed) {
30606 s.add(ch);
30607 beginable = false;
30608 }
30609
30610 s.position++;
30611 }
30612
30613 s.emitBlock();
30614 return s.blocks;
30615 }
30616 /**
30617 * Explodes a piece of text into single-font blocks using a given markup
30618 *
30619 * @param {string} text
30620 * @param {boolean|'md'|'markdown'|'html'} markupSystem
30621 * @returns {Array.<{text: string, mod: string}>}
30622 * @private
30623 */
30624
30625 }, {
30626 key: "splitBlocks",
30627 value: function splitBlocks(text, markupSystem) {
30628 var system = this.decodeMarkupSystem(markupSystem);
30629
30630 if (system === 'none') {
30631 return [{
30632 text: text,
30633 mod: 'normal'
30634 }];
30635 } else if (system === 'markdown') {
30636 return this.splitMarkdownBlocks(text);
30637 } else if (system === 'html') {
30638 return this.splitHtmlBlocks(text);
30639 }
30640 }
30641 /**
30642 * @param {string} text
30643 * @returns {boolean} true if text length over the current max with
30644 * @private
30645 */
30646
30647 }, {
30648 key: "overMaxWidth",
30649 value: function overMaxWidth(text) {
30650 var width = this.ctx.measureText(text).width;
30651 return this.lines.curWidth() + width > this.parent.fontOptions.maxWdt;
30652 }
30653 /**
30654 * Determine the longest part of the sentence which still fits in the
30655 * current max width.
30656 *
30657 * @param {Array} words Array of strings signifying a text lines
30658 * @return {number} index of first item in string making string go over max
30659 * @private
30660 */
30661
30662 }, {
30663 key: "getLongestFit",
30664 value: function getLongestFit(words) {
30665 var text = '';
30666 var w = 0;
30667
30668 while (w < words.length) {
30669 var pre = text === '' ? '' : ' ';
30670 var newText = text + pre + words[w];
30671 if (this.overMaxWidth(newText)) break;
30672 text = newText;
30673 w++;
30674 }
30675
30676 return w;
30677 }
30678 /**
30679 * Determine the longest part of the string which still fits in the
30680 * current max width.
30681 *
30682 * @param {Array} words Array of strings signifying a text lines
30683 * @return {number} index of first item in string making string go over max
30684 */
30685
30686 }, {
30687 key: "getLongestFitWord",
30688 value: function getLongestFitWord(words) {
30689 var w = 0;
30690
30691 while (w < words.length) {
30692 if (this.overMaxWidth(words.slice(0, w))) break;
30693 w++;
30694 }
30695
30696 return w;
30697 }
30698 /**
30699 * Split the passed text into lines, according to width constraint (if any).
30700 *
30701 * The method assumes that the input string is a single line, i.e. without lines break.
30702 *
30703 * This method retains spaces, if still present (case `font.multi: false`).
30704 * A space which falls on an internal line break, will be replaced by a newline.
30705 * There is no special handling of tabs; these go along with the flow.
30706 *
30707 * @param {string} str
30708 * @param {string} [mod='normal']
30709 * @param {boolean} [appendLast=false]
30710 * @private
30711 */
30712
30713 }, {
30714 key: "splitStringIntoLines",
30715 value: function splitStringIntoLines(str) {
30716 var mod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'normal';
30717 var appendLast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
30718 // Set the canvas context font, based upon the current selected/hover state
30719 // and the provided mod, so the text measurement performed by getLongestFit
30720 // will be accurate - and not just use the font of whoever last used the canvas.
30721 this.parent.getFormattingValues(this.ctx, this.selected, this.hover, mod); // Still-present spaces are relevant, retain them
30722
30723 str = str.replace(/^( +)/g, '$1\r');
30724 str = str.replace(/([^\r][^ ]*)( +)/g, '$1\r$2\r');
30725 var words = str.split('\r');
30726
30727 while (words.length > 0) {
30728 var w = this.getLongestFit(words);
30729
30730 if (w === 0) {
30731 // Special case: the first word is already larger than the max width.
30732 var word = words[0]; // Break the word to the largest part that fits the line
30733
30734 var x = this.getLongestFitWord(word);
30735 this.lines.newLine(word.slice(0, x), mod); // Adjust the word, so that the rest will be done next iteration
30736
30737 words[0] = word.slice(x);
30738 } else {
30739 // skip any space that is replaced by a newline
30740 var newW = w;
30741
30742 if (words[w - 1] === ' ') {
30743 w--;
30744 } else if (words[newW] === ' ') {
30745 newW++;
30746 }
30747
30748 var text = words.slice(0, w).join("");
30749
30750 if (w == words.length && appendLast) {
30751 this.lines.append(text, mod);
30752 } else {
30753 this.lines.newLine(text, mod);
30754 } // Adjust the word, so that the rest will be done next iteration
30755
30756
30757 words = words.slice(newW);
30758 }
30759 }
30760 }
30761 }]);
30762
30763 return LabelSplitter;
30764 }();
30765
30766 /**
30767 * List of special styles for multi-fonts
30768 * @private
30769 */
30770
30771 var multiFontStyle = ['bold', 'ital', 'boldital', 'mono'];
30772 /**
30773 * A Label to be used for Nodes or Edges.
30774 */
30775
30776 var Label =
30777 /*#__PURE__*/
30778 function () {
30779 /**
30780 * @param {Object} body
30781 * @param {Object} options
30782 * @param {boolean} [edgelabel=false]
30783 */
30784 function Label(body, options) {
30785 var edgelabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
30786
30787 _classCallCheck(this, Label);
30788
30789 this.body = body;
30790 this.pointToSelf = false;
30791 this.baseSize = undefined;
30792 this.fontOptions = {}; // instance variable containing the *instance-local* font options
30793
30794 this.setOptions(options);
30795 this.size = {
30796 top: 0,
30797 left: 0,
30798 width: 0,
30799 height: 0,
30800 yLine: 0
30801 };
30802 this.isEdgeLabel = edgelabel;
30803 }
30804 /**
30805 * @param {Object} options the options of the parent Node-instance
30806 */
30807
30808
30809 _createClass(Label, [{
30810 key: "setOptions",
30811 value: function setOptions(options) {
30812 this.elementOptions = options; // Reference to the options of the parent Node-instance
30813
30814 this.initFontOptions(options.font);
30815
30816 if (ComponentUtil.isValidLabel(options.label)) {
30817 this.labelDirty = true;
30818 } else {
30819 // Bad label! Change the option value to prevent bad stuff happening
30820 options.label = undefined;
30821 }
30822
30823 if (options.font !== undefined && options.font !== null) {
30824 // font options can be deleted at various levels
30825 if (typeof options.font === 'string') {
30826 this.baseSize = this.fontOptions.size;
30827 } else if (_typeof(options.font) === 'object') {
30828 var size = options.font.size;
30829
30830 if (size !== undefined) {
30831 this.baseSize = size;
30832 }
30833 }
30834 }
30835 }
30836 /**
30837 * Init the font Options structure.
30838 *
30839 * Member fontOptions serves as an accumulator for the current font options.
30840 * As such, it needs to be completely separated from the node options.
30841 *
30842 * @param {Object} newFontOptions the new font options to process
30843 * @private
30844 */
30845
30846 }, {
30847 key: "initFontOptions",
30848 value: function initFontOptions(newFontOptions) {
30849 var _this = this;
30850
30851 // Prepare the multi-font option objects.
30852 // These will be filled in propagateFonts(), if required
30853 forEach(multiFontStyle, function (style) {
30854 _this.fontOptions[style] = {};
30855 }); // Handle shorthand option, if present
30856
30857 if (Label.parseFontString(this.fontOptions, newFontOptions)) {
30858 this.fontOptions.vadjust = 0;
30859 return;
30860 } // Copy over the non-multifont options, if specified
30861
30862
30863 forEach(newFontOptions, function (prop, n) {
30864 if (prop !== undefined && prop !== null && _typeof(prop) !== 'object') {
30865 _this.fontOptions[n] = prop;
30866 }
30867 });
30868 }
30869 /**
30870 * If in-variable is a string, parse it as a font specifier.
30871 *
30872 * Note that following is not done here and have to be done after the call:
30873 * - Not all font options are set (vadjust, mod)
30874 *
30875 * @param {Object} outOptions out-parameter, object in which to store the parse results (if any)
30876 * @param {Object} inOptions font options to parse
30877 * @return {boolean} true if font parsed as string, false otherwise
30878 * @static
30879 */
30880
30881 }, {
30882 key: "constrain",
30883
30884 /**
30885 * Set the width and height constraints based on 'nearest' value
30886 *
30887 * @param {Array} pile array of option objects to consider
30888 * @returns {object} the actual constraint values to use
30889 * @private
30890 */
30891 value: function constrain(pile) {
30892 // NOTE: constrainWidth and constrainHeight never set!
30893 // NOTE: for edge labels, only 'maxWdt' set
30894 // Node labels can set all the fields
30895 var fontOptions = {
30896 constrainWidth: false,
30897 maxWdt: -1,
30898 minWdt: -1,
30899 constrainHeight: false,
30900 minHgt: -1,
30901 valign: 'middle'
30902 };
30903 var widthConstraint = topMost(pile, 'widthConstraint');
30904
30905 if (typeof widthConstraint === 'number') {
30906 fontOptions.maxWdt = Number(widthConstraint);
30907 fontOptions.minWdt = Number(widthConstraint);
30908 } else if (_typeof(widthConstraint) === 'object') {
30909 var widthConstraintMaximum = topMost(pile, ['widthConstraint', 'maximum']);
30910
30911 if (typeof widthConstraintMaximum === 'number') {
30912 fontOptions.maxWdt = Number(widthConstraintMaximum);
30913 }
30914
30915 var widthConstraintMinimum = topMost(pile, ['widthConstraint', 'minimum']);
30916
30917 if (typeof widthConstraintMinimum === 'number') {
30918 fontOptions.minWdt = Number(widthConstraintMinimum);
30919 }
30920 }
30921
30922 var heightConstraint = topMost(pile, 'heightConstraint');
30923
30924 if (typeof heightConstraint === 'number') {
30925 fontOptions.minHgt = Number(heightConstraint);
30926 } else if (_typeof(heightConstraint) === 'object') {
30927 var heightConstraintMinimum = topMost(pile, ['heightConstraint', 'minimum']);
30928
30929 if (typeof heightConstraintMinimum === 'number') {
30930 fontOptions.minHgt = Number(heightConstraintMinimum);
30931 }
30932
30933 var heightConstraintValign = topMost(pile, ['heightConstraint', 'valign']);
30934
30935 if (typeof heightConstraintValign === 'string') {
30936 if (heightConstraintValign === 'top' || heightConstraintValign === 'bottom') {
30937 fontOptions.valign = heightConstraintValign;
30938 }
30939 }
30940 }
30941
30942 return fontOptions;
30943 }
30944 /**
30945 * Set options and update internal state
30946 *
30947 * @param {Object} options options to set
30948 * @param {Array} pile array of option objects to consider for option 'chosen'
30949 */
30950
30951 }, {
30952 key: "update",
30953 value: function update(options, pile) {
30954 this.setOptions(options, true);
30955 this.propagateFonts(pile);
30956 deepExtend(this.fontOptions, this.constrain(pile));
30957 this.fontOptions.chooser = ComponentUtil.choosify('label', pile);
30958 }
30959 /**
30960 * When margins are set in an element, adjust sizes is called to remove them
30961 * from the width/height constraints. This must be done prior to label sizing.
30962 *
30963 * @param {{top: number, right: number, bottom: number, left: number}} margins
30964 */
30965
30966 }, {
30967 key: "adjustSizes",
30968 value: function adjustSizes(margins) {
30969 var widthBias = margins ? margins.right + margins.left : 0;
30970
30971 if (this.fontOptions.constrainWidth) {
30972 this.fontOptions.maxWdt -= widthBias;
30973 this.fontOptions.minWdt -= widthBias;
30974 }
30975
30976 var heightBias = margins ? margins.top + margins.bottom : 0;
30977
30978 if (this.fontOptions.constrainHeight) {
30979 this.fontOptions.minHgt -= heightBias;
30980 }
30981 } /////////////////////////////////////////////////////////
30982 // Methods for handling options piles
30983 // Eventually, these will be moved to a separate class
30984 /////////////////////////////////////////////////////////
30985
30986 /**
30987 * Add the font members of the passed list of option objects to the pile.
30988 *
30989 * @param {Pile} dstPile pile of option objects add to
30990 * @param {Pile} srcPile pile of option objects to take font options from
30991 * @private
30992 */
30993
30994 }, {
30995 key: "addFontOptionsToPile",
30996 value: function addFontOptionsToPile(dstPile, srcPile) {
30997 for (var i = 0; i < srcPile.length; ++i) {
30998 this.addFontToPile(dstPile, srcPile[i]);
30999 }
31000 }
31001 /**
31002 * Add given font option object to the list of objects (the 'pile') to consider for determining
31003 * multi-font option values.
31004 *
31005 * @param {Pile} pile pile of option objects to use
31006 * @param {object} options instance to add to pile
31007 * @private
31008 */
31009
31010 }, {
31011 key: "addFontToPile",
31012 value: function addFontToPile(pile, options) {
31013 if (options === undefined) return;
31014 if (options.font === undefined || options.font === null) return;
31015 var item = options.font;
31016 pile.push(item);
31017 }
31018 /**
31019 * Collect all own-property values from the font pile that aren't multi-font option objectss.
31020 *
31021 * @param {Pile} pile pile of option objects to use
31022 * @returns {object} object with all current own basic font properties
31023 * @private
31024 */
31025
31026 }, {
31027 key: "getBasicOptions",
31028 value: function getBasicOptions(pile) {
31029 var ret = {}; // Scans the whole pile to get all options present
31030
31031 for (var n = 0; n < pile.length; ++n) {
31032 var fontOptions = pile[n]; // Convert shorthand if necessary
31033
31034 var tmpShorthand = {};
31035
31036 if (Label.parseFontString(tmpShorthand, fontOptions)) {
31037 fontOptions = tmpShorthand;
31038 }
31039
31040 forEach(fontOptions, function (opt, name) {
31041 if (opt === undefined) return; // multi-font option need not be present
31042
31043 if (ret.hasOwnProperty(name)) return; // Keep first value we encounter
31044
31045 if (multiFontStyle.indexOf(name) !== -1) {
31046 // Skip multi-font properties but we do need the structure
31047 ret[name] = {};
31048 } else {
31049 ret[name] = opt;
31050 }
31051 });
31052 }
31053
31054 return ret;
31055 }
31056 /**
31057 * Return the value for given option for the given multi-font.
31058 *
31059 * All available option objects are trawled in the set order to construct the option values.
31060 *
31061 * ---------------------------------------------------------------------
31062 * ## Traversal of pile for multi-fonts
31063 *
31064 * The determination of multi-font option values is a special case, because any values not
31065 * present in the multi-font options should by definition be taken from the main font options,
31066 * i.e. from the current 'parent' object of the multi-font option.
31067 *
31068 * ### Search order for multi-fonts
31069 *
31070 * 'bold' used as example:
31071 *
31072 * - search in option group 'bold' in local properties
31073 * - search in main font option group in local properties
31074 *
31075 * ---------------------------------------------------------------------
31076 *
31077 * @param {Pile} pile pile of option objects to use
31078 * @param {MultiFontStyle} multiName sub path for the multi-font
31079 * @param {string} option the option to search for, for the given multi-font
31080 * @returns {string|number} the value for the given option
31081 * @private
31082 */
31083
31084 }, {
31085 key: "getFontOption",
31086 value: function getFontOption(pile, multiName, option) {
31087 var multiFont; // Search multi font in local properties
31088
31089 for (var n = 0; n < pile.length; ++n) {
31090 var fontOptions = pile[n];
31091
31092 if (fontOptions.hasOwnProperty(multiName)) {
31093 multiFont = fontOptions[multiName];
31094 if (multiFont === undefined || multiFont === null) continue; // Convert shorthand if necessary
31095 // TODO: inefficient to do this conversion every time; find a better way.
31096
31097 var tmpShorthand = {};
31098
31099 if (Label.parseFontString(tmpShorthand, multiFont)) {
31100 multiFont = tmpShorthand;
31101 }
31102
31103 if (multiFont.hasOwnProperty(option)) {
31104 return multiFont[option];
31105 }
31106 }
31107 } // Option is not mentioned in the multi font options; take it from the parent font options.
31108 // These have already been converted with getBasicOptions(), so use the converted values.
31109
31110
31111 if (this.fontOptions.hasOwnProperty(option)) {
31112 return this.fontOptions[option];
31113 } // A value **must** be found; you should never get here.
31114
31115
31116 throw new Error("Did not find value for multi-font for property: '" + option + "'");
31117 }
31118 /**
31119 * Return all options values for the given multi-font.
31120 *
31121 * All available option objects are trawled in the set order to construct the option values.
31122 *
31123 * @param {Pile} pile pile of option objects to use
31124 * @param {MultiFontStyle} multiName sub path for the mod-font
31125 * @returns {MultiFontOptions}
31126 * @private
31127 */
31128
31129 }, {
31130 key: "getFontOptions",
31131 value: function getFontOptions(pile, multiName) {
31132 var result = {};
31133 var optionNames = ['color', 'size', 'face', 'mod', 'vadjust']; // List of allowed options per multi-font
31134
31135 for (var i = 0; i < optionNames.length; ++i) {
31136 var mod = optionNames[i];
31137 result[mod] = this.getFontOption(pile, multiName, mod);
31138 }
31139
31140 return result;
31141 } /////////////////////////////////////////////////////////
31142 // End methods for handling options piles
31143 /////////////////////////////////////////////////////////
31144
31145 /**
31146 * Collapse the font options for the multi-font to single objects, from
31147 * the chain of option objects passed (the 'pile').
31148 *
31149 * @param {Pile} pile sequence of option objects to consider.
31150 * First item in list assumed to be the newly set options.
31151 */
31152
31153 }, {
31154 key: "propagateFonts",
31155 value: function propagateFonts(pile) {
31156 var _this2 = this;
31157
31158 var fontPile = []; // sequence of font objects to consider, order important
31159 // Note that this.elementOptions is not used here.
31160
31161 this.addFontOptionsToPile(fontPile, pile);
31162 this.fontOptions = this.getBasicOptions(fontPile); // We set multifont values even if multi === false, for consistency (things break otherwise)
31163
31164 var _loop = function _loop(i) {
31165 var mod = multiFontStyle[i];
31166 var modOptions = _this2.fontOptions[mod];
31167
31168 var tmpMultiFontOptions = _this2.getFontOptions(fontPile, mod); // Copy over found values
31169
31170
31171 forEach(tmpMultiFontOptions, function (option, n) {
31172 modOptions[n] = option;
31173 });
31174 modOptions.size = Number(modOptions.size);
31175 modOptions.vadjust = Number(modOptions.vadjust);
31176 };
31177
31178 for (var i = 0; i < multiFontStyle.length; ++i) {
31179 _loop(i);
31180 }
31181 }
31182 /**
31183 * Main function. This is called from anything that wants to draw a label.
31184 * @param {CanvasRenderingContext2D} ctx
31185 * @param {number} x
31186 * @param {number} y
31187 * @param {boolean} selected
31188 * @param {boolean} hover
31189 * @param {string} [baseline='middle']
31190 */
31191
31192 }, {
31193 key: "draw",
31194 value: function draw(ctx, x, y, selected, hover) {
31195 var baseline = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'middle';
31196 // if no label, return
31197 if (this.elementOptions.label === undefined) return; // check if we have to render the label
31198
31199 var viewFontSize = this.fontOptions.size * this.body.view.scale;
31200 if (this.elementOptions.label && viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1) return; // This ensures that there will not be HUGE letters on screen
31201 // by setting an upper limit on the visible text size (regardless of zoomLevel)
31202
31203 if (viewFontSize >= this.elementOptions.scaling.label.maxVisible) {
31204 viewFontSize = Number(this.elementOptions.scaling.label.maxVisible) / this.body.view.scale;
31205 } // update the size cache if required
31206
31207
31208 this.calculateLabelSize(ctx, selected, hover, x, y, baseline);
31209
31210 this._drawBackground(ctx);
31211
31212 this._drawText(ctx, x, this.size.yLine, baseline, viewFontSize);
31213 }
31214 /**
31215 * Draws the label background
31216 * @param {CanvasRenderingContext2D} ctx
31217 * @private
31218 */
31219
31220 }, {
31221 key: "_drawBackground",
31222 value: function _drawBackground(ctx) {
31223 if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") {
31224 ctx.fillStyle = this.fontOptions.background;
31225 var size = this.getSize();
31226 ctx.fillRect(size.left, size.top, size.width, size.height);
31227 }
31228 }
31229 /**
31230 *
31231 * @param {CanvasRenderingContext2D} ctx
31232 * @param {number} x
31233 * @param {number} y
31234 * @param {string} [baseline='middle']
31235 * @param {number} viewFontSize
31236 * @private
31237 */
31238
31239 }, {
31240 key: "_drawText",
31241 value: function _drawText(ctx, x, y) {
31242 var baseline = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'middle';
31243 var viewFontSize = arguments.length > 4 ? arguments[4] : undefined;
31244
31245 var _this$_setAlignment = this._setAlignment(ctx, x, y, baseline);
31246
31247 var _this$_setAlignment2 = _slicedToArray(_this$_setAlignment, 2);
31248
31249 x = _this$_setAlignment2[0];
31250 y = _this$_setAlignment2[1];
31251 ctx.textAlign = 'left';
31252 x = x - this.size.width / 2; // Shift label 1/2-distance to the left
31253
31254 if (this.fontOptions.valign && this.size.height > this.size.labelHeight) {
31255 if (this.fontOptions.valign === 'top') {
31256 y -= (this.size.height - this.size.labelHeight) / 2;
31257 }
31258
31259 if (this.fontOptions.valign === 'bottom') {
31260 y += (this.size.height - this.size.labelHeight) / 2;
31261 }
31262 } // draw the text
31263
31264
31265 for (var i = 0; i < this.lineCount; i++) {
31266 var line = this.lines[i];
31267
31268 if (line && line.blocks) {
31269 var width = 0;
31270
31271 if (this.isEdgeLabel || this.fontOptions.align === 'center') {
31272 width += (this.size.width - line.width) / 2;
31273 } else if (this.fontOptions.align === 'right') {
31274 width += this.size.width - line.width;
31275 }
31276
31277 for (var j = 0; j < line.blocks.length; j++) {
31278 var block = line.blocks[j];
31279 ctx.font = block.font;
31280
31281 var _this$_getColor = this._getColor(block.color, viewFontSize, block.strokeColor),
31282 _this$_getColor2 = _slicedToArray(_this$_getColor, 2),
31283 fontColor = _this$_getColor2[0],
31284 strokeColor = _this$_getColor2[1];
31285
31286 if (block.strokeWidth > 0) {
31287 ctx.lineWidth = block.strokeWidth;
31288 ctx.strokeStyle = strokeColor;
31289 ctx.lineJoin = 'round';
31290 }
31291
31292 ctx.fillStyle = fontColor;
31293
31294 if (block.strokeWidth > 0) {
31295 ctx.strokeText(block.text, x + width, y + block.vadjust);
31296 }
31297
31298 ctx.fillText(block.text, x + width, y + block.vadjust);
31299 width += block.width;
31300 }
31301
31302 y += line.height;
31303 }
31304 }
31305 }
31306 /**
31307 *
31308 * @param {CanvasRenderingContext2D} ctx
31309 * @param {number} x
31310 * @param {number} y
31311 * @param {string} baseline
31312 * @returns {Array.<number>}
31313 * @private
31314 */
31315
31316 }, {
31317 key: "_setAlignment",
31318 value: function _setAlignment(ctx, x, y, baseline) {
31319 // check for label alignment (for edges)
31320 // TODO: make alignment for nodes
31321 if (this.isEdgeLabel && this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) {
31322 x = 0;
31323 y = 0;
31324 var lineMargin = 2;
31325
31326 if (this.fontOptions.align === 'top') {
31327 ctx.textBaseline = 'alphabetic';
31328 y -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers
31329 } else if (this.fontOptions.align === 'bottom') {
31330 ctx.textBaseline = 'hanging';
31331 y += 2 * lineMargin; // distance from edge, required because we use hanging. Hanging has less difference between browsers
31332 } else {
31333 ctx.textBaseline = 'middle';
31334 }
31335 } else {
31336 ctx.textBaseline = baseline;
31337 }
31338
31339 return [x, y];
31340 }
31341 /**
31342 * fade in when relative scale is between threshold and threshold - 1.
31343 * If the relative scale would be smaller than threshold -1 the draw function would have returned before coming here.
31344 *
31345 * @param {string} color The font color to use
31346 * @param {number} viewFontSize
31347 * @param {string} initialStrokeColor
31348 * @returns {Array.<string>} An array containing the font color and stroke color
31349 * @private
31350 */
31351
31352 }, {
31353 key: "_getColor",
31354 value: function _getColor(color, viewFontSize, initialStrokeColor) {
31355 var fontColor = color || '#000000';
31356 var strokeColor = initialStrokeColor || '#ffffff';
31357
31358 if (viewFontSize <= this.elementOptions.scaling.label.drawThreshold) {
31359 var opacity = Math.max(0, Math.min(1, 1 - (this.elementOptions.scaling.label.drawThreshold - viewFontSize)));
31360 fontColor = overrideOpacity(fontColor, opacity);
31361 strokeColor = overrideOpacity(strokeColor, opacity);
31362 }
31363
31364 return [fontColor, strokeColor];
31365 }
31366 /**
31367 *
31368 * @param {CanvasRenderingContext2D} ctx
31369 * @param {boolean} selected
31370 * @param {boolean} hover
31371 * @returns {{width: number, height: number}}
31372 */
31373
31374 }, {
31375 key: "getTextSize",
31376 value: function getTextSize(ctx) {
31377 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
31378 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
31379
31380 this._processLabel(ctx, selected, hover);
31381
31382 return {
31383 width: this.size.width,
31384 height: this.size.height,
31385 lineCount: this.lineCount
31386 };
31387 }
31388 /**
31389 * Get the current dimensions of the label
31390 *
31391 * @return {rect}
31392 */
31393
31394 }, {
31395 key: "getSize",
31396 value: function getSize() {
31397 var lineMargin = 2;
31398 var x = this.size.left; // default values which might be overridden below
31399
31400 var y = this.size.top - 0.5 * lineMargin; // idem
31401
31402 if (this.isEdgeLabel) {
31403 var x2 = -this.size.width * 0.5;
31404
31405 switch (this.fontOptions.align) {
31406 case 'middle':
31407 x = x2;
31408 y = -this.size.height * 0.5;
31409 break;
31410
31411 case 'top':
31412 x = x2;
31413 y = -(this.size.height + lineMargin);
31414 break;
31415
31416 case 'bottom':
31417 x = x2;
31418 y = lineMargin;
31419 break;
31420 }
31421 }
31422
31423 var ret = {
31424 left: x,
31425 top: y,
31426 width: this.size.width,
31427 height: this.size.height
31428 };
31429 return ret;
31430 }
31431 /**
31432 *
31433 * @param {CanvasRenderingContext2D} ctx
31434 * @param {boolean} selected
31435 * @param {boolean} hover
31436 * @param {number} [x=0]
31437 * @param {number} [y=0]
31438 * @param {'middle'|'hanging'} [baseline='middle']
31439 */
31440
31441 }, {
31442 key: "calculateLabelSize",
31443 value: function calculateLabelSize(ctx, selected, hover) {
31444 var x = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
31445 var y = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
31446 var baseline = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'middle';
31447
31448 this._processLabel(ctx, selected, hover);
31449
31450 this.size.left = x - this.size.width * 0.5;
31451 this.size.top = y - this.size.height * 0.5;
31452 this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.fontOptions.size;
31453
31454 if (baseline === "hanging") {
31455 this.size.top += 0.5 * this.fontOptions.size;
31456 this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers
31457
31458 this.size.yLine += 4; // distance from node
31459 }
31460 }
31461 /**
31462 *
31463 * @param {CanvasRenderingContext2D} ctx
31464 * @param {boolean} selected
31465 * @param {boolean} hover
31466 * @param {string} mod
31467 * @returns {{color, size, face, mod, vadjust, strokeWidth: *, strokeColor: (*|string|allOptions.edges.font.strokeColor|{string}|allOptions.nodes.font.strokeColor|Array)}}
31468 */
31469
31470 }, {
31471 key: "getFormattingValues",
31472 value: function getFormattingValues(ctx, selected, hover, mod) {
31473 var getValue = function getValue(fontOptions, mod, option) {
31474 if (mod === "normal") {
31475 if (option === 'mod') return "";
31476 return fontOptions[option];
31477 }
31478
31479 if (fontOptions[mod][option] !== undefined) {
31480 // Grumbl leaving out test on undefined equals false for ""
31481 return fontOptions[mod][option];
31482 } else {
31483 // Take from parent font option
31484 return fontOptions[option];
31485 }
31486 };
31487
31488 var values = {
31489 color: getValue(this.fontOptions, mod, 'color'),
31490 size: getValue(this.fontOptions, mod, 'size'),
31491 face: getValue(this.fontOptions, mod, 'face'),
31492 mod: getValue(this.fontOptions, mod, 'mod'),
31493 vadjust: getValue(this.fontOptions, mod, 'vadjust'),
31494 strokeWidth: this.fontOptions.strokeWidth,
31495 strokeColor: this.fontOptions.strokeColor
31496 };
31497
31498 if (selected || hover) {
31499 if (mod === "normal" && this.fontOptions.chooser === true && this.elementOptions.labelHighlightBold) {
31500 values.mod = 'bold';
31501 } else {
31502 if (typeof this.fontOptions.chooser === 'function') {
31503 this.fontOptions.chooser(values, this.elementOptions.id, selected, hover);
31504 }
31505 }
31506 }
31507
31508 var fontString = "";
31509
31510 if (values.mod !== undefined && values.mod !== "") {
31511 // safeguard for undefined - this happened
31512 fontString += values.mod + " ";
31513 }
31514
31515 fontString += values.size + "px " + values.face;
31516 ctx.font = fontString.replace(/"/g, "");
31517 values.font = ctx.font;
31518 values.height = values.size;
31519 return values;
31520 }
31521 /**
31522 *
31523 * @param {boolean} selected
31524 * @param {boolean} hover
31525 * @returns {boolean}
31526 */
31527
31528 }, {
31529 key: "differentState",
31530 value: function differentState(selected, hover) {
31531 return selected !== this.selectedState || hover !== this.hoverState;
31532 }
31533 /**
31534 * This explodes the passed text into lines and determines the width, height and number of lines.
31535 *
31536 * @param {CanvasRenderingContext2D} ctx
31537 * @param {boolean} selected
31538 * @param {boolean} hover
31539 * @param {string} inText the text to explode
31540 * @returns {{width, height, lines}|*}
31541 * @private
31542 */
31543
31544 }, {
31545 key: "_processLabelText",
31546 value: function _processLabelText(ctx, selected, hover, inText) {
31547 var splitter = new LabelSplitter(ctx, this, selected, hover);
31548 return splitter.process(inText);
31549 }
31550 /**
31551 * This explodes the label string into lines and sets the width, height and number of lines.
31552 * @param {CanvasRenderingContext2D} ctx
31553 * @param {boolean} selected
31554 * @param {boolean} hover
31555 * @private
31556 */
31557
31558 }, {
31559 key: "_processLabel",
31560 value: function _processLabel(ctx, selected, hover) {
31561 if (this.labelDirty === false && !this.differentState(selected, hover)) return;
31562
31563 var state = this._processLabelText(ctx, selected, hover, this.elementOptions.label);
31564
31565 if (this.fontOptions.minWdt > 0 && state.width < this.fontOptions.minWdt) {
31566 state.width = this.fontOptions.minWdt;
31567 }
31568
31569 this.size.labelHeight = state.height;
31570
31571 if (this.fontOptions.minHgt > 0 && state.height < this.fontOptions.minHgt) {
31572 state.height = this.fontOptions.minHgt;
31573 }
31574
31575 this.lines = state.lines;
31576 this.lineCount = state.lines.length;
31577 this.size.width = state.width;
31578 this.size.height = state.height;
31579 this.selectedState = selected;
31580 this.hoverState = hover;
31581 this.labelDirty = false;
31582 }
31583 /**
31584 * Check if this label is visible
31585 *
31586 * @return {boolean} true if this label will be show, false otherwise
31587 */
31588
31589 }, {
31590 key: "visible",
31591 value: function visible() {
31592 if (this.size.width === 0 || this.size.height === 0 || this.elementOptions.label === undefined) {
31593 return false; // nothing to display
31594 }
31595
31596 var viewFontSize = this.fontOptions.size * this.body.view.scale;
31597
31598 if (viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1) {
31599 return false; // Too small or too far away to show
31600 }
31601
31602 return true;
31603 }
31604 }], [{
31605 key: "parseFontString",
31606 value: function parseFontString(outOptions, inOptions) {
31607 if (!inOptions || typeof inOptions !== 'string') return false;
31608 var newOptionsArray = inOptions.split(" ");
31609 outOptions.size = +newOptionsArray[0].replace("px", '');
31610 outOptions.face = newOptionsArray[1];
31611 outOptions.color = newOptionsArray[2];
31612 return true;
31613 }
31614 }]);
31615
31616 return Label;
31617 }();
31618
31619 // `Array.prototype.fill` method
31620 // https://tc39.github.io/ecma262/#sec-array.prototype.fill
31621 _export({ target: 'Array', proto: true }, {
31622 fill: arrayFill
31623 });
31624
31625 // https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
31626 addToUnscopables('fill');
31627
31628 /**
31629 * The Base class for all Nodes.
31630 */
31631 var NodeBase =
31632 /*#__PURE__*/
31633 function () {
31634 /**
31635 * @param {Object} options
31636 * @param {Object} body
31637 * @param {Label} labelModule
31638 */
31639 function NodeBase(options, body, labelModule) {
31640 _classCallCheck(this, NodeBase);
31641
31642 this.body = body;
31643 this.labelModule = labelModule;
31644 this.setOptions(options);
31645 this.top = undefined;
31646 this.left = undefined;
31647 this.height = undefined;
31648 this.width = undefined;
31649 this.radius = undefined;
31650 this.margin = undefined;
31651 this.refreshNeeded = true;
31652 this.boundingBox = {
31653 top: 0,
31654 left: 0,
31655 right: 0,
31656 bottom: 0
31657 };
31658 }
31659 /**
31660 *
31661 * @param {Object} options
31662 */
31663
31664
31665 _createClass(NodeBase, [{
31666 key: "setOptions",
31667 value: function setOptions(options) {
31668 this.options = options;
31669 }
31670 /**
31671 *
31672 * @param {Label} labelModule
31673 * @private
31674 */
31675
31676 }, {
31677 key: "_setMargins",
31678 value: function _setMargins(labelModule) {
31679 this.margin = {};
31680
31681 if (this.options.margin) {
31682 if (_typeof(this.options.margin) == 'object') {
31683 this.margin.top = this.options.margin.top;
31684 this.margin.right = this.options.margin.right;
31685 this.margin.bottom = this.options.margin.bottom;
31686 this.margin.left = this.options.margin.left;
31687 } else {
31688 this.margin.top = this.options.margin;
31689 this.margin.right = this.options.margin;
31690 this.margin.bottom = this.options.margin;
31691 this.margin.left = this.options.margin;
31692 }
31693 }
31694
31695 labelModule.adjustSizes(this.margin);
31696 }
31697 /**
31698 *
31699 * @param {CanvasRenderingContext2D} ctx
31700 * @param {number} angle
31701 * @returns {number}
31702 * @private
31703 */
31704
31705 }, {
31706 key: "_distanceToBorder",
31707 value: function _distanceToBorder(ctx, angle) {
31708 var borderWidth = this.options.borderWidth;
31709 this.resize(ctx);
31710 return Math.min(Math.abs(this.width / 2 / Math.cos(angle)), Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
31711 }
31712 /**
31713 *
31714 * @param {CanvasRenderingContext2D} ctx
31715 * @param {ArrowOptions} values
31716 */
31717
31718 }, {
31719 key: "enableShadow",
31720 value: function enableShadow(ctx, values) {
31721 if (values.shadow) {
31722 ctx.shadowColor = values.shadowColor;
31723 ctx.shadowBlur = values.shadowSize;
31724 ctx.shadowOffsetX = values.shadowX;
31725 ctx.shadowOffsetY = values.shadowY;
31726 }
31727 }
31728 /**
31729 *
31730 * @param {CanvasRenderingContext2D} ctx
31731 * @param {ArrowOptions} values
31732 */
31733
31734 }, {
31735 key: "disableShadow",
31736 value: function disableShadow(ctx, values) {
31737 if (values.shadow) {
31738 ctx.shadowColor = 'rgba(0,0,0,0)';
31739 ctx.shadowBlur = 0;
31740 ctx.shadowOffsetX = 0;
31741 ctx.shadowOffsetY = 0;
31742 }
31743 }
31744 /**
31745 *
31746 * @param {CanvasRenderingContext2D} ctx
31747 * @param {ArrowOptions} values
31748 */
31749
31750 }, {
31751 key: "enableBorderDashes",
31752 value: function enableBorderDashes(ctx, values) {
31753 if (values.borderDashes !== false) {
31754 if (ctx.setLineDash !== undefined) {
31755 var dashes = values.borderDashes;
31756
31757 if (dashes === true) {
31758 dashes = [5, 15];
31759 }
31760
31761 ctx.setLineDash(dashes);
31762 } else {
31763 console.warn("setLineDash is not supported in this browser. The dashed borders cannot be used.");
31764 this.options.shapeProperties.borderDashes = false;
31765 values.borderDashes = false;
31766 }
31767 }
31768 }
31769 /**
31770 *
31771 * @param {CanvasRenderingContext2D} ctx
31772 * @param {ArrowOptions} values
31773 */
31774
31775 }, {
31776 key: "disableBorderDashes",
31777 value: function disableBorderDashes(ctx, values) {
31778 if (values.borderDashes !== false) {
31779 if (ctx.setLineDash !== undefined) {
31780 ctx.setLineDash([0]);
31781 } else {
31782 console.warn("setLineDash is not supported in this browser. The dashed borders cannot be used.");
31783 this.options.shapeProperties.borderDashes = false;
31784 values.borderDashes = false;
31785 }
31786 }
31787 }
31788 /**
31789 * Determine if the shape of a node needs to be recalculated.
31790 *
31791 * @param {boolean} selected
31792 * @param {boolean} hover
31793 * @returns {boolean}
31794 * @protected
31795 */
31796
31797 }, {
31798 key: "needsRefresh",
31799 value: function needsRefresh(selected, hover) {
31800 if (this.refreshNeeded === true) {
31801 // This is probably not the best location to reset this member.
31802 // However, in the current logic, it is the most convenient one.
31803 this.refreshNeeded = false;
31804 return true;
31805 }
31806
31807 return this.width === undefined || this.labelModule.differentState(selected, hover);
31808 }
31809 /**
31810 *
31811 * @param {CanvasRenderingContext2D} ctx
31812 * @param {ArrowOptions} values
31813 */
31814
31815 }, {
31816 key: "initContextForDraw",
31817 value: function initContextForDraw(ctx, values) {
31818 var borderWidth = values.borderWidth / this.body.view.scale;
31819 ctx.lineWidth = Math.min(this.width, borderWidth);
31820 ctx.strokeStyle = values.borderColor;
31821 ctx.fillStyle = values.color;
31822 }
31823 /**
31824 *
31825 * @param {CanvasRenderingContext2D} ctx
31826 * @param {ArrowOptions} values
31827 */
31828
31829 }, {
31830 key: "performStroke",
31831 value: function performStroke(ctx, values) {
31832 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.
31833
31834 ctx.save(); // if borders are zero width, they will be drawn with width 1 by default. This prevents that
31835
31836 if (borderWidth > 0) {
31837 this.enableBorderDashes(ctx, values); //draw the border
31838
31839 ctx.stroke(); //disable dashed border for other elements
31840
31841 this.disableBorderDashes(ctx, values);
31842 }
31843
31844 ctx.restore();
31845 }
31846 /**
31847 *
31848 * @param {CanvasRenderingContext2D} ctx
31849 * @param {ArrowOptions} values
31850 */
31851
31852 }, {
31853 key: "performFill",
31854 value: function performFill(ctx, values) {
31855 // draw shadow if enabled
31856 this.enableShadow(ctx, values); // draw the background
31857
31858 ctx.fill(); // disable shadows for other elements.
31859
31860 this.disableShadow(ctx, values);
31861 this.performStroke(ctx, values);
31862 }
31863 /**
31864 *
31865 * @param {number} margin
31866 * @private
31867 */
31868
31869 }, {
31870 key: "_addBoundingBoxMargin",
31871 value: function _addBoundingBoxMargin(margin) {
31872 this.boundingBox.left -= margin;
31873 this.boundingBox.top -= margin;
31874 this.boundingBox.bottom += margin;
31875 this.boundingBox.right += margin;
31876 }
31877 /**
31878 * Actual implementation of this method call.
31879 *
31880 * Doing it like this makes it easier to override
31881 * in the child classes.
31882 *
31883 * @param {number} x width
31884 * @param {number} y height
31885 * @param {CanvasRenderingContext2D} ctx
31886 * @param {boolean} selected
31887 * @param {boolean} hover
31888 * @private
31889 */
31890
31891 }, {
31892 key: "_updateBoundingBox",
31893 value: function _updateBoundingBox(x, y, ctx, selected, hover) {
31894 if (ctx !== undefined) {
31895 this.resize(ctx, selected, hover);
31896 }
31897
31898 this.left = x - this.width / 2;
31899 this.top = y - this.height / 2;
31900 this.boundingBox.left = this.left;
31901 this.boundingBox.top = this.top;
31902 this.boundingBox.bottom = this.top + this.height;
31903 this.boundingBox.right = this.left + this.width;
31904 }
31905 /**
31906 * Default implementation of this method call.
31907 * This acts as a stub which can be overridden.
31908 *
31909 * @param {number} x width
31910 * @param {number} y height
31911 * @param {CanvasRenderingContext2D} ctx
31912 * @param {boolean} selected
31913 * @param {boolean} hover
31914 */
31915
31916 }, {
31917 key: "updateBoundingBox",
31918 value: function updateBoundingBox(x, y, ctx, selected, hover) {
31919 this._updateBoundingBox(x, y, ctx, selected, hover);
31920 }
31921 /**
31922 * Determine the dimensions to use for nodes with an internal label
31923 *
31924 * Currently, these are: Circle, Ellipse, Database, Box
31925 * The other nodes have external labels, and will not call this method
31926 *
31927 * If there is no label, decent default values are supplied.
31928 *
31929 * @param {CanvasRenderingContext2D} ctx
31930 * @param {boolean} [selected]
31931 * @param {boolean} [hover]
31932 * @returns {{width:number, height:number}}
31933 */
31934
31935 }, {
31936 key: "getDimensionsFromLabel",
31937 value: function getDimensionsFromLabel(ctx, selected, hover) {
31938 // NOTE: previously 'textSize' was not put in 'this' for Ellipse
31939 // TODO: examine the consequences.
31940 this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
31941 var width = this.textSize.width;
31942 var height = this.textSize.height;
31943 var DEFAULT_SIZE = 14;
31944
31945 if (width === 0) {
31946 // This happens when there is no label text set
31947 width = DEFAULT_SIZE; // use a decent default
31948
31949 height = DEFAULT_SIZE; // if width zero, then height also always zero
31950 }
31951
31952 return {
31953 width: width,
31954 height: height
31955 };
31956 }
31957 }]);
31958
31959 return NodeBase;
31960 }();
31961
31962 /**
31963 * A Box Node/Cluster shape.
31964 *
31965 * @extends NodeBase
31966 */
31967
31968 var Box =
31969 /*#__PURE__*/
31970 function (_NodeBase) {
31971 _inherits(Box, _NodeBase);
31972
31973 /**
31974 * @param {Object} options
31975 * @param {Object} body
31976 * @param {Label} labelModule
31977 */
31978 function Box(options, body, labelModule) {
31979 var _this;
31980
31981 _classCallCheck(this, Box);
31982
31983 _this = _possibleConstructorReturn(this, _getPrototypeOf(Box).call(this, options, body, labelModule));
31984
31985 _this._setMargins(labelModule);
31986
31987 return _this;
31988 }
31989 /**
31990 *
31991 * @param {CanvasRenderingContext2D} ctx
31992 * @param {boolean} [selected]
31993 * @param {boolean} [hover]
31994 */
31995
31996
31997 _createClass(Box, [{
31998 key: "resize",
31999 value: function resize(ctx) {
32000 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
32001 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
32002
32003 if (this.needsRefresh(selected, hover)) {
32004 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
32005 this.width = dimensions.width + this.margin.right + this.margin.left;
32006 this.height = dimensions.height + this.margin.top + this.margin.bottom;
32007 this.radius = this.width / 2;
32008 }
32009 }
32010 /**
32011 *
32012 * @param {CanvasRenderingContext2D} ctx
32013 * @param {number} x width
32014 * @param {number} y height
32015 * @param {boolean} selected
32016 * @param {boolean} hover
32017 * @param {ArrowOptions} values
32018 */
32019
32020 }, {
32021 key: "draw",
32022 value: function draw(ctx, x, y, selected, hover, values) {
32023 this.resize(ctx, selected, hover);
32024 this.left = x - this.width / 2;
32025 this.top = y - this.height / 2;
32026 this.initContextForDraw(ctx, values);
32027 ctx.roundRect(this.left, this.top, this.width, this.height, values.borderRadius);
32028 this.performFill(ctx, values);
32029 this.updateBoundingBox(x, y, ctx, selected, hover);
32030 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, this.top + this.textSize.height / 2 + this.margin.top, selected, hover);
32031 }
32032 /**
32033 *
32034 * @param {number} x width
32035 * @param {number} y height
32036 * @param {CanvasRenderingContext2D} ctx
32037 * @param {boolean} selected
32038 * @param {boolean} hover
32039 */
32040
32041 }, {
32042 key: "updateBoundingBox",
32043 value: function updateBoundingBox(x, y, ctx, selected, hover) {
32044 this._updateBoundingBox(x, y, ctx, selected, hover);
32045
32046 var borderRadius = this.options.shapeProperties.borderRadius; // only effective for box
32047
32048 this._addBoundingBoxMargin(borderRadius);
32049 }
32050 /**
32051 *
32052 * @param {CanvasRenderingContext2D} ctx
32053 * @param {number} angle
32054 * @returns {number}
32055 */
32056
32057 }, {
32058 key: "distanceToBorder",
32059 value: function distanceToBorder(ctx, angle) {
32060 this.resize(ctx);
32061 var borderWidth = this.options.borderWidth;
32062 return Math.min(Math.abs(this.width / 2 / Math.cos(angle)), Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
32063 }
32064 }]);
32065
32066 return Box;
32067 }(NodeBase);
32068
32069 /**
32070 * NOTE: This is a bad base class
32071 *
32072 * Child classes are:
32073 *
32074 * Image - uses *only* image methods
32075 * Circle - uses *only* _drawRawCircle
32076 * CircleImage - uses all
32077 *
32078 * TODO: Refactor, move _drawRawCircle to different module, derive Circle from NodeBase
32079 * Rename this to ImageBase
32080 * Consolidate common code in Image and CircleImage to base class
32081 *
32082 * @extends NodeBase
32083 */
32084
32085 var CircleImageBase =
32086 /*#__PURE__*/
32087 function (_NodeBase) {
32088 _inherits(CircleImageBase, _NodeBase);
32089
32090 /**
32091 * @param {Object} options
32092 * @param {Object} body
32093 * @param {Label} labelModule
32094 */
32095 function CircleImageBase(options, body, labelModule) {
32096 var _this;
32097
32098 _classCallCheck(this, CircleImageBase);
32099
32100 _this = _possibleConstructorReturn(this, _getPrototypeOf(CircleImageBase).call(this, options, body, labelModule));
32101 _this.labelOffset = 0;
32102 _this.selected = false;
32103 return _this;
32104 }
32105 /**
32106 *
32107 * @param {Object} options
32108 * @param {Object} [imageObj]
32109 * @param {Object} [imageObjAlt]
32110 */
32111
32112
32113 _createClass(CircleImageBase, [{
32114 key: "setOptions",
32115 value: function setOptions(options, imageObj, imageObjAlt) {
32116 this.options = options;
32117
32118 if (!(imageObj === undefined && imageObjAlt === undefined)) {
32119 this.setImages(imageObj, imageObjAlt);
32120 }
32121 }
32122 /**
32123 * Set the images for this node.
32124 *
32125 * The images can be updated after the initial setting of options;
32126 * therefore, this method needs to be reentrant.
32127 *
32128 * For correct working in error cases, it is necessary to properly set
32129 * field 'nodes.brokenImage' in the options.
32130 *
32131 * @param {Image} imageObj required; main image to show for this node
32132 * @param {Image|undefined} imageObjAlt optional; image to show when node is selected
32133 */
32134
32135 }, {
32136 key: "setImages",
32137 value: function setImages(imageObj, imageObjAlt) {
32138 if (imageObjAlt && this.selected) {
32139 this.imageObj = imageObjAlt;
32140 this.imageObjAlt = imageObj;
32141 } else {
32142 this.imageObj = imageObj;
32143 this.imageObjAlt = imageObjAlt;
32144 }
32145 }
32146 /**
32147 * Set selection and switch between the base and the selected image.
32148 *
32149 * Do the switch only if imageObjAlt exists.
32150 *
32151 * @param {boolean} selected value of new selected state for current node
32152 */
32153
32154 }, {
32155 key: "switchImages",
32156 value: function switchImages(selected) {
32157 var selection_changed = selected && !this.selected || !selected && this.selected;
32158 this.selected = selected; // Remember new selection
32159
32160 if (this.imageObjAlt !== undefined && selection_changed) {
32161 var imageTmp = this.imageObj;
32162 this.imageObj = this.imageObjAlt;
32163 this.imageObjAlt = imageTmp;
32164 }
32165 }
32166 /**
32167 * Returns Image Padding from node options
32168 *
32169 * @returns {{top: number,left: number,bottom: number,right: number}} image padding inside this shape
32170 * @private
32171 */
32172
32173 }, {
32174 key: "_getImagePadding",
32175 value: function _getImagePadding() {
32176 var imgPadding = {
32177 top: 0,
32178 right: 0,
32179 bottom: 0,
32180 left: 0
32181 };
32182
32183 if (this.options.imagePadding) {
32184 var optImgPadding = this.options.imagePadding;
32185
32186 if (_typeof(optImgPadding) == 'object') {
32187 imgPadding.top = optImgPadding.top;
32188 imgPadding.right = optImgPadding.right;
32189 imgPadding.bottom = optImgPadding.bottom;
32190 imgPadding.left = optImgPadding.left;
32191 } else {
32192 imgPadding.top = optImgPadding;
32193 imgPadding.right = optImgPadding;
32194 imgPadding.bottom = optImgPadding;
32195 imgPadding.left = optImgPadding;
32196 }
32197 }
32198
32199 return imgPadding;
32200 }
32201 /**
32202 * Adjust the node dimensions for a loaded image.
32203 *
32204 * Pre: this.imageObj is valid
32205 */
32206
32207 }, {
32208 key: "_resizeImage",
32209 value: function _resizeImage() {
32210 var width, height;
32211
32212 if (this.options.shapeProperties.useImageSize === false) {
32213 // Use the size property
32214 var ratio_width = 1;
32215 var ratio_height = 1; // Only calculate the proper ratio if both width and height not zero
32216
32217 if (this.imageObj.width && this.imageObj.height) {
32218 if (this.imageObj.width > this.imageObj.height) {
32219 ratio_width = this.imageObj.width / this.imageObj.height;
32220 } else {
32221 ratio_height = this.imageObj.height / this.imageObj.width;
32222 }
32223 }
32224
32225 width = this.options.size * 2 * ratio_width;
32226 height = this.options.size * 2 * ratio_height;
32227 } else {
32228 // Use the image size with image padding
32229 var imgPadding = this._getImagePadding();
32230
32231 width = this.imageObj.width + imgPadding.left + imgPadding.right;
32232 height = this.imageObj.height + imgPadding.top + imgPadding.bottom;
32233 }
32234
32235 this.width = width;
32236 this.height = height;
32237 this.radius = 0.5 * this.width;
32238 }
32239 /**
32240 *
32241 * @param {CanvasRenderingContext2D} ctx
32242 * @param {number} x width
32243 * @param {number} y height
32244 * @param {ArrowOptions} values
32245 * @private
32246 */
32247
32248 }, {
32249 key: "_drawRawCircle",
32250 value: function _drawRawCircle(ctx, x, y, values) {
32251 this.initContextForDraw(ctx, values);
32252 ctx.circle(x, y, values.size);
32253 this.performFill(ctx, values);
32254 }
32255 /**
32256 *
32257 * @param {CanvasRenderingContext2D} ctx
32258 * @param {ArrowOptions} values
32259 * @private
32260 */
32261
32262 }, {
32263 key: "_drawImageAtPosition",
32264 value: function _drawImageAtPosition(ctx, values) {
32265 if (this.imageObj.width != 0) {
32266 // draw the image
32267 ctx.globalAlpha = 1.0; // draw shadow if enabled
32268
32269 this.enableShadow(ctx, values);
32270 var factor = 1;
32271
32272 if (this.options.shapeProperties.interpolation === true) {
32273 factor = this.imageObj.width / this.width / this.body.view.scale;
32274 }
32275
32276 var imgPadding = this._getImagePadding();
32277
32278 var imgPosLeft = this.left + imgPadding.left;
32279 var imgPosTop = this.top + imgPadding.top;
32280 var imgWidth = this.width - imgPadding.left - imgPadding.right;
32281 var imgHeight = this.height - imgPadding.top - imgPadding.bottom;
32282 this.imageObj.drawImageAtPosition(ctx, factor, imgPosLeft, imgPosTop, imgWidth, imgHeight); // disable shadows for other elements.
32283
32284 this.disableShadow(ctx, values);
32285 }
32286 }
32287 /**
32288 *
32289 * @param {CanvasRenderingContext2D} ctx
32290 * @param {number} x width
32291 * @param {number} y height
32292 * @param {boolean} selected
32293 * @param {boolean} hover
32294 * @private
32295 */
32296
32297 }, {
32298 key: "_drawImageLabel",
32299 value: function _drawImageLabel(ctx, x, y, selected, hover) {
32300 var yLabel;
32301 var offset = 0;
32302
32303 if (this.height !== undefined) {
32304 offset = this.height * 0.5;
32305 var labelDimensions = this.labelModule.getTextSize(ctx, selected, hover);
32306
32307 if (labelDimensions.lineCount >= 1) {
32308 offset += labelDimensions.height / 2;
32309 }
32310 }
32311
32312 yLabel = y + offset;
32313
32314 if (this.options.label) {
32315 this.labelOffset = offset;
32316 }
32317
32318 this.labelModule.draw(ctx, x, yLabel, selected, hover, 'hanging');
32319 }
32320 }]);
32321
32322 return CircleImageBase;
32323 }(NodeBase);
32324
32325 /**
32326 * A Circle Node/Cluster shape.
32327 *
32328 * @extends CircleImageBase
32329 */
32330
32331 var Circle =
32332 /*#__PURE__*/
32333 function (_CircleImageBase) {
32334 _inherits(Circle, _CircleImageBase);
32335
32336 /**
32337 * @param {Object} options
32338 * @param {Object} body
32339 * @param {Label} labelModule
32340 */
32341 function Circle(options, body, labelModule) {
32342 var _this;
32343
32344 _classCallCheck(this, Circle);
32345
32346 _this = _possibleConstructorReturn(this, _getPrototypeOf(Circle).call(this, options, body, labelModule));
32347
32348 _this._setMargins(labelModule);
32349
32350 return _this;
32351 }
32352 /**
32353 *
32354 * @param {CanvasRenderingContext2D} ctx
32355 * @param {boolean} [selected]
32356 * @param {boolean} [hover]
32357 */
32358
32359
32360 _createClass(Circle, [{
32361 key: "resize",
32362 value: function resize(ctx) {
32363 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
32364 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
32365
32366 if (this.needsRefresh(selected, hover)) {
32367 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
32368 var diameter = Math.max(dimensions.width + this.margin.right + this.margin.left, dimensions.height + this.margin.top + this.margin.bottom);
32369 this.options.size = diameter / 2; // NOTE: this size field only set here, not in Ellipse, Database, Box
32370
32371 this.width = diameter;
32372 this.height = diameter;
32373 this.radius = this.width / 2;
32374 }
32375 }
32376 /**
32377 *
32378 * @param {CanvasRenderingContext2D} ctx
32379 * @param {number} x width
32380 * @param {number} y height
32381 * @param {boolean} selected
32382 * @param {boolean} hover
32383 * @param {ArrowOptions} values
32384 */
32385
32386 }, {
32387 key: "draw",
32388 value: function draw(ctx, x, y, selected, hover, values) {
32389 this.resize(ctx, selected, hover);
32390 this.left = x - this.width / 2;
32391 this.top = y - this.height / 2;
32392
32393 this._drawRawCircle(ctx, x, y, values);
32394
32395 this.updateBoundingBox(x, y);
32396 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, y, selected, hover);
32397 }
32398 /**
32399 *
32400 * @param {number} x width
32401 * @param {number} y height
32402 */
32403
32404 }, {
32405 key: "updateBoundingBox",
32406 value: function updateBoundingBox(x, y) {
32407 this.boundingBox.top = y - this.options.size;
32408 this.boundingBox.left = x - this.options.size;
32409 this.boundingBox.right = x + this.options.size;
32410 this.boundingBox.bottom = y + this.options.size;
32411 }
32412 /**
32413 *
32414 * @param {CanvasRenderingContext2D} ctx
32415 * @param {number} angle - Unused
32416 * @returns {number}
32417 */
32418
32419 }, {
32420 key: "distanceToBorder",
32421 value: function distanceToBorder(ctx, angle) {
32422 // eslint-disable-line no-unused-vars
32423 this.resize(ctx);
32424 return this.width * 0.5;
32425 }
32426 }]);
32427
32428 return Circle;
32429 }(CircleImageBase);
32430
32431 /**
32432 * A CircularImage Node/Cluster shape.
32433 *
32434 * @extends CircleImageBase
32435 */
32436
32437 var CircularImage =
32438 /*#__PURE__*/
32439 function (_CircleImageBase) {
32440 _inherits(CircularImage, _CircleImageBase);
32441
32442 /**
32443 * @param {Object} options
32444 * @param {Object} body
32445 * @param {Label} labelModule
32446 * @param {Image} imageObj
32447 * @param {Image} imageObjAlt
32448 */
32449 function CircularImage(options, body, labelModule, imageObj, imageObjAlt) {
32450 var _this;
32451
32452 _classCallCheck(this, CircularImage);
32453
32454 _this = _possibleConstructorReturn(this, _getPrototypeOf(CircularImage).call(this, options, body, labelModule));
32455
32456 _this.setImages(imageObj, imageObjAlt);
32457
32458 return _this;
32459 }
32460 /**
32461 *
32462 * @param {CanvasRenderingContext2D} ctx
32463 * @param {boolean} [selected]
32464 * @param {boolean} [hover]
32465 */
32466
32467
32468 _createClass(CircularImage, [{
32469 key: "resize",
32470 value: function resize(ctx) {
32471 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
32472 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
32473 var imageAbsent = this.imageObj.src === undefined || this.imageObj.width === undefined || this.imageObj.height === undefined;
32474
32475 if (imageAbsent) {
32476 var diameter = this.options.size * 2;
32477 this.width = diameter;
32478 this.height = diameter;
32479 this.radius = 0.5 * this.width;
32480 return;
32481 } // At this point, an image is present, i.e. this.imageObj is valid.
32482
32483
32484 if (this.needsRefresh(selected, hover)) {
32485 this._resizeImage();
32486 }
32487 }
32488 /**
32489 *
32490 * @param {CanvasRenderingContext2D} ctx
32491 * @param {number} x width
32492 * @param {number} y height
32493 * @param {boolean} selected
32494 * @param {boolean} hover
32495 * @param {ArrowOptions} values
32496 */
32497
32498 }, {
32499 key: "draw",
32500 value: function draw(ctx, x, y, selected, hover, values) {
32501 this.switchImages(selected);
32502 this.resize();
32503 this.left = x - this.width / 2;
32504 this.top = y - this.height / 2; // draw the background circle. IMPORTANT: the stroke in this method is used by the clip method below.
32505
32506 this._drawRawCircle(ctx, x, y, values); // now we draw in the circle, we save so we can revert the clip operation after drawing.
32507
32508
32509 ctx.save(); // clip is used to use the stroke in drawRawCircle as an area that we can draw in.
32510
32511 ctx.clip(); // draw the image
32512
32513 this._drawImageAtPosition(ctx, values); // restore so we can again draw on the full canvas
32514
32515
32516 ctx.restore();
32517
32518 this._drawImageLabel(ctx, x, y, selected, hover);
32519
32520 this.updateBoundingBox(x, y);
32521 } // TODO: compare with Circle.updateBoundingBox(), consolidate? More stuff is happening here
32522
32523 /**
32524 *
32525 * @param {number} x width
32526 * @param {number} y height
32527 */
32528
32529 }, {
32530 key: "updateBoundingBox",
32531 value: function updateBoundingBox(x, y) {
32532 this.boundingBox.top = y - this.options.size;
32533 this.boundingBox.left = x - this.options.size;
32534 this.boundingBox.right = x + this.options.size;
32535 this.boundingBox.bottom = y + this.options.size; // TODO: compare with Image.updateBoundingBox(), consolidate?
32536
32537 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
32538 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
32539 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelOffset);
32540 }
32541 /**
32542 *
32543 * @param {CanvasRenderingContext2D} ctx
32544 * @param {number} angle - Unused
32545 * @returns {number}
32546 */
32547
32548 }, {
32549 key: "distanceToBorder",
32550 value: function distanceToBorder(ctx, angle) {
32551 // eslint-disable-line no-unused-vars
32552 this.resize(ctx);
32553 return this.width * 0.5;
32554 }
32555 }]);
32556
32557 return CircularImage;
32558 }(CircleImageBase);
32559
32560 /**
32561 * A Database Node/Cluster shape.
32562 *
32563 * @extends NodeBase
32564 */
32565
32566 var Database =
32567 /*#__PURE__*/
32568 function (_NodeBase) {
32569 _inherits(Database, _NodeBase);
32570
32571 /**
32572 * @param {Object} options
32573 * @param {Object} body
32574 * @param {Label} labelModule
32575 */
32576 function Database(options, body, labelModule) {
32577 var _this;
32578
32579 _classCallCheck(this, Database);
32580
32581 _this = _possibleConstructorReturn(this, _getPrototypeOf(Database).call(this, options, body, labelModule));
32582
32583 _this._setMargins(labelModule);
32584
32585 return _this;
32586 }
32587 /**
32588 *
32589 * @param {CanvasRenderingContext2D} ctx
32590 * @param {boolean} selected
32591 * @param {boolean} hover
32592 */
32593
32594
32595 _createClass(Database, [{
32596 key: "resize",
32597 value: function resize(ctx, selected, hover) {
32598 if (this.needsRefresh(selected, hover)) {
32599 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
32600 var size = dimensions.width + this.margin.right + this.margin.left;
32601 this.width = size;
32602 this.height = size;
32603 this.radius = this.width / 2;
32604 }
32605 }
32606 /**
32607 *
32608 * @param {CanvasRenderingContext2D} ctx
32609 * @param {number} x width
32610 * @param {number} y height
32611 * @param {boolean} selected
32612 * @param {boolean} hover
32613 * @param {ArrowOptions} values
32614 */
32615
32616 }, {
32617 key: "draw",
32618 value: function draw(ctx, x, y, selected, hover, values) {
32619 this.resize(ctx, selected, hover);
32620 this.left = x - this.width / 2;
32621 this.top = y - this.height / 2;
32622 this.initContextForDraw(ctx, values);
32623 ctx.database(x - this.width / 2, y - this.height / 2, this.width, this.height);
32624 this.performFill(ctx, values);
32625 this.updateBoundingBox(x, y, ctx, selected, hover);
32626 this.labelModule.draw(ctx, this.left + this.textSize.width / 2 + this.margin.left, this.top + this.textSize.height / 2 + this.margin.top, selected, hover);
32627 }
32628 /**
32629 *
32630 * @param {CanvasRenderingContext2D} ctx
32631 * @param {number} angle
32632 * @returns {number}
32633 */
32634
32635 }, {
32636 key: "distanceToBorder",
32637 value: function distanceToBorder(ctx, angle) {
32638 return this._distanceToBorder(ctx, angle);
32639 }
32640 }]);
32641
32642 return Database;
32643 }(NodeBase);
32644
32645 /**
32646 * Base class for constructing Node/Cluster Shapes.
32647 *
32648 * @extends NodeBase
32649 */
32650
32651 var ShapeBase =
32652 /*#__PURE__*/
32653 function (_NodeBase) {
32654 _inherits(ShapeBase, _NodeBase);
32655
32656 /**
32657 * @param {Object} options
32658 * @param {Object} body
32659 * @param {Label} labelModule
32660 */
32661 function ShapeBase(options, body, labelModule) {
32662 _classCallCheck(this, ShapeBase);
32663
32664 return _possibleConstructorReturn(this, _getPrototypeOf(ShapeBase).call(this, options, body, labelModule));
32665 }
32666 /**
32667 *
32668 * @param {CanvasRenderingContext2D} ctx
32669 * @param {boolean} [selected]
32670 * @param {boolean} [hover]
32671 * @param {Object} [values={size: this.options.size}]
32672 */
32673
32674
32675 _createClass(ShapeBase, [{
32676 key: "resize",
32677 value: function resize(ctx) {
32678 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
32679 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
32680 var values = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
32681 size: this.options.size
32682 };
32683
32684 if (this.needsRefresh(selected, hover)) {
32685 this.labelModule.getTextSize(ctx, selected, hover);
32686 var size = 2 * values.size;
32687 this.width = size;
32688 this.height = size;
32689 this.radius = 0.5 * this.width;
32690 }
32691 }
32692 /**
32693 *
32694 * @param {CanvasRenderingContext2D} ctx
32695 * @param {string} shape
32696 * @param {number} sizeMultiplier - Unused! TODO: Remove next major release
32697 * @param {number} x
32698 * @param {number} y
32699 * @param {boolean} selected
32700 * @param {boolean} hover
32701 * @param {ArrowOptions} values
32702 * @private
32703 */
32704
32705 }, {
32706 key: "_drawShape",
32707 value: function _drawShape(ctx, shape, sizeMultiplier, x, y, selected, hover, values) {
32708 this.resize(ctx, selected, hover, values);
32709 this.left = x - this.width / 2;
32710 this.top = y - this.height / 2;
32711 this.initContextForDraw(ctx, values);
32712 ctx[shape](x, y, values.size);
32713 this.performFill(ctx, values);
32714
32715 if (this.options.icon !== undefined) {
32716 if (this.options.icon.code !== undefined) {
32717 ctx.font = (selected ? "bold " : "") + this.height / 2 + "px " + (this.options.icon.face || 'FontAwesome');
32718 ctx.fillStyle = this.options.icon.color || "black";
32719 ctx.textAlign = "center";
32720 ctx.textBaseline = "middle";
32721 ctx.fillText(this.options.icon.code, x, y);
32722 }
32723 }
32724
32725 if (this.options.label !== undefined) {
32726 // Need to call following here in order to ensure value for `this.labelModule.size.height`
32727 this.labelModule.calculateLabelSize(ctx, selected, hover, x, y, 'hanging');
32728 var yLabel = y + 0.5 * this.height + 0.5 * this.labelModule.size.height;
32729 this.labelModule.draw(ctx, x, yLabel, selected, hover, 'hanging');
32730 }
32731
32732 this.updateBoundingBox(x, y);
32733 }
32734 /**
32735 *
32736 * @param {number} x
32737 * @param {number} y
32738 */
32739
32740 }, {
32741 key: "updateBoundingBox",
32742 value: function updateBoundingBox(x, y) {
32743 this.boundingBox.top = y - this.options.size;
32744 this.boundingBox.left = x - this.options.size;
32745 this.boundingBox.right = x + this.options.size;
32746 this.boundingBox.bottom = y + this.options.size;
32747
32748 if (this.options.label !== undefined && this.labelModule.size.width > 0) {
32749 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
32750 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
32751 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelModule.size.height);
32752 }
32753 }
32754 }]);
32755
32756 return ShapeBase;
32757 }(NodeBase);
32758
32759 /**
32760 * A Diamond Node/Cluster shape.
32761 *
32762 * @extends ShapeBase
32763 */
32764
32765 var Diamond =
32766 /*#__PURE__*/
32767 function (_ShapeBase) {
32768 _inherits(Diamond, _ShapeBase);
32769
32770 /**
32771 * @param {Object} options
32772 * @param {Object} body
32773 * @param {Label} labelModule
32774 */
32775 function Diamond(options, body, labelModule) {
32776 _classCallCheck(this, Diamond);
32777
32778 return _possibleConstructorReturn(this, _getPrototypeOf(Diamond).call(this, options, body, labelModule));
32779 }
32780 /**
32781 *
32782 * @param {CanvasRenderingContext2D} ctx
32783 * @param {number} x width
32784 * @param {number} y height
32785 * @param {boolean} selected
32786 * @param {boolean} hover
32787 * @param {ArrowOptions} values
32788 */
32789
32790
32791 _createClass(Diamond, [{
32792 key: "draw",
32793 value: function draw(ctx, x, y, selected, hover, values) {
32794 this._drawShape(ctx, 'diamond', 4, x, y, selected, hover, values);
32795 }
32796 /**
32797 *
32798 * @param {CanvasRenderingContext2D} ctx
32799 * @param {number} angle
32800 * @returns {number}
32801 */
32802
32803 }, {
32804 key: "distanceToBorder",
32805 value: function distanceToBorder(ctx, angle) {
32806 return this._distanceToBorder(ctx, angle);
32807 }
32808 }]);
32809
32810 return Diamond;
32811 }(ShapeBase);
32812
32813 /**
32814 * A Dot Node/Cluster shape.
32815 *
32816 * @extends ShapeBase
32817 */
32818
32819 var Dot =
32820 /*#__PURE__*/
32821 function (_ShapeBase) {
32822 _inherits(Dot, _ShapeBase);
32823
32824 /**
32825 * @param {Object} options
32826 * @param {Object} body
32827 * @param {Label} labelModule
32828 */
32829 function Dot(options, body, labelModule) {
32830 _classCallCheck(this, Dot);
32831
32832 return _possibleConstructorReturn(this, _getPrototypeOf(Dot).call(this, options, body, labelModule));
32833 }
32834 /**
32835 *
32836 * @param {CanvasRenderingContext2D} ctx
32837 * @param {number} x width
32838 * @param {number} y height
32839 * @param {boolean} selected
32840 * @param {boolean} hover
32841 * @param {ArrowOptions} values
32842 */
32843
32844
32845 _createClass(Dot, [{
32846 key: "draw",
32847 value: function draw(ctx, x, y, selected, hover, values) {
32848 this._drawShape(ctx, 'circle', 2, x, y, selected, hover, values);
32849 }
32850 /**
32851 *
32852 * @param {CanvasRenderingContext2D} ctx
32853 * @param {number} angle
32854 * @returns {number}
32855 */
32856
32857 }, {
32858 key: "distanceToBorder",
32859 value: function distanceToBorder(ctx, angle) {
32860 // eslint-disable-line no-unused-vars
32861 this.resize(ctx);
32862 return this.options.size;
32863 }
32864 }]);
32865
32866 return Dot;
32867 }(ShapeBase);
32868
32869 /**
32870 * Am Ellipse Node/Cluster shape.
32871 *
32872 * @extends NodeBase
32873 */
32874
32875 var Ellipse =
32876 /*#__PURE__*/
32877 function (_NodeBase) {
32878 _inherits(Ellipse, _NodeBase);
32879
32880 /**
32881 * @param {Object} options
32882 * @param {Object} body
32883 * @param {Label} labelModule
32884 */
32885 function Ellipse(options, body, labelModule) {
32886 _classCallCheck(this, Ellipse);
32887
32888 return _possibleConstructorReturn(this, _getPrototypeOf(Ellipse).call(this, options, body, labelModule));
32889 }
32890 /**
32891 *
32892 * @param {CanvasRenderingContext2D} ctx
32893 * @param {boolean} [selected]
32894 * @param {boolean} [hover]
32895 */
32896
32897
32898 _createClass(Ellipse, [{
32899 key: "resize",
32900 value: function resize(ctx) {
32901 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
32902 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
32903
32904 if (this.needsRefresh(selected, hover)) {
32905 var dimensions = this.getDimensionsFromLabel(ctx, selected, hover);
32906 this.height = dimensions.height * 2;
32907 this.width = dimensions.width + dimensions.height;
32908 this.radius = 0.5 * this.width;
32909 }
32910 }
32911 /**
32912 *
32913 * @param {CanvasRenderingContext2D} ctx
32914 * @param {number} x width
32915 * @param {number} y height
32916 * @param {boolean} selected
32917 * @param {boolean} hover
32918 * @param {ArrowOptions} values
32919 */
32920
32921 }, {
32922 key: "draw",
32923 value: function draw(ctx, x, y, selected, hover, values) {
32924 this.resize(ctx, selected, hover);
32925 this.left = x - this.width * 0.5;
32926 this.top = y - this.height * 0.5;
32927 this.initContextForDraw(ctx, values);
32928 ctx.ellipse_vis(this.left, this.top, this.width, this.height);
32929 this.performFill(ctx, values);
32930 this.updateBoundingBox(x, y, ctx, selected, hover);
32931 this.labelModule.draw(ctx, x, y, selected, hover);
32932 }
32933 /**
32934 *
32935 * @param {CanvasRenderingContext2D} ctx
32936 * @param {number} angle
32937 * @returns {number}
32938 */
32939
32940 }, {
32941 key: "distanceToBorder",
32942 value: function distanceToBorder(ctx, angle) {
32943 this.resize(ctx);
32944 var a = this.width * 0.5;
32945 var b = this.height * 0.5;
32946 var w = Math.sin(angle) * a;
32947 var h = Math.cos(angle) * b;
32948 return a * b / Math.sqrt(w * w + h * h);
32949 }
32950 }]);
32951
32952 return Ellipse;
32953 }(NodeBase);
32954
32955 /**
32956 * An icon replacement for the default Node shape.
32957 *
32958 * @extends NodeBase
32959 */
32960
32961 var Icon =
32962 /*#__PURE__*/
32963 function (_NodeBase) {
32964 _inherits(Icon, _NodeBase);
32965
32966 /**
32967 * @param {Object} options
32968 * @param {Object} body
32969 * @param {Label} labelModule
32970 */
32971 function Icon(options, body, labelModule) {
32972 var _this;
32973
32974 _classCallCheck(this, Icon);
32975
32976 _this = _possibleConstructorReturn(this, _getPrototypeOf(Icon).call(this, options, body, labelModule));
32977
32978 _this._setMargins(labelModule);
32979
32980 return _this;
32981 }
32982 /**
32983 *
32984 * @param {CanvasRenderingContext2D} ctx - Unused.
32985 * @param {boolean} [selected]
32986 * @param {boolean} [hover]
32987 */
32988
32989
32990 _createClass(Icon, [{
32991 key: "resize",
32992 value: function resize(ctx, selected, hover) {
32993 if (this.needsRefresh(selected, hover)) {
32994 this.iconSize = {
32995 width: Number(this.options.icon.size),
32996 height: Number(this.options.icon.size)
32997 };
32998 this.width = this.iconSize.width + this.margin.right + this.margin.left;
32999 this.height = this.iconSize.height + this.margin.top + this.margin.bottom;
33000 this.radius = 0.5 * this.width;
33001 }
33002 }
33003 /**
33004 *
33005 * @param {CanvasRenderingContext2D} ctx
33006 * @param {number} x width
33007 * @param {number} y height
33008 * @param {boolean} selected
33009 * @param {boolean} hover
33010 * @param {ArrowOptions} values
33011 */
33012
33013 }, {
33014 key: "draw",
33015 value: function draw(ctx, x, y, selected, hover, values) {
33016 this.resize(ctx, selected, hover);
33017 this.options.icon.size = this.options.icon.size || 50;
33018 this.left = x - this.width / 2;
33019 this.top = y - this.height / 2;
33020
33021 this._icon(ctx, x, y, selected, hover, values);
33022
33023 if (this.options.label !== undefined) {
33024 var iconTextSpacing = 5;
33025 this.labelModule.draw(ctx, this.left + this.iconSize.width / 2 + this.margin.left, y + this.height / 2 + iconTextSpacing, selected);
33026 }
33027
33028 this.updateBoundingBox(x, y);
33029 }
33030 /**
33031 *
33032 * @param {number} x
33033 * @param {number} y
33034 */
33035
33036 }, {
33037 key: "updateBoundingBox",
33038 value: function updateBoundingBox(x, y) {
33039 this.boundingBox.top = y - this.options.icon.size * 0.5;
33040 this.boundingBox.left = x - this.options.icon.size * 0.5;
33041 this.boundingBox.right = x + this.options.icon.size * 0.5;
33042 this.boundingBox.bottom = y + this.options.icon.size * 0.5;
33043
33044 if (this.options.label !== undefined && this.labelModule.size.width > 0) {
33045 var iconTextSpacing = 5;
33046 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
33047 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
33048 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelModule.size.height + iconTextSpacing);
33049 }
33050 }
33051 /**
33052 *
33053 * @param {CanvasRenderingContext2D} ctx
33054 * @param {number} x width
33055 * @param {number} y height
33056 * @param {boolean} selected
33057 * @param {boolean} hover - Unused
33058 * @param {ArrowOptions} values
33059 */
33060
33061 }, {
33062 key: "_icon",
33063 value: function _icon(ctx, x, y, selected, hover, values) {
33064 var iconSize = Number(this.options.icon.size);
33065
33066 if (this.options.icon.code !== undefined) {
33067 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
33068 // properly) substitute slightly bigger size for bold font face.
33069 (this.options.icon.weight != null && selected ? 5 : 0) + iconSize + "px", this.options.icon.face].join(" "); // draw icon
33070
33071 ctx.fillStyle = this.options.icon.color || "black";
33072 ctx.textAlign = "center";
33073 ctx.textBaseline = "middle"; // draw shadow if enabled
33074
33075 this.enableShadow(ctx, values);
33076 ctx.fillText(this.options.icon.code, x, y); // disable shadows for other elements.
33077
33078 this.disableShadow(ctx, values);
33079 } else {
33080 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.');
33081 }
33082 }
33083 /**
33084 *
33085 * @param {CanvasRenderingContext2D} ctx
33086 * @param {number} angle
33087 * @returns {number}
33088 */
33089
33090 }, {
33091 key: "distanceToBorder",
33092 value: function distanceToBorder(ctx, angle) {
33093 return this._distanceToBorder(ctx, angle);
33094 }
33095 }]);
33096
33097 return Icon;
33098 }(NodeBase);
33099
33100 /**
33101 * An image-based replacement for the default Node shape.
33102 *
33103 * @extends CircleImageBase
33104 */
33105
33106 var Image$1 =
33107 /*#__PURE__*/
33108 function (_CircleImageBase) {
33109 _inherits(Image, _CircleImageBase);
33110
33111 /**
33112 * @param {Object} options
33113 * @param {Object} body
33114 * @param {Label} labelModule
33115 * @param {Image} imageObj
33116 * @param {Image} imageObjAlt
33117 */
33118 function Image(options, body, labelModule, imageObj, imageObjAlt) {
33119 var _this;
33120
33121 _classCallCheck(this, Image);
33122
33123 _this = _possibleConstructorReturn(this, _getPrototypeOf(Image).call(this, options, body, labelModule));
33124
33125 _this.setImages(imageObj, imageObjAlt);
33126
33127 return _this;
33128 }
33129 /**
33130 *
33131 * @param {CanvasRenderingContext2D} ctx - Unused.
33132 * @param {boolean} [selected]
33133 * @param {boolean} [hover]
33134 */
33135
33136
33137 _createClass(Image, [{
33138 key: "resize",
33139 value: function resize(ctx) {
33140 var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selected;
33141 var hover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.hover;
33142 var imageAbsent = this.imageObj.src === undefined || this.imageObj.width === undefined || this.imageObj.height === undefined;
33143
33144 if (imageAbsent) {
33145 var side = this.options.size * 2;
33146 this.width = side;
33147 this.height = side;
33148 return;
33149 }
33150
33151 if (this.needsRefresh(selected, hover)) {
33152 this._resizeImage();
33153 }
33154 }
33155 /**
33156 *
33157 * @param {CanvasRenderingContext2D} ctx
33158 * @param {number} x width
33159 * @param {number} y height
33160 * @param {boolean} selected
33161 * @param {boolean} hover
33162 * @param {ArrowOptions} values
33163 */
33164
33165 }, {
33166 key: "draw",
33167 value: function draw(ctx, x, y, selected, hover, values) {
33168 this.switchImages(selected);
33169 this.resize();
33170 this.left = x - this.width / 2;
33171 this.top = y - this.height / 2;
33172
33173 if (this.options.shapeProperties.useBorderWithImage === true) {
33174 var neutralborderWidth = this.options.borderWidth;
33175 var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth;
33176 var borderWidth = (selected ? selectionLineWidth : neutralborderWidth) / this.body.view.scale;
33177 ctx.lineWidth = Math.min(this.width, borderWidth);
33178 ctx.beginPath(); // setup the line properties.
33179
33180 ctx.strokeStyle = selected ? this.options.color.highlight.border : hover ? this.options.color.hover.border : this.options.color.border; // set a fillstyle
33181
33182 ctx.fillStyle = selected ? this.options.color.highlight.background : hover ? this.options.color.hover.background : this.options.color.background; // 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
33183
33184 ctx.rect(this.left - 0.5 * ctx.lineWidth, this.top - 0.5 * ctx.lineWidth, this.width + ctx.lineWidth, this.height + ctx.lineWidth);
33185 ctx.fill();
33186 this.performStroke(ctx, values);
33187 ctx.closePath();
33188 }
33189
33190 this._drawImageAtPosition(ctx, values);
33191
33192 this._drawImageLabel(ctx, x, y, selected, hover);
33193
33194 this.updateBoundingBox(x, y);
33195 }
33196 /**
33197 *
33198 * @param {number} x
33199 * @param {number} y
33200 */
33201
33202 }, {
33203 key: "updateBoundingBox",
33204 value: function updateBoundingBox(x, y) {
33205 this.resize();
33206
33207 this._updateBoundingBox(x, y);
33208
33209 if (this.options.label !== undefined && this.labelModule.size.width > 0) {
33210 this.boundingBox.left = Math.min(this.boundingBox.left, this.labelModule.size.left);
33211 this.boundingBox.right = Math.max(this.boundingBox.right, this.labelModule.size.left + this.labelModule.size.width);
33212 this.boundingBox.bottom = Math.max(this.boundingBox.bottom, this.boundingBox.bottom + this.labelOffset);
33213 }
33214 }
33215 /**
33216 *
33217 * @param {CanvasRenderingContext2D} ctx
33218 * @param {number} angle
33219 * @returns {number}
33220 */
33221
33222 }, {
33223 key: "distanceToBorder",
33224 value: function distanceToBorder(ctx, angle) {
33225 return this._distanceToBorder(ctx, angle);
33226 }
33227 }]);
33228
33229 return Image;
33230 }(CircleImageBase);
33231
33232 /**
33233 * A Square Node/Cluster shape.
33234 *
33235 * @extends ShapeBase
33236 */
33237
33238 var Square =
33239 /*#__PURE__*/
33240 function (_ShapeBase) {
33241 _inherits(Square, _ShapeBase);
33242
33243 /**
33244 * @param {Object} options
33245 * @param {Object} body
33246 * @param {Label} labelModule
33247 */
33248 function Square(options, body, labelModule) {
33249 _classCallCheck(this, Square);
33250
33251 return _possibleConstructorReturn(this, _getPrototypeOf(Square).call(this, options, body, labelModule));
33252 }
33253 /**
33254 *
33255 * @param {CanvasRenderingContext2D} ctx
33256 * @param {number} x width
33257 * @param {number} y height
33258 * @param {boolean} selected
33259 * @param {boolean} hover
33260 * @param {ArrowOptions} values
33261 */
33262
33263
33264 _createClass(Square, [{
33265 key: "draw",
33266 value: function draw(ctx, x, y, selected, hover, values) {
33267 this._drawShape(ctx, 'square', 2, x, y, selected, hover, values);
33268 }
33269 /**
33270 *
33271 * @param {CanvasRenderingContext2D} ctx
33272 * @param {number} angle
33273 * @returns {number}
33274 */
33275
33276 }, {
33277 key: "distanceToBorder",
33278 value: function distanceToBorder(ctx, angle) {
33279 return this._distanceToBorder(ctx, angle);
33280 }
33281 }]);
33282
33283 return Square;
33284 }(ShapeBase);
33285
33286 /**
33287 * A Hexagon Node/Cluster shape.
33288 *
33289 * @extends ShapeBase
33290 */
33291
33292 var Hexagon =
33293 /*#__PURE__*/
33294 function (_ShapeBase) {
33295 _inherits(Hexagon, _ShapeBase);
33296
33297 /**
33298 * @param {Object} options
33299 * @param {Object} body
33300 * @param {Label} labelModule
33301 */
33302 function Hexagon(options, body, labelModule) {
33303 _classCallCheck(this, Hexagon);
33304
33305 return _possibleConstructorReturn(this, _getPrototypeOf(Hexagon).call(this, options, body, labelModule));
33306 }
33307 /**
33308 *
33309 * @param {CanvasRenderingContext2D} ctx
33310 * @param {number} x width
33311 * @param {number} y height
33312 * @param {boolean} selected
33313 * @param {boolean} hover
33314 * @param {ArrowOptions} values
33315 */
33316
33317
33318 _createClass(Hexagon, [{
33319 key: "draw",
33320 value: function draw(ctx, x, y, selected, hover, values) {
33321 this._drawShape(ctx, 'hexagon', 4, x, y, selected, hover, values);
33322 }
33323 /**
33324 *
33325 * @param {CanvasRenderingContext2D} ctx
33326 * @param {number} angle
33327 * @returns {number}
33328 */
33329
33330 }, {
33331 key: "distanceToBorder",
33332 value: function distanceToBorder(ctx, angle) {
33333 return this._distanceToBorder(ctx, angle);
33334 }
33335 }]);
33336
33337 return Hexagon;
33338 }(ShapeBase);
33339
33340 /**
33341 * A Star Node/Cluster shape.
33342 *
33343 * @extends ShapeBase
33344 */
33345
33346 var Star =
33347 /*#__PURE__*/
33348 function (_ShapeBase) {
33349 _inherits(Star, _ShapeBase);
33350
33351 /**
33352 * @param {Object} options
33353 * @param {Object} body
33354 * @param {Label} labelModule
33355 */
33356 function Star(options, body, labelModule) {
33357 _classCallCheck(this, Star);
33358
33359 return _possibleConstructorReturn(this, _getPrototypeOf(Star).call(this, options, body, labelModule));
33360 }
33361 /**
33362 *
33363 * @param {CanvasRenderingContext2D} ctx
33364 * @param {number} x width
33365 * @param {number} y height
33366 * @param {boolean} selected
33367 * @param {boolean} hover
33368 * @param {ArrowOptions} values
33369 */
33370
33371
33372 _createClass(Star, [{
33373 key: "draw",
33374 value: function draw(ctx, x, y, selected, hover, values) {
33375 this._drawShape(ctx, 'star', 4, x, y, selected, hover, values);
33376 }
33377 /**
33378 *
33379 * @param {CanvasRenderingContext2D} ctx
33380 * @param {number} angle
33381 * @returns {number}
33382 */
33383
33384 }, {
33385 key: "distanceToBorder",
33386 value: function distanceToBorder(ctx, angle) {
33387 return this._distanceToBorder(ctx, angle);
33388 }
33389 }]);
33390
33391 return Star;
33392 }(ShapeBase);
33393
33394 /**
33395 * A text-based replacement for the default Node shape.
33396 *
33397 * @extends NodeBase
33398 */
33399
33400 var Text =
33401 /*#__PURE__*/
33402 function (_NodeBase) {
33403 _inherits(Text, _NodeBase);
33404
33405 /**
33406 * @param {Object} options
33407 * @param {Object} body
33408 * @param {Label} labelModule
33409 */
33410 function Text(options, body, labelModule) {
33411 var _this;
33412
33413 _classCallCheck(this, Text);
33414
33415 _this = _possibleConstructorReturn(this, _getPrototypeOf(Text).call(this, options, body, labelModule));
33416
33417 _this._setMargins(labelModule);
33418
33419 return _this;
33420 }
33421 /**
33422 *
33423 * @param {CanvasRenderingContext2D} ctx
33424 * @param {boolean} selected
33425 * @param {boolean} hover
33426 */
33427
33428
33429 _createClass(Text, [{
33430 key: "resize",
33431 value: function resize(ctx, selected, hover) {
33432 if (this.needsRefresh(selected, hover)) {
33433 this.textSize = this.labelModule.getTextSize(ctx, selected, hover);
33434 this.width = this.textSize.width + this.margin.right + this.margin.left;
33435 this.height = this.textSize.height + this.margin.top + this.margin.bottom;
33436 this.radius = 0.5 * this.width;
33437 }
33438 }
33439 /**
33440 *
33441 * @param {CanvasRenderingContext2D} ctx
33442 * @param {number} x width
33443 * @param {number} y height
33444 * @param {boolean} selected
33445 * @param {boolean} hover
33446 * @param {ArrowOptions} values
33447 */
33448
33449 }, {
33450 key: "draw",
33451 value: function draw(ctx, x, y, selected, hover, values) {
33452 this.resize(ctx, selected, hover);
33453 this.left = x - this.width / 2;
33454 this.top = y - this.height / 2; // draw shadow if enabled
33455
33456 this.enableShadow(ctx, values);
33457 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.
33458
33459 this.disableShadow(ctx, values);
33460 this.updateBoundingBox(x, y, ctx, selected, hover);
33461 }
33462 /**
33463 *
33464 * @param {CanvasRenderingContext2D} ctx
33465 * @param {number} angle
33466 * @returns {number}
33467 */
33468
33469 }, {
33470 key: "distanceToBorder",
33471 value: function distanceToBorder(ctx, angle) {
33472 return this._distanceToBorder(ctx, angle);
33473 }
33474 }]);
33475
33476 return Text;
33477 }(NodeBase);
33478
33479 /**
33480 * A Triangle Node/Cluster shape.
33481 *
33482 * @extends ShapeBase
33483 */
33484
33485 var Triangle =
33486 /*#__PURE__*/
33487 function (_ShapeBase) {
33488 _inherits(Triangle, _ShapeBase);
33489
33490 /**
33491 * @param {Object} options
33492 * @param {Object} body
33493 * @param {Label} labelModule
33494 */
33495 function Triangle(options, body, labelModule) {
33496 _classCallCheck(this, Triangle);
33497
33498 return _possibleConstructorReturn(this, _getPrototypeOf(Triangle).call(this, options, body, labelModule));
33499 }
33500 /**
33501 *
33502 * @param {CanvasRenderingContext2D} ctx
33503 * @param {number} x
33504 * @param {number} y
33505 * @param {boolean} selected
33506 * @param {boolean} hover
33507 * @param {ArrowOptions} values
33508 */
33509
33510
33511 _createClass(Triangle, [{
33512 key: "draw",
33513 value: function draw(ctx, x, y, selected, hover, values) {
33514 this._drawShape(ctx, 'triangle', 3, x, y, selected, hover, values);
33515 }
33516 /**
33517 *
33518 * @param {CanvasRenderingContext2D} ctx
33519 * @param {number} angle
33520 * @returns {number}
33521 */
33522
33523 }, {
33524 key: "distanceToBorder",
33525 value: function distanceToBorder(ctx, angle) {
33526 return this._distanceToBorder(ctx, angle);
33527 }
33528 }]);
33529
33530 return Triangle;
33531 }(ShapeBase);
33532
33533 /**
33534 * A downward facing Triangle Node/Cluster shape.
33535 *
33536 * @extends ShapeBase
33537 */
33538
33539 var TriangleDown =
33540 /*#__PURE__*/
33541 function (_ShapeBase) {
33542 _inherits(TriangleDown, _ShapeBase);
33543
33544 /**
33545 * @param {Object} options
33546 * @param {Object} body
33547 * @param {Label} labelModule
33548 */
33549 function TriangleDown(options, body, labelModule) {
33550 _classCallCheck(this, TriangleDown);
33551
33552 return _possibleConstructorReturn(this, _getPrototypeOf(TriangleDown).call(this, options, body, labelModule));
33553 }
33554 /**
33555 *
33556 * @param {CanvasRenderingContext2D} ctx
33557 * @param {number} x
33558 * @param {number} y
33559 * @param {boolean} selected
33560 * @param {boolean} hover
33561 * @param {ArrowOptions} values
33562 */
33563
33564
33565 _createClass(TriangleDown, [{
33566 key: "draw",
33567 value: function draw(ctx, x, y, selected, hover, values) {
33568 this._drawShape(ctx, 'triangleDown', 3, x, y, selected, hover, values);
33569 }
33570 /**
33571 *
33572 * @param {CanvasRenderingContext2D} ctx
33573 * @param {number} angle
33574 * @returns {number}
33575 */
33576
33577 }, {
33578 key: "distanceToBorder",
33579 value: function distanceToBorder(ctx, angle) {
33580 return this._distanceToBorder(ctx, angle);
33581 }
33582 }]);
33583
33584 return TriangleDown;
33585 }(ShapeBase);
33586
33587 var errorFound = false;
33588 var allOptions;
33589 var printStyle = 'background: #FFeeee; color: #dd0000';
33590 /**
33591 * Used to validate options.
33592 */
33593
33594 var Validator =
33595 /*#__PURE__*/
33596 function () {
33597 /**
33598 * @ignore
33599 */
33600 function Validator() {
33601 _classCallCheck(this, Validator);
33602 }
33603 /**
33604 * Main function to be called
33605 * @param {Object} options
33606 * @param {Object} referenceOptions
33607 * @param {Object} subObject
33608 * @returns {boolean}
33609 * @static
33610 */
33611
33612
33613 _createClass(Validator, null, [{
33614 key: "validate",
33615 value: function validate(options, referenceOptions, subObject) {
33616 errorFound = false;
33617 allOptions = referenceOptions;
33618 var usedOptions = referenceOptions;
33619
33620 if (subObject !== undefined) {
33621 usedOptions = referenceOptions[subObject];
33622 }
33623
33624 Validator.parse(options, usedOptions, []);
33625 return errorFound;
33626 }
33627 /**
33628 * Will traverse an object recursively and check every value
33629 * @param {Object} options
33630 * @param {Object} referenceOptions
33631 * @param {array} path | where to look for the actual option
33632 * @static
33633 */
33634
33635 }, {
33636 key: "parse",
33637 value: function parse(options, referenceOptions, path) {
33638 for (var option in options) {
33639 if (options.hasOwnProperty(option)) {
33640 Validator.check(option, options, referenceOptions, path);
33641 }
33642 }
33643 }
33644 /**
33645 * Check every value. If the value is an object, call the parse function on that object.
33646 * @param {string} option
33647 * @param {Object} options
33648 * @param {Object} referenceOptions
33649 * @param {array} path | where to look for the actual option
33650 * @static
33651 */
33652
33653 }, {
33654 key: "check",
33655 value: function check(option, options, referenceOptions, path) {
33656 if (referenceOptions[option] === undefined && referenceOptions.__any__ === undefined) {
33657 Validator.getSuggestion(option, referenceOptions, path);
33658 return;
33659 }
33660
33661 var referenceOption = option;
33662 var is_object = true;
33663
33664 if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {
33665 // NOTE: This only triggers if the __any__ is in the top level of the options object.
33666 // THAT'S A REALLY BAD PLACE TO ALLOW IT!!!!
33667 // TODO: Examine if needed, remove if possible
33668 // __any__ is a wildcard. Any value is accepted and will be further analysed by reference.
33669 referenceOption = '__any__'; // if the any-subgroup is not a predefined object in the configurator,
33670 // we do not look deeper into the object.
33671
33672 is_object = Validator.getType(options[option]) === 'object';
33673 }
33674
33675 var refOptionObj = referenceOptions[referenceOption];
33676
33677 if (is_object && refOptionObj.__type__ !== undefined) {
33678 refOptionObj = refOptionObj.__type__;
33679 }
33680
33681 Validator.checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path);
33682 }
33683 /**
33684 *
33685 * @param {string} option | the option property
33686 * @param {Object} options | The supplied options object
33687 * @param {Object} referenceOptions | The reference options containing all options and their allowed formats
33688 * @param {string} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
33689 * @param {string} refOptionObj | This is the type object from the reference options
33690 * @param {Array} path | where in the object is the option
33691 * @static
33692 */
33693
33694 }, {
33695 key: "checkFields",
33696 value: function checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path) {
33697 var log = function log(message) {
33698 console.log('%c' + message + Validator.printLocation(path, option), printStyle);
33699 };
33700
33701 var optionType = Validator.getType(options[option]);
33702 var refOptionType = refOptionObj[optionType];
33703
33704 if (refOptionType !== undefined) {
33705 // if the type is correct, we check if it is supposed to be one of a few select values
33706 if (Validator.getType(refOptionType) === 'array' && refOptionType.indexOf(options[option]) === -1) {
33707 log('Invalid option detected in "' + option + '".' + ' Allowed values are:' + Validator.print(refOptionType) + ' not "' + options[option] + '". ');
33708 errorFound = true;
33709 } else if (optionType === 'object' && referenceOption !== "__any__") {
33710 path = copyAndExtendArray(path, option);
33711 Validator.parse(options[option], referenceOptions[referenceOption], path);
33712 }
33713 } else if (refOptionObj['any'] === undefined) {
33714 // type of the field is incorrect and the field cannot be any
33715 log('Invalid type received for "' + option + '". Expected: ' + Validator.print(Object.keys(refOptionObj)) + '. Received [' + optionType + '] "' + options[option] + '"');
33716 errorFound = true;
33717 }
33718 }
33719 /**
33720 *
33721 * @param {Object|boolean|number|string|Array.<number>|Date|Node|Moment|undefined|null} object
33722 * @returns {string}
33723 * @static
33724 */
33725
33726 }, {
33727 key: "getType",
33728 value: function getType(object) {
33729 var type = _typeof(object);
33730
33731 if (type === 'object') {
33732 if (object === null) {
33733 return 'null';
33734 }
33735
33736 if (object instanceof Boolean) {
33737 return 'boolean';
33738 }
33739
33740 if (object instanceof Number) {
33741 return 'number';
33742 }
33743
33744 if (object instanceof String) {
33745 return 'string';
33746 }
33747
33748 if (Array.isArray(object)) {
33749 return 'array';
33750 }
33751
33752 if (object instanceof Date) {
33753 return 'date';
33754 }
33755
33756 if (object.nodeType !== undefined) {
33757 return 'dom';
33758 }
33759
33760 if (object._isAMomentObject === true) {
33761 return 'moment';
33762 }
33763
33764 return 'object';
33765 } else if (type === 'number') {
33766 return 'number';
33767 } else if (type === 'boolean') {
33768 return 'boolean';
33769 } else if (type === 'string') {
33770 return 'string';
33771 } else if (type === undefined) {
33772 return 'undefined';
33773 }
33774
33775 return type;
33776 }
33777 /**
33778 * @param {string} option
33779 * @param {Object} options
33780 * @param {Array.<string>} path
33781 * @static
33782 */
33783
33784 }, {
33785 key: "getSuggestion",
33786 value: function getSuggestion(option, options, path) {
33787 var localSearch = Validator.findInOptions(option, options, path, false);
33788 var globalSearch = Validator.findInOptions(option, allOptions, [], true);
33789 var localSearchThreshold = 8;
33790 var globalSearchThreshold = 4;
33791 var msg;
33792
33793 if (localSearch.indexMatch !== undefined) {
33794 msg = ' in ' + Validator.printLocation(localSearch.path, option, '') + 'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n';
33795 } else if (globalSearch.distance <= globalSearchThreshold && localSearch.distance > globalSearch.distance) {
33796 msg = ' in ' + Validator.printLocation(localSearch.path, option, '') + 'Perhaps it was misplaced? Matching option found at: ' + Validator.printLocation(globalSearch.path, globalSearch.closestMatch, '');
33797 } else if (localSearch.distance <= localSearchThreshold) {
33798 msg = '. Did you mean "' + localSearch.closestMatch + '"?' + Validator.printLocation(localSearch.path, option);
33799 } else {
33800 msg = '. Did you mean one of these: ' + Validator.print(Object.keys(options)) + Validator.printLocation(path, option);
33801 }
33802
33803 console.log('%cUnknown option detected: "' + option + '"' + msg, printStyle);
33804 errorFound = true;
33805 }
33806 /**
33807 * traverse the options in search for a match.
33808 * @param {string} option
33809 * @param {Object} options
33810 * @param {Array} path | where to look for the actual option
33811 * @param {boolean} [recursive=false]
33812 * @returns {{closestMatch: string, path: Array, distance: number}}
33813 * @static
33814 */
33815
33816 }, {
33817 key: "findInOptions",
33818 value: function findInOptions(option, options, path) {
33819 var recursive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
33820 var min = 1e9;
33821 var closestMatch = '';
33822 var closestMatchPath = [];
33823 var lowerCaseOption = option.toLowerCase();
33824 var indexMatch = undefined;
33825
33826 for (var op in options) {
33827 // eslint-disable-line guard-for-in
33828 var distance = void 0;
33829
33830 if (options[op].__type__ !== undefined && recursive === true) {
33831 var result = Validator.findInOptions(option, options[op], copyAndExtendArray(path, op));
33832
33833 if (min > result.distance) {
33834 closestMatch = result.closestMatch;
33835 closestMatchPath = result.path;
33836 min = result.distance;
33837 indexMatch = result.indexMatch;
33838 }
33839 } else {
33840 if (op.toLowerCase().indexOf(lowerCaseOption) !== -1) {
33841 indexMatch = op;
33842 }
33843
33844 distance = Validator.levenshteinDistance(option, op);
33845
33846 if (min > distance) {
33847 closestMatch = op;
33848 closestMatchPath = copyArray(path);
33849 min = distance;
33850 }
33851 }
33852 }
33853
33854 return {
33855 closestMatch: closestMatch,
33856 path: closestMatchPath,
33857 distance: min,
33858 indexMatch: indexMatch
33859 };
33860 }
33861 /**
33862 * @param {Array.<string>} path
33863 * @param {Object} option
33864 * @param {string} prefix
33865 * @returns {String}
33866 * @static
33867 */
33868
33869 }, {
33870 key: "printLocation",
33871 value: function printLocation(path, option) {
33872 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Problem value found at: \n';
33873 var str = '\n\n' + prefix + 'options = {\n';
33874
33875 for (var i = 0; i < path.length; i++) {
33876 for (var j = 0; j < i + 1; j++) {
33877 str += ' ';
33878 }
33879
33880 str += path[i] + ': {\n';
33881 }
33882
33883 for (var _j = 0; _j < path.length + 1; _j++) {
33884 str += ' ';
33885 }
33886
33887 str += option + '\n';
33888
33889 for (var _i = 0; _i < path.length + 1; _i++) {
33890 for (var _j2 = 0; _j2 < path.length - _i; _j2++) {
33891 str += ' ';
33892 }
33893
33894 str += '}\n';
33895 }
33896
33897 return str + '\n\n';
33898 }
33899 /**
33900 * @param {Object} options
33901 * @returns {String}
33902 * @static
33903 */
33904
33905 }, {
33906 key: "print",
33907 value: function print(options) {
33908 return JSON.stringify(options).replace(/(\")|(\[)|(\])|(,"__type__")/g, "").replace(/(\,)/g, ', ');
33909 }
33910 /**
33911 * Compute the edit distance between the two given strings
33912 * http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
33913 *
33914 * Copyright (c) 2011 Andrei Mackenzie
33915 *
33916 * 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:
33917 *
33918 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
33919 *
33920 * 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.
33921 *
33922 * @param {string} a
33923 * @param {string} b
33924 * @returns {Array.<Array.<number>>}}
33925 * @static
33926 */
33927
33928 }, {
33929 key: "levenshteinDistance",
33930 value: function levenshteinDistance(a, b) {
33931 if (a.length === 0) return b.length;
33932 if (b.length === 0) return a.length;
33933 var matrix = []; // increment along the first column of each row
33934
33935 var i;
33936
33937 for (i = 0; i <= b.length; i++) {
33938 matrix[i] = [i];
33939 } // increment each column in the first row
33940
33941
33942 var j;
33943
33944 for (j = 0; j <= a.length; j++) {
33945 matrix[0][j] = j;
33946 } // Fill in the rest of the matrix
33947
33948
33949 for (i = 1; i <= b.length; i++) {
33950 for (j = 1; j <= a.length; j++) {
33951 if (b.charAt(i - 1) == a.charAt(j - 1)) {
33952 matrix[i][j] = matrix[i - 1][j - 1];
33953 } else {
33954 matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
33955 Math.min(matrix[i][j - 1] + 1, // insertion
33956 matrix[i - 1][j] + 1)); // deletion
33957 }
33958 }
33959 }
33960
33961 return matrix[b.length][a.length];
33962 }
33963 }]);
33964
33965 return Validator;
33966 }();
33967
33968 /**
33969 * A node. A node can be connected to other nodes via one or multiple edges.
33970 */
33971
33972 var Node =
33973 /*#__PURE__*/
33974 function () {
33975 /**
33976 *
33977 * @param {object} options An object containing options for the node. All
33978 * options are optional, except for the id.
33979 * {number} id Id of the node. Required
33980 * {string} label Text label for the node
33981 * {number} x Horizontal position of the node
33982 * {number} y Vertical position of the node
33983 * {string} shape Node shape
33984 * {string} image An image url
33985 * {string} title A title text, can be HTML
33986 * {anytype} group A group name or number
33987 *
33988 * @param {Object} body Shared state of current network instance
33989 * @param {Network.Images} imagelist A list with images. Only needed when the node has an image
33990 * @param {Groups} grouplist A list with groups. Needed for retrieving group options
33991 * @param {Object} globalOptions Current global node options; these serve as defaults for the node instance
33992 * @param {Object} defaultOptions Global default options for nodes; note that this is also the prototype
33993 * for parameter `globalOptions`.
33994 */
33995 function Node(options, body, imagelist, grouplist, globalOptions, defaultOptions) {
33996 _classCallCheck(this, Node);
33997
33998 this.options = bridgeObject(globalOptions);
33999 this.globalOptions = globalOptions;
34000 this.defaultOptions = defaultOptions;
34001 this.body = body;
34002 this.edges = []; // all edges connected to this node
34003 // set defaults for the options
34004
34005 this.id = undefined;
34006 this.imagelist = imagelist;
34007 this.grouplist = grouplist; // state options
34008
34009 this.x = undefined;
34010 this.y = undefined;
34011 this.baseSize = this.options.size;
34012 this.baseFontSize = this.options.font.size;
34013 this.predefinedPosition = false; // used to check if initial fit should just take the range or approximate
34014
34015 this.selected = false;
34016 this.hover = false;
34017 this.labelModule = new Label(this.body, this.options, false
34018 /* Not edge label */
34019 );
34020 this.setOptions(options);
34021 }
34022 /**
34023 * Attach a edge to the node
34024 * @param {Edge} edge
34025 */
34026
34027
34028 _createClass(Node, [{
34029 key: "attachEdge",
34030 value: function attachEdge(edge) {
34031 if (this.edges.indexOf(edge) === -1) {
34032 this.edges.push(edge);
34033 }
34034 }
34035 /**
34036 * Detach a edge from the node
34037 *
34038 * @param {Edge} edge
34039 */
34040
34041 }, {
34042 key: "detachEdge",
34043 value: function detachEdge(edge) {
34044 var index = this.edges.indexOf(edge);
34045
34046 if (index != -1) {
34047 this.edges.splice(index, 1);
34048 }
34049 }
34050 /**
34051 * Set or overwrite options for the node
34052 *
34053 * @param {Object} options an object with options
34054 * @returns {null|boolean}
34055 */
34056
34057 }, {
34058 key: "setOptions",
34059 value: function setOptions(options) {
34060 var currentShape = this.options.shape;
34061
34062 if (!options) {
34063 return; // Note that the return value will be 'undefined'! This is OK.
34064 } // Save the color for later.
34065 // This is necessary in order to prevent local color from being overwritten by group color.
34066 // TODO: To prevent such workarounds the way options are handled should be rewritten from scratch.
34067 // This is not the only problem with current options handling.
34068
34069
34070 if (typeof options.color !== 'undefined') {
34071 this._localColor = options.color;
34072 } // basic options
34073
34074
34075 if (options.id !== undefined) {
34076 this.id = options.id;
34077 }
34078
34079 if (this.id === undefined) {
34080 throw new Error("Node must have an id");
34081 }
34082
34083 Node.checkMass(options, this.id); // set these options locally
34084 // clear x and y positions
34085
34086 if (options.x !== undefined) {
34087 if (options.x === null) {
34088 this.x = undefined;
34089 this.predefinedPosition = false;
34090 } else {
34091 this.x = parseInt(options.x);
34092 this.predefinedPosition = true;
34093 }
34094 }
34095
34096 if (options.y !== undefined) {
34097 if (options.y === null) {
34098 this.y = undefined;
34099 this.predefinedPosition = false;
34100 } else {
34101 this.y = parseInt(options.y);
34102 this.predefinedPosition = true;
34103 }
34104 }
34105
34106 if (options.size !== undefined) {
34107 this.baseSize = options.size;
34108 }
34109
34110 if (options.value !== undefined) {
34111 options.value = parseFloat(options.value);
34112 } // this transforms all shorthands into fully defined options
34113
34114
34115 Node.parseOptions(this.options, options, true, this.globalOptions, this.grouplist);
34116 var pile = [options, this.options, this.defaultOptions];
34117 this.chooser = ComponentUtil.choosify('node', pile);
34118
34119 this._load_images();
34120
34121 this.updateLabelModule(options);
34122 this.updateShape(currentShape);
34123 return options.hidden !== undefined || options.physics !== undefined;
34124 }
34125 /**
34126 * Load the images from the options, for the nodes that need them.
34127 *
34128 * Images are always loaded, even if they are not used in the current shape.
34129 * The user may switch to an image shape later on.
34130 *
34131 * @private
34132 */
34133
34134 }, {
34135 key: "_load_images",
34136 value: function _load_images() {
34137 if (this.options.shape === 'circularImage' || this.options.shape === 'image') {
34138 if (this.options.image === undefined) {
34139 throw new Error("Option image must be defined for node type '" + this.options.shape + "'");
34140 }
34141 }
34142
34143 if (this.options.image === undefined) {
34144 return;
34145 }
34146
34147 if (this.imagelist === undefined) {
34148 throw new Error("Internal Error: No images provided");
34149 }
34150
34151 if (typeof this.options.image === 'string') {
34152 this.imageObj = this.imagelist.load(this.options.image, this.options.brokenImage, this.id);
34153 } else {
34154 if (this.options.image.unselected === undefined) {
34155 throw new Error("No unselected image provided");
34156 }
34157
34158 this.imageObj = this.imagelist.load(this.options.image.unselected, this.options.brokenImage, this.id);
34159
34160 if (this.options.image.selected !== undefined) {
34161 this.imageObjAlt = this.imagelist.load(this.options.image.selected, this.options.brokenImage, this.id);
34162 } else {
34163 this.imageObjAlt = undefined;
34164 }
34165 }
34166 }
34167 /**
34168 * Copy group option values into the node options.
34169 *
34170 * The group options override the global node options, so the copy of group options
34171 * must happen *after* the global node options have been set.
34172 *
34173 * This method must also be called also if the global node options have changed and the group options did not.
34174 *
34175 * @param {Object} parentOptions
34176 * @param {Object} newOptions new values for the options, currently only passed in for check
34177 * @param {Object} groupList
34178 */
34179
34180 }, {
34181 key: "getFormattingValues",
34182
34183 /**
34184 *
34185 * @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: *}}
34186 */
34187 value: function getFormattingValues() {
34188 var values = {
34189 color: this.options.color.background,
34190 borderWidth: this.options.borderWidth,
34191 borderColor: this.options.color.border,
34192 size: this.options.size,
34193 borderDashes: this.options.shapeProperties.borderDashes,
34194 borderRadius: this.options.shapeProperties.borderRadius,
34195 shadow: this.options.shadow.enabled,
34196 shadowColor: this.options.shadow.color,
34197 shadowSize: this.options.shadow.size,
34198 shadowX: this.options.shadow.x,
34199 shadowY: this.options.shadow.y
34200 };
34201
34202 if (this.selected || this.hover) {
34203 if (this.chooser === true) {
34204 if (this.selected) {
34205 values.borderWidth *= 2;
34206 values.color = this.options.color.highlight.background;
34207 values.borderColor = this.options.color.highlight.border;
34208 values.shadow = this.options.shadow.enabled;
34209 } else if (this.hover) {
34210 values.color = this.options.color.hover.background;
34211 values.borderColor = this.options.color.hover.border;
34212 values.shadow = this.options.shadow.enabled;
34213 }
34214 } else if (typeof this.chooser === 'function') {
34215 this.chooser(values, this.options.id, this.selected, this.hover);
34216
34217 if (values.shadow === false) {
34218 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) {
34219 values.shadow = true;
34220 }
34221 }
34222 }
34223 } else {
34224 values.shadow = this.options.shadow.enabled;
34225 }
34226
34227 return values;
34228 }
34229 /**
34230 *
34231 * @param {Object} options
34232 */
34233
34234 }, {
34235 key: "updateLabelModule",
34236 value: function updateLabelModule(options) {
34237 if (this.options.label === undefined || this.options.label === null) {
34238 this.options.label = '';
34239 }
34240
34241 Node.updateGroupOptions(this.options, _objectSpread2({}, options, {
34242 color: options && options.color || this._localColor || undefined
34243 }), this.grouplist); //
34244 // Note:The prototype chain for this.options is:
34245 //
34246 // this.options -> NodesHandler.options -> NodesHandler.defaultOptions
34247 // (also: this.globalOptions)
34248 //
34249 // Note that the prototypes are mentioned explicitly in the pile list below;
34250 // WE DON'T WANT THE ORDER OF THE PROTOTYPES!!!! At least, not for font handling of labels.
34251 // This is a good indication that the prototype usage of options is deficient.
34252 //
34253
34254 var currentGroup = this.grouplist.get(this.options.group, false);
34255 var pile = [options, // new options
34256 this.options, // current node options, see comment above for prototype
34257 currentGroup, // group options, if any
34258 this.globalOptions, // Currently set global node options
34259 this.defaultOptions // Default global node options
34260 ];
34261 this.labelModule.update(this.options, pile);
34262
34263 if (this.labelModule.baseSize !== undefined) {
34264 this.baseFontSize = this.labelModule.baseSize;
34265 }
34266 }
34267 /**
34268 *
34269 * @param {string} currentShape
34270 */
34271
34272 }, {
34273 key: "updateShape",
34274 value: function updateShape(currentShape) {
34275 if (currentShape === this.options.shape && this.shape) {
34276 this.shape.setOptions(this.options, this.imageObj, this.imageObjAlt);
34277 } else {
34278 // choose draw method depending on the shape
34279 switch (this.options.shape) {
34280 case 'box':
34281 this.shape = new Box(this.options, this.body, this.labelModule);
34282 break;
34283
34284 case 'circle':
34285 this.shape = new Circle(this.options, this.body, this.labelModule);
34286 break;
34287
34288 case 'circularImage':
34289 this.shape = new CircularImage(this.options, this.body, this.labelModule, this.imageObj, this.imageObjAlt);
34290 break;
34291
34292 case 'database':
34293 this.shape = new Database(this.options, this.body, this.labelModule);
34294 break;
34295
34296 case 'diamond':
34297 this.shape = new Diamond(this.options, this.body, this.labelModule);
34298 break;
34299
34300 case 'dot':
34301 this.shape = new Dot(this.options, this.body, this.labelModule);
34302 break;
34303
34304 case 'ellipse':
34305 this.shape = new Ellipse(this.options, this.body, this.labelModule);
34306 break;
34307
34308 case 'icon':
34309 this.shape = new Icon(this.options, this.body, this.labelModule);
34310 break;
34311
34312 case 'image':
34313 this.shape = new Image$1(this.options, this.body, this.labelModule, this.imageObj, this.imageObjAlt);
34314 break;
34315
34316 case 'square':
34317 this.shape = new Square(this.options, this.body, this.labelModule);
34318 break;
34319
34320 case 'hexagon':
34321 this.shape = new Hexagon(this.options, this.body, this.labelModule);
34322 break;
34323
34324 case 'star':
34325 this.shape = new Star(this.options, this.body, this.labelModule);
34326 break;
34327
34328 case 'text':
34329 this.shape = new Text(this.options, this.body, this.labelModule);
34330 break;
34331
34332 case 'triangle':
34333 this.shape = new Triangle(this.options, this.body, this.labelModule);
34334 break;
34335
34336 case 'triangleDown':
34337 this.shape = new TriangleDown(this.options, this.body, this.labelModule);
34338 break;
34339
34340 default:
34341 this.shape = new Ellipse(this.options, this.body, this.labelModule);
34342 break;
34343 }
34344 }
34345
34346 this.needsRefresh();
34347 }
34348 /**
34349 * select this node
34350 */
34351
34352 }, {
34353 key: "select",
34354 value: function select() {
34355 this.selected = true;
34356 this.needsRefresh();
34357 }
34358 /**
34359 * unselect this node
34360 */
34361
34362 }, {
34363 key: "unselect",
34364 value: function unselect() {
34365 this.selected = false;
34366 this.needsRefresh();
34367 }
34368 /**
34369 * Reset the calculated size of the node, forces it to recalculate its size
34370 */
34371
34372 }, {
34373 key: "needsRefresh",
34374 value: function needsRefresh() {
34375 this.shape.refreshNeeded = true;
34376 }
34377 /**
34378 * get the title of this node.
34379 * @return {string} title The title of the node, or undefined when no title
34380 * has been set.
34381 */
34382
34383 }, {
34384 key: "getTitle",
34385 value: function getTitle() {
34386 return this.options.title;
34387 }
34388 /**
34389 * Calculate the distance to the border of the Node
34390 * @param {CanvasRenderingContext2D} ctx
34391 * @param {number} angle Angle in radians
34392 * @returns {number} distance Distance to the border in pixels
34393 */
34394
34395 }, {
34396 key: "distanceToBorder",
34397 value: function distanceToBorder(ctx, angle) {
34398 return this.shape.distanceToBorder(ctx, angle);
34399 }
34400 /**
34401 * Check if this node has a fixed x and y position
34402 * @return {boolean} true if fixed, false if not
34403 */
34404
34405 }, {
34406 key: "isFixed",
34407 value: function isFixed() {
34408 return this.options.fixed.x && this.options.fixed.y;
34409 }
34410 /**
34411 * check if this node is selecte
34412 * @return {boolean} selected True if node is selected, else false
34413 */
34414
34415 }, {
34416 key: "isSelected",
34417 value: function isSelected() {
34418 return this.selected;
34419 }
34420 /**
34421 * Retrieve the value of the node. Can be undefined
34422 * @return {number} value
34423 */
34424
34425 }, {
34426 key: "getValue",
34427 value: function getValue() {
34428 return this.options.value;
34429 }
34430 /**
34431 * Get the current dimensions of the label
34432 *
34433 * @return {rect}
34434 */
34435
34436 }, {
34437 key: "getLabelSize",
34438 value: function getLabelSize() {
34439 return this.labelModule.size();
34440 }
34441 /**
34442 * Adjust the value range of the node. The node will adjust it's size
34443 * based on its value.
34444 * @param {number} min
34445 * @param {number} max
34446 * @param {number} total
34447 */
34448
34449 }, {
34450 key: "setValueRange",
34451 value: function setValueRange(min, max, total) {
34452 if (this.options.value !== undefined) {
34453 var scale = this.options.scaling.customScalingFunction(min, max, total, this.options.value);
34454 var sizeDiff = this.options.scaling.max - this.options.scaling.min;
34455
34456 if (this.options.scaling.label.enabled === true) {
34457 var fontDiff = this.options.scaling.label.max - this.options.scaling.label.min;
34458 this.options.font.size = this.options.scaling.label.min + scale * fontDiff;
34459 }
34460
34461 this.options.size = this.options.scaling.min + scale * sizeDiff;
34462 } else {
34463 this.options.size = this.baseSize;
34464 this.options.font.size = this.baseFontSize;
34465 }
34466
34467 this.updateLabelModule();
34468 }
34469 /**
34470 * Draw this node in the given canvas
34471 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
34472 * @param {CanvasRenderingContext2D} ctx
34473 */
34474
34475 }, {
34476 key: "draw",
34477 value: function draw(ctx) {
34478 var values = this.getFormattingValues();
34479 this.shape.draw(ctx, this.x, this.y, this.selected, this.hover, values);
34480 }
34481 /**
34482 * Update the bounding box of the shape
34483 * @param {CanvasRenderingContext2D} ctx
34484 */
34485
34486 }, {
34487 key: "updateBoundingBox",
34488 value: function updateBoundingBox(ctx) {
34489 this.shape.updateBoundingBox(this.x, this.y, ctx);
34490 }
34491 /**
34492 * Recalculate the size of this node in the given canvas
34493 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
34494 * @param {CanvasRenderingContext2D} ctx
34495 */
34496
34497 }, {
34498 key: "resize",
34499 value: function resize(ctx) {
34500 var values = this.getFormattingValues();
34501 this.shape.resize(ctx, this.selected, this.hover, values);
34502 }
34503 /**
34504 * Determine all visual elements of this node instance, in which the given
34505 * point falls within the bounding shape.
34506 *
34507 * @param {point} point
34508 * @returns {Array.<nodeClickItem|nodeLabelClickItem>} list with the items which are on the point
34509 */
34510
34511 }, {
34512 key: "getItemsOnPoint",
34513 value: function getItemsOnPoint(point) {
34514 var ret = [];
34515
34516 if (this.labelModule.visible()) {
34517 if (ComponentUtil.pointInRect(this.labelModule.getSize(), point)) {
34518 ret.push({
34519 nodeId: this.id,
34520 labelId: 0
34521 });
34522 }
34523 }
34524
34525 if (ComponentUtil.pointInRect(this.shape.boundingBox, point)) {
34526 ret.push({
34527 nodeId: this.id
34528 });
34529 }
34530
34531 return ret;
34532 }
34533 /**
34534 * Check if this object is overlapping with the provided object
34535 * @param {Object} obj an object with parameters left, top, right, bottom
34536 * @return {boolean} True if location is located on node
34537 */
34538
34539 }, {
34540 key: "isOverlappingWith",
34541 value: function isOverlappingWith(obj) {
34542 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;
34543 }
34544 /**
34545 * Check if this object is overlapping with the provided object
34546 * @param {Object} obj an object with parameters left, top, right, bottom
34547 * @return {boolean} True if location is located on node
34548 */
34549
34550 }, {
34551 key: "isBoundingBoxOverlappingWith",
34552 value: function isBoundingBoxOverlappingWith(obj) {
34553 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;
34554 }
34555 /**
34556 * Check valid values for mass
34557 *
34558 * The mass may not be negative or zero. If it is, reset to 1
34559 *
34560 * @param {object} options
34561 * @param {Node.id} id
34562 * @static
34563 */
34564
34565 }], [{
34566 key: "updateGroupOptions",
34567 value: function updateGroupOptions(parentOptions, newOptions, groupList) {
34568 if (groupList === undefined) return; // No groups, nothing to do
34569
34570 var group = parentOptions.group; // paranoia: the selected group is already merged into node options, check.
34571
34572 if (newOptions !== undefined && newOptions.group !== undefined && group !== newOptions.group) {
34573 throw new Error("updateGroupOptions: group values in options don't match.");
34574 }
34575
34576 var hasGroup = typeof group === 'number' || typeof group === 'string' && group != '';
34577 if (!hasGroup) return; // current node has no group, no need to merge
34578
34579 var groupObj = groupList.get(group); // Skip merging of group font options into parent; these are required to be distinct for labels
34580 // Also skip mergin of color IF it is already defined in the node itself. This is to avoid the color of the
34581 // group overriding the color set at the node level
34582 // TODO: It might not be a good idea either to merge the rest of the options, investigate this.
34583
34584 var skipProperties = ['font'];
34585 if (newOptions !== undefined && newOptions.color !== undefined && newOptions.color != null) skipProperties.push('color');
34586 selectiveNotDeepExtend(skipProperties, parentOptions, groupObj); // the color object needs to be completely defined.
34587 // Since groups can partially overwrite the colors, we parse it again, just in case.
34588
34589 parentOptions.color = parseColor(parentOptions.color);
34590 }
34591 /**
34592 * This process all possible shorthands in the new options and makes sure that the parentOptions are fully defined.
34593 * Static so it can also be used by the handler.
34594 *
34595 * @param {Object} parentOptions
34596 * @param {Object} newOptions
34597 * @param {boolean} [allowDeletion=false]
34598 * @param {Object} [globalOptions={}]
34599 * @param {Object} [groupList]
34600 * @static
34601 */
34602
34603 }, {
34604 key: "parseOptions",
34605 value: function parseOptions(parentOptions, newOptions) {
34606 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
34607 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
34608 var groupList = arguments.length > 4 ? arguments[4] : undefined;
34609 var fields = ['color', 'fixed', 'shadow'];
34610 selectiveNotDeepExtend(fields, parentOptions, newOptions, allowDeletion);
34611 Node.checkMass(newOptions); // merge the shadow options into the parent.
34612
34613 mergeOptions(parentOptions, newOptions, 'shadow', globalOptions); // individual shape newOptions
34614
34615 if (newOptions.color !== undefined && newOptions.color !== null) {
34616 var parsedColor = parseColor(newOptions.color);
34617 fillIfDefined(parentOptions.color, parsedColor);
34618 } else if (allowDeletion === true && newOptions.color === null) {
34619 parentOptions.color = bridgeObject(globalOptions.color); // set the object back to the global options
34620 } // handle the fixed options
34621
34622
34623 if (newOptions.fixed !== undefined && newOptions.fixed !== null) {
34624 if (typeof newOptions.fixed === 'boolean') {
34625 parentOptions.fixed.x = newOptions.fixed;
34626 parentOptions.fixed.y = newOptions.fixed;
34627 } else {
34628 if (newOptions.fixed.x !== undefined && typeof newOptions.fixed.x === 'boolean') {
34629 parentOptions.fixed.x = newOptions.fixed.x;
34630 }
34631
34632 if (newOptions.fixed.y !== undefined && typeof newOptions.fixed.y === 'boolean') {
34633 parentOptions.fixed.y = newOptions.fixed.y;
34634 }
34635 }
34636 }
34637
34638 if (allowDeletion === true && newOptions.font === null) {
34639 parentOptions.font = bridgeObject(globalOptions.font); // set the object back to the global options
34640 }
34641
34642 Node.updateGroupOptions(parentOptions, newOptions, groupList); // handle the scaling options, specifically the label part
34643
34644 if (newOptions.scaling !== undefined) {
34645 mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', globalOptions.scaling);
34646 }
34647 }
34648 }, {
34649 key: "checkMass",
34650 value: function checkMass(options, id) {
34651 if (options.mass !== undefined && options.mass <= 0) {
34652 var strId = '';
34653
34654 if (id !== undefined) {
34655 strId = ' in node id: ' + id;
34656 }
34657
34658 console.log('%cNegative or zero mass disallowed' + strId + ', setting mass to 1.', printStyle);
34659 options.mass = 1;
34660 }
34661 }
34662 }]);
34663
34664 return Node;
34665 }();
34666
34667 /**
34668 * Handler for Nodes
34669 */
34670
34671 var NodesHandler =
34672 /*#__PURE__*/
34673 function () {
34674 /**
34675 * @param {Object} body
34676 * @param {Images} images
34677 * @param {Array.<Group>} groups
34678 * @param {LayoutEngine} layoutEngine
34679 */
34680 function NodesHandler(body, images, groups, layoutEngine) {
34681 var _this = this;
34682
34683 _classCallCheck(this, NodesHandler);
34684
34685 this.body = body;
34686 this.images = images;
34687 this.groups = groups;
34688 this.layoutEngine = layoutEngine; // create the node API in the body container
34689
34690 this.body.functions.createNode = this.create.bind(this);
34691 this.nodesListeners = {
34692 add: function add(event, params) {
34693 _this.add(params.items);
34694 },
34695 update: function update(event, params) {
34696 _this.update(params.items, params.data, params.oldData);
34697 },
34698 remove: function remove(event, params) {
34699 _this.remove(params.items);
34700 }
34701 };
34702 this.defaultOptions = {
34703 borderWidth: 1,
34704 borderWidthSelected: 2,
34705 brokenImage: undefined,
34706 color: {
34707 border: '#2B7CE9',
34708 background: '#97C2FC',
34709 highlight: {
34710 border: '#2B7CE9',
34711 background: '#D2E5FF'
34712 },
34713 hover: {
34714 border: '#2B7CE9',
34715 background: '#D2E5FF'
34716 }
34717 },
34718 fixed: {
34719 x: false,
34720 y: false
34721 },
34722 font: {
34723 color: '#343434',
34724 size: 14,
34725 // px
34726 face: 'arial',
34727 background: 'none',
34728 strokeWidth: 0,
34729 // px
34730 strokeColor: '#ffffff',
34731 align: 'center',
34732 vadjust: 0,
34733 multi: false,
34734 bold: {
34735 mod: 'bold'
34736 },
34737 boldital: {
34738 mod: 'bold italic'
34739 },
34740 ital: {
34741 mod: 'italic'
34742 },
34743 mono: {
34744 mod: '',
34745 size: 15,
34746 // px
34747 face: 'monospace',
34748 vadjust: 2
34749 }
34750 },
34751 group: undefined,
34752 hidden: false,
34753 icon: {
34754 face: 'FontAwesome',
34755 //'FontAwesome',
34756 code: undefined,
34757 //'\uf007',
34758 size: 50,
34759 //50,
34760 color: '#2B7CE9' //'#aa00ff'
34761
34762 },
34763 image: undefined,
34764 // --> URL
34765 imagePadding: {
34766 // only for image shape
34767 top: 0,
34768 right: 0,
34769 bottom: 0,
34770 left: 0
34771 },
34772 label: undefined,
34773 labelHighlightBold: true,
34774 level: undefined,
34775 margin: {
34776 top: 5,
34777 right: 5,
34778 bottom: 5,
34779 left: 5
34780 },
34781 mass: 1,
34782 physics: true,
34783 scaling: {
34784 min: 10,
34785 max: 30,
34786 label: {
34787 enabled: false,
34788 min: 14,
34789 max: 30,
34790 maxVisible: 30,
34791 drawThreshold: 5
34792 },
34793 customScalingFunction: function customScalingFunction(min, max, total, value) {
34794 if (max === min) {
34795 return 0.5;
34796 } else {
34797 var scale = 1 / (max - min);
34798 return Math.max(0, (value - min) * scale);
34799 }
34800 }
34801 },
34802 shadow: {
34803 enabled: false,
34804 color: 'rgba(0,0,0,0.5)',
34805 size: 10,
34806 x: 5,
34807 y: 5
34808 },
34809 shape: 'ellipse',
34810 shapeProperties: {
34811 borderDashes: false,
34812 // only for borders
34813 borderRadius: 6,
34814 // only for box shape
34815 interpolation: true,
34816 // only for image and circularImage shapes
34817 useImageSize: false,
34818 // only for image and circularImage shapes
34819 useBorderWithImage: false // only for image shape
34820
34821 },
34822 size: 25,
34823 title: undefined,
34824 value: undefined,
34825 x: undefined,
34826 y: undefined
34827 }; // Protect from idiocy
34828
34829 if (this.defaultOptions.mass <= 0) {
34830 throw 'Internal error: mass in defaultOptions of NodesHandler may not be zero or negative';
34831 }
34832
34833 this.options = bridgeObject(this.defaultOptions);
34834 this.bindEventListeners();
34835 }
34836 /**
34837 * Binds event listeners
34838 */
34839
34840
34841 _createClass(NodesHandler, [{
34842 key: "bindEventListeners",
34843 value: function bindEventListeners() {
34844 var _this2 = this;
34845
34846 // refresh the nodes. Used when reverting from hierarchical layout
34847 this.body.emitter.on('refreshNodes', this.refresh.bind(this));
34848 this.body.emitter.on('refresh', this.refresh.bind(this));
34849 this.body.emitter.on('destroy', function () {
34850 forEach(_this2.nodesListeners, function (callback, event) {
34851 if (_this2.body.data.nodes) _this2.body.data.nodes.off(event, callback);
34852 });
34853 delete _this2.body.functions.createNode;
34854 delete _this2.nodesListeners.add;
34855 delete _this2.nodesListeners.update;
34856 delete _this2.nodesListeners.remove;
34857 delete _this2.nodesListeners;
34858 });
34859 }
34860 /**
34861 *
34862 * @param {Object} options
34863 */
34864
34865 }, {
34866 key: "setOptions",
34867 value: function setOptions(options) {
34868 if (options !== undefined) {
34869 Node.parseOptions(this.options, options); // update the shape in all nodes
34870
34871 if (options.shape !== undefined) {
34872 for (var nodeId in this.body.nodes) {
34873 if (this.body.nodes.hasOwnProperty(nodeId)) {
34874 this.body.nodes[nodeId].updateShape();
34875 }
34876 }
34877 } // update the font in all nodes
34878
34879
34880 if (options.font !== undefined) {
34881 for (var _nodeId in this.body.nodes) {
34882 if (this.body.nodes.hasOwnProperty(_nodeId)) {
34883 this.body.nodes[_nodeId].updateLabelModule();
34884
34885 this.body.nodes[_nodeId].needsRefresh();
34886 }
34887 }
34888 } // update the shape size in all nodes
34889
34890
34891 if (options.size !== undefined) {
34892 for (var _nodeId2 in this.body.nodes) {
34893 if (this.body.nodes.hasOwnProperty(_nodeId2)) {
34894 this.body.nodes[_nodeId2].needsRefresh();
34895 }
34896 }
34897 } // update the state of the variables if needed
34898
34899
34900 if (options.hidden !== undefined || options.physics !== undefined) {
34901 this.body.emitter.emit('_dataChanged');
34902 }
34903 }
34904 }
34905 /**
34906 * Set a data set with nodes for the network
34907 * @param {Array | DataSet | DataView} nodes The data containing the nodes.
34908 * @param {boolean} [doNotEmit=false]
34909 * @private
34910 */
34911
34912 }, {
34913 key: "setData",
34914 value: function setData(nodes) {
34915 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
34916 var oldNodesData = this.body.data.nodes;
34917
34918 if (nodes instanceof DataSet || nodes instanceof DataView$2) {
34919 this.body.data.nodes = nodes;
34920 } else if (Array.isArray(nodes)) {
34921 this.body.data.nodes = new DataSet();
34922 this.body.data.nodes.add(nodes);
34923 } else if (!nodes) {
34924 this.body.data.nodes = new DataSet();
34925 } else {
34926 throw new TypeError('Array or DataSet expected');
34927 }
34928
34929 if (oldNodesData) {
34930 // unsubscribe from old dataset
34931 forEach(this.nodesListeners, function (callback, event) {
34932 oldNodesData.off(event, callback);
34933 });
34934 } // remove drawn nodes
34935
34936
34937 this.body.nodes = {};
34938
34939 if (this.body.data.nodes) {
34940 // subscribe to new dataset
34941 var me = this;
34942 forEach(this.nodesListeners, function (callback, event) {
34943 me.body.data.nodes.on(event, callback);
34944 }); // draw all new nodes
34945
34946 var ids = this.body.data.nodes.getIds();
34947 this.add(ids, true);
34948 }
34949
34950 if (doNotEmit === false) {
34951 this.body.emitter.emit("_dataChanged");
34952 }
34953 }
34954 /**
34955 * Add nodes
34956 * @param {number[] | string[]} ids
34957 * @param {boolean} [doNotEmit=false]
34958 * @private
34959 */
34960
34961 }, {
34962 key: "add",
34963 value: function add(ids) {
34964 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
34965 var id;
34966 var newNodes = [];
34967
34968 for (var i = 0; i < ids.length; i++) {
34969 id = ids[i];
34970 var properties = this.body.data.nodes.get(id);
34971 var node = this.create(properties);
34972 newNodes.push(node);
34973 this.body.nodes[id] = node; // note: this may replace an existing node
34974 }
34975
34976 this.layoutEngine.positionInitially(newNodes);
34977
34978 if (doNotEmit === false) {
34979 this.body.emitter.emit("_dataChanged");
34980 }
34981 }
34982 /**
34983 * Update existing nodes, or create them when not yet existing
34984 * @param {number[] | string[]} ids id's of changed nodes
34985 * @param {Array} changedData array with changed data
34986 * @param {Array|undefined} oldData optional; array with previous data
34987 * @private
34988 */
34989
34990 }, {
34991 key: "update",
34992 value: function update(ids, changedData, oldData) {
34993 var nodes = this.body.nodes;
34994 var dataChanged = false;
34995
34996 for (var i = 0; i < ids.length; i++) {
34997 var id = ids[i];
34998 var node = nodes[id];
34999 var data = changedData[i];
35000
35001 if (node !== undefined) {
35002 // update node
35003 if (node.setOptions(data)) {
35004 dataChanged = true;
35005 }
35006 } else {
35007 dataChanged = true; // create node
35008
35009 node = this.create(data);
35010 nodes[id] = node;
35011 }
35012 }
35013
35014 if (!dataChanged && oldData !== undefined) {
35015 // Check for any changes which should trigger a layout recalculation
35016 // For now, this is just 'level' for hierarchical layout
35017 // Assumption: old and new data arranged in same order; at time of writing, this holds.
35018 dataChanged = changedData.some(function (newValue, index) {
35019 var oldValue = oldData[index];
35020 return oldValue && oldValue.level !== newValue.level;
35021 });
35022 }
35023
35024 if (dataChanged === true) {
35025 this.body.emitter.emit("_dataChanged");
35026 } else {
35027 this.body.emitter.emit("_dataUpdated");
35028 }
35029 }
35030 /**
35031 * Remove existing nodes. If nodes do not exist, the method will just ignore it.
35032 * @param {number[] | string[]} ids
35033 * @private
35034 */
35035
35036 }, {
35037 key: "remove",
35038 value: function remove(ids) {
35039 var nodes = this.body.nodes;
35040
35041 for (var i = 0; i < ids.length; i++) {
35042 var id = ids[i];
35043 delete nodes[id];
35044 }
35045
35046 this.body.emitter.emit("_dataChanged");
35047 }
35048 /**
35049 * create a node
35050 * @param {Object} properties
35051 * @param {class} [constructorClass=Node.default]
35052 * @returns {*}
35053 */
35054
35055 }, {
35056 key: "create",
35057 value: function create(properties) {
35058 var constructorClass = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Node;
35059 return new constructorClass(properties, this.body, this.images, this.groups, this.options, this.defaultOptions);
35060 }
35061 /**
35062 *
35063 * @param {boolean} [clearPositions=false]
35064 */
35065
35066 }, {
35067 key: "refresh",
35068 value: function refresh() {
35069 var _this3 = this;
35070
35071 var clearPositions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
35072 forEach(this.body.nodes, function (node, nodeId) {
35073 var data = _this3.body.data.nodes.get(nodeId);
35074
35075 if (data !== undefined) {
35076 if (clearPositions === true) {
35077 node.setOptions({
35078 x: null,
35079 y: null
35080 });
35081 }
35082
35083 node.setOptions({
35084 fixed: false
35085 });
35086 node.setOptions(data);
35087 }
35088 });
35089 }
35090 /**
35091 * Returns the positions of the nodes.
35092 * @param {Array.<Node.id>|String} [ids] --> optional, can be array of nodeIds, can be string
35093 * @returns {{}}
35094 */
35095
35096 }, {
35097 key: "getPositions",
35098 value: function getPositions(ids) {
35099 var dataArray = {};
35100
35101 if (ids !== undefined) {
35102 if (Array.isArray(ids) === true) {
35103 for (var i = 0; i < ids.length; i++) {
35104 if (this.body.nodes[ids[i]] !== undefined) {
35105 var node = this.body.nodes[ids[i]];
35106 dataArray[ids[i]] = {
35107 x: Math.round(node.x),
35108 y: Math.round(node.y)
35109 };
35110 }
35111 }
35112 } else {
35113 if (this.body.nodes[ids] !== undefined) {
35114 var _node = this.body.nodes[ids];
35115 dataArray[ids] = {
35116 x: Math.round(_node.x),
35117 y: Math.round(_node.y)
35118 };
35119 }
35120 }
35121 } else {
35122 for (var _i = 0; _i < this.body.nodeIndices.length; _i++) {
35123 var _node2 = this.body.nodes[this.body.nodeIndices[_i]];
35124 dataArray[this.body.nodeIndices[_i]] = {
35125 x: Math.round(_node2.x),
35126 y: Math.round(_node2.y)
35127 };
35128 }
35129 }
35130
35131 return dataArray;
35132 }
35133 /**
35134 * Load the XY positions of the nodes into the dataset.
35135 */
35136
35137 }, {
35138 key: "storePositions",
35139 value: function storePositions() {
35140 // todo: add support for clusters and hierarchical.
35141 var dataArray = [];
35142 var dataset = this.body.data.nodes.getDataSet();
35143
35144 for (var nodeId in dataset._data) {
35145 if (dataset._data.hasOwnProperty(nodeId)) {
35146 var node = this.body.nodes[nodeId];
35147
35148 if (dataset._data[nodeId].x != Math.round(node.x) || dataset._data[nodeId].y != Math.round(node.y)) {
35149 dataArray.push({
35150 id: node.id,
35151 x: Math.round(node.x),
35152 y: Math.round(node.y)
35153 });
35154 }
35155 }
35156 }
35157
35158 dataset.update(dataArray);
35159 }
35160 /**
35161 * get the bounding box of a node.
35162 * @param {Node.id} nodeId
35163 * @returns {j|*}
35164 */
35165
35166 }, {
35167 key: "getBoundingBox",
35168 value: function getBoundingBox(nodeId) {
35169 if (this.body.nodes[nodeId] !== undefined) {
35170 return this.body.nodes[nodeId].shape.boundingBox;
35171 }
35172 }
35173 /**
35174 * Get the Ids of nodes connected to this node.
35175 * @param {Node.id} nodeId
35176 * @param {'to'|'from'|undefined} direction values 'from' and 'to' select respectively parent and child nodes only.
35177 * Any other value returns both parent and child nodes.
35178 * @returns {Array}
35179 */
35180
35181 }, {
35182 key: "getConnectedNodes",
35183 value: function getConnectedNodes(nodeId, direction) {
35184 var nodeList = [];
35185
35186 if (this.body.nodes[nodeId] !== undefined) {
35187 var node = this.body.nodes[nodeId];
35188 var nodeObj = {}; // used to quickly check if node already exists
35189
35190 for (var i = 0; i < node.edges.length; i++) {
35191 var edge = node.edges[i];
35192
35193 if (direction !== 'to' && edge.toId == node.id) {
35194 // these are double equals since ids can be numeric or string
35195 if (nodeObj[edge.fromId] === undefined) {
35196 nodeList.push(edge.fromId);
35197 nodeObj[edge.fromId] = true;
35198 }
35199 } else if (direction !== 'from' && edge.fromId == node.id) {
35200 // these are double equals since ids can be numeric or string
35201 if (nodeObj[edge.toId] === undefined) {
35202 nodeList.push(edge.toId);
35203 nodeObj[edge.toId] = true;
35204 }
35205 }
35206 }
35207 }
35208
35209 return nodeList;
35210 }
35211 /**
35212 * Get the ids of the edges connected to this node.
35213 * @param {Node.id} nodeId
35214 * @returns {*}
35215 */
35216
35217 }, {
35218 key: "getConnectedEdges",
35219 value: function getConnectedEdges(nodeId) {
35220 var edgeList = [];
35221
35222 if (this.body.nodes[nodeId] !== undefined) {
35223 var node = this.body.nodes[nodeId];
35224
35225 for (var i = 0; i < node.edges.length; i++) {
35226 edgeList.push(node.edges[i].id);
35227 }
35228 } else {
35229 console.log("NodeId provided for getConnectedEdges does not exist. Provided: ", nodeId);
35230 }
35231
35232 return edgeList;
35233 }
35234 /**
35235 * Move a node.
35236 *
35237 * @param {Node.id} nodeId
35238 * @param {number} x
35239 * @param {number} y
35240 */
35241
35242 }, {
35243 key: "moveNode",
35244 value: function moveNode(nodeId, x, y) {
35245 var _this4 = this;
35246
35247 if (this.body.nodes[nodeId] !== undefined) {
35248 this.body.nodes[nodeId].x = Number(x);
35249 this.body.nodes[nodeId].y = Number(y);
35250 setTimeout(function () {
35251 _this4.body.emitter.emit("startSimulation");
35252 }, 0);
35253 } else {
35254 console.log("Node id supplied to moveNode does not exist. Provided: ", nodeId);
35255 }
35256 }
35257 }]);
35258
35259 return NodesHandler;
35260 }();
35261
35262 var $hypot = Math.hypot;
35263 var abs$3 = Math.abs;
35264 var sqrt = Math.sqrt;
35265
35266 // Chrome 77 bug
35267 // https://bugs.chromium.org/p/v8/issues/detail?id=9546
35268 var BUGGY$1 = !!$hypot && $hypot(Infinity, NaN) !== Infinity;
35269
35270 // `Math.hypot` method
35271 // https://tc39.github.io/ecma262/#sec-math.hypot
35272 _export({ target: 'Math', stat: true, forced: BUGGY$1 }, {
35273 hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars
35274 var sum = 0;
35275 var i = 0;
35276 var aLen = arguments.length;
35277 var larg = 0;
35278 var arg, div;
35279 while (i < aLen) {
35280 arg = abs$3(arguments[i++]);
35281 if (larg < arg) {
35282 div = larg / arg;
35283 sum = sum * div * div + 1;
35284 larg = arg;
35285 } else if (arg > 0) {
35286 div = arg / larg;
35287 sum += div * div;
35288 } else sum += arg;
35289 }
35290 return larg === Infinity ? Infinity : larg * sqrt(sum);
35291 }
35292 });
35293
35294 /** ============================================================================
35295 * Location of all the endpoint drawing routines.
35296 *
35297 * Every endpoint has its own drawing routine, which contains an endpoint definition.
35298 *
35299 * The endpoint definitions must have the following properies:
35300 *
35301 * - (0,0) is the connection point to the node it attaches to
35302 * - The endpoints are orientated to the positive x-direction
35303 * - The length of the endpoint is at most 1
35304 *
35305 * As long as the endpoint classes remain simple and not too numerous, they will
35306 * be contained within this module.
35307 * All classes here except `EndPoints` should be considered as private to this module.
35308 *
35309 * -----------------------------------------------------------------------------
35310 * ### Further Actions
35311 *
35312 * After adding a new endpoint here, you also need to do the following things:
35313 *
35314 * - Add the new endpoint name to `network/options.js` in array `endPoints`.
35315 * - Add the new endpoint name to the documentation.
35316 * Scan for 'arrows.to.type` and add it to the description.
35317 * - Add the endpoint to the examples. At the very least, add it to example
35318 * `edgeStyles/arrowTypes`.
35319 * ============================================================================= */
35320
35321 /**
35322 * Common methods for endpoints
35323 *
35324 * @class
35325 */
35326 var EndPoint =
35327 /*#__PURE__*/
35328 function () {
35329 function EndPoint() {
35330 _classCallCheck(this, EndPoint);
35331 }
35332
35333 _createClass(EndPoint, null, [{
35334 key: "transform",
35335
35336 /**
35337 * Apply transformation on points for display.
35338 *
35339 * The following is done:
35340 * - rotate by the specified angle
35341 * - multiply the (normalized) coordinates by the passed length
35342 * - offset by the target coordinates
35343 *
35344 * @param points - The point(s) to be transformed.
35345 * @param arrowData - The data determining the result of the transformation.
35346 */
35347 value: function transform(points, arrowData) {
35348 if (!Array.isArray(points)) {
35349 points = [points];
35350 }
35351
35352 var x = arrowData.point.x;
35353 var y = arrowData.point.y;
35354 var angle = arrowData.angle;
35355 var length = arrowData.length;
35356
35357 for (var i = 0; i < points.length; ++i) {
35358 var p = points[i];
35359 var xt = p.x * Math.cos(angle) - p.y * Math.sin(angle);
35360 var yt = p.x * Math.sin(angle) + p.y * Math.cos(angle);
35361 p.x = x + length * xt;
35362 p.y = y + length * yt;
35363 }
35364 }
35365 /**
35366 * Draw a closed path using the given real coordinates.
35367 *
35368 * @param ctx - The path will be rendered into this context.
35369 * @param points - The points of the path.
35370 */
35371
35372 }, {
35373 key: "drawPath",
35374 value: function drawPath(ctx, points) {
35375 ctx.beginPath();
35376 ctx.moveTo(points[0].x, points[0].y);
35377
35378 for (var i = 1; i < points.length; ++i) {
35379 ctx.lineTo(points[i].x, points[i].y);
35380 }
35381
35382 ctx.closePath();
35383 }
35384 }]);
35385
35386 return EndPoint;
35387 }();
35388 /**
35389 * Drawing methods for the arrow endpoint.
35390 */
35391
35392
35393 var Image$2 =
35394 /*#__PURE__*/
35395 function (_EndPoint) {
35396 _inherits(Image, _EndPoint);
35397
35398 function Image() {
35399 _classCallCheck(this, Image);
35400
35401 return _possibleConstructorReturn(this, _getPrototypeOf(Image).apply(this, arguments));
35402 }
35403
35404 _createClass(Image, null, [{
35405 key: "draw",
35406
35407 /**
35408 * Draw this shape at the end of a line.
35409 *
35410 * @param ctx - The shape will be rendered into this context.
35411 * @param arrowData - The data determining the shape.
35412 *
35413 * @returns False as there is no way to fill an image.
35414 */
35415 value: function draw(ctx, arrowData) {
35416 if (arrowData.image) {
35417 ctx.save();
35418 ctx.translate(arrowData.point.x, arrowData.point.y);
35419 ctx.rotate(Math.PI / 2 + arrowData.angle);
35420 var width = arrowData.imageWidth != null ? arrowData.imageWidth : arrowData.image.width;
35421 var height = arrowData.imageHeight != null ? arrowData.imageHeight : arrowData.image.height;
35422 arrowData.image.drawImageAtPosition(ctx, 1, // scale
35423 -width / 2, // x
35424 0, // y
35425 width, height);
35426 ctx.restore();
35427 }
35428
35429 return false;
35430 }
35431 }]);
35432
35433 return Image;
35434 }(EndPoint);
35435 /**
35436 * Drawing methods for the arrow endpoint.
35437 */
35438
35439
35440 var Arrow =
35441 /*#__PURE__*/
35442 function (_EndPoint2) {
35443 _inherits(Arrow, _EndPoint2);
35444
35445 function Arrow() {
35446 _classCallCheck(this, Arrow);
35447
35448 return _possibleConstructorReturn(this, _getPrototypeOf(Arrow).apply(this, arguments));
35449 }
35450
35451 _createClass(Arrow, null, [{
35452 key: "draw",
35453
35454 /**
35455 * Draw this shape at the end of a line.
35456 *
35457 * @param ctx - The shape will be rendered into this context.
35458 * @param arrowData - The data determining the shape.
35459 *
35460 * @returns True because ctx.fill() can be used to fill the arrow.
35461 */
35462 value: function draw(ctx, arrowData) {
35463 // Normalized points of closed path, in the order that they should be drawn.
35464 // (0, 0) is the attachment point, and the point around which should be rotated
35465 var points = [{
35466 x: 0,
35467 y: 0
35468 }, {
35469 x: -1,
35470 y: 0.3
35471 }, {
35472 x: -0.9,
35473 y: 0
35474 }, {
35475 x: -1,
35476 y: -0.3
35477 }];
35478 EndPoint.transform(points, arrowData);
35479 EndPoint.drawPath(ctx, points);
35480 return true;
35481 }
35482 }]);
35483
35484 return Arrow;
35485 }(EndPoint);
35486 /**
35487 * Drawing methods for the crow endpoint.
35488 */
35489
35490
35491 var Crow =
35492 /*#__PURE__*/
35493 function () {
35494 function Crow() {
35495 _classCallCheck(this, Crow);
35496 }
35497
35498 _createClass(Crow, null, [{
35499 key: "draw",
35500
35501 /**
35502 * Draw this shape at the end of a line.
35503 *
35504 * @param ctx - The shape will be rendered into this context.
35505 * @param arrowData - The data determining the shape.
35506 *
35507 * @returns True because ctx.fill() can be used to fill the arrow.
35508 */
35509 value: function draw(ctx, arrowData) {
35510 // Normalized points of closed path, in the order that they should be drawn.
35511 // (0, 0) is the attachment point, and the point around which should be rotated
35512 var points = [{
35513 x: -1,
35514 y: 0
35515 }, {
35516 x: 0,
35517 y: 0.3
35518 }, {
35519 x: -0.4,
35520 y: 0
35521 }, {
35522 x: 0,
35523 y: -0.3
35524 }];
35525 EndPoint.transform(points, arrowData);
35526 EndPoint.drawPath(ctx, points);
35527 return true;
35528 }
35529 }]);
35530
35531 return Crow;
35532 }();
35533 /**
35534 * Drawing methods for the curve endpoint.
35535 */
35536
35537
35538 var Curve =
35539 /*#__PURE__*/
35540 function () {
35541 function Curve() {
35542 _classCallCheck(this, Curve);
35543 }
35544
35545 _createClass(Curve, null, [{
35546 key: "draw",
35547
35548 /**
35549 * Draw this shape at the end of a line.
35550 *
35551 * @param ctx - The shape will be rendered into this context.
35552 * @param arrowData - The data determining the shape.
35553 *
35554 * @returns True because ctx.fill() can be used to fill the arrow.
35555 */
35556 value: function draw(ctx, arrowData) {
35557 // Normalized points of closed path, in the order that they should be drawn.
35558 // (0, 0) is the attachment point, and the point around which should be rotated
35559 var point = {
35560 x: -0.4,
35561 y: 0
35562 };
35563 EndPoint.transform(point, arrowData); // Update endpoint style for drawing transparent arc.
35564
35565 ctx.strokeStyle = ctx.fillStyle;
35566 ctx.fillStyle = "rgba(0, 0, 0, 0)"; // Define curve endpoint as semicircle.
35567
35568 var pi = Math.PI;
35569 var startAngle = arrowData.angle - pi / 2;
35570 var endAngle = arrowData.angle + pi / 2;
35571 ctx.beginPath();
35572 ctx.arc(point.x, point.y, arrowData.length * 0.4, startAngle, endAngle, false);
35573 ctx.stroke();
35574 return true;
35575 }
35576 }]);
35577
35578 return Curve;
35579 }();
35580 /**
35581 * Drawing methods for the inverted curve endpoint.
35582 */
35583
35584
35585 var InvertedCurve =
35586 /*#__PURE__*/
35587 function () {
35588 function InvertedCurve() {
35589 _classCallCheck(this, InvertedCurve);
35590 }
35591
35592 _createClass(InvertedCurve, null, [{
35593 key: "draw",
35594
35595 /**
35596 * Draw this shape at the end of a line.
35597 *
35598 * @param ctx - The shape will be rendered into this context.
35599 * @param arrowData - The data determining the shape.
35600 *
35601 * @returns True because ctx.fill() can be used to fill the arrow.
35602 */
35603 value: function draw(ctx, arrowData) {
35604 // Normalized points of closed path, in the order that they should be drawn.
35605 // (0, 0) is the attachment point, and the point around which should be rotated
35606 var point = {
35607 x: -0.3,
35608 y: 0
35609 };
35610 EndPoint.transform(point, arrowData); // Update endpoint style for drawing transparent arc.
35611
35612 ctx.strokeStyle = ctx.fillStyle;
35613 ctx.fillStyle = "rgba(0, 0, 0, 0)"; // Define inverted curve endpoint as semicircle.
35614
35615 var pi = Math.PI;
35616 var startAngle = arrowData.angle + pi / 2;
35617 var endAngle = arrowData.angle + 3 * pi / 2;
35618 ctx.beginPath();
35619 ctx.arc(point.x, point.y, arrowData.length * 0.4, startAngle, endAngle, false);
35620 ctx.stroke();
35621 return true;
35622 }
35623 }]);
35624
35625 return InvertedCurve;
35626 }();
35627 /**
35628 * Drawing methods for the trinagle endpoint.
35629 */
35630
35631
35632 var Triangle$1 =
35633 /*#__PURE__*/
35634 function () {
35635 function Triangle() {
35636 _classCallCheck(this, Triangle);
35637 }
35638
35639 _createClass(Triangle, null, [{
35640 key: "draw",
35641
35642 /**
35643 * Draw this shape at the end of a line.
35644 *
35645 * @param ctx - The shape will be rendered into this context.
35646 * @param arrowData - The data determining the shape.
35647 *
35648 * @returns True because ctx.fill() can be used to fill the arrow.
35649 */
35650 value: function draw(ctx, arrowData) {
35651 // Normalized points of closed path, in the order that they should be drawn.
35652 // (0, 0) is the attachment point, and the point around which should be rotated
35653 var points = [{
35654 x: 0.02,
35655 y: 0
35656 }, {
35657 x: -1,
35658 y: 0.3
35659 }, {
35660 x: -1,
35661 y: -0.3
35662 }];
35663 EndPoint.transform(points, arrowData);
35664 EndPoint.drawPath(ctx, points);
35665 return true;
35666 }
35667 }]);
35668
35669 return Triangle;
35670 }();
35671 /**
35672 * Drawing methods for the inverted trinagle endpoint.
35673 */
35674
35675
35676 var InvertedTriangle =
35677 /*#__PURE__*/
35678 function () {
35679 function InvertedTriangle() {
35680 _classCallCheck(this, InvertedTriangle);
35681 }
35682
35683 _createClass(InvertedTriangle, null, [{
35684 key: "draw",
35685
35686 /**
35687 * Draw this shape at the end of a line.
35688 *
35689 * @param ctx - The shape will be rendered into this context.
35690 * @param arrowData - The data determining the shape.
35691 *
35692 * @returns True because ctx.fill() can be used to fill the arrow.
35693 */
35694 value: function draw(ctx, arrowData) {
35695 // Normalized points of closed path, in the order that they should be drawn.
35696 // (0, 0) is the attachment point, and the point around which should be rotated
35697 var points = [{
35698 x: 0,
35699 y: 0.3
35700 }, {
35701 x: 0,
35702 y: -0.3
35703 }, {
35704 x: -1,
35705 y: 0
35706 }];
35707 EndPoint.transform(points, arrowData);
35708 EndPoint.drawPath(ctx, points);
35709 return true;
35710 }
35711 }]);
35712
35713 return InvertedTriangle;
35714 }();
35715 /**
35716 * Drawing methods for the circle endpoint.
35717 */
35718
35719
35720 var Circle$1 =
35721 /*#__PURE__*/
35722 function () {
35723 function Circle() {
35724 _classCallCheck(this, Circle);
35725 }
35726
35727 _createClass(Circle, null, [{
35728 key: "draw",
35729
35730 /**
35731 * Draw this shape at the end of a line.
35732 *
35733 * @param ctx - The shape will be rendered into this context.
35734 * @param arrowData - The data determining the shape.
35735 *
35736 * @returns True because ctx.fill() can be used to fill the arrow.
35737 */
35738 value: function draw(ctx, arrowData) {
35739 var point = {
35740 x: -0.4,
35741 y: 0
35742 };
35743 EndPoint.transform(point, arrowData);
35744 ctx.circle(point.x, point.y, arrowData.length * 0.4);
35745 return true;
35746 }
35747 }]);
35748
35749 return Circle;
35750 }();
35751 /**
35752 * Drawing methods for the bar endpoint.
35753 */
35754
35755
35756 var Bar =
35757 /*#__PURE__*/
35758 function () {
35759 function Bar() {
35760 _classCallCheck(this, Bar);
35761 }
35762
35763 _createClass(Bar, null, [{
35764 key: "draw",
35765
35766 /**
35767 * Draw this shape at the end of a line.
35768 *
35769 * @param ctx - The shape will be rendered into this context.
35770 * @param arrowData - The data determining the shape.
35771 *
35772 * @returns True because ctx.fill() can be used to fill the arrow.
35773 */
35774 value: function draw(ctx, arrowData) {
35775 /*
35776 var points = [
35777 {x:0, y:0.5},
35778 {x:0, y:-0.5}
35779 ];
35780 EndPoint.transform(points, arrowData);
35781 ctx.beginPath();
35782 ctx.moveTo(points[0].x, points[0].y);
35783 ctx.lineTo(points[1].x, points[1].y);
35784 ctx.stroke();
35785 */
35786 var points = [{
35787 x: 0,
35788 y: 0.5
35789 }, {
35790 x: 0,
35791 y: -0.5
35792 }, {
35793 x: -0.15,
35794 y: -0.5
35795 }, {
35796 x: -0.15,
35797 y: 0.5
35798 }];
35799 EndPoint.transform(points, arrowData);
35800 EndPoint.drawPath(ctx, points);
35801 return true;
35802 }
35803 }]);
35804
35805 return Bar;
35806 }();
35807 /**
35808 * Drawing methods for the box endpoint.
35809 */
35810
35811
35812 var Box$1 =
35813 /*#__PURE__*/
35814 function () {
35815 function Box() {
35816 _classCallCheck(this, Box);
35817 }
35818
35819 _createClass(Box, null, [{
35820 key: "draw",
35821
35822 /**
35823 * Draw this shape at the end of a line.
35824 *
35825 * @param ctx - The shape will be rendered into this context.
35826 * @param arrowData - The data determining the shape.
35827 *
35828 * @returns True because ctx.fill() can be used to fill the arrow.
35829 */
35830 value: function draw(ctx, arrowData) {
35831 var points = [{
35832 x: 0,
35833 y: 0.3
35834 }, {
35835 x: 0,
35836 y: -0.3
35837 }, {
35838 x: -0.6,
35839 y: -0.3
35840 }, {
35841 x: -0.6,
35842 y: 0.3
35843 }];
35844 EndPoint.transform(points, arrowData);
35845 EndPoint.drawPath(ctx, points);
35846 return true;
35847 }
35848 }]);
35849
35850 return Box;
35851 }();
35852 /**
35853 * Drawing methods for the diamond endpoint.
35854 */
35855
35856
35857 var Diamond$1 =
35858 /*#__PURE__*/
35859 function () {
35860 function Diamond() {
35861 _classCallCheck(this, Diamond);
35862 }
35863
35864 _createClass(Diamond, null, [{
35865 key: "draw",
35866
35867 /**
35868 * Draw this shape at the end of a line.
35869 *
35870 * @param ctx - The shape will be rendered into this context.
35871 * @param arrowData - The data determining the shape.
35872 *
35873 * @returns True because ctx.fill() can be used to fill the arrow.
35874 */
35875 value: function draw(ctx, arrowData) {
35876 var points = [{
35877 x: 0,
35878 y: 0
35879 }, {
35880 x: -0.5,
35881 y: -0.3
35882 }, {
35883 x: -1,
35884 y: 0
35885 }, {
35886 x: -0.5,
35887 y: 0.3
35888 }];
35889 EndPoint.transform(points, arrowData);
35890 EndPoint.drawPath(ctx, points);
35891 return true;
35892 }
35893 }]);
35894
35895 return Diamond;
35896 }();
35897 /**
35898 * Drawing methods for the vee endpoint.
35899 */
35900
35901
35902 var Vee =
35903 /*#__PURE__*/
35904 function () {
35905 function Vee() {
35906 _classCallCheck(this, Vee);
35907 }
35908
35909 _createClass(Vee, null, [{
35910 key: "draw",
35911
35912 /**
35913 * Draw this shape at the end of a line.
35914 *
35915 * @param ctx - The shape will be rendered into this context.
35916 * @param arrowData - The data determining the shape.
35917 *
35918 * @returns True because ctx.fill() can be used to fill the arrow.
35919 */
35920 value: function draw(ctx, arrowData) {
35921 // Normalized points of closed path, in the order that they should be drawn.
35922 // (0, 0) is the attachment point, and the point around which should be rotated
35923 var points = [{
35924 x: -1,
35925 y: 0.3
35926 }, {
35927 x: -0.5,
35928 y: 0
35929 }, {
35930 x: -1,
35931 y: -0.3
35932 }, {
35933 x: 0,
35934 y: 0
35935 }];
35936 EndPoint.transform(points, arrowData);
35937 EndPoint.drawPath(ctx, points);
35938 return true;
35939 }
35940 }]);
35941
35942 return Vee;
35943 }();
35944 /**
35945 * Drawing methods for the endpoints.
35946 */
35947
35948
35949 var EndPoints =
35950 /*#__PURE__*/
35951 function () {
35952 function EndPoints() {
35953 _classCallCheck(this, EndPoints);
35954 }
35955
35956 _createClass(EndPoints, null, [{
35957 key: "draw",
35958
35959 /**
35960 * Draw an endpoint.
35961 *
35962 * @param ctx - The shape will be rendered into this context.
35963 * @param arrowData - The data determining the shape.
35964 *
35965 * @returns True if ctx.fill() can be used to fill the arrow, false otherwise.
35966 */
35967 value: function draw(ctx, arrowData) {
35968 var type;
35969
35970 if (arrowData.type) {
35971 type = arrowData.type.toLowerCase();
35972 }
35973
35974 switch (type) {
35975 case "image":
35976 return Image$2.draw(ctx, arrowData);
35977
35978 case "circle":
35979 return Circle$1.draw(ctx, arrowData);
35980
35981 case "box":
35982 return Box$1.draw(ctx, arrowData);
35983
35984 case "crow":
35985 return Crow.draw(ctx, arrowData);
35986
35987 case "curve":
35988 return Curve.draw(ctx, arrowData);
35989
35990 case "diamond":
35991 return Diamond$1.draw(ctx, arrowData);
35992
35993 case "inv_curve":
35994 return InvertedCurve.draw(ctx, arrowData);
35995
35996 case "triangle":
35997 return Triangle$1.draw(ctx, arrowData);
35998
35999 case "inv_triangle":
36000 return InvertedTriangle.draw(ctx, arrowData);
36001
36002 case "bar":
36003 return Bar.draw(ctx, arrowData);
36004
36005 case "vee":
36006 return Vee.draw(ctx, arrowData);
36007
36008 case "arrow": // fall-through
36009
36010 default:
36011 return Arrow.draw(ctx, arrowData);
36012 }
36013 }
36014 }]);
36015
36016 return EndPoints;
36017 }();
36018
36019 /**
36020 * The Base Class for all edges.
36021 */
36022
36023 var EdgeBase =
36024 /*#__PURE__*/
36025 function () {
36026 /**
36027 * Create a new instance.
36028 *
36029 * @param options - The options object of given edge.
36030 * @param _body - The body of the network.
36031 * @param _labelModule - Label module.
36032 */
36033 function EdgeBase(options, _body, _labelModule) {
36034 _classCallCheck(this, EdgeBase);
36035
36036 this._body = _body;
36037 this._labelModule = _labelModule;
36038 this.color = {};
36039 this.colorDirty = true;
36040 this.hoverWidth = 1.5;
36041 this.selectionWidth = 2;
36042 this.setOptions(options);
36043 this.fromPoint = this.from;
36044 this.toPoint = this.to;
36045 }
36046 /** @inheritdoc */
36047
36048
36049 _createClass(EdgeBase, [{
36050 key: "connect",
36051 value: function connect() {
36052 this.from = this._body.nodes[this.options.from];
36053 this.to = this._body.nodes[this.options.to];
36054 }
36055 /** @inheritdoc */
36056
36057 }, {
36058 key: "cleanup",
36059 value: function cleanup() {
36060 return false;
36061 }
36062 /**
36063 * Set new edge options.
36064 *
36065 * @param options - The new edge options object.
36066 */
36067
36068 }, {
36069 key: "setOptions",
36070 value: function setOptions(options) {
36071 this.options = options;
36072 this.from = this._body.nodes[this.options.from];
36073 this.to = this._body.nodes[this.options.to];
36074 this.id = this.options.id;
36075 }
36076 /** @inheritdoc */
36077
36078 }, {
36079 key: "drawLine",
36080 value: function drawLine(ctx, values, _selected, _hover) {
36081 var viaNode = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.getViaNode();
36082 // set style
36083 ctx.strokeStyle = this.getColor(ctx, values);
36084 ctx.lineWidth = values.width;
36085
36086 if (values.dashes !== false) {
36087 this._drawDashedLine(ctx, values, viaNode);
36088 } else {
36089 this._drawLine(ctx, values, viaNode);
36090 }
36091 }
36092 /**
36093 * Draw a line with given style between two nodes through supplied node(s).
36094 *
36095 * @param ctx - The context that will be used for rendering.
36096 * @param values - Formatting values like color, opacity or shadow.
36097 * @param viaNode - Additional control point(s) for the edge.
36098 * @param fromPoint - TODO: Seems ignored, remove?
36099 * @param toPoint - TODO: Seems ignored, remove?
36100 */
36101
36102 }, {
36103 key: "_drawLine",
36104 value: function _drawLine(ctx, values, viaNode, fromPoint, toPoint) {
36105 if (this.from != this.to) {
36106 // draw line
36107 this._line(ctx, values, viaNode, fromPoint, toPoint);
36108 } else {
36109 var _this$_getCircleData = this._getCircleData(ctx),
36110 _this$_getCircleData2 = _slicedToArray(_this$_getCircleData, 3),
36111 x = _this$_getCircleData2[0],
36112 y = _this$_getCircleData2[1],
36113 radius = _this$_getCircleData2[2];
36114
36115 this._circle(ctx, values, x, y, radius);
36116 }
36117 }
36118 /**
36119 * Draw a dashed line with given style between two nodes through supplied node(s).
36120 *
36121 * @param ctx - The context that will be used for rendering.
36122 * @param values - Formatting values like color, opacity or shadow.
36123 * @param viaNode - Additional control point(s) for the edge.
36124 * @param _fromPoint - Ignored (TODO: remove in the future).
36125 * @param _toPoint - Ignored (TODO: remove in the future).
36126 */
36127
36128 }, {
36129 key: "_drawDashedLine",
36130 value: function _drawDashedLine(ctx, values, viaNode, _fromPoint, _toPoint) {
36131 ctx.lineCap = "round";
36132 var pattern = Array.isArray(values.dashes) ? values.dashes : [5, 5]; // only firefox and chrome support this method, else we use the legacy one.
36133
36134 if (ctx.setLineDash !== undefined) {
36135 ctx.save(); // set dash settings for chrome or firefox
36136
36137 ctx.setLineDash(pattern);
36138 ctx.lineDashOffset = 0; // draw the line
36139
36140 if (this.from != this.to) {
36141 // draw line
36142 this._line(ctx, values, viaNode);
36143 } else {
36144 var _this$_getCircleData3 = this._getCircleData(ctx),
36145 _this$_getCircleData4 = _slicedToArray(_this$_getCircleData3, 3),
36146 x = _this$_getCircleData4[0],
36147 y = _this$_getCircleData4[1],
36148 radius = _this$_getCircleData4[2];
36149
36150 this._circle(ctx, values, x, y, radius);
36151 } // restore the dash settings.
36152
36153
36154 ctx.setLineDash([0]);
36155 ctx.lineDashOffset = 0;
36156 ctx.restore();
36157 } else {
36158 // unsupporting smooth lines
36159 if (this.from != this.to) {
36160 // draw line
36161 ctx.dashedLine(this.from.x, this.from.y, this.to.x, this.to.y, pattern);
36162 } else {
36163 var _this$_getCircleData5 = this._getCircleData(ctx),
36164 _this$_getCircleData6 = _slicedToArray(_this$_getCircleData5, 3),
36165 _x = _this$_getCircleData6[0],
36166 _y = _this$_getCircleData6[1],
36167 _radius = _this$_getCircleData6[2];
36168
36169 this._circle(ctx, values, _x, _y, _radius);
36170 } // draw shadow if enabled
36171
36172
36173 this.enableShadow(ctx, values);
36174 ctx.stroke(); // disable shadows for other elements.
36175
36176 this.disableShadow(ctx, values);
36177 }
36178 }
36179 /**
36180 * Find the intersection between the border of the node and the edge.
36181 *
36182 * @param node - The node (either from or to node of the edge).
36183 * @param ctx - The context that will be used for rendering.
36184 * @param options - Additional options.
36185 *
36186 * @returns Cartesian coordinates of the intersection between the border of the node and the edge.
36187 */
36188
36189 }, {
36190 key: "findBorderPosition",
36191 value: function findBorderPosition(node, ctx, options) {
36192 if (this.from != this.to) {
36193 return this._findBorderPosition(node, ctx, options);
36194 } else {
36195 return this._findBorderPositionCircle(node, ctx, options);
36196 }
36197 }
36198 /** @inheritdoc */
36199
36200 }, {
36201 key: "findBorderPositions",
36202 value: function findBorderPositions(ctx) {
36203 if (this.from != this.to) {
36204 return {
36205 from: this._findBorderPosition(this.from, ctx),
36206 to: this._findBorderPosition(this.to, ctx)
36207 };
36208 } else {
36209 var _this$_getCircleData$ = this._getCircleData(ctx).slice(0, 2),
36210 _this$_getCircleData$2 = _slicedToArray(_this$_getCircleData$, 2),
36211 x = _this$_getCircleData$2[0],
36212 y = _this$_getCircleData$2[1];
36213
36214 return {
36215 from: this._findBorderPositionCircle(this.from, ctx, {
36216 x: x,
36217 y: y,
36218 low: 0.25,
36219 high: 0.6,
36220 direction: -1
36221 }),
36222 to: this._findBorderPositionCircle(this.from, ctx, {
36223 x: x,
36224 y: y,
36225 low: 0.6,
36226 high: 0.8,
36227 direction: 1
36228 })
36229 };
36230 }
36231 }
36232 /**
36233 * Compute the center point and radius of an edge connected to the same node at both ends.
36234 *
36235 * @param ctx - The context that will be used for rendering.
36236 *
36237 * @returns `[x, y, radius]`
36238 */
36239
36240 }, {
36241 key: "_getCircleData",
36242 value: function _getCircleData(ctx) {
36243 var x;
36244 var y;
36245 var node = this.from;
36246 var radius = this.options.selfReferenceSize;
36247
36248 if (ctx !== undefined) {
36249 if (node.shape.width === undefined) {
36250 node.shape.resize(ctx);
36251 }
36252 } // get circle coordinates
36253
36254
36255 if (node.shape.width > node.shape.height) {
36256 x = node.x + node.shape.width * 0.5;
36257 y = node.y - radius;
36258 } else {
36259 x = node.x + radius;
36260 y = node.y - node.shape.height * 0.5;
36261 }
36262
36263 return [x, y, radius];
36264 }
36265 /**
36266 * Get a point on a circle.
36267 *
36268 * @param x - Center of the circle on the x axis.
36269 * @param y - Center of the circle on the y axis.
36270 * @param radius - Radius of the circle.
36271 * @param position - Value between 0 (line start) and 1 (line end).
36272 *
36273 * @returns Cartesian coordinates of requested point on the circle.
36274 */
36275
36276 }, {
36277 key: "_pointOnCircle",
36278 value: function _pointOnCircle(x, y, radius, position) {
36279 var angle = position * 2 * Math.PI;
36280 return {
36281 x: x + radius * Math.cos(angle),
36282 y: y - radius * Math.sin(angle)
36283 };
36284 }
36285 /**
36286 * Find the intersection between the border of the node and the edge.
36287 *
36288 * @remarks
36289 * This function uses binary search to look for the point where the circle crosses the border of the node.
36290 *
36291 * @param nearNode - The node (either from or to node of the edge).
36292 * @param ctx - The context that will be used for rendering.
36293 * @param options - Additional options.
36294 *
36295 * @returns Cartesian coordinates of the intersection between the border of the node and the edge.
36296 */
36297
36298 }, {
36299 key: "_findBorderPositionCircle",
36300 value: function _findBorderPositionCircle(nearNode, ctx, options) {
36301 var x = options.x;
36302 var y = options.y;
36303 var low = options.low;
36304 var high = options.high;
36305 var direction = options.direction;
36306 var maxIterations = 10;
36307 var radius = this.options.selfReferenceSize;
36308 var threshold = 0.05;
36309 var pos;
36310 var middle = (low + high) * 0.5;
36311 var iteration = 0;
36312
36313 do {
36314 middle = (low + high) * 0.5;
36315 pos = this._pointOnCircle(x, y, radius, middle);
36316 var angle = Math.atan2(nearNode.y - pos.y, nearNode.x - pos.x);
36317 var distanceToBorder = nearNode.distanceToBorder(ctx, angle);
36318 var distanceToPoint = Math.sqrt(Math.pow(pos.x - nearNode.x, 2) + Math.pow(pos.y - nearNode.y, 2));
36319 var difference = distanceToBorder - distanceToPoint;
36320
36321 if (Math.abs(difference) < threshold) {
36322 break; // found
36323 } else if (difference > 0) {
36324 // distance to nodes is larger than distance to border --> t needs to be bigger if we're looking at the to node.
36325 if (direction > 0) {
36326 low = middle;
36327 } else {
36328 high = middle;
36329 }
36330 } else {
36331 if (direction > 0) {
36332 high = middle;
36333 } else {
36334 low = middle;
36335 }
36336 }
36337
36338 ++iteration;
36339 } while (low <= high && iteration < maxIterations);
36340
36341 return _objectSpread2({}, pos, {
36342 t: middle
36343 });
36344 }
36345 /**
36346 * Get the line width of the edge. Depends on width and whether one of the connected nodes is selected.
36347 *
36348 * @param selected - Determines wheter the line is selected.
36349 * @param hover - Determines wheter the line is being hovered, only applies if selected is false.
36350 *
36351 * @returns The width of the line.
36352 */
36353
36354 }, {
36355 key: "getLineWidth",
36356 value: function getLineWidth(selected, hover) {
36357 if (selected === true) {
36358 return Math.max(this.selectionWidth, 0.3 / this._body.view.scale);
36359 } else if (hover === true) {
36360 return Math.max(this.hoverWidth, 0.3 / this._body.view.scale);
36361 } else {
36362 return Math.max(this.options.width, 0.3 / this._body.view.scale);
36363 }
36364 }
36365 /**
36366 * Compute the color or gradient for given edge.
36367 *
36368 * @param ctx - The context that will be used for rendering.
36369 * @param values - Formatting values like color, opacity or shadow.
36370 * @param _selected - Ignored (TODO: remove in the future).
36371 * @param _hover - Ignored (TODO: remove in the future).
36372 *
36373 * @returns Color string if single color is inherited or gradient if two.
36374 */
36375
36376 }, {
36377 key: "getColor",
36378 value: function getColor(ctx, values) {
36379 if (values.inheritsColor !== false) {
36380 // when this is a loop edge, just use the 'from' method
36381 if (values.inheritsColor === "both" && this.from.id !== this.to.id) {
36382 var grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y);
36383 var fromColor = this.from.options.color.highlight.border;
36384 var toColor = this.to.options.color.highlight.border;
36385
36386 if (this.from.selected === false && this.to.selected === false) {
36387 fromColor = overrideOpacity(this.from.options.color.border, values.opacity);
36388 toColor = overrideOpacity(this.to.options.color.border, values.opacity);
36389 } else if (this.from.selected === true && this.to.selected === false) {
36390 toColor = this.to.options.color.border;
36391 } else if (this.from.selected === false && this.to.selected === true) {
36392 fromColor = this.from.options.color.border;
36393 }
36394
36395 grd.addColorStop(0, fromColor);
36396 grd.addColorStop(1, toColor); // -------------------- this returns -------------------- //
36397
36398 return grd;
36399 }
36400
36401 if (values.inheritsColor === "to") {
36402 return overrideOpacity(this.to.options.color.border, values.opacity);
36403 } else {
36404 // "from"
36405 return overrideOpacity(this.from.options.color.border, values.opacity);
36406 }
36407 } else {
36408 return overrideOpacity(values.color, values.opacity);
36409 }
36410 }
36411 /**
36412 * Draw a line from a node to itself, a circle.
36413 *
36414 * @param ctx - The context that will be used for rendering.
36415 * @param values - Formatting values like color, opacity or shadow.
36416 * @param x - Center of the circle on the x axis.
36417 * @param y - Center of the circle on the y axis.
36418 * @param radius - Radius of the circle.
36419 */
36420
36421 }, {
36422 key: "_circle",
36423 value: function _circle(ctx, values, x, y, radius) {
36424 // draw shadow if enabled
36425 this.enableShadow(ctx, values); // draw a circle
36426
36427 ctx.beginPath();
36428 ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
36429 ctx.stroke(); // disable shadows for other elements.
36430
36431 this.disableShadow(ctx, values);
36432 }
36433 /**
36434 * @inheritdoc
36435 *
36436 * @remarks
36437 * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
36438 */
36439
36440 }, {
36441 key: "getDistanceToEdge",
36442 value: function getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
36443 if (this.from != this.to) {
36444 return this._getDistanceToEdge(x1, y1, x2, y2, x3, y3);
36445 } else {
36446 var _this$_getCircleData7 = this._getCircleData(undefined),
36447 _this$_getCircleData8 = _slicedToArray(_this$_getCircleData7, 3),
36448 x = _this$_getCircleData8[0],
36449 y = _this$_getCircleData8[1],
36450 radius = _this$_getCircleData8[2];
36451
36452 var dx = x - x3;
36453 var dy = y - y3;
36454 return Math.abs(Math.sqrt(dx * dx + dy * dy) - radius);
36455 }
36456 }
36457 /**
36458 * Calculate the distance between a point (x3, y3) and a line segment from (x1, y1) to (x2, y2).
36459 *
36460 * @param x1 - First end of the line segment on the x axis.
36461 * @param y1 - First end of the line segment on the y axis.
36462 * @param x2 - Second end of the line segment on the x axis.
36463 * @param y2 - Second end of the line segment on the y axis.
36464 * @param x3 - Position of the point on the x axis.
36465 * @param y3 - Position of the point on the y axis.
36466 *
36467 * @returns The distance between the line segment and the point.
36468 */
36469
36470 }, {
36471 key: "_getDistanceToLine",
36472 value: function _getDistanceToLine(x1, y1, x2, y2, x3, y3) {
36473 var px = x2 - x1;
36474 var py = y2 - y1;
36475 var something = px * px + py * py;
36476 var u = ((x3 - x1) * px + (y3 - y1) * py) / something;
36477
36478 if (u > 1) {
36479 u = 1;
36480 } else if (u < 0) {
36481 u = 0;
36482 }
36483
36484 var x = x1 + u * px;
36485 var y = y1 + u * py;
36486 var dx = x - x3;
36487 var dy = y - y3; //# Note: If the actual distance does not matter,
36488 //# if you only want to compare what this function
36489 //# returns to other results of this function, you
36490 //# can just return the squared distance instead
36491 //# (i.e. remove the sqrt) to gain a little performance
36492
36493 return Math.sqrt(dx * dx + dy * dy);
36494 }
36495 /** @inheritdoc */
36496
36497 }, {
36498 key: "getArrowData",
36499 value: function getArrowData(ctx, position, viaNode, _selected, _hover, values) {
36500 // set lets
36501 var angle;
36502 var arrowPoint;
36503 var node1;
36504 var node2;
36505 var reversed;
36506 var scaleFactor;
36507 var type;
36508 var lineWidth = values.width;
36509
36510 if (position === "from") {
36511 node1 = this.from;
36512 node2 = this.to;
36513 reversed = values.fromArrowScale < 0;
36514 scaleFactor = Math.abs(values.fromArrowScale);
36515 type = values.fromArrowType;
36516 } else if (position === "to") {
36517 node1 = this.to;
36518 node2 = this.from;
36519 reversed = values.toArrowScale < 0;
36520 scaleFactor = Math.abs(values.toArrowScale);
36521 type = values.toArrowType;
36522 } else {
36523 node1 = this.to;
36524 node2 = this.from;
36525 reversed = values.middleArrowScale < 0;
36526 scaleFactor = Math.abs(values.middleArrowScale);
36527 type = values.middleArrowType;
36528 }
36529
36530 var length = 15 * scaleFactor + 3 * lineWidth; // 3* lineWidth is the width of the edge.
36531 // if not connected to itself
36532
36533 if (node1 != node2) {
36534 var approximateEdgeLength = Math.hypot(node1.x - node2.x, node1.y - node2.y);
36535 var relativeLength = length / approximateEdgeLength;
36536
36537 if (position !== "middle") {
36538 // draw arrow head
36539 if (this.options.smooth.enabled === true) {
36540 var pointT = this._findBorderPosition(node1, ctx, {
36541 via: viaNode
36542 });
36543
36544 var guidePos = this.getPoint(pointT.t + relativeLength * (position === "from" ? 1 : -1), viaNode);
36545 angle = Math.atan2(pointT.y - guidePos.y, pointT.x - guidePos.x);
36546 arrowPoint = pointT;
36547 } else {
36548 angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
36549 arrowPoint = this._findBorderPosition(node1, ctx);
36550 }
36551 } else {
36552 // Negative half length reverses arrow direction.
36553 var halfLength = (reversed ? -relativeLength : relativeLength) / 2;
36554 var guidePos1 = this.getPoint(0.5 + halfLength, viaNode);
36555 var guidePos2 = this.getPoint(0.5 - halfLength, viaNode);
36556 angle = Math.atan2(guidePos1.y - guidePos2.y, guidePos1.x - guidePos2.x);
36557 arrowPoint = this.getPoint(0.5, viaNode);
36558 }
36559 } else {
36560 // draw circle
36561 var _this$_getCircleData9 = this._getCircleData(ctx),
36562 _this$_getCircleData10 = _slicedToArray(_this$_getCircleData9, 3),
36563 x = _this$_getCircleData10[0],
36564 y = _this$_getCircleData10[1],
36565 radius = _this$_getCircleData10[2];
36566
36567 if (position === "from") {
36568 var _pointT = this._findBorderPositionCircle(this.from, ctx, {
36569 x: x,
36570 y: y,
36571 low: 0.25,
36572 high: 0.6,
36573 direction: -1
36574 });
36575
36576 angle = _pointT.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
36577 arrowPoint = _pointT;
36578 } else if (position === "to") {
36579 var _pointT2 = this._findBorderPositionCircle(this.from, ctx, {
36580 x: x,
36581 y: y,
36582 low: 0.6,
36583 high: 1.0,
36584 direction: 1
36585 });
36586
36587 angle = _pointT2.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
36588 arrowPoint = _pointT2;
36589 } else {
36590 arrowPoint = this._pointOnCircle(x, y, radius, 0.175);
36591 angle = 3.9269908169872414; // === 0.175 * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
36592 }
36593 }
36594
36595 var xi = arrowPoint.x - length * 0.9 * Math.cos(angle);
36596 var yi = arrowPoint.y - length * 0.9 * Math.sin(angle);
36597 var arrowCore = {
36598 x: xi,
36599 y: yi
36600 };
36601 return {
36602 point: arrowPoint,
36603 core: arrowCore,
36604 angle: angle,
36605 length: length,
36606 type: type
36607 };
36608 }
36609 /** @inheritdoc */
36610
36611 }, {
36612 key: "drawArrowHead",
36613 value: function drawArrowHead(ctx, values, _selected, _hover, arrowData) {
36614 // set style
36615 ctx.strokeStyle = this.getColor(ctx, values);
36616 ctx.fillStyle = ctx.strokeStyle;
36617 ctx.lineWidth = values.width;
36618 var canFill = EndPoints.draw(ctx, arrowData);
36619
36620 if (canFill) {
36621 // draw shadow if enabled
36622 this.enableShadow(ctx, values);
36623 ctx.fill(); // disable shadows for other elements.
36624
36625 this.disableShadow(ctx, values);
36626 }
36627 }
36628 /**
36629 * Set the shadow formatting values in the context if enabled, do nothing otherwise.
36630 *
36631 * @param ctx - The context that will be used for rendering.
36632 * @param values - Formatting values for the shadow.
36633 */
36634
36635 }, {
36636 key: "enableShadow",
36637 value: function enableShadow(ctx, values) {
36638 if (values.shadow === true) {
36639 ctx.shadowColor = values.shadowColor;
36640 ctx.shadowBlur = values.shadowSize;
36641 ctx.shadowOffsetX = values.shadowX;
36642 ctx.shadowOffsetY = values.shadowY;
36643 }
36644 }
36645 /**
36646 * Reset the shadow formatting values in the context if enabled, do nothing otherwise.
36647 *
36648 * @param ctx - The context that will be used for rendering.
36649 * @param values - Formatting values for the shadow.
36650 */
36651
36652 }, {
36653 key: "disableShadow",
36654 value: function disableShadow(ctx, values) {
36655 if (values.shadow === true) {
36656 ctx.shadowColor = "rgba(0,0,0,0)";
36657 ctx.shadowBlur = 0;
36658 ctx.shadowOffsetX = 0;
36659 ctx.shadowOffsetY = 0;
36660 }
36661 }
36662 /**
36663 * Render the background according to the formatting values.
36664 *
36665 * @param ctx - The context that will be used for rendering.
36666 * @param values - Formatting values for the background.
36667 */
36668
36669 }, {
36670 key: "drawBackground",
36671 value: function drawBackground(ctx, values) {
36672 if (values.background !== false) {
36673 // save original line attrs
36674 var origCtxAttr = {
36675 strokeStyle: ctx.strokeStyle,
36676 lineWidth: ctx.lineWidth,
36677 dashes: ctx.dashes
36678 };
36679 ctx.strokeStyle = values.backgroundColor;
36680 ctx.lineWidth = values.backgroundSize;
36681 this.setStrokeDashed(ctx, values.backgroundDashes);
36682 ctx.stroke(); // restore original line attrs
36683
36684 ctx.strokeStyle = origCtxAttr.strokeStyle;
36685 ctx.lineWidth = origCtxAttr.lineWidth;
36686 ctx.dashes = origCtxAttr.dashes;
36687 this.setStrokeDashed(ctx, values.dashes);
36688 }
36689 }
36690 /**
36691 * Set the line dash pattern if supported. Logs a warning to the console if it isn't supported.
36692 *
36693 * @param ctx - The context that will be used for rendering.
36694 * @param dashes - The pattern [line, space, line…], true for default dashed line or false for normal line.
36695 */
36696
36697 }, {
36698 key: "setStrokeDashed",
36699 value: function setStrokeDashed(ctx, dashes) {
36700 if (dashes !== false) {
36701 if (ctx.setLineDash !== undefined) {
36702 var pattern = Array.isArray(dashes) ? dashes : [5, 5];
36703 ctx.setLineDash(pattern);
36704 } else {
36705 console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");
36706 }
36707 } else {
36708 if (ctx.setLineDash !== undefined) {
36709 ctx.setLineDash([]);
36710 } else {
36711 console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");
36712 }
36713 }
36714 }
36715 }]);
36716
36717 return EdgeBase;
36718 }();
36719
36720 /**
36721 * The Base Class for all Bezier edges.
36722 * Bezier curves are used to model smooth gradual curves in paths between nodes.
36723 */
36724
36725 var BezierEdgeBase =
36726 /*#__PURE__*/
36727 function (_EdgeBase) {
36728 _inherits(BezierEdgeBase, _EdgeBase);
36729
36730 /**
36731 * Create a new instance.
36732 *
36733 * @param options - The options object of given edge.
36734 * @param body - The body of the network.
36735 * @param labelModule - Label module.
36736 */
36737 function BezierEdgeBase(options, body, labelModule) {
36738 _classCallCheck(this, BezierEdgeBase);
36739
36740 return _possibleConstructorReturn(this, _getPrototypeOf(BezierEdgeBase).call(this, options, body, labelModule));
36741 }
36742 /**
36743 * Find the intersection between the border of the node and the edge.
36744 *
36745 * @remarks
36746 * This function uses binary search to look for the point where the bezier curve crosses the border of the node.
36747 *
36748 * @param nearNode - The node (either from or to node of the edge).
36749 * @param ctx - The context that will be used for rendering.
36750 * @param viaNode - Additional node(s) the edge passes through.
36751 *
36752 * @returns Cartesian coordinates of the intersection between the border of the node and the edge.
36753 */
36754
36755
36756 _createClass(BezierEdgeBase, [{
36757 key: "_findBorderPositionBezier",
36758 value: function _findBorderPositionBezier(nearNode, ctx) {
36759 var viaNode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._getViaCoordinates();
36760 var maxIterations = 10;
36761 var threshold = 0.2;
36762 var from = false;
36763 var high = 1;
36764 var low = 0;
36765 var node = this.to;
36766 var pos;
36767 var middle;
36768
36769 if (nearNode.id === this.from.id) {
36770 node = this.from;
36771 from = true;
36772 }
36773
36774 var iteration = 0;
36775
36776 do {
36777 middle = (low + high) * 0.5;
36778 pos = this.getPoint(middle, viaNode);
36779 var angle = Math.atan2(node.y - pos.y, node.x - pos.x);
36780 var distanceToBorder = node.distanceToBorder(ctx, angle);
36781 var distanceToPoint = Math.sqrt(Math.pow(pos.x - node.x, 2) + Math.pow(pos.y - node.y, 2));
36782 var difference = distanceToBorder - distanceToPoint;
36783
36784 if (Math.abs(difference) < threshold) {
36785 break; // found
36786 } else if (difference < 0) {
36787 // distance to nodes is larger than distance to border --> t needs to be bigger if we're looking at the to node.
36788 if (from === false) {
36789 low = middle;
36790 } else {
36791 high = middle;
36792 }
36793 } else {
36794 if (from === false) {
36795 high = middle;
36796 } else {
36797 low = middle;
36798 }
36799 }
36800
36801 ++iteration;
36802 } while (low <= high && iteration < maxIterations);
36803
36804 return _objectSpread2({}, pos, {
36805 t: middle
36806 });
36807 }
36808 /**
36809 * Calculate the distance between a point (x3,y3) and a line segment from (x1,y1) to (x2,y2).
36810 *
36811 * @remarks
36812 * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
36813 *
36814 * @param x1 - First end of the line segment on the x axis.
36815 * @param y1 - First end of the line segment on the y axis.
36816 * @param x2 - Second end of the line segment on the x axis.
36817 * @param y2 - Second end of the line segment on the y axis.
36818 * @param x3 - Position of the point on the x axis.
36819 * @param y3 - Position of the point on the y axis.
36820 * @param via - The control point for the edge.
36821 *
36822 * @returns The distance between the line segment and the point.
36823 */
36824
36825 }, {
36826 key: "_getDistanceToBezierEdge",
36827 value: function _getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, via) {
36828 // x3,y3 is the point
36829 var minDistance = 1e9;
36830 var distance;
36831 var i, t, x, y;
36832 var lastX = x1;
36833 var lastY = y1;
36834
36835 for (i = 1; i < 10; i++) {
36836 t = 0.1 * i;
36837 x = Math.pow(1 - t, 2) * x1 + 2 * t * (1 - t) * via.x + Math.pow(t, 2) * x2;
36838 y = Math.pow(1 - t, 2) * y1 + 2 * t * (1 - t) * via.y + Math.pow(t, 2) * y2;
36839
36840 if (i > 0) {
36841 distance = this._getDistanceToLine(lastX, lastY, x, y, x3, y3);
36842 minDistance = distance < minDistance ? distance : minDistance;
36843 }
36844
36845 lastX = x;
36846 lastY = y;
36847 }
36848
36849 return minDistance;
36850 }
36851 /**
36852 * Render a bezier curve between two nodes.
36853 *
36854 * @remarks
36855 * The method accepts zero, one or two control points.
36856 * Passing zero control points just draws a straight line.
36857 *
36858 * @param ctx - The context that will be used for rendering.
36859 * @param values - Style options for edge drawing.
36860 * @param viaNode1 - First control point for curve drawing.
36861 * @param viaNode2 - Second control point for curve drawing.
36862 */
36863
36864 }, {
36865 key: "_bezierCurve",
36866 value: function _bezierCurve(ctx, values, viaNode1, viaNode2) {
36867 ctx.beginPath();
36868 ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
36869
36870 if (viaNode1 != null && viaNode1.x != null) {
36871 if (viaNode2 != null && viaNode2.x != null) {
36872 ctx.bezierCurveTo(viaNode1.x, viaNode1.y, viaNode2.x, viaNode2.y, this.toPoint.x, this.toPoint.y);
36873 } else {
36874 ctx.quadraticCurveTo(viaNode1.x, viaNode1.y, this.toPoint.x, this.toPoint.y);
36875 }
36876 } else {
36877 // fallback to normal straight edge
36878 ctx.lineTo(this.toPoint.x, this.toPoint.y);
36879 } // draw a background
36880
36881
36882 this.drawBackground(ctx, values); // draw shadow if enabled
36883
36884 this.enableShadow(ctx, values);
36885 ctx.stroke();
36886 this.disableShadow(ctx, values);
36887 }
36888 /** @inheritdoc */
36889
36890 }, {
36891 key: "getViaNode",
36892 value: function getViaNode() {
36893 return this._getViaCoordinates();
36894 }
36895 }]);
36896
36897 return BezierEdgeBase;
36898 }(EdgeBase);
36899
36900 /**
36901 * A Dynamic Bezier Edge. Bezier curves are used to model smooth gradual
36902 * curves in paths between nodes. The Dynamic piece refers to how the curve
36903 * reacts to physics changes.
36904 *
36905 * @extends BezierEdgeBase
36906 */
36907
36908 var BezierEdgeDynamic =
36909 /*#__PURE__*/
36910 function (_BezierEdgeBase) {
36911 _inherits(BezierEdgeDynamic, _BezierEdgeBase);
36912
36913 /**
36914 * Create a new instance.
36915 *
36916 * @param options - The options object of given edge.
36917 * @param body - The body of the network.
36918 * @param labelModule - Label module.
36919 */
36920 function BezierEdgeDynamic(options, body, labelModule) {
36921 var _this;
36922
36923 _classCallCheck(this, BezierEdgeDynamic);
36924
36925 //this.via = undefined; // Here for completeness but not allowed to defined before super() is invoked.
36926 _this = _possibleConstructorReturn(this, _getPrototypeOf(BezierEdgeDynamic).call(this, options, body, labelModule)); // --> this calls the setOptions below
36927
36928 _this.via = _this.via; // constructor → super → super → setOptions → setupSupportNode
36929
36930 _this._boundFunction = function () {
36931 _this.positionBezierNode();
36932 };
36933
36934 _this._body.emitter.on("_repositionBezierNodes", _this._boundFunction);
36935
36936 return _this;
36937 }
36938 /** @inheritdoc */
36939
36940
36941 _createClass(BezierEdgeDynamic, [{
36942 key: "setOptions",
36943 value: function setOptions(options) {
36944 _get(_getPrototypeOf(BezierEdgeDynamic.prototype), "setOptions", this).call(this, options); // check if the physics has changed.
36945
36946
36947 var physicsChange = false;
36948
36949 if (this.options.physics !== options.physics) {
36950 physicsChange = true;
36951 } // set the options and the to and from nodes
36952
36953
36954 this.options = options;
36955 this.id = this.options.id;
36956 this.from = this._body.nodes[this.options.from];
36957 this.to = this._body.nodes[this.options.to]; // setup the support node and connect
36958
36959 this.setupSupportNode();
36960 this.connect(); // when we change the physics state of the edge, we reposition the support node.
36961
36962 if (physicsChange === true) {
36963 this.via.setOptions({
36964 physics: this.options.physics
36965 });
36966 this.positionBezierNode();
36967 }
36968 }
36969 /** @inheritdoc */
36970
36971 }, {
36972 key: "connect",
36973 value: function connect() {
36974 this.from = this._body.nodes[this.options.from];
36975 this.to = this._body.nodes[this.options.to];
36976
36977 if (this.from === undefined || this.to === undefined || this.options.physics === false) {
36978 this.via.setOptions({
36979 physics: false
36980 });
36981 } else {
36982 // fix weird behaviour where a self referencing node has physics enabled
36983 if (this.from.id === this.to.id) {
36984 this.via.setOptions({
36985 physics: false
36986 });
36987 } else {
36988 this.via.setOptions({
36989 physics: true
36990 });
36991 }
36992 }
36993 }
36994 /** @inheritdoc */
36995
36996 }, {
36997 key: "cleanup",
36998 value: function cleanup() {
36999 this._body.emitter.off("_repositionBezierNodes", this._boundFunction);
37000
37001 if (this.via !== undefined) {
37002 delete this._body.nodes[this.via.id];
37003 this.via = undefined;
37004 return true;
37005 }
37006
37007 return false;
37008 }
37009 /**
37010 * Create and add a support node if not already present.
37011 *
37012 * @remarks
37013 * Bezier curves require an anchor point to calculate the smooth flow.
37014 * These points are nodes.
37015 * These nodes are invisible but are used for the force calculation.
37016 *
37017 * The changed data is not called, if needed, it is returned by the main edge constructor.
37018 */
37019
37020 }, {
37021 key: "setupSupportNode",
37022 value: function setupSupportNode() {
37023 if (this.via === undefined) {
37024 var nodeId = "edgeId:" + this.id;
37025
37026 var node = this._body.functions.createNode({
37027 id: nodeId,
37028 shape: "circle",
37029 physics: true,
37030 hidden: true
37031 });
37032
37033 this._body.nodes[nodeId] = node;
37034 this.via = node;
37035 this.via.parentEdgeId = this.id;
37036 this.positionBezierNode();
37037 }
37038 }
37039 /**
37040 * Position bezier node.
37041 */
37042
37043 }, {
37044 key: "positionBezierNode",
37045 value: function positionBezierNode() {
37046 if (this.via !== undefined && this.from !== undefined && this.to !== undefined) {
37047 this.via.x = 0.5 * (this.from.x + this.to.x);
37048 this.via.y = 0.5 * (this.from.y + this.to.y);
37049 } else if (this.via !== undefined) {
37050 this.via.x = 0;
37051 this.via.y = 0;
37052 }
37053 }
37054 /** @inheritdoc */
37055
37056 }, {
37057 key: "_line",
37058 value: function _line(ctx, values, viaNode) {
37059 this._bezierCurve(ctx, values, viaNode);
37060 }
37061 /** @inheritdoc */
37062
37063 }, {
37064 key: "_getViaCoordinates",
37065 value: function _getViaCoordinates() {
37066 return this.via;
37067 }
37068 /** @inheritdoc */
37069
37070 }, {
37071 key: "getViaNode",
37072 value: function getViaNode() {
37073 return this.via;
37074 }
37075 /** @inheritdoc */
37076
37077 }, {
37078 key: "getPoint",
37079 value: function getPoint(position) {
37080 var viaNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.via;
37081
37082 if (this.from === this.to) {
37083 var _this$_getCircleData = this._getCircleData(),
37084 _this$_getCircleData2 = _slicedToArray(_this$_getCircleData, 3),
37085 cx = _this$_getCircleData2[0],
37086 cy = _this$_getCircleData2[1],
37087 cr = _this$_getCircleData2[2];
37088
37089 var a = 2 * Math.PI * (1 - position);
37090 return {
37091 x: cx + cr * Math.sin(a),
37092 y: cy + cr - cr * (1 - Math.cos(a))
37093 };
37094 } else {
37095 return {
37096 x: Math.pow(1 - position, 2) * this.fromPoint.x + 2 * position * (1 - position) * viaNode.x + Math.pow(position, 2) * this.toPoint.x,
37097 y: Math.pow(1 - position, 2) * this.fromPoint.y + 2 * position * (1 - position) * viaNode.y + Math.pow(position, 2) * this.toPoint.y
37098 };
37099 }
37100 }
37101 /** @inheritdoc */
37102
37103 }, {
37104 key: "_findBorderPosition",
37105 value: function _findBorderPosition(nearNode, ctx) {
37106 return this._findBorderPositionBezier(nearNode, ctx, this.via);
37107 }
37108 /** @inheritdoc */
37109
37110 }, {
37111 key: "_getDistanceToEdge",
37112 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
37113 // x3,y3 is the point
37114 return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, this.via);
37115 }
37116 }]);
37117
37118 return BezierEdgeDynamic;
37119 }(BezierEdgeBase);
37120
37121 /**
37122 * A Static Bezier Edge. Bezier curves are used to model smooth gradual curves in paths between nodes.
37123 */
37124
37125 var BezierEdgeStatic =
37126 /*#__PURE__*/
37127 function (_BezierEdgeBase) {
37128 _inherits(BezierEdgeStatic, _BezierEdgeBase);
37129
37130 /**
37131 * Create a new instance.
37132 *
37133 * @param options - The options object of given edge.
37134 * @param body - The body of the network.
37135 * @param labelModule - Label module.
37136 */
37137 function BezierEdgeStatic(options, body, labelModule) {
37138 _classCallCheck(this, BezierEdgeStatic);
37139
37140 return _possibleConstructorReturn(this, _getPrototypeOf(BezierEdgeStatic).call(this, options, body, labelModule));
37141 }
37142 /** @inheritdoc */
37143
37144
37145 _createClass(BezierEdgeStatic, [{
37146 key: "_line",
37147 value: function _line(ctx, values, viaNode) {
37148 this._bezierCurve(ctx, values, viaNode);
37149 }
37150 /** @inheritdoc */
37151
37152 }, {
37153 key: "getViaNode",
37154 value: function getViaNode() {
37155 return this._getViaCoordinates();
37156 }
37157 /**
37158 * Compute the coordinates of the via node.
37159 *
37160 * @remarks
37161 * We do not use the to and fromPoints here to make the via nodes the same as edges without arrows.
37162 *
37163 * @returns Cartesian coordinates of the via node.
37164 */
37165
37166 }, {
37167 key: "_getViaCoordinates",
37168 value: function _getViaCoordinates() {
37169 // Assumption: x/y coordinates in from/to always defined
37170 var factor = this.options.smooth.roundness;
37171 var type = this.options.smooth.type;
37172 var dx = Math.abs(this.from.x - this.to.x);
37173 var dy = Math.abs(this.from.y - this.to.y);
37174
37175 if (type === "discrete" || type === "diagonalCross") {
37176 var stepX;
37177 var stepY;
37178
37179 if (dx <= dy) {
37180 stepX = stepY = factor * dy;
37181 } else {
37182 stepX = stepY = factor * dx;
37183 }
37184
37185 if (this.from.x > this.to.x) {
37186 stepX = -stepX;
37187 }
37188
37189 if (this.from.y >= this.to.y) {
37190 stepY = -stepY;
37191 }
37192
37193 var xVia = this.from.x + stepX;
37194 var yVia = this.from.y + stepY;
37195
37196 if (type === "discrete") {
37197 if (dx <= dy) {
37198 xVia = dx < factor * dy ? this.from.x : xVia;
37199 } else {
37200 yVia = dy < factor * dx ? this.from.y : yVia;
37201 }
37202 }
37203
37204 return {
37205 x: xVia,
37206 y: yVia
37207 };
37208 } else if (type === "straightCross") {
37209 var _stepX = (1 - factor) * dx;
37210
37211 var _stepY = (1 - factor) * dy;
37212
37213 if (dx <= dy) {
37214 // up - down
37215 _stepX = 0;
37216
37217 if (this.from.y < this.to.y) {
37218 _stepY = -_stepY;
37219 }
37220 } else {
37221 // left - right
37222 if (this.from.x < this.to.x) {
37223 _stepX = -_stepX;
37224 }
37225
37226 _stepY = 0;
37227 }
37228
37229 return {
37230 x: this.to.x + _stepX,
37231 y: this.to.y + _stepY
37232 };
37233 } else if (type === "horizontal") {
37234 var _stepX2 = (1 - factor) * dx;
37235
37236 if (this.from.x < this.to.x) {
37237 _stepX2 = -_stepX2;
37238 }
37239
37240 return {
37241 x: this.to.x + _stepX2,
37242 y: this.from.y
37243 };
37244 } else if (type === "vertical") {
37245 var _stepY2 = (1 - factor) * dy;
37246
37247 if (this.from.y < this.to.y) {
37248 _stepY2 = -_stepY2;
37249 }
37250
37251 return {
37252 x: this.from.x,
37253 y: this.to.y + _stepY2
37254 };
37255 } else if (type === "curvedCW") {
37256 dx = this.to.x - this.from.x;
37257 dy = this.from.y - this.to.y;
37258 var radius = Math.sqrt(dx * dx + dy * dy);
37259 var pi = Math.PI;
37260 var originalAngle = Math.atan2(dy, dx);
37261 var myAngle = (originalAngle + (factor * 0.5 + 0.5) * pi) % (2 * pi);
37262 return {
37263 x: this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle),
37264 y: this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle)
37265 };
37266 } else if (type === "curvedCCW") {
37267 dx = this.to.x - this.from.x;
37268 dy = this.from.y - this.to.y;
37269
37270 var _radius = Math.sqrt(dx * dx + dy * dy);
37271
37272 var _pi = Math.PI;
37273
37274 var _originalAngle = Math.atan2(dy, dx);
37275
37276 var _myAngle = (_originalAngle + (-factor * 0.5 + 0.5) * _pi) % (2 * _pi);
37277
37278 return {
37279 x: this.from.x + (factor * 0.5 + 0.5) * _radius * Math.sin(_myAngle),
37280 y: this.from.y + (factor * 0.5 + 0.5) * _radius * Math.cos(_myAngle)
37281 };
37282 } else {
37283 // continuous
37284 var _stepX3;
37285
37286 var _stepY3;
37287
37288 if (dx <= dy) {
37289 _stepX3 = _stepY3 = factor * dy;
37290 } else {
37291 _stepX3 = _stepY3 = factor * dx;
37292 }
37293
37294 if (this.from.x > this.to.x) {
37295 _stepX3 = -_stepX3;
37296 }
37297
37298 if (this.from.y >= this.to.y) {
37299 _stepY3 = -_stepY3;
37300 }
37301
37302 var _xVia = this.from.x + _stepX3;
37303
37304 var _yVia = this.from.y + _stepY3;
37305
37306 if (dx <= dy) {
37307 if (this.from.x <= this.to.x) {
37308 _xVia = this.to.x < _xVia ? this.to.x : _xVia;
37309 } else {
37310 _xVia = this.to.x > _xVia ? this.to.x : _xVia;
37311 }
37312 } else {
37313 if (this.from.y >= this.to.y) {
37314 _yVia = this.to.y > _yVia ? this.to.y : _yVia;
37315 } else {
37316 _yVia = this.to.y < _yVia ? this.to.y : _yVia;
37317 }
37318 }
37319
37320 return {
37321 x: _xVia,
37322 y: _yVia
37323 };
37324 }
37325 }
37326 /** @inheritdoc */
37327
37328 }, {
37329 key: "_findBorderPosition",
37330 value: function _findBorderPosition(nearNode, ctx) {
37331 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
37332 return this._findBorderPositionBezier(nearNode, ctx, options.via);
37333 }
37334 /** @inheritdoc */
37335
37336 }, {
37337 key: "_getDistanceToEdge",
37338 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
37339 var viaNode = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : this._getViaCoordinates();
37340 // x3,y3 is the point
37341 return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, viaNode);
37342 }
37343 /** @inheritdoc */
37344
37345 }, {
37346 key: "getPoint",
37347 value: function getPoint(position) {
37348 var viaNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._getViaCoordinates();
37349 var t = position;
37350 var x = Math.pow(1 - t, 2) * this.fromPoint.x + 2 * t * (1 - t) * viaNode.x + Math.pow(t, 2) * this.toPoint.x;
37351 var y = Math.pow(1 - t, 2) * this.fromPoint.y + 2 * t * (1 - t) * viaNode.y + Math.pow(t, 2) * this.toPoint.y;
37352 return {
37353 x: x,
37354 y: y
37355 };
37356 }
37357 }]);
37358
37359 return BezierEdgeStatic;
37360 }(BezierEdgeBase);
37361
37362 /**
37363 * A Base Class for all Cubic Bezier Edges. Bezier curves are used to model
37364 * smooth gradual curves in paths between nodes.
37365 *
37366 * @extends BezierEdgeBase
37367 */
37368
37369 var CubicBezierEdgeBase =
37370 /*#__PURE__*/
37371 function (_BezierEdgeBase) {
37372 _inherits(CubicBezierEdgeBase, _BezierEdgeBase);
37373
37374 /**
37375 * Create a new instance.
37376 *
37377 * @param options - The options object of given edge.
37378 * @param body - The body of the network.
37379 * @param labelModule - Label module.
37380 */
37381 function CubicBezierEdgeBase(options, body, labelModule) {
37382 _classCallCheck(this, CubicBezierEdgeBase);
37383
37384 return _possibleConstructorReturn(this, _getPrototypeOf(CubicBezierEdgeBase).call(this, options, body, labelModule));
37385 }
37386 /**
37387 * Calculate the distance between a point (x3,y3) and a line segment from (x1,y1) to (x2,y2).
37388 *
37389 * @remarks
37390 * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
37391 * https://en.wikipedia.org/wiki/B%C3%A9zier_curve
37392 *
37393 * @param x1 - First end of the line segment on the x axis.
37394 * @param y1 - First end of the line segment on the y axis.
37395 * @param x2 - Second end of the line segment on the x axis.
37396 * @param y2 - Second end of the line segment on the y axis.
37397 * @param x3 - Position of the point on the x axis.
37398 * @param y3 - Position of the point on the y axis.
37399 * @param via1 - The first point this edge passes through.
37400 * @param via2 - The second point this edge passes through.
37401 *
37402 * @returns The distance between the line segment and the point.
37403 */
37404
37405
37406 _createClass(CubicBezierEdgeBase, [{
37407 key: "_getDistanceToBezierEdge2",
37408 value: function _getDistanceToBezierEdge2(x1, y1, x2, y2, x3, y3, via1, via2) {
37409 // x3,y3 is the point
37410 var minDistance = 1e9;
37411 var lastX = x1;
37412 var lastY = y1;
37413 var vec = [0, 0, 0, 0];
37414
37415 for (var i = 1; i < 10; i++) {
37416 var t = 0.1 * i;
37417 vec[0] = Math.pow(1 - t, 3);
37418 vec[1] = 3 * t * Math.pow(1 - t, 2);
37419 vec[2] = 3 * Math.pow(t, 2) * (1 - t);
37420 vec[3] = Math.pow(t, 3);
37421 var x = vec[0] * x1 + vec[1] * via1.x + vec[2] * via2.x + vec[3] * x2;
37422 var y = vec[0] * y1 + vec[1] * via1.y + vec[2] * via2.y + vec[3] * y2;
37423
37424 if (i > 0) {
37425 var distance = this._getDistanceToLine(lastX, lastY, x, y, x3, y3);
37426
37427 minDistance = distance < minDistance ? distance : minDistance;
37428 }
37429
37430 lastX = x;
37431 lastY = y;
37432 }
37433
37434 return minDistance;
37435 }
37436 }]);
37437
37438 return CubicBezierEdgeBase;
37439 }(BezierEdgeBase);
37440
37441 /**
37442 * A Cubic Bezier Edge. Bezier curves are used to model smooth gradual curves in paths between nodes.
37443 */
37444
37445 var CubicBezierEdge =
37446 /*#__PURE__*/
37447 function (_CubicBezierEdgeBase) {
37448 _inherits(CubicBezierEdge, _CubicBezierEdgeBase);
37449
37450 /**
37451 * Create a new instance.
37452 *
37453 * @param options - The options object of given edge.
37454 * @param body - The body of the network.
37455 * @param labelModule - Label module.
37456 */
37457 function CubicBezierEdge(options, body, labelModule) {
37458 _classCallCheck(this, CubicBezierEdge);
37459
37460 return _possibleConstructorReturn(this, _getPrototypeOf(CubicBezierEdge).call(this, options, body, labelModule));
37461 }
37462 /** @inheritdoc */
37463
37464
37465 _createClass(CubicBezierEdge, [{
37466 key: "_line",
37467 value: function _line(ctx, values, viaNodes) {
37468 // get the coordinates of the support points.
37469 var via1 = viaNodes[0];
37470 var via2 = viaNodes[1];
37471
37472 this._bezierCurve(ctx, values, via1, via2);
37473 }
37474 /**
37475 * Compute the additional points the edge passes through.
37476 *
37477 * @returns Cartesian coordinates of the points the edge passes through.
37478 */
37479
37480 }, {
37481 key: "_getViaCoordinates",
37482 value: function _getViaCoordinates() {
37483 var dx = this.from.x - this.to.x;
37484 var dy = this.from.y - this.to.y;
37485 var x1;
37486 var y1;
37487 var x2;
37488 var y2;
37489 var roundness = this.options.smooth.roundness; // horizontal if x > y or if direction is forced or if direction is horizontal
37490
37491 if ((Math.abs(dx) > Math.abs(dy) || this.options.smooth.forceDirection === true || this.options.smooth.forceDirection === "horizontal") && this.options.smooth.forceDirection !== "vertical") {
37492 y1 = this.from.y;
37493 y2 = this.to.y;
37494 x1 = this.from.x - roundness * dx;
37495 x2 = this.to.x + roundness * dx;
37496 } else {
37497 y1 = this.from.y - roundness * dy;
37498 y2 = this.to.y + roundness * dy;
37499 x1 = this.from.x;
37500 x2 = this.to.x;
37501 }
37502
37503 return [{
37504 x: x1,
37505 y: y1
37506 }, {
37507 x: x2,
37508 y: y2
37509 }];
37510 }
37511 /** @inheritdoc */
37512
37513 }, {
37514 key: "getViaNode",
37515 value: function getViaNode() {
37516 return this._getViaCoordinates();
37517 }
37518 /** @inheritdoc */
37519
37520 }, {
37521 key: "_findBorderPosition",
37522 value: function _findBorderPosition(nearNode, ctx) {
37523 return this._findBorderPositionBezier(nearNode, ctx);
37524 }
37525 /** @inheritdoc */
37526
37527 }, {
37528 key: "_getDistanceToEdge",
37529 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
37530 var _ref = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : this._getViaCoordinates(),
37531 _ref2 = _slicedToArray(_ref, 2),
37532 via1 = _ref2[0],
37533 via2 = _ref2[1];
37534
37535 // x3,y3 is the point
37536 return this._getDistanceToBezierEdge2(x1, y1, x2, y2, x3, y3, via1, via2);
37537 }
37538 /** @inheritdoc */
37539
37540 }, {
37541 key: "getPoint",
37542 value: function getPoint(position) {
37543 var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._getViaCoordinates(),
37544 _ref4 = _slicedToArray(_ref3, 2),
37545 via1 = _ref4[0],
37546 via2 = _ref4[1];
37547
37548 var t = position;
37549 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)];
37550 var x = vec[0] * this.fromPoint.x + vec[1] * via1.x + vec[2] * via2.x + vec[3] * this.toPoint.x;
37551 var y = vec[0] * this.fromPoint.y + vec[1] * via1.y + vec[2] * via2.y + vec[3] * this.toPoint.y;
37552 return {
37553 x: x,
37554 y: y
37555 };
37556 }
37557 }]);
37558
37559 return CubicBezierEdge;
37560 }(CubicBezierEdgeBase);
37561
37562 /**
37563 * A Straight Edge.
37564 */
37565
37566 var StraightEdge =
37567 /*#__PURE__*/
37568 function (_EdgeBase) {
37569 _inherits(StraightEdge, _EdgeBase);
37570
37571 /**
37572 * Create a new instance.
37573 *
37574 * @param options - The options object of given edge.
37575 * @param body - The body of the network.
37576 * @param labelModule - Label module.
37577 */
37578 function StraightEdge(options, body, labelModule) {
37579 _classCallCheck(this, StraightEdge);
37580
37581 return _possibleConstructorReturn(this, _getPrototypeOf(StraightEdge).call(this, options, body, labelModule));
37582 }
37583 /** @inheritdoc */
37584
37585
37586 _createClass(StraightEdge, [{
37587 key: "_line",
37588 value: function _line(ctx, values) {
37589 // draw a straight line
37590 ctx.beginPath();
37591 ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
37592 ctx.lineTo(this.toPoint.x, this.toPoint.y); // draw shadow if enabled
37593
37594 this.enableShadow(ctx, values);
37595 ctx.stroke();
37596 this.disableShadow(ctx, values);
37597 }
37598 /** @inheritdoc */
37599
37600 }, {
37601 key: "getViaNode",
37602 value: function getViaNode() {
37603 return undefined;
37604 }
37605 /** @inheritdoc */
37606
37607 }, {
37608 key: "getPoint",
37609 value: function getPoint(position) {
37610 return {
37611 x: (1 - position) * this.fromPoint.x + position * this.toPoint.x,
37612 y: (1 - position) * this.fromPoint.y + position * this.toPoint.y
37613 };
37614 }
37615 /** @inheritdoc */
37616
37617 }, {
37618 key: "_findBorderPosition",
37619 value: function _findBorderPosition(nearNode, ctx) {
37620 var node1 = this.to;
37621 var node2 = this.from;
37622
37623 if (nearNode.id === this.from.id) {
37624 node1 = this.from;
37625 node2 = this.to;
37626 }
37627
37628 var angle = Math.atan2(node1.y - node2.y, node1.x - node2.x);
37629 var dx = node1.x - node2.x;
37630 var dy = node1.y - node2.y;
37631 var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
37632 var toBorderDist = nearNode.distanceToBorder(ctx, angle);
37633 var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
37634 return {
37635 x: (1 - toBorderPoint) * node2.x + toBorderPoint * node1.x,
37636 y: (1 - toBorderPoint) * node2.y + toBorderPoint * node1.y,
37637 t: 0
37638 };
37639 }
37640 /** @inheritdoc */
37641
37642 }, {
37643 key: "_getDistanceToEdge",
37644 value: function _getDistanceToEdge(x1, y1, x2, y2, x3, y3) {
37645 // x3,y3 is the point
37646 return this._getDistanceToLine(x1, y1, x2, y2, x3, y3);
37647 }
37648 }]);
37649
37650 return StraightEdge;
37651 }(EdgeBase);
37652
37653 /**
37654 * An edge connects two nodes and has a specific direction.
37655 */
37656
37657 var Edge =
37658 /*#__PURE__*/
37659 function () {
37660 /**
37661 * @param {Object} options values specific to this edge, must contain at least 'from' and 'to'
37662 * @param {Object} body shared state from Network instance
37663 * @param {Network.Images} imagelist A list with images. Only needed when the edge has image arrows.
37664 * @param {Object} globalOptions options from the EdgesHandler instance
37665 * @param {Object} defaultOptions default options from the EdgeHandler instance. Value and reference are constant
37666 */
37667 function Edge(options, body, imagelist, globalOptions, defaultOptions) {
37668 _classCallCheck(this, Edge);
37669
37670 if (body === undefined) {
37671 throw new Error("No body provided");
37672 } // Since globalOptions is constant in values as well as reference,
37673 // Following needs to be done only once.
37674
37675
37676 this.options = bridgeObject(globalOptions);
37677 this.globalOptions = globalOptions;
37678 this.defaultOptions = defaultOptions;
37679 this.body = body;
37680 this.imagelist = imagelist; // initialize variables
37681
37682 this.id = undefined;
37683 this.fromId = undefined;
37684 this.toId = undefined;
37685 this.selected = false;
37686 this.hover = false;
37687 this.labelDirty = true;
37688 this.baseWidth = this.options.width;
37689 this.baseFontSize = this.options.font.size;
37690 this.from = undefined; // a node
37691
37692 this.to = undefined; // a node
37693
37694 this.edgeType = undefined;
37695 this.connected = false;
37696 this.labelModule = new Label(this.body, this.options, true
37697 /* It's an edge label */
37698 );
37699 this.setOptions(options);
37700 }
37701 /**
37702 * Set or overwrite options for the edge
37703 * @param {Object} options an object with options
37704 * @returns {undefined|boolean} undefined if no options, true if layout affecting data changed, false otherwise.
37705 */
37706
37707
37708 _createClass(Edge, [{
37709 key: "setOptions",
37710 value: function setOptions(options) {
37711 if (!options) {
37712 return;
37713 } // Following options if changed affect the layout.
37714
37715
37716 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;
37717 Edge.parseOptions(this.options, options, true, this.globalOptions);
37718
37719 if (options.id !== undefined) {
37720 this.id = options.id;
37721 }
37722
37723 if (options.from !== undefined) {
37724 this.fromId = options.from;
37725 }
37726
37727 if (options.to !== undefined) {
37728 this.toId = options.to;
37729 }
37730
37731 if (options.title !== undefined) {
37732 this.title = options.title;
37733 }
37734
37735 if (options.value !== undefined) {
37736 options.value = parseFloat(options.value);
37737 }
37738
37739 var pile = [options, this.options, this.defaultOptions];
37740 this.chooser = ComponentUtil.choosify('edge', pile); // update label Module
37741
37742 this.updateLabelModule(options); // Update edge type, this if changed affects the layout.
37743
37744 affectsLayout = this.updateEdgeType() || affectsLayout; // if anything has been updates, reset the selection width and the hover width
37745
37746 this._setInteractionWidths(); // A node is connected when it has a from and to node that both exist in the network.body.nodes.
37747
37748
37749 this.connect();
37750 return affectsLayout;
37751 }
37752 /**
37753 *
37754 * @param {Object} parentOptions
37755 * @param {Object} newOptions
37756 * @param {boolean} [allowDeletion=false]
37757 * @param {Object} [globalOptions={}]
37758 * @param {boolean} [copyFromGlobals=false]
37759 */
37760
37761 }, {
37762 key: "getFormattingValues",
37763
37764 /**
37765 *
37766 * @returns {ArrowOptions}
37767 */
37768 value: function getFormattingValues() {
37769 var toArrow = this.options.arrows.to === true || this.options.arrows.to.enabled === true;
37770 var fromArrow = this.options.arrows.from === true || this.options.arrows.from.enabled === true;
37771 var middleArrow = this.options.arrows.middle === true || this.options.arrows.middle.enabled === true;
37772 var inheritsColor = this.options.color.inherit;
37773 var values = {
37774 toArrow: toArrow,
37775 toArrowScale: this.options.arrows.to.scaleFactor,
37776 toArrowType: this.options.arrows.to.type,
37777 toArrowSrc: this.options.arrows.to.src,
37778 toArrowImageWidth: this.options.arrows.to.imageWidth,
37779 toArrowImageHeight: this.options.arrows.to.imageHeight,
37780 middleArrow: middleArrow,
37781 middleArrowScale: this.options.arrows.middle.scaleFactor,
37782 middleArrowType: this.options.arrows.middle.type,
37783 middleArrowSrc: this.options.arrows.middle.src,
37784 middleArrowImageWidth: this.options.arrows.middle.imageWidth,
37785 middleArrowImageHeight: this.options.arrows.middle.imageHeight,
37786 fromArrow: fromArrow,
37787 fromArrowScale: this.options.arrows.from.scaleFactor,
37788 fromArrowType: this.options.arrows.from.type,
37789 fromArrowSrc: this.options.arrows.from.src,
37790 fromArrowImageWidth: this.options.arrows.from.imageWidth,
37791 fromArrowImageHeight: this.options.arrows.from.imageHeight,
37792 arrowStrikethrough: this.options.arrowStrikethrough,
37793 color: inheritsColor ? undefined : this.options.color.color,
37794 inheritsColor: inheritsColor,
37795 opacity: this.options.color.opacity,
37796 hidden: this.options.hidden,
37797 length: this.options.length,
37798 shadow: this.options.shadow.enabled,
37799 shadowColor: this.options.shadow.color,
37800 shadowSize: this.options.shadow.size,
37801 shadowX: this.options.shadow.x,
37802 shadowY: this.options.shadow.y,
37803 dashes: this.options.dashes,
37804 width: this.options.width,
37805 background: this.options.background.enabled,
37806 backgroundColor: this.options.background.color,
37807 backgroundSize: this.options.background.size,
37808 backgroundDashes: this.options.background.dashes
37809 };
37810
37811 if (this.selected || this.hover) {
37812 if (this.chooser === true) {
37813 if (this.selected) {
37814 var selectedWidth = this.options.selectionWidth;
37815
37816 if (typeof selectedWidth === 'function') {
37817 values.width = selectedWidth(values.width);
37818 } else if (typeof selectedWidth === 'number') {
37819 values.width += selectedWidth;
37820 }
37821
37822 values.width = Math.max(values.width, 0.3 / this.body.view.scale);
37823 values.color = this.options.color.highlight;
37824 values.shadow = this.options.shadow.enabled;
37825 } else if (this.hover) {
37826 var hoverWidth = this.options.hoverWidth;
37827
37828 if (typeof hoverWidth === 'function') {
37829 values.width = hoverWidth(values.width);
37830 } else if (typeof hoverWidth === 'number') {
37831 values.width += hoverWidth;
37832 }
37833
37834 values.width = Math.max(values.width, 0.3 / this.body.view.scale);
37835 values.color = this.options.color.hover;
37836 values.shadow = this.options.shadow.enabled;
37837 }
37838 } else if (typeof this.chooser === 'function') {
37839 this.chooser(values, this.options.id, this.selected, this.hover);
37840
37841 if (values.color !== undefined) {
37842 values.inheritsColor = false;
37843 }
37844
37845 if (values.shadow === false) {
37846 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) {
37847 values.shadow = true;
37848 }
37849 }
37850 }
37851 } else {
37852 values.shadow = this.options.shadow.enabled;
37853 values.width = Math.max(values.width, 0.3 / this.body.view.scale);
37854 }
37855
37856 return values;
37857 }
37858 /**
37859 * update the options in the label module
37860 *
37861 * @param {Object} options
37862 */
37863
37864 }, {
37865 key: "updateLabelModule",
37866 value: function updateLabelModule(options) {
37867 var pile = [options, this.options, this.globalOptions, // Currently set global edge options
37868 this.defaultOptions];
37869 this.labelModule.update(this.options, pile);
37870
37871 if (this.labelModule.baseSize !== undefined) {
37872 this.baseFontSize = this.labelModule.baseSize;
37873 }
37874 }
37875 /**
37876 * update the edge type, set the options
37877 * @returns {boolean}
37878 */
37879
37880 }, {
37881 key: "updateEdgeType",
37882 value: function updateEdgeType() {
37883 var smooth = this.options.smooth;
37884 var dataChanged = false;
37885 var changeInType = true;
37886
37887 if (this.edgeType !== undefined) {
37888 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) {
37889 changeInType = false;
37890 }
37891
37892 if (changeInType === true) {
37893 dataChanged = this.cleanup();
37894 }
37895 }
37896
37897 if (changeInType === true) {
37898 if (smooth.enabled === true) {
37899 if (smooth.type === 'dynamic') {
37900 dataChanged = true;
37901 this.edgeType = new BezierEdgeDynamic(this.options, this.body, this.labelModule);
37902 } else if (smooth.type === 'cubicBezier') {
37903 this.edgeType = new CubicBezierEdge(this.options, this.body, this.labelModule);
37904 } else {
37905 this.edgeType = new BezierEdgeStatic(this.options, this.body, this.labelModule);
37906 }
37907 } else {
37908 this.edgeType = new StraightEdge(this.options, this.body, this.labelModule);
37909 }
37910 } else {
37911 // if nothing changes, we just set the options.
37912 this.edgeType.setOptions(this.options);
37913 }
37914
37915 return dataChanged;
37916 }
37917 /**
37918 * Connect an edge to its nodes
37919 */
37920
37921 }, {
37922 key: "connect",
37923 value: function connect() {
37924 this.disconnect();
37925 this.from = this.body.nodes[this.fromId] || undefined;
37926 this.to = this.body.nodes[this.toId] || undefined;
37927 this.connected = this.from !== undefined && this.to !== undefined;
37928
37929 if (this.connected === true) {
37930 this.from.attachEdge(this);
37931 this.to.attachEdge(this);
37932 } else {
37933 if (this.from) {
37934 this.from.detachEdge(this);
37935 }
37936
37937 if (this.to) {
37938 this.to.detachEdge(this);
37939 }
37940 }
37941
37942 this.edgeType.connect();
37943 }
37944 /**
37945 * Disconnect an edge from its nodes
37946 */
37947
37948 }, {
37949 key: "disconnect",
37950 value: function disconnect() {
37951 if (this.from) {
37952 this.from.detachEdge(this);
37953 this.from = undefined;
37954 }
37955
37956 if (this.to) {
37957 this.to.detachEdge(this);
37958 this.to = undefined;
37959 }
37960
37961 this.connected = false;
37962 }
37963 /**
37964 * get the title of this edge.
37965 * @return {string} title The title of the edge, or undefined when no title
37966 * has been set.
37967 */
37968
37969 }, {
37970 key: "getTitle",
37971 value: function getTitle() {
37972 return this.title;
37973 }
37974 /**
37975 * check if this node is selecte
37976 * @return {boolean} selected True if node is selected, else false
37977 */
37978
37979 }, {
37980 key: "isSelected",
37981 value: function isSelected() {
37982 return this.selected;
37983 }
37984 /**
37985 * Retrieve the value of the edge. Can be undefined
37986 * @return {number} value
37987 */
37988
37989 }, {
37990 key: "getValue",
37991 value: function getValue() {
37992 return this.options.value;
37993 }
37994 /**
37995 * Adjust the value range of the edge. The edge will adjust it's width
37996 * based on its value.
37997 * @param {number} min
37998 * @param {number} max
37999 * @param {number} total
38000 */
38001
38002 }, {
38003 key: "setValueRange",
38004 value: function setValueRange(min, max, total) {
38005 if (this.options.value !== undefined) {
38006 var scale = this.options.scaling.customScalingFunction(min, max, total, this.options.value);
38007 var widthDiff = this.options.scaling.max - this.options.scaling.min;
38008
38009 if (this.options.scaling.label.enabled === true) {
38010 var fontDiff = this.options.scaling.label.max - this.options.scaling.label.min;
38011 this.options.font.size = this.options.scaling.label.min + scale * fontDiff;
38012 }
38013
38014 this.options.width = this.options.scaling.min + scale * widthDiff;
38015 } else {
38016 this.options.width = this.baseWidth;
38017 this.options.font.size = this.baseFontSize;
38018 }
38019
38020 this._setInteractionWidths();
38021
38022 this.updateLabelModule();
38023 }
38024 /**
38025 *
38026 * @private
38027 */
38028
38029 }, {
38030 key: "_setInteractionWidths",
38031 value: function _setInteractionWidths() {
38032 if (typeof this.options.hoverWidth === 'function') {
38033 this.edgeType.hoverWidth = this.options.hoverWidth(this.options.width);
38034 } else {
38035 this.edgeType.hoverWidth = this.options.hoverWidth + this.options.width;
38036 }
38037
38038 if (typeof this.options.selectionWidth === 'function') {
38039 this.edgeType.selectionWidth = this.options.selectionWidth(this.options.width);
38040 } else {
38041 this.edgeType.selectionWidth = this.options.selectionWidth + this.options.width;
38042 }
38043 }
38044 /**
38045 * Redraw a edge
38046 * Draw this edge in the given canvas
38047 * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
38048 * @param {CanvasRenderingContext2D} ctx
38049 */
38050
38051 }, {
38052 key: "draw",
38053 value: function draw(ctx) {
38054 var values = this.getFormattingValues();
38055
38056 if (values.hidden) {
38057 return;
38058 } // get the via node from the edge type
38059
38060
38061 var viaNode = this.edgeType.getViaNode();
38062 var arrowData = {}; // restore edge targets to defaults
38063
38064 this.edgeType.fromPoint = this.edgeType.from;
38065 this.edgeType.toPoint = this.edgeType.to; // from and to arrows give a different end point for edges. we set them here
38066
38067 if (values.fromArrow) {
38068 arrowData.from = this.edgeType.getArrowData(ctx, "from", viaNode, this.selected, this.hover, values);
38069 if (values.arrowStrikethrough === false) this.edgeType.fromPoint = arrowData.from.core;
38070
38071 if (values.fromArrowSrc) {
38072 arrowData.from.image = this.imagelist.load(values.fromArrowSrc);
38073 }
38074
38075 if (values.fromArrowImageWidth) {
38076 arrowData.from.imageWidth = values.fromArrowImageWidth;
38077 }
38078
38079 if (values.fromArrowImageHeight) {
38080 arrowData.from.imageHeight = values.fromArrowImageHeight;
38081 }
38082 }
38083
38084 if (values.toArrow) {
38085 arrowData.to = this.edgeType.getArrowData(ctx, "to", viaNode, this.selected, this.hover, values);
38086 if (values.arrowStrikethrough === false) this.edgeType.toPoint = arrowData.to.core;
38087
38088 if (values.toArrowSrc) {
38089 arrowData.to.image = this.imagelist.load(values.toArrowSrc);
38090 }
38091
38092 if (values.toArrowImageWidth) {
38093 arrowData.to.imageWidth = values.toArrowImageWidth;
38094 }
38095
38096 if (values.toArrowImageHeight) {
38097 arrowData.to.imageHeight = values.toArrowImageHeight;
38098 }
38099 } // the middle arrow depends on the line, which can depend on the to and from arrows so we do this one lastly.
38100
38101
38102 if (values.middleArrow) {
38103 arrowData.middle = this.edgeType.getArrowData(ctx, "middle", viaNode, this.selected, this.hover, values);
38104
38105 if (values.middleArrowSrc) {
38106 arrowData.middle.image = this.imagelist.load(values.middleArrowSrc);
38107 }
38108
38109 if (values.middleArrowImageWidth) {
38110 arrowData.middle.imageWidth = values.middleArrowImageWidth;
38111 }
38112
38113 if (values.middleArrowImageHeight) {
38114 arrowData.middle.imageHeight = values.middleArrowImageHeight;
38115 }
38116 } // draw everything
38117
38118
38119 this.edgeType.drawLine(ctx, values, this.selected, this.hover, viaNode);
38120 this.drawArrows(ctx, arrowData, values);
38121 this.drawLabel(ctx, viaNode);
38122 }
38123 /**
38124 *
38125 * @param {CanvasRenderingContext2D} ctx
38126 * @param {Object} arrowData
38127 * @param {ArrowOptions} values
38128 */
38129
38130 }, {
38131 key: "drawArrows",
38132 value: function drawArrows(ctx, arrowData, values) {
38133 if (values.fromArrow) {
38134 this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.from);
38135 }
38136
38137 if (values.middleArrow) {
38138 this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.middle);
38139 }
38140
38141 if (values.toArrow) {
38142 this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.to);
38143 }
38144 }
38145 /**
38146 *
38147 * @param {CanvasRenderingContext2D} ctx
38148 * @param {Node} viaNode
38149 */
38150
38151 }, {
38152 key: "drawLabel",
38153 value: function drawLabel(ctx, viaNode) {
38154 if (this.options.label !== undefined) {
38155 // set style
38156 var node1 = this.from;
38157 var node2 = this.to;
38158
38159 if (this.labelModule.differentState(this.selected, this.hover)) {
38160 this.labelModule.getTextSize(ctx, this.selected, this.hover);
38161 }
38162
38163 if (node1.id != node2.id) {
38164 this.labelModule.pointToSelf = false;
38165 var point = this.edgeType.getPoint(0.5, viaNode);
38166 ctx.save();
38167
38168 var rotationPoint = this._getRotation(ctx);
38169
38170 if (rotationPoint.angle != 0) {
38171 ctx.translate(rotationPoint.x, rotationPoint.y);
38172 ctx.rotate(rotationPoint.angle);
38173 } // draw the label
38174
38175
38176 this.labelModule.draw(ctx, point.x, point.y, this.selected, this.hover);
38177 /*
38178 // Useful debug code: draw a border around the label
38179 // This should **not** be enabled in production!
38180 var size = this.labelModule.getSize();; // ;; intentional so lint catches it
38181 ctx.strokeStyle = "#ff0000";
38182 ctx.strokeRect(size.left, size.top, size.width, size.height);
38183 // End debug code
38184 */
38185
38186 ctx.restore();
38187 } else {
38188 // Ignore the orientations.
38189 this.labelModule.pointToSelf = true;
38190 var x, y;
38191 var radius = this.options.selfReferenceSize;
38192
38193 if (node1.shape.width > node1.shape.height) {
38194 x = node1.x + node1.shape.width * 0.5;
38195 y = node1.y - radius;
38196 } else {
38197 x = node1.x + radius;
38198 y = node1.y - node1.shape.height * 0.5;
38199 }
38200
38201 point = this._pointOnCircle(x, y, radius, 0.125);
38202 this.labelModule.draw(ctx, point.x, point.y, this.selected, this.hover);
38203 }
38204 }
38205 }
38206 /**
38207 * Determine all visual elements of this edge instance, in which the given
38208 * point falls within the bounding shape.
38209 *
38210 * @param {point} point
38211 * @returns {Array.<edgeClickItem|edgeLabelClickItem>} list with the items which are on the point
38212 */
38213
38214 }, {
38215 key: "getItemsOnPoint",
38216 value: function getItemsOnPoint(point) {
38217 var ret = [];
38218
38219 if (this.labelModule.visible()) {
38220 var rotationPoint = this._getRotation();
38221
38222 if (ComponentUtil.pointInRect(this.labelModule.getSize(), point, rotationPoint)) {
38223 ret.push({
38224 edgeId: this.id,
38225 labelId: 0
38226 });
38227 }
38228 }
38229
38230 var obj = {
38231 left: point.x,
38232 top: point.y
38233 };
38234
38235 if (this.isOverlappingWith(obj)) {
38236 ret.push({
38237 edgeId: this.id
38238 });
38239 }
38240
38241 return ret;
38242 }
38243 /**
38244 * Check if this object is overlapping with the provided object
38245 * @param {Object} obj an object with parameters left, top
38246 * @return {boolean} True if location is located on the edge
38247 */
38248
38249 }, {
38250 key: "isOverlappingWith",
38251 value: function isOverlappingWith(obj) {
38252 if (this.connected) {
38253 var distMax = 10;
38254 var xFrom = this.from.x;
38255 var yFrom = this.from.y;
38256 var xTo = this.to.x;
38257 var yTo = this.to.y;
38258 var xObj = obj.left;
38259 var yObj = obj.top;
38260 var dist = this.edgeType.getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
38261 return dist < distMax;
38262 } else {
38263 return false;
38264 }
38265 }
38266 /**
38267 * Determine the rotation point, if any.
38268 *
38269 * @param {CanvasRenderingContext2D} [ctx] if passed, do a recalculation of the label size
38270 * @returns {rotationPoint} the point to rotate around and the angle in radians to rotate
38271 * @private
38272 */
38273
38274 }, {
38275 key: "_getRotation",
38276 value: function _getRotation(ctx) {
38277 var viaNode = this.edgeType.getViaNode();
38278 var point = this.edgeType.getPoint(0.5, viaNode);
38279
38280 if (ctx !== undefined) {
38281 this.labelModule.calculateLabelSize(ctx, this.selected, this.hover, point.x, point.y);
38282 }
38283
38284 var ret = {
38285 x: point.x,
38286 y: this.labelModule.size.yLine,
38287 angle: 0
38288 };
38289
38290 if (!this.labelModule.visible()) {
38291 return ret; // Don't even bother doing the atan2, there's nothing to draw
38292 }
38293
38294 if (this.options.font.align === "horizontal") {
38295 return ret; // No need to calculate angle
38296 }
38297
38298 var dy = this.from.y - this.to.y;
38299 var dx = this.from.x - this.to.x;
38300 var angle = Math.atan2(dy, dx); // radians
38301 // rotate so that label is readable
38302
38303 if (angle < -1 && dx < 0 || angle > 0 && dx < 0) {
38304 angle += Math.PI;
38305 }
38306
38307 ret.angle = angle;
38308 return ret;
38309 }
38310 /**
38311 * Get a point on a circle
38312 * @param {number} x
38313 * @param {number} y
38314 * @param {number} radius
38315 * @param {number} percentage Value between 0 (line start) and 1 (line end)
38316 * @return {Object} point
38317 * @private
38318 */
38319
38320 }, {
38321 key: "_pointOnCircle",
38322 value: function _pointOnCircle(x, y, radius, percentage) {
38323 var angle = percentage * 2 * Math.PI;
38324 return {
38325 x: x + radius * Math.cos(angle),
38326 y: y - radius * Math.sin(angle)
38327 };
38328 }
38329 /**
38330 * Sets selected state to true
38331 */
38332
38333 }, {
38334 key: "select",
38335 value: function select() {
38336 this.selected = true;
38337 }
38338 /**
38339 * Sets selected state to false
38340 */
38341
38342 }, {
38343 key: "unselect",
38344 value: function unselect() {
38345 this.selected = false;
38346 }
38347 /**
38348 * cleans all required things on delete
38349 * @returns {*}
38350 */
38351
38352 }, {
38353 key: "cleanup",
38354 value: function cleanup() {
38355 return this.edgeType.cleanup();
38356 }
38357 /**
38358 * Remove edge from the list and perform necessary cleanup.
38359 */
38360
38361 }, {
38362 key: "remove",
38363 value: function remove() {
38364 this.cleanup();
38365 this.disconnect();
38366 delete this.body.edges[this.id];
38367 }
38368 /**
38369 * Check if both connecting nodes exist
38370 * @returns {boolean}
38371 */
38372
38373 }, {
38374 key: "endPointsValid",
38375 value: function endPointsValid() {
38376 return this.body.nodes[this.fromId] !== undefined && this.body.nodes[this.toId] !== undefined;
38377 }
38378 }], [{
38379 key: "parseOptions",
38380 value: function parseOptions(parentOptions, newOptions) {
38381 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
38382 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
38383 var copyFromGlobals = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
38384 var fields = ['arrowStrikethrough', 'id', 'from', 'hidden', 'hoverWidth', 'labelHighlightBold', 'length', 'line', 'opacity', 'physics', 'scaling', 'selectionWidth', 'selfReferenceSize', 'to', 'title', 'value', 'width', 'font', 'chosen', 'widthConstraint']; // only deep extend the items in the field array. These do not have shorthand.
38385
38386 selectiveDeepExtend(fields, parentOptions, newOptions, allowDeletion); // Only copy label if it's a legal value.
38387
38388 if (ComponentUtil.isValidLabel(newOptions.label)) {
38389 parentOptions.label = newOptions.label;
38390 } else if (!ComponentUtil.isValidLabel(parentOptions.label)) {
38391 parentOptions.label = undefined;
38392 }
38393
38394 mergeOptions(parentOptions, newOptions, 'smooth', globalOptions);
38395 mergeOptions(parentOptions, newOptions, 'shadow', globalOptions);
38396 mergeOptions(parentOptions, newOptions, 'background', globalOptions);
38397
38398 if (newOptions.dashes !== undefined && newOptions.dashes !== null) {
38399 parentOptions.dashes = newOptions.dashes;
38400 } else if (allowDeletion === true && newOptions.dashes === null) {
38401 parentOptions.dashes = Object.create(globalOptions.dashes); // this sets the pointer of the option back to the global option.
38402 } // set the scaling newOptions
38403
38404
38405 if (newOptions.scaling !== undefined && newOptions.scaling !== null) {
38406 if (newOptions.scaling.min !== undefined) {
38407 parentOptions.scaling.min = newOptions.scaling.min;
38408 }
38409
38410 if (newOptions.scaling.max !== undefined) {
38411 parentOptions.scaling.max = newOptions.scaling.max;
38412 }
38413
38414 mergeOptions(parentOptions.scaling, newOptions.scaling, 'label', globalOptions.scaling);
38415 } else if (allowDeletion === true && newOptions.scaling === null) {
38416 parentOptions.scaling = Object.create(globalOptions.scaling); // this sets the pointer of the option back to the global option.
38417 } // handle multiple input cases for arrows
38418
38419
38420 if (newOptions.arrows !== undefined && newOptions.arrows !== null) {
38421 if (typeof newOptions.arrows === 'string') {
38422 var arrows = newOptions.arrows.toLowerCase();
38423 parentOptions.arrows.to.enabled = arrows.indexOf("to") != -1;
38424 parentOptions.arrows.middle.enabled = arrows.indexOf("middle") != -1;
38425 parentOptions.arrows.from.enabled = arrows.indexOf("from") != -1;
38426 } else if (_typeof(newOptions.arrows) === 'object') {
38427 mergeOptions(parentOptions.arrows, newOptions.arrows, 'to', globalOptions.arrows);
38428 mergeOptions(parentOptions.arrows, newOptions.arrows, 'middle', globalOptions.arrows);
38429 mergeOptions(parentOptions.arrows, newOptions.arrows, 'from', globalOptions.arrows);
38430 } else {
38431 throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:" + JSON.stringify(newOptions.arrows));
38432 }
38433 } else if (allowDeletion === true && newOptions.arrows === null) {
38434 parentOptions.arrows = Object.create(globalOptions.arrows); // this sets the pointer of the option back to the global option.
38435 } // handle multiple input cases for color
38436
38437
38438 if (newOptions.color !== undefined && newOptions.color !== null) {
38439 var fromColor = isString(newOptions.color) ? {
38440 color: newOptions.color,
38441 highlight: newOptions.color,
38442 hover: newOptions.color,
38443 inherit: false,
38444 opacity: 1
38445 } : newOptions.color;
38446 var toColor = parentOptions.color; // If passed, fill in values from default options - required in the case of no prototype bridging
38447
38448 if (copyFromGlobals) {
38449 deepExtend(toColor, globalOptions.color, false, allowDeletion);
38450 } else {
38451 // Clear local properties - need to do it like this in order to retain prototype bridges
38452 for (var i in toColor) {
38453 if (toColor.hasOwnProperty(i)) {
38454 delete toColor[i];
38455 }
38456 }
38457 }
38458
38459 if (isString(toColor)) {
38460 toColor.color = toColor;
38461 toColor.highlight = toColor;
38462 toColor.hover = toColor;
38463 toColor.inherit = false;
38464
38465 if (fromColor.opacity === undefined) {
38466 toColor.opacity = 1.0; // set default
38467 }
38468 } else {
38469 var colorsDefined = false;
38470
38471 if (fromColor.color !== undefined) {
38472 toColor.color = fromColor.color;
38473 colorsDefined = true;
38474 }
38475
38476 if (fromColor.highlight !== undefined) {
38477 toColor.highlight = fromColor.highlight;
38478 colorsDefined = true;
38479 }
38480
38481 if (fromColor.hover !== undefined) {
38482 toColor.hover = fromColor.hover;
38483 colorsDefined = true;
38484 }
38485
38486 if (fromColor.inherit !== undefined) {
38487 toColor.inherit = fromColor.inherit;
38488 }
38489
38490 if (fromColor.opacity !== undefined) {
38491 toColor.opacity = Math.min(1, Math.max(0, fromColor.opacity));
38492 }
38493
38494 if (colorsDefined === true) {
38495 toColor.inherit = false;
38496 } else {
38497 if (toColor.inherit === undefined) {
38498 toColor.inherit = 'from'; // Set default
38499 }
38500 }
38501 }
38502 } else if (allowDeletion === true && newOptions.color === null) {
38503 parentOptions.color = bridgeObject(globalOptions.color); // set the object back to the global options
38504 }
38505
38506 if (allowDeletion === true && newOptions.font === null) {
38507 parentOptions.font = bridgeObject(globalOptions.font); // set the object back to the global options
38508 }
38509 }
38510 }]);
38511
38512 return Edge;
38513 }();
38514
38515 /**
38516 * Handler for Edges
38517 */
38518
38519 var EdgesHandler =
38520 /*#__PURE__*/
38521 function () {
38522 /**
38523 * @param {Object} body
38524 * @param {Array.<Image>} images
38525 * @param {Array.<Group>} groups
38526 */
38527 function EdgesHandler(body, images, groups) {
38528 var _this = this;
38529
38530 _classCallCheck(this, EdgesHandler);
38531
38532 this.body = body;
38533 this.images = images;
38534 this.groups = groups; // create the edge API in the body container
38535
38536 this.body.functions.createEdge = this.create.bind(this);
38537 this.edgesListeners = {
38538 add: function add(event, params) {
38539 _this.add(params.items);
38540 },
38541 update: function update(event, params) {
38542 _this.update(params.items);
38543 },
38544 remove: function remove(event, params) {
38545 _this.remove(params.items);
38546 }
38547 };
38548 this.options = {};
38549 this.defaultOptions = {
38550 arrows: {
38551 to: {
38552 enabled: false,
38553 scaleFactor: 1,
38554 type: 'arrow'
38555 },
38556 // boolean / {arrowScaleFactor:1} / {enabled: false, arrowScaleFactor:1}
38557 middle: {
38558 enabled: false,
38559 scaleFactor: 1,
38560 type: 'arrow'
38561 },
38562 from: {
38563 enabled: false,
38564 scaleFactor: 1,
38565 type: 'arrow'
38566 }
38567 },
38568 arrowStrikethrough: true,
38569 color: {
38570 color: '#848484',
38571 highlight: '#848484',
38572 hover: '#848484',
38573 inherit: 'from',
38574 opacity: 1.0
38575 },
38576 dashes: false,
38577 font: {
38578 color: '#343434',
38579 size: 14,
38580 // px
38581 face: 'arial',
38582 background: 'none',
38583 strokeWidth: 2,
38584 // px
38585 strokeColor: '#ffffff',
38586 align: 'horizontal',
38587 multi: false,
38588 vadjust: 0,
38589 bold: {
38590 mod: 'bold'
38591 },
38592 boldital: {
38593 mod: 'bold italic'
38594 },
38595 ital: {
38596 mod: 'italic'
38597 },
38598 mono: {
38599 mod: '',
38600 size: 15,
38601 // px
38602 face: 'courier new',
38603 vadjust: 2
38604 }
38605 },
38606 hidden: false,
38607 hoverWidth: 1.5,
38608 label: undefined,
38609 labelHighlightBold: true,
38610 length: undefined,
38611 physics: true,
38612 scaling: {
38613 min: 1,
38614 max: 15,
38615 label: {
38616 enabled: true,
38617 min: 14,
38618 max: 30,
38619 maxVisible: 30,
38620 drawThreshold: 5
38621 },
38622 customScalingFunction: function customScalingFunction(min, max, total, value) {
38623 if (max === min) {
38624 return 0.5;
38625 } else {
38626 var scale = 1 / (max - min);
38627 return Math.max(0, (value - min) * scale);
38628 }
38629 }
38630 },
38631 selectionWidth: 1.5,
38632 selfReferenceSize: 20,
38633 shadow: {
38634 enabled: false,
38635 color: 'rgba(0,0,0,0.5)',
38636 size: 10,
38637 x: 5,
38638 y: 5
38639 },
38640 background: {
38641 enabled: false,
38642 color: 'rgba(111,111,111,1)',
38643 size: 10,
38644 dashes: false
38645 },
38646 smooth: {
38647 enabled: true,
38648 type: "dynamic",
38649 forceDirection: 'none',
38650 roundness: 0.5
38651 },
38652 title: undefined,
38653 width: 1,
38654 value: undefined
38655 };
38656 deepExtend(this.options, this.defaultOptions);
38657 this.bindEventListeners();
38658 }
38659 /**
38660 * Binds event listeners
38661 */
38662
38663
38664 _createClass(EdgesHandler, [{
38665 key: "bindEventListeners",
38666 value: function bindEventListeners() {
38667 var _this2 = this;
38668
38669 // this allows external modules to force all dynamic curves to turn static.
38670 this.body.emitter.on("_forceDisableDynamicCurves", function (type) {
38671 var emit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
38672
38673 if (type === 'dynamic') {
38674 type = 'continuous';
38675 }
38676
38677 var dataChanged = false;
38678
38679 for (var edgeId in _this2.body.edges) {
38680 if (_this2.body.edges.hasOwnProperty(edgeId)) {
38681 var edge = _this2.body.edges[edgeId];
38682 var edgeData = _this2.body.data.edges._data[edgeId]; // only forcibly remove the smooth curve if the data has been set of the edge has the smooth curves defined.
38683 // this is because a change in the global would not affect these curves.
38684
38685 if (edgeData !== undefined) {
38686 var smoothOptions = edgeData.smooth;
38687
38688 if (smoothOptions !== undefined) {
38689 if (smoothOptions.enabled === true && smoothOptions.type === 'dynamic') {
38690 if (type === undefined) {
38691 edge.setOptions({
38692 smooth: false
38693 });
38694 } else {
38695 edge.setOptions({
38696 smooth: {
38697 type: type
38698 }
38699 });
38700 }
38701
38702 dataChanged = true;
38703 }
38704 }
38705 }
38706 }
38707 }
38708
38709 if (emit === true && dataChanged === true) {
38710 _this2.body.emitter.emit("_dataChanged");
38711 }
38712 }); // this is called when options of EXISTING nodes or edges have changed.
38713 //
38714 // NOTE: Not true, called when options have NOT changed, for both existing as well as new nodes.
38715 // See update() for logic.
38716 // TODO: Verify and examine the consequences of this. It might still trigger when
38717 // non-option fields have changed, but then reconnecting edges is still useless.
38718 // Alternatively, it might also be called when edges are removed.
38719 //
38720
38721 this.body.emitter.on("_dataUpdated", function () {
38722 _this2.reconnectEdges();
38723 }); // refresh the edges. Used when reverting from hierarchical layout
38724
38725 this.body.emitter.on("refreshEdges", this.refresh.bind(this));
38726 this.body.emitter.on("refresh", this.refresh.bind(this));
38727 this.body.emitter.on("destroy", function () {
38728 forEach(_this2.edgesListeners, function (callback, event) {
38729 if (_this2.body.data.edges) _this2.body.data.edges.off(event, callback);
38730 });
38731 delete _this2.body.functions.createEdge;
38732 delete _this2.edgesListeners.add;
38733 delete _this2.edgesListeners.update;
38734 delete _this2.edgesListeners.remove;
38735 delete _this2.edgesListeners;
38736 });
38737 }
38738 /**
38739 *
38740 * @param {Object} options
38741 */
38742
38743 }, {
38744 key: "setOptions",
38745 value: function setOptions(options) {
38746 if (options !== undefined) {
38747 // use the parser from the Edge class to fill in all shorthand notations
38748 Edge.parseOptions(this.options, options, true, this.defaultOptions, true); // update smooth settings in all edges
38749
38750 var dataChanged = false;
38751
38752 if (options.smooth !== undefined) {
38753 for (var edgeId in this.body.edges) {
38754 if (this.body.edges.hasOwnProperty(edgeId)) {
38755 dataChanged = this.body.edges[edgeId].updateEdgeType() || dataChanged;
38756 }
38757 }
38758 } // update fonts in all edges
38759
38760
38761 if (options.font !== undefined) {
38762 for (var _edgeId in this.body.edges) {
38763 if (this.body.edges.hasOwnProperty(_edgeId)) {
38764 this.body.edges[_edgeId].updateLabelModule();
38765 }
38766 }
38767 } // update the state of the variables if needed
38768
38769
38770 if (options.hidden !== undefined || options.physics !== undefined || dataChanged === true) {
38771 this.body.emitter.emit('_dataChanged');
38772 }
38773 }
38774 }
38775 /**
38776 * Load edges by reading the data table
38777 * @param {Array | DataSet | DataView} edges The data containing the edges.
38778 * @param {boolean} [doNotEmit=false]
38779 * @private
38780 */
38781
38782 }, {
38783 key: "setData",
38784 value: function setData(edges) {
38785 var _this3 = this;
38786
38787 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
38788 var oldEdgesData = this.body.data.edges;
38789
38790 if (edges instanceof DataSet || edges instanceof DataView$2) {
38791 this.body.data.edges = edges;
38792 } else if (Array.isArray(edges)) {
38793 this.body.data.edges = new DataSet();
38794 this.body.data.edges.add(edges);
38795 } else if (!edges) {
38796 this.body.data.edges = new DataSet();
38797 } else {
38798 throw new TypeError('Array or DataSet expected');
38799 } // TODO: is this null or undefined or false?
38800
38801
38802 if (oldEdgesData) {
38803 // unsubscribe from old dataset
38804 forEach(this.edgesListeners, function (callback, event) {
38805 oldEdgesData.off(event, callback);
38806 });
38807 } // remove drawn edges
38808
38809
38810 this.body.edges = {}; // TODO: is this null or undefined or false?
38811
38812 if (this.body.data.edges) {
38813 // subscribe to new dataset
38814 forEach(this.edgesListeners, function (callback, event) {
38815 _this3.body.data.edges.on(event, callback);
38816 }); // draw all new nodes
38817
38818 var ids = this.body.data.edges.getIds();
38819 this.add(ids, true);
38820 }
38821
38822 this.body.emitter.emit('_adjustEdgesForHierarchicalLayout');
38823
38824 if (doNotEmit === false) {
38825 this.body.emitter.emit("_dataChanged");
38826 }
38827 }
38828 /**
38829 * Add edges
38830 * @param {number[] | string[]} ids
38831 * @param {boolean} [doNotEmit=false]
38832 * @private
38833 */
38834
38835 }, {
38836 key: "add",
38837 value: function add(ids) {
38838 var doNotEmit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
38839 var edges = this.body.edges;
38840 var edgesData = this.body.data.edges;
38841
38842 for (var i = 0; i < ids.length; i++) {
38843 var id = ids[i];
38844 var oldEdge = edges[id];
38845
38846 if (oldEdge) {
38847 oldEdge.disconnect();
38848 }
38849
38850 var data = edgesData.get(id, {
38851 "showInternalIds": true
38852 });
38853 edges[id] = this.create(data);
38854 }
38855
38856 this.body.emitter.emit('_adjustEdgesForHierarchicalLayout');
38857
38858 if (doNotEmit === false) {
38859 this.body.emitter.emit("_dataChanged");
38860 }
38861 }
38862 /**
38863 * Update existing edges, or create them when not yet existing
38864 * @param {number[] | string[]} ids
38865 * @private
38866 */
38867
38868 }, {
38869 key: "update",
38870 value: function update(ids) {
38871 var edges = this.body.edges;
38872 var edgesData = this.body.data.edges;
38873 var dataChanged = false;
38874
38875 for (var i = 0; i < ids.length; i++) {
38876 var id = ids[i];
38877 var data = edgesData.get(id);
38878 var edge = edges[id];
38879
38880 if (edge !== undefined) {
38881 // update edge
38882 edge.disconnect();
38883 dataChanged = edge.setOptions(data) || dataChanged; // if a support node is added, data can be changed.
38884
38885 edge.connect();
38886 } else {
38887 // create edge
38888 this.body.edges[id] = this.create(data);
38889 dataChanged = true;
38890 }
38891 }
38892
38893 if (dataChanged === true) {
38894 this.body.emitter.emit('_adjustEdgesForHierarchicalLayout');
38895 this.body.emitter.emit("_dataChanged");
38896 } else {
38897 this.body.emitter.emit("_dataUpdated");
38898 }
38899 }
38900 /**
38901 * Remove existing edges. Non existing ids will be ignored
38902 * @param {number[] | string[]} ids
38903 * @param {boolean} [emit=true]
38904 * @private
38905 */
38906
38907 }, {
38908 key: "remove",
38909 value: function remove(ids) {
38910 var emit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
38911 if (ids.length === 0) return; // early out
38912
38913 var edges = this.body.edges;
38914 forEach(ids, function (id) {
38915 var edge = edges[id];
38916
38917 if (edge !== undefined) {
38918 edge.remove();
38919 }
38920 });
38921
38922 if (emit) {
38923 this.body.emitter.emit("_dataChanged");
38924 }
38925 }
38926 /**
38927 * Refreshes Edge Handler
38928 */
38929
38930 }, {
38931 key: "refresh",
38932 value: function refresh() {
38933 var _this4 = this;
38934
38935 forEach(this.body.edges, function (edge, edgeId) {
38936 var data = _this4.body.data.edges._data[edgeId];
38937
38938 if (data !== undefined) {
38939 edge.setOptions(data);
38940 }
38941 });
38942 }
38943 /**
38944 *
38945 * @param {Object} properties
38946 * @returns {Edge}
38947 */
38948
38949 }, {
38950 key: "create",
38951 value: function create(properties) {
38952 return new Edge(properties, this.body, this.images, this.options, this.defaultOptions);
38953 }
38954 /**
38955 * Reconnect all edges
38956 * @private
38957 */
38958
38959 }, {
38960 key: "reconnectEdges",
38961 value: function reconnectEdges() {
38962 var id;
38963 var nodes = this.body.nodes;
38964 var edges = this.body.edges;
38965
38966 for (id in nodes) {
38967 if (nodes.hasOwnProperty(id)) {
38968 nodes[id].edges = [];
38969 }
38970 }
38971
38972 for (id in edges) {
38973 if (edges.hasOwnProperty(id)) {
38974 var edge = edges[id];
38975 edge.from = null;
38976 edge.to = null;
38977 edge.connect();
38978 }
38979 }
38980 }
38981 /**
38982 *
38983 * @param {Edge.id} edgeId
38984 * @returns {Array}
38985 */
38986
38987 }, {
38988 key: "getConnectedNodes",
38989 value: function getConnectedNodes(edgeId) {
38990 var nodeList = [];
38991
38992 if (this.body.edges[edgeId] !== undefined) {
38993 var edge = this.body.edges[edgeId];
38994
38995 if (edge.fromId !== undefined) {
38996 nodeList.push(edge.fromId);
38997 }
38998
38999 if (edge.toId !== undefined) {
39000 nodeList.push(edge.toId);
39001 }
39002 }
39003
39004 return nodeList;
39005 }
39006 /**
39007 * There is no direct relation between the nodes and the edges DataSet,
39008 * so the right place to do call this is in the handler for event `_dataUpdated`.
39009 */
39010
39011 }, {
39012 key: "_updateState",
39013 value: function _updateState() {
39014 this._addMissingEdges();
39015
39016 this._removeInvalidEdges();
39017 }
39018 /**
39019 * Scan for missing nodes and remove corresponding edges, if any.
39020 * @private
39021 */
39022
39023 }, {
39024 key: "_removeInvalidEdges",
39025 value: function _removeInvalidEdges() {
39026 var _this5 = this;
39027
39028 var edgesToDelete = [];
39029 forEach(this.body.edges, function (edge, id) {
39030 var toNode = _this5.body.nodes[edge.toId];
39031 var fromNode = _this5.body.nodes[edge.fromId]; // Skip clustering edges here, let the Clustering module handle those
39032
39033 if (toNode !== undefined && toNode.isCluster === true || fromNode !== undefined && fromNode.isCluster === true) {
39034 return;
39035 }
39036
39037 if (toNode === undefined || fromNode === undefined) {
39038 edgesToDelete.push(id);
39039 }
39040 });
39041 this.remove(edgesToDelete, false);
39042 }
39043 /**
39044 * add all edges from dataset that are not in the cached state
39045 * @private
39046 */
39047
39048 }, {
39049 key: "_addMissingEdges",
39050 value: function _addMissingEdges() {
39051 var edgesData = this.body.data.edges;
39052
39053 if (edgesData === undefined || edgesData === null) {
39054 return; // No edges DataSet yet; can happen on startup
39055 }
39056
39057 var edges = this.body.edges;
39058 var addIds = [];
39059 edgesData.forEach(function (edgeData, edgeId) {
39060 var edge = edges[edgeId];
39061
39062 if (edge === undefined) {
39063 addIds.push(edgeId);
39064 }
39065 });
39066 this.add(addIds, true);
39067 }
39068 }]);
39069
39070 return EdgesHandler;
39071 }();
39072
39073 /**
39074 * Barnes Hut Solver
39075 */
39076 var BarnesHutSolver =
39077 /*#__PURE__*/
39078 function () {
39079 /**
39080 * @param {Object} body
39081 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
39082 * @param {Object} options
39083 */
39084 function BarnesHutSolver(body, physicsBody, options) {
39085 _classCallCheck(this, BarnesHutSolver);
39086
39087 this.body = body;
39088 this.physicsBody = physicsBody;
39089 this.barnesHutTree;
39090 this.setOptions(options);
39091 this.randomSeed = 5; // debug: show grid
39092 // this.body.emitter.on("afterDrawing", (ctx) => {this._debug(ctx,'#ff0000')})
39093 }
39094 /**
39095 *
39096 * @param {Object} options
39097 */
39098
39099
39100 _createClass(BarnesHutSolver, [{
39101 key: "setOptions",
39102 value: function setOptions(options) {
39103 this.options = options;
39104 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
39105
39106 this.overlapAvoidanceFactor = 1 - Math.max(0, Math.min(1, this.options.avoidOverlap));
39107 }
39108 /**
39109 *
39110 * @returns {number} random integer
39111 */
39112
39113 }, {
39114 key: "seededRandom",
39115 value: function seededRandom() {
39116 var x = Math.sin(this.randomSeed++) * 10000;
39117 return x - Math.floor(x);
39118 }
39119 /**
39120 * This function calculates the forces the nodes apply on each other based on a gravitational model.
39121 * The Barnes Hut method is used to speed up this N-body simulation.
39122 *
39123 * @private
39124 */
39125
39126 }, {
39127 key: "solve",
39128 value: function solve() {
39129 if (this.options.gravitationalConstant !== 0 && this.physicsBody.physicsNodeIndices.length > 0) {
39130 var node;
39131 var nodes = this.body.nodes;
39132 var nodeIndices = this.physicsBody.physicsNodeIndices;
39133 var nodeCount = nodeIndices.length; // create the tree
39134
39135 var barnesHutTree = this._formBarnesHutTree(nodes, nodeIndices); // for debugging
39136
39137
39138 this.barnesHutTree = barnesHutTree; // place the nodes one by one recursively
39139
39140 for (var i = 0; i < nodeCount; i++) {
39141 node = nodes[nodeIndices[i]];
39142
39143 if (node.options.mass > 0) {
39144 // starting with root is irrelevant, it never passes the BarnesHutSolver condition
39145 this._getForceContributions(barnesHutTree.root, node);
39146 }
39147 }
39148 }
39149 }
39150 /**
39151 * @param {Object} parentBranch
39152 * @param {Node} node
39153 * @private
39154 */
39155
39156 }, {
39157 key: "_getForceContributions",
39158 value: function _getForceContributions(parentBranch, node) {
39159 this._getForceContribution(parentBranch.children.NW, node);
39160
39161 this._getForceContribution(parentBranch.children.NE, node);
39162
39163 this._getForceContribution(parentBranch.children.SW, node);
39164
39165 this._getForceContribution(parentBranch.children.SE, node);
39166 }
39167 /**
39168 * This function traverses the barnesHutTree. It checks when it can approximate distant nodes with their center of mass.
39169 * If a region contains a single node, we check if it is not itself, then we apply the force.
39170 *
39171 * @param {Object} parentBranch
39172 * @param {Node} node
39173 * @private
39174 */
39175
39176 }, {
39177 key: "_getForceContribution",
39178 value: function _getForceContribution(parentBranch, node) {
39179 // we get no force contribution from an empty region
39180 if (parentBranch.childrenCount > 0) {
39181 var dx, dy, distance; // get the distance from the center of mass to the node.
39182
39183 dx = parentBranch.centerOfMass.x - node.x;
39184 dy = parentBranch.centerOfMass.y - node.y;
39185 distance = Math.sqrt(dx * dx + dy * dy); // BarnesHutSolver condition
39186 // original condition : s/d < theta = passed === d/s > 1/theta = passed
39187 // calcSize = 1/s --> d * 1/s > 1/theta = passed
39188
39189 if (distance * parentBranch.calcSize > this.thetaInversed) {
39190 this._calculateForces(distance, dx, dy, node, parentBranch);
39191 } else {
39192 // Did not pass the condition, go into children if available
39193 if (parentBranch.childrenCount === 4) {
39194 this._getForceContributions(parentBranch, node);
39195 } else {
39196 // parentBranch must have only one node, if it was empty we wouldnt be here
39197 if (parentBranch.children.data.id != node.id) {
39198 // if it is not self
39199 this._calculateForces(distance, dx, dy, node, parentBranch);
39200 }
39201 }
39202 }
39203 }
39204 }
39205 /**
39206 * Calculate the forces based on the distance.
39207 *
39208 * @param {number} distance
39209 * @param {number} dx
39210 * @param {number} dy
39211 * @param {Node} node
39212 * @param {Object} parentBranch
39213 * @private
39214 */
39215
39216 }, {
39217 key: "_calculateForces",
39218 value: function _calculateForces(distance, dx, dy, node, parentBranch) {
39219 if (distance === 0) {
39220 distance = 0.1;
39221 dx = distance;
39222 }
39223
39224 if (this.overlapAvoidanceFactor < 1 && node.shape.radius) {
39225 distance = Math.max(0.1 + this.overlapAvoidanceFactor * node.shape.radius, distance - node.shape.radius);
39226 } // the dividing by the distance cubed instead of squared allows us to get the fx and fy components without sines and cosines
39227 // it is shorthand for gravityforce with distance squared and fx = dx/distance * gravityForce
39228
39229
39230 var gravityForce = this.options.gravitationalConstant * parentBranch.mass * node.options.mass / Math.pow(distance, 3);
39231 var fx = dx * gravityForce;
39232 var fy = dy * gravityForce;
39233 this.physicsBody.forces[node.id].x += fx;
39234 this.physicsBody.forces[node.id].y += fy;
39235 }
39236 /**
39237 * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes.
39238 *
39239 * @param {Array.<Node>} nodes
39240 * @param {Array.<number>} nodeIndices
39241 * @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
39242 * @private
39243 */
39244
39245 }, {
39246 key: "_formBarnesHutTree",
39247 value: function _formBarnesHutTree(nodes, nodeIndices) {
39248 var node;
39249 var nodeCount = nodeIndices.length;
39250 var minX = nodes[nodeIndices[0]].x;
39251 var minY = nodes[nodeIndices[0]].y;
39252 var maxX = nodes[nodeIndices[0]].x;
39253 var maxY = nodes[nodeIndices[0]].y; // get the range of the nodes
39254
39255 for (var i = 1; i < nodeCount; i++) {
39256 var _node = nodes[nodeIndices[i]];
39257 var x = _node.x;
39258 var y = _node.y;
39259
39260 if (_node.options.mass > 0) {
39261 if (x < minX) {
39262 minX = x;
39263 }
39264
39265 if (x > maxX) {
39266 maxX = x;
39267 }
39268
39269 if (y < minY) {
39270 minY = y;
39271 }
39272
39273 if (y > maxY) {
39274 maxY = y;
39275 }
39276 }
39277 } // make the range a square
39278
39279
39280 var sizeDiff = Math.abs(maxX - minX) - Math.abs(maxY - minY); // difference between X and Y
39281
39282 if (sizeDiff > 0) {
39283 minY -= 0.5 * sizeDiff;
39284 maxY += 0.5 * sizeDiff;
39285 } // xSize > ySize
39286 else {
39287 minX += 0.5 * sizeDiff;
39288 maxX -= 0.5 * sizeDiff;
39289 } // xSize < ySize
39290
39291
39292 var minimumTreeSize = 1e-5;
39293 var rootSize = Math.max(minimumTreeSize, Math.abs(maxX - minX));
39294 var halfRootSize = 0.5 * rootSize;
39295 var centerX = 0.5 * (minX + maxX),
39296 centerY = 0.5 * (minY + maxY); // construct the barnesHutTree
39297
39298 var barnesHutTree = {
39299 root: {
39300 centerOfMass: {
39301 x: 0,
39302 y: 0
39303 },
39304 mass: 0,
39305 range: {
39306 minX: centerX - halfRootSize,
39307 maxX: centerX + halfRootSize,
39308 minY: centerY - halfRootSize,
39309 maxY: centerY + halfRootSize
39310 },
39311 size: rootSize,
39312 calcSize: 1 / rootSize,
39313 children: {
39314 data: null
39315 },
39316 maxWidth: 0,
39317 level: 0,
39318 childrenCount: 4
39319 }
39320 };
39321
39322 this._splitBranch(barnesHutTree.root); // place the nodes one by one recursively
39323
39324
39325 for (var _i = 0; _i < nodeCount; _i++) {
39326 node = nodes[nodeIndices[_i]];
39327
39328 if (node.options.mass > 0) {
39329 this._placeInTree(barnesHutTree.root, node);
39330 }
39331 } // make global
39332
39333
39334 return barnesHutTree;
39335 }
39336 /**
39337 * this updates the mass of a branch. this is increased by adding a node.
39338 *
39339 * @param {Object} parentBranch
39340 * @param {Node} node
39341 * @private
39342 */
39343
39344 }, {
39345 key: "_updateBranchMass",
39346 value: function _updateBranchMass(parentBranch, node) {
39347 var centerOfMass = parentBranch.centerOfMass;
39348 var totalMass = parentBranch.mass + node.options.mass;
39349 var totalMassInv = 1 / totalMass;
39350 centerOfMass.x = centerOfMass.x * parentBranch.mass + node.x * node.options.mass;
39351 centerOfMass.x *= totalMassInv;
39352 centerOfMass.y = centerOfMass.y * parentBranch.mass + node.y * node.options.mass;
39353 centerOfMass.y *= totalMassInv;
39354 parentBranch.mass = totalMass;
39355 var biggestSize = Math.max(Math.max(node.height, node.radius), node.width);
39356 parentBranch.maxWidth = parentBranch.maxWidth < biggestSize ? biggestSize : parentBranch.maxWidth;
39357 }
39358 /**
39359 * determine in which branch the node will be placed.
39360 *
39361 * @param {Object} parentBranch
39362 * @param {Node} node
39363 * @param {boolean} skipMassUpdate
39364 * @private
39365 */
39366
39367 }, {
39368 key: "_placeInTree",
39369 value: function _placeInTree(parentBranch, node, skipMassUpdate) {
39370 if (skipMassUpdate != true || skipMassUpdate === undefined) {
39371 // update the mass of the branch.
39372 this._updateBranchMass(parentBranch, node);
39373 }
39374
39375 var range = parentBranch.children.NW.range;
39376 var region;
39377
39378 if (range.maxX > node.x) {
39379 // in NW or SW
39380 if (range.maxY > node.y) {
39381 region = "NW";
39382 } else {
39383 region = "SW";
39384 }
39385 } else {
39386 // in NE or SE
39387 if (range.maxY > node.y) {
39388 region = "NE";
39389 } else {
39390 region = "SE";
39391 }
39392 }
39393
39394 this._placeInRegion(parentBranch, node, region);
39395 }
39396 /**
39397 * actually place the node in a region (or branch)
39398 *
39399 * @param {Object} parentBranch
39400 * @param {Node} node
39401 * @param {'NW'| 'NE' | 'SW' | 'SE'} region
39402 * @private
39403 */
39404
39405 }, {
39406 key: "_placeInRegion",
39407 value: function _placeInRegion(parentBranch, node, region) {
39408 var children = parentBranch.children[region];
39409
39410 switch (children.childrenCount) {
39411 case 0:
39412 // place node here
39413 children.children.data = node;
39414 children.childrenCount = 1;
39415
39416 this._updateBranchMass(children, node);
39417
39418 break;
39419
39420 case 1:
39421 // convert into children
39422 // if there are two nodes exactly overlapping (on init, on opening of cluster etc.)
39423 // we move one node a little bit and we do not put it in the tree.
39424 if (children.children.data.x === node.x && children.children.data.y === node.y) {
39425 node.x += this.seededRandom();
39426 node.y += this.seededRandom();
39427 } else {
39428 this._splitBranch(children);
39429
39430 this._placeInTree(children, node);
39431 }
39432
39433 break;
39434
39435 case 4:
39436 // place in branch
39437 this._placeInTree(children, node);
39438
39439 break;
39440 }
39441 }
39442 /**
39443 * this function splits a branch into 4 sub branches. If the branch contained a node, we place it in the subbranch
39444 * after the split is complete.
39445 *
39446 * @param {Object} parentBranch
39447 * @private
39448 */
39449
39450 }, {
39451 key: "_splitBranch",
39452 value: function _splitBranch(parentBranch) {
39453 // if the branch is shaded with a node, replace the node in the new subset.
39454 var containedNode = null;
39455
39456 if (parentBranch.childrenCount === 1) {
39457 containedNode = parentBranch.children.data;
39458 parentBranch.mass = 0;
39459 parentBranch.centerOfMass.x = 0;
39460 parentBranch.centerOfMass.y = 0;
39461 }
39462
39463 parentBranch.childrenCount = 4;
39464 parentBranch.children.data = null;
39465
39466 this._insertRegion(parentBranch, "NW");
39467
39468 this._insertRegion(parentBranch, "NE");
39469
39470 this._insertRegion(parentBranch, "SW");
39471
39472 this._insertRegion(parentBranch, "SE");
39473
39474 if (containedNode != null) {
39475 this._placeInTree(parentBranch, containedNode);
39476 }
39477 }
39478 /**
39479 * This function subdivides the region into four new segments.
39480 * Specifically, this inserts a single new segment.
39481 * It fills the children section of the parentBranch
39482 *
39483 * @param {Object} parentBranch
39484 * @param {'NW'| 'NE' | 'SW' | 'SE'} region
39485 * @private
39486 */
39487
39488 }, {
39489 key: "_insertRegion",
39490 value: function _insertRegion(parentBranch, region) {
39491 var minX, maxX, minY, maxY;
39492 var childSize = 0.5 * parentBranch.size;
39493
39494 switch (region) {
39495 case "NW":
39496 minX = parentBranch.range.minX;
39497 maxX = parentBranch.range.minX + childSize;
39498 minY = parentBranch.range.minY;
39499 maxY = parentBranch.range.minY + childSize;
39500 break;
39501
39502 case "NE":
39503 minX = parentBranch.range.minX + childSize;
39504 maxX = parentBranch.range.maxX;
39505 minY = parentBranch.range.minY;
39506 maxY = parentBranch.range.minY + childSize;
39507 break;
39508
39509 case "SW":
39510 minX = parentBranch.range.minX;
39511 maxX = parentBranch.range.minX + childSize;
39512 minY = parentBranch.range.minY + childSize;
39513 maxY = parentBranch.range.maxY;
39514 break;
39515
39516 case "SE":
39517 minX = parentBranch.range.minX + childSize;
39518 maxX = parentBranch.range.maxX;
39519 minY = parentBranch.range.minY + childSize;
39520 maxY = parentBranch.range.maxY;
39521 break;
39522 }
39523
39524 parentBranch.children[region] = {
39525 centerOfMass: {
39526 x: 0,
39527 y: 0
39528 },
39529 mass: 0,
39530 range: {
39531 minX: minX,
39532 maxX: maxX,
39533 minY: minY,
39534 maxY: maxY
39535 },
39536 size: 0.5 * parentBranch.size,
39537 calcSize: 2 * parentBranch.calcSize,
39538 children: {
39539 data: null
39540 },
39541 maxWidth: 0,
39542 level: parentBranch.level + 1,
39543 childrenCount: 0
39544 };
39545 } //--------------------------- DEBUGGING BELOW ---------------------------//
39546
39547 /**
39548 * This function is for debugging purposed, it draws the tree.
39549 *
39550 * @param {CanvasRenderingContext2D} ctx
39551 * @param {string} color
39552 * @private
39553 */
39554
39555 }, {
39556 key: "_debug",
39557 value: function _debug(ctx, color) {
39558 if (this.barnesHutTree !== undefined) {
39559 ctx.lineWidth = 1;
39560
39561 this._drawBranch(this.barnesHutTree.root, ctx, color);
39562 }
39563 }
39564 /**
39565 * This function is for debugging purposes. It draws the branches recursively.
39566 *
39567 * @param {Object} branch
39568 * @param {CanvasRenderingContext2D} ctx
39569 * @param {string} color
39570 * @private
39571 */
39572
39573 }, {
39574 key: "_drawBranch",
39575 value: function _drawBranch(branch, ctx, color) {
39576 if (color === undefined) {
39577 color = "#FF0000";
39578 }
39579
39580 if (branch.childrenCount === 4) {
39581 this._drawBranch(branch.children.NW, ctx);
39582
39583 this._drawBranch(branch.children.NE, ctx);
39584
39585 this._drawBranch(branch.children.SE, ctx);
39586
39587 this._drawBranch(branch.children.SW, ctx);
39588 }
39589
39590 ctx.strokeStyle = color;
39591 ctx.beginPath();
39592 ctx.moveTo(branch.range.minX, branch.range.minY);
39593 ctx.lineTo(branch.range.maxX, branch.range.minY);
39594 ctx.stroke();
39595 ctx.beginPath();
39596 ctx.moveTo(branch.range.maxX, branch.range.minY);
39597 ctx.lineTo(branch.range.maxX, branch.range.maxY);
39598 ctx.stroke();
39599 ctx.beginPath();
39600 ctx.moveTo(branch.range.maxX, branch.range.maxY);
39601 ctx.lineTo(branch.range.minX, branch.range.maxY);
39602 ctx.stroke();
39603 ctx.beginPath();
39604 ctx.moveTo(branch.range.minX, branch.range.maxY);
39605 ctx.lineTo(branch.range.minX, branch.range.minY);
39606 ctx.stroke();
39607 /*
39608 if (branch.mass > 0) {
39609 ctx.circle(branch.centerOfMass.x, branch.centerOfMass.y, 3*branch.mass);
39610 ctx.stroke();
39611 }
39612 */
39613 }
39614 }]);
39615
39616 return BarnesHutSolver;
39617 }();
39618
39619 /**
39620 * Repulsion Solver
39621 */
39622 var RepulsionSolver =
39623 /*#__PURE__*/
39624 function () {
39625 /**
39626 * @param {Object} body
39627 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
39628 * @param {Object} options
39629 */
39630 function RepulsionSolver(body, physicsBody, options) {
39631 _classCallCheck(this, RepulsionSolver);
39632
39633 this.body = body;
39634 this.physicsBody = physicsBody;
39635 this.setOptions(options);
39636 }
39637 /**
39638 *
39639 * @param {Object} options
39640 */
39641
39642
39643 _createClass(RepulsionSolver, [{
39644 key: "setOptions",
39645 value: function setOptions(options) {
39646 this.options = options;
39647 }
39648 /**
39649 * Calculate the forces the nodes apply on each other based on a repulsion field.
39650 * This field is linearly approximated.
39651 *
39652 * @private
39653 */
39654
39655 }, {
39656 key: "solve",
39657 value: function solve() {
39658 var dx, dy, distance, fx, fy, repulsingForce, node1, node2;
39659 var nodes = this.body.nodes;
39660 var nodeIndices = this.physicsBody.physicsNodeIndices;
39661 var forces = this.physicsBody.forces; // repulsing forces between nodes
39662
39663 var nodeDistance = this.options.nodeDistance; // approximation constants
39664
39665 var a = -2 / 3 / nodeDistance;
39666 var b = 4 / 3; // we loop from i over all but the last entree in the array
39667 // j loops from i+1 to the last. This way we do not double count any of the indices, nor i === j
39668
39669 for (var i = 0; i < nodeIndices.length - 1; i++) {
39670 node1 = nodes[nodeIndices[i]];
39671
39672 for (var j = i + 1; j < nodeIndices.length; j++) {
39673 node2 = nodes[nodeIndices[j]];
39674 dx = node2.x - node1.x;
39675 dy = node2.y - node1.y;
39676 distance = Math.sqrt(dx * dx + dy * dy); // same condition as BarnesHutSolver, making sure nodes are never 100% overlapping.
39677
39678 if (distance === 0) {
39679 distance = 0.1 * Math.random();
39680 dx = distance;
39681 }
39682
39683 if (distance < 2 * nodeDistance) {
39684 if (distance < 0.5 * nodeDistance) {
39685 repulsingForce = 1.0;
39686 } else {
39687 repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / nodeDistance - 1) * steepness))
39688 }
39689
39690 repulsingForce = repulsingForce / distance;
39691 fx = dx * repulsingForce;
39692 fy = dy * repulsingForce;
39693 forces[node1.id].x -= fx;
39694 forces[node1.id].y -= fy;
39695 forces[node2.id].x += fx;
39696 forces[node2.id].y += fy;
39697 }
39698 }
39699 }
39700 }
39701 }]);
39702
39703 return RepulsionSolver;
39704 }();
39705
39706 /**
39707 * Hierarchical Repulsion Solver
39708 */
39709 var HierarchicalRepulsionSolver =
39710 /*#__PURE__*/
39711 function () {
39712 /**
39713 * @param {Object} body
39714 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
39715 * @param {Object} options
39716 */
39717 function HierarchicalRepulsionSolver(body, physicsBody, options) {
39718 _classCallCheck(this, HierarchicalRepulsionSolver);
39719
39720 this.body = body;
39721 this.physicsBody = physicsBody;
39722 this.setOptions(options);
39723 }
39724 /**
39725 *
39726 * @param {Object} options
39727 */
39728
39729
39730 _createClass(HierarchicalRepulsionSolver, [{
39731 key: "setOptions",
39732 value: function setOptions(options) {
39733 this.options = options;
39734 this.overlapAvoidanceFactor = Math.max(0, Math.min(1, this.options.avoidOverlap || 0));
39735 }
39736 /**
39737 * Calculate the forces the nodes apply on each other based on a repulsion field.
39738 * This field is linearly approximated.
39739 *
39740 * @private
39741 */
39742
39743 }, {
39744 key: "solve",
39745 value: function solve() {
39746 var nodes = this.body.nodes;
39747 var nodeIndices = this.physicsBody.physicsNodeIndices;
39748 var forces = this.physicsBody.forces; // repulsing forces between nodes
39749
39750 var nodeDistance = this.options.nodeDistance; // we loop from i over all but the last entree in the array
39751 // j loops from i+1 to the last. This way we do not double count any of the indices, nor i === j
39752
39753 for (var i = 0; i < nodeIndices.length - 1; i++) {
39754 var node1 = nodes[nodeIndices[i]];
39755
39756 for (var j = i + 1; j < nodeIndices.length; j++) {
39757 var node2 = nodes[nodeIndices[j]]; // nodes only affect nodes on their level
39758
39759 if (node1.level === node2.level) {
39760 var theseNodesDistance = nodeDistance + this.overlapAvoidanceFactor * ((node1.shape.radius || 0) / 2 + (node2.shape.radius || 0) / 2);
39761 var dx = node2.x - node1.x;
39762 var dy = node2.y - node1.y;
39763 var distance = Math.sqrt(dx * dx + dy * dy);
39764 var steepness = 0.05;
39765 var repulsingForce = void 0;
39766
39767 if (distance < theseNodesDistance) {
39768 repulsingForce = -Math.pow(steepness * distance, 2) + Math.pow(steepness * theseNodesDistance, 2);
39769 } else {
39770 repulsingForce = 0;
39771 } // normalize force with
39772
39773
39774 if (distance === 0) {
39775 distance = (_readOnlyError("distance"), 0.01);
39776 } else {
39777 repulsingForce = repulsingForce / distance;
39778 }
39779
39780 var fx = dx * repulsingForce;
39781 var fy = dy * repulsingForce;
39782 forces[node1.id].x -= fx;
39783 forces[node1.id].y -= fy;
39784 forces[node2.id].x += fx;
39785 forces[node2.id].y += fy;
39786 }
39787 }
39788 }
39789 }
39790 }]);
39791
39792 return HierarchicalRepulsionSolver;
39793 }();
39794
39795 /**
39796 * Spring Solver
39797 */
39798 var SpringSolver =
39799 /*#__PURE__*/
39800 function () {
39801 /**
39802 * @param {Object} body
39803 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
39804 * @param {Object} options
39805 */
39806 function SpringSolver(body, physicsBody, options) {
39807 _classCallCheck(this, SpringSolver);
39808
39809 this.body = body;
39810 this.physicsBody = physicsBody;
39811 this.setOptions(options);
39812 }
39813 /**
39814 *
39815 * @param {Object} options
39816 */
39817
39818
39819 _createClass(SpringSolver, [{
39820 key: "setOptions",
39821 value: function setOptions(options) {
39822 this.options = options;
39823 }
39824 /**
39825 * This function calculates the springforces on the nodes, accounting for the support nodes.
39826 *
39827 * @private
39828 */
39829
39830 }, {
39831 key: "solve",
39832 value: function solve() {
39833 var edgeLength, edge;
39834 var edgeIndices = this.physicsBody.physicsEdgeIndices;
39835 var edges = this.body.edges;
39836 var node1, node2, node3; // forces caused by the edges, modelled as springs
39837
39838 for (var i = 0; i < edgeIndices.length; i++) {
39839 edge = edges[edgeIndices[i]];
39840
39841 if (edge.connected === true && edge.toId !== edge.fromId) {
39842 // only calculate forces if nodes are in the same sector
39843 if (this.body.nodes[edge.toId] !== undefined && this.body.nodes[edge.fromId] !== undefined) {
39844 if (edge.edgeType.via !== undefined) {
39845 edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
39846 node1 = edge.to;
39847 node2 = edge.edgeType.via;
39848 node3 = edge.from;
39849
39850 this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
39851
39852 this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
39853 } else {
39854 // the * 1.5 is here so the edge looks as large as a smooth edge. It does not initially because the smooth edges use
39855 // the support nodes which exert a repulsive force on the to and from nodes, making the edge appear larger.
39856 edgeLength = edge.options.length === undefined ? this.options.springLength * 1.5 : edge.options.length;
39857
39858 this._calculateSpringForce(edge.from, edge.to, edgeLength);
39859 }
39860 }
39861 }
39862 }
39863 }
39864 /**
39865 * This is the code actually performing the calculation for the function above.
39866 *
39867 * @param {Node} node1
39868 * @param {Node} node2
39869 * @param {number} edgeLength
39870 * @private
39871 */
39872
39873 }, {
39874 key: "_calculateSpringForce",
39875 value: function _calculateSpringForce(node1, node2, edgeLength) {
39876 var dx = node1.x - node2.x;
39877 var dy = node1.y - node2.y;
39878 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.
39879
39880 var springForce = this.options.springConstant * (edgeLength - distance) / distance;
39881 var fx = dx * springForce;
39882 var fy = dy * springForce; // handle the case where one node is not part of the physcis
39883
39884 if (this.physicsBody.forces[node1.id] !== undefined) {
39885 this.physicsBody.forces[node1.id].x += fx;
39886 this.physicsBody.forces[node1.id].y += fy;
39887 }
39888
39889 if (this.physicsBody.forces[node2.id] !== undefined) {
39890 this.physicsBody.forces[node2.id].x -= fx;
39891 this.physicsBody.forces[node2.id].y -= fy;
39892 }
39893 }
39894 }]);
39895
39896 return SpringSolver;
39897 }();
39898
39899 /**
39900 * Hierarchical Spring Solver
39901 */
39902 var HierarchicalSpringSolver =
39903 /*#__PURE__*/
39904 function () {
39905 /**
39906 * @param {Object} body
39907 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
39908 * @param {Object} options
39909 */
39910 function HierarchicalSpringSolver(body, physicsBody, options) {
39911 _classCallCheck(this, HierarchicalSpringSolver);
39912
39913 this.body = body;
39914 this.physicsBody = physicsBody;
39915 this.setOptions(options);
39916 }
39917 /**
39918 *
39919 * @param {Object} options
39920 */
39921
39922
39923 _createClass(HierarchicalSpringSolver, [{
39924 key: "setOptions",
39925 value: function setOptions(options) {
39926 this.options = options;
39927 }
39928 /**
39929 * This function calculates the springforces on the nodes, accounting for the support nodes.
39930 *
39931 * @private
39932 */
39933
39934 }, {
39935 key: "solve",
39936 value: function solve() {
39937 var edgeLength, edge;
39938 var dx, dy, fx, fy, springForce, distance;
39939 var edges = this.body.edges;
39940 var factor = 0.5;
39941 var edgeIndices = this.physicsBody.physicsEdgeIndices;
39942 var nodeIndices = this.physicsBody.physicsNodeIndices;
39943 var forces = this.physicsBody.forces; // initialize the spring force counters
39944
39945 for (var i = 0; i < nodeIndices.length; i++) {
39946 var nodeId = nodeIndices[i];
39947 forces[nodeId].springFx = 0;
39948 forces[nodeId].springFy = 0;
39949 } // forces caused by the edges, modelled as springs
39950
39951
39952 for (var _i = 0; _i < edgeIndices.length; _i++) {
39953 edge = edges[edgeIndices[_i]];
39954
39955 if (edge.connected === true) {
39956 edgeLength = edge.options.length === undefined ? this.options.springLength : edge.options.length;
39957 dx = edge.from.x - edge.to.x;
39958 dy = edge.from.y - edge.to.y;
39959 distance = Math.sqrt(dx * dx + dy * dy);
39960 distance = distance === 0 ? 0.01 : distance; // the 1/distance is so the fx and fy can be calculated without sine or cosine.
39961
39962 springForce = this.options.springConstant * (edgeLength - distance) / distance;
39963 fx = dx * springForce;
39964 fy = dy * springForce;
39965
39966 if (edge.to.level != edge.from.level) {
39967 if (forces[edge.toId] !== undefined) {
39968 forces[edge.toId].springFx -= fx;
39969 forces[edge.toId].springFy -= fy;
39970 }
39971
39972 if (forces[edge.fromId] !== undefined) {
39973 forces[edge.fromId].springFx += fx;
39974 forces[edge.fromId].springFy += fy;
39975 }
39976 } else {
39977 if (forces[edge.toId] !== undefined) {
39978 forces[edge.toId].x -= factor * fx;
39979 forces[edge.toId].y -= factor * fy;
39980 }
39981
39982 if (forces[edge.fromId] !== undefined) {
39983 forces[edge.fromId].x += factor * fx;
39984 forces[edge.fromId].y += factor * fy;
39985 }
39986 }
39987 }
39988 } // normalize spring forces
39989
39990
39991 springForce = 1;
39992 var springFx, springFy;
39993
39994 for (var _i2 = 0; _i2 < nodeIndices.length; _i2++) {
39995 var _nodeId = nodeIndices[_i2];
39996 springFx = Math.min(springForce, Math.max(-springForce, forces[_nodeId].springFx));
39997 springFy = Math.min(springForce, Math.max(-springForce, forces[_nodeId].springFy));
39998 forces[_nodeId].x += springFx;
39999 forces[_nodeId].y += springFy;
40000 } // retain energy balance
40001
40002
40003 var totalFx = 0;
40004 var totalFy = 0;
40005
40006 for (var _i3 = 0; _i3 < nodeIndices.length; _i3++) {
40007 var _nodeId2 = nodeIndices[_i3];
40008 totalFx += forces[_nodeId2].x;
40009 totalFy += forces[_nodeId2].y;
40010 }
40011
40012 var correctionFx = totalFx / nodeIndices.length;
40013 var correctionFy = totalFy / nodeIndices.length;
40014
40015 for (var _i4 = 0; _i4 < nodeIndices.length; _i4++) {
40016 var _nodeId3 = nodeIndices[_i4];
40017 forces[_nodeId3].x -= correctionFx;
40018 forces[_nodeId3].y -= correctionFy;
40019 }
40020 }
40021 }]);
40022
40023 return HierarchicalSpringSolver;
40024 }();
40025
40026 /**
40027 * Central Gravity Solver
40028 */
40029 var CentralGravitySolver =
40030 /*#__PURE__*/
40031 function () {
40032 /**
40033 * @param {Object} body
40034 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
40035 * @param {Object} options
40036 */
40037 function CentralGravitySolver(body, physicsBody, options) {
40038 _classCallCheck(this, CentralGravitySolver);
40039
40040 this.body = body;
40041 this.physicsBody = physicsBody;
40042 this.setOptions(options);
40043 }
40044 /**
40045 *
40046 * @param {Object} options
40047 */
40048
40049
40050 _createClass(CentralGravitySolver, [{
40051 key: "setOptions",
40052 value: function setOptions(options) {
40053 this.options = options;
40054 }
40055 /**
40056 * Calculates forces for each node
40057 */
40058
40059 }, {
40060 key: "solve",
40061 value: function solve() {
40062 var dx, dy, distance, node;
40063 var nodes = this.body.nodes;
40064 var nodeIndices = this.physicsBody.physicsNodeIndices;
40065 var forces = this.physicsBody.forces;
40066
40067 for (var i = 0; i < nodeIndices.length; i++) {
40068 var nodeId = nodeIndices[i];
40069 node = nodes[nodeId];
40070 dx = -node.x;
40071 dy = -node.y;
40072 distance = Math.sqrt(dx * dx + dy * dy);
40073
40074 this._calculateForces(distance, dx, dy, forces, node);
40075 }
40076 }
40077 /**
40078 * Calculate the forces based on the distance.
40079 * @param {number} distance
40080 * @param {number} dx
40081 * @param {number} dy
40082 * @param {Object<Node.id, vis.Node>} forces
40083 * @param {Node} node
40084 * @private
40085 */
40086
40087 }, {
40088 key: "_calculateForces",
40089 value: function _calculateForces(distance, dx, dy, forces, node) {
40090 var gravityForce = distance === 0 ? 0 : this.options.centralGravity / distance;
40091 forces[node.id].x = dx * gravityForce;
40092 forces[node.id].y = dy * gravityForce;
40093 }
40094 }]);
40095
40096 return CentralGravitySolver;
40097 }();
40098
40099 /**
40100 * @extends BarnesHutSolver
40101 */
40102
40103 var ForceAtlas2BasedRepulsionSolver =
40104 /*#__PURE__*/
40105 function (_BarnesHutSolver) {
40106 _inherits(ForceAtlas2BasedRepulsionSolver, _BarnesHutSolver);
40107
40108 /**
40109 * @param {Object} body
40110 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
40111 * @param {Object} options
40112 */
40113 function ForceAtlas2BasedRepulsionSolver(body, physicsBody, options) {
40114 _classCallCheck(this, ForceAtlas2BasedRepulsionSolver);
40115
40116 return _possibleConstructorReturn(this, _getPrototypeOf(ForceAtlas2BasedRepulsionSolver).call(this, body, physicsBody, options));
40117 }
40118 /**
40119 * Calculate the forces based on the distance.
40120 *
40121 * @param {number} distance
40122 * @param {number} dx
40123 * @param {number} dy
40124 * @param {Node} node
40125 * @param {Object} parentBranch
40126 * @private
40127 */
40128
40129
40130 _createClass(ForceAtlas2BasedRepulsionSolver, [{
40131 key: "_calculateForces",
40132 value: function _calculateForces(distance, dx, dy, node, parentBranch) {
40133 if (distance === 0) {
40134 distance = 0.1 * Math.random();
40135 dx = distance;
40136 }
40137
40138 if (this.overlapAvoidanceFactor < 1 && node.shape.radius) {
40139 distance = Math.max(0.1 + this.overlapAvoidanceFactor * node.shape.radius, distance - node.shape.radius);
40140 }
40141
40142 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
40143 // it is shorthand for gravityforce with distance squared and fx = dx/distance * gravityForce
40144
40145 var gravityForce = this.options.gravitationalConstant * parentBranch.mass * node.options.mass * degree / Math.pow(distance, 2);
40146 var fx = dx * gravityForce;
40147 var fy = dy * gravityForce;
40148 this.physicsBody.forces[node.id].x += fx;
40149 this.physicsBody.forces[node.id].y += fy;
40150 }
40151 }]);
40152
40153 return ForceAtlas2BasedRepulsionSolver;
40154 }(BarnesHutSolver);
40155
40156 /**
40157 * @extends CentralGravitySolver
40158 */
40159
40160 var ForceAtlas2BasedCentralGravitySolver =
40161 /*#__PURE__*/
40162 function (_CentralGravitySolver) {
40163 _inherits(ForceAtlas2BasedCentralGravitySolver, _CentralGravitySolver);
40164
40165 /**
40166 * @param {Object} body
40167 * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
40168 * @param {Object} options
40169 */
40170 function ForceAtlas2BasedCentralGravitySolver(body, physicsBody, options) {
40171 _classCallCheck(this, ForceAtlas2BasedCentralGravitySolver);
40172
40173 return _possibleConstructorReturn(this, _getPrototypeOf(ForceAtlas2BasedCentralGravitySolver).call(this, body, physicsBody, options));
40174 }
40175 /**
40176 * Calculate the forces based on the distance.
40177 *
40178 * @param {number} distance
40179 * @param {number} dx
40180 * @param {number} dy
40181 * @param {Object<Node.id, Node>} forces
40182 * @param {Node} node
40183 * @private
40184 */
40185
40186
40187 _createClass(ForceAtlas2BasedCentralGravitySolver, [{
40188 key: "_calculateForces",
40189 value: function _calculateForces(distance, dx, dy, forces, node) {
40190 if (distance > 0) {
40191 var degree = node.edges.length + 1;
40192 var gravityForce = this.options.centralGravity * degree * node.options.mass;
40193 forces[node.id].x = dx * gravityForce;
40194 forces[node.id].y = dy * gravityForce;
40195 }
40196 }
40197 }]);
40198
40199 return ForceAtlas2BasedCentralGravitySolver;
40200 }(CentralGravitySolver);
40201
40202 /**
40203 * The physics engine
40204 */
40205
40206 var PhysicsEngine =
40207 /*#__PURE__*/
40208 function () {
40209 /**
40210 * @param {Object} body
40211 */
40212 function PhysicsEngine(body) {
40213 _classCallCheck(this, PhysicsEngine);
40214
40215 this.body = body;
40216 this.physicsBody = {
40217 physicsNodeIndices: [],
40218 physicsEdgeIndices: [],
40219 forces: {},
40220 velocities: {}
40221 };
40222 this.physicsEnabled = true;
40223 this.simulationInterval = 1000 / 60;
40224 this.requiresTimeout = true;
40225 this.previousStates = {};
40226 this.referenceState = {};
40227 this.freezeCache = {};
40228 this.renderTimer = undefined; // parameters for the adaptive timestep
40229
40230 this.adaptiveTimestep = false;
40231 this.adaptiveTimestepEnabled = false;
40232 this.adaptiveCounter = 0;
40233 this.adaptiveInterval = 3;
40234 this.stabilized = false;
40235 this.startedStabilization = false;
40236 this.stabilizationIterations = 0;
40237 this.ready = false; // will be set to true if the stabilize
40238 // default options
40239
40240 this.options = {};
40241 this.defaultOptions = {
40242 enabled: true,
40243 barnesHut: {
40244 theta: 0.5,
40245 gravitationalConstant: -2000,
40246 centralGravity: 0.3,
40247 springLength: 95,
40248 springConstant: 0.04,
40249 damping: 0.09,
40250 avoidOverlap: 0
40251 },
40252 forceAtlas2Based: {
40253 theta: 0.5,
40254 gravitationalConstant: -50,
40255 centralGravity: 0.01,
40256 springConstant: 0.08,
40257 springLength: 100,
40258 damping: 0.4,
40259 avoidOverlap: 0
40260 },
40261 repulsion: {
40262 centralGravity: 0.2,
40263 springLength: 200,
40264 springConstant: 0.05,
40265 nodeDistance: 100,
40266 damping: 0.09,
40267 avoidOverlap: 0
40268 },
40269 hierarchicalRepulsion: {
40270 centralGravity: 0.0,
40271 springLength: 100,
40272 springConstant: 0.01,
40273 nodeDistance: 120,
40274 damping: 0.09
40275 },
40276 maxVelocity: 50,
40277 minVelocity: 0.75,
40278 // px/s
40279 solver: 'barnesHut',
40280 stabilization: {
40281 enabled: true,
40282 iterations: 1000,
40283 // maximum number of iteration to stabilize
40284 updateInterval: 50,
40285 onlyDynamicEdges: false,
40286 fit: true
40287 },
40288 timestep: 0.5,
40289 adaptiveTimestep: true
40290 };
40291 extend(this.options, this.defaultOptions);
40292 this.timestep = 0.5;
40293 this.layoutFailed = false;
40294 this.bindEventListeners();
40295 }
40296 /**
40297 * Binds event listeners
40298 */
40299
40300
40301 _createClass(PhysicsEngine, [{
40302 key: "bindEventListeners",
40303 value: function bindEventListeners() {
40304 var _this = this;
40305
40306 this.body.emitter.on('initPhysics', function () {
40307 _this.initPhysics();
40308 });
40309 this.body.emitter.on('_layoutFailed', function () {
40310 _this.layoutFailed = true;
40311 });
40312 this.body.emitter.on('resetPhysics', function () {
40313 _this.stopSimulation();
40314
40315 _this.ready = false;
40316 });
40317 this.body.emitter.on('disablePhysics', function () {
40318 _this.physicsEnabled = false;
40319
40320 _this.stopSimulation();
40321 });
40322 this.body.emitter.on('restorePhysics', function () {
40323 _this.setOptions(_this.options);
40324
40325 if (_this.ready === true) {
40326 _this.startSimulation();
40327 }
40328 });
40329 this.body.emitter.on('startSimulation', function () {
40330 if (_this.ready === true) {
40331 _this.startSimulation();
40332 }
40333 });
40334 this.body.emitter.on('stopSimulation', function () {
40335 _this.stopSimulation();
40336 });
40337 this.body.emitter.on('destroy', function () {
40338 _this.stopSimulation(false);
40339
40340 _this.body.emitter.off();
40341 });
40342 this.body.emitter.on("_dataChanged", function () {
40343 // Nodes and/or edges have been added or removed, update shortcut lists.
40344 _this.updatePhysicsData();
40345 }); // debug: show forces
40346 // this.body.emitter.on("afterDrawing", (ctx) => {this._drawForces(ctx);});
40347 }
40348 /**
40349 * set the physics options
40350 * @param {Object} options
40351 */
40352
40353 }, {
40354 key: "setOptions",
40355 value: function setOptions(options) {
40356 if (options !== undefined) {
40357 if (options === false) {
40358 this.options.enabled = false;
40359 this.physicsEnabled = false;
40360 this.stopSimulation();
40361 } else if (options === true) {
40362 this.options.enabled = true;
40363 this.physicsEnabled = true;
40364 this.startSimulation();
40365 } else {
40366 this.physicsEnabled = true;
40367 selectiveNotDeepExtend(['stabilization'], this.options, options);
40368 mergeOptions(this.options, options, 'stabilization');
40369
40370 if (options.enabled === undefined) {
40371 this.options.enabled = true;
40372 }
40373
40374 if (this.options.enabled === false) {
40375 this.physicsEnabled = false;
40376 this.stopSimulation();
40377 } // set the timestep
40378
40379
40380 this.timestep = this.options.timestep;
40381 }
40382 }
40383
40384 this.init();
40385 }
40386 /**
40387 * configure the engine.
40388 */
40389
40390 }, {
40391 key: "init",
40392 value: function init() {
40393 var options;
40394
40395 if (this.options.solver === 'forceAtlas2Based') {
40396 options = this.options.forceAtlas2Based;
40397 this.nodesSolver = new ForceAtlas2BasedRepulsionSolver(this.body, this.physicsBody, options);
40398 this.edgesSolver = new SpringSolver(this.body, this.physicsBody, options);
40399 this.gravitySolver = new ForceAtlas2BasedCentralGravitySolver(this.body, this.physicsBody, options);
40400 } else if (this.options.solver === 'repulsion') {
40401 options = this.options.repulsion;
40402 this.nodesSolver = new RepulsionSolver(this.body, this.physicsBody, options);
40403 this.edgesSolver = new SpringSolver(this.body, this.physicsBody, options);
40404 this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
40405 } else if (this.options.solver === 'hierarchicalRepulsion') {
40406 options = this.options.hierarchicalRepulsion;
40407 this.nodesSolver = new HierarchicalRepulsionSolver(this.body, this.physicsBody, options);
40408 this.edgesSolver = new HierarchicalSpringSolver(this.body, this.physicsBody, options);
40409 this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
40410 } else {
40411 // barnesHut
40412 options = this.options.barnesHut;
40413 this.nodesSolver = new BarnesHutSolver(this.body, this.physicsBody, options);
40414 this.edgesSolver = new SpringSolver(this.body, this.physicsBody, options);
40415 this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
40416 }
40417
40418 this.modelOptions = options;
40419 }
40420 /**
40421 * initialize the engine
40422 */
40423
40424 }, {
40425 key: "initPhysics",
40426 value: function initPhysics() {
40427 if (this.physicsEnabled === true && this.options.enabled === true) {
40428 if (this.options.stabilization.enabled === true) {
40429 this.stabilize();
40430 } else {
40431 this.stabilized = false;
40432 this.ready = true;
40433 this.body.emitter.emit('fit', {}, this.layoutFailed); // if the layout failed, we use the approximation for the zoom
40434
40435 this.startSimulation();
40436 }
40437 } else {
40438 this.ready = true;
40439 this.body.emitter.emit('fit');
40440 }
40441 }
40442 /**
40443 * Start the simulation
40444 */
40445
40446 }, {
40447 key: "startSimulation",
40448 value: function startSimulation() {
40449 if (this.physicsEnabled === true && this.options.enabled === true) {
40450 this.stabilized = false; // when visible, adaptivity is disabled.
40451
40452 this.adaptiveTimestep = false; // this sets the width of all nodes initially which could be required for the avoidOverlap
40453
40454 this.body.emitter.emit("_resizeNodes");
40455
40456 if (this.viewFunction === undefined) {
40457 this.viewFunction = this.simulationStep.bind(this);
40458 this.body.emitter.on('initRedraw', this.viewFunction);
40459 this.body.emitter.emit('_startRendering');
40460 }
40461 } else {
40462 this.body.emitter.emit('_redraw');
40463 }
40464 }
40465 /**
40466 * Stop the simulation, force stabilization.
40467 * @param {boolean} [emit=true]
40468 */
40469
40470 }, {
40471 key: "stopSimulation",
40472 value: function stopSimulation() {
40473 var emit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
40474 this.stabilized = true;
40475
40476 if (emit === true) {
40477 this._emitStabilized();
40478 }
40479
40480 if (this.viewFunction !== undefined) {
40481 this.body.emitter.off('initRedraw', this.viewFunction);
40482 this.viewFunction = undefined;
40483
40484 if (emit === true) {
40485 this.body.emitter.emit('_stopRendering');
40486 }
40487 }
40488 }
40489 /**
40490 * The viewFunction inserts this step into each render loop. It calls the physics tick and handles the cleanup at stabilized.
40491 *
40492 */
40493
40494 }, {
40495 key: "simulationStep",
40496 value: function simulationStep() {
40497 // check if the physics have settled
40498 var startTime = Date.now();
40499 this.physicsTick();
40500 var physicsTime = Date.now() - startTime; // run double speed if it is a little graph
40501
40502 if ((physicsTime < 0.4 * this.simulationInterval || this.runDoubleSpeed === true) && this.stabilized === false) {
40503 this.physicsTick(); // this makes sure there is no jitter. The decision is taken once to run it at double speed.
40504
40505 this.runDoubleSpeed = true;
40506 }
40507
40508 if (this.stabilized === true) {
40509 this.stopSimulation();
40510 }
40511 }
40512 /**
40513 * trigger the stabilized event.
40514 *
40515 * @param {number} [amountOfIterations=this.stabilizationIterations]
40516 * @private
40517 */
40518
40519 }, {
40520 key: "_emitStabilized",
40521 value: function _emitStabilized() {
40522 var _this2 = this;
40523
40524 var amountOfIterations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.stabilizationIterations;
40525
40526 if (this.stabilizationIterations > 1 || this.startedStabilization === true) {
40527 setTimeout(function () {
40528 _this2.body.emitter.emit('stabilized', {
40529 iterations: amountOfIterations
40530 });
40531
40532 _this2.startedStabilization = false;
40533 _this2.stabilizationIterations = 0;
40534 }, 0);
40535 }
40536 }
40537 /**
40538 * Calculate the forces for one physics iteration and move the nodes.
40539 * @private
40540 */
40541
40542 }, {
40543 key: "physicsStep",
40544 value: function physicsStep() {
40545 this.gravitySolver.solve();
40546 this.nodesSolver.solve();
40547 this.edgesSolver.solve();
40548 this.moveNodes();
40549 }
40550 /**
40551 * Make dynamic adjustments to the timestep, based on current state.
40552 *
40553 * Helper function for physicsTick().
40554 * @private
40555 */
40556
40557 }, {
40558 key: "adjustTimeStep",
40559 value: function adjustTimeStep() {
40560 var factor = 1.2; // Factor for increasing the timestep on success.
40561 // we compare the two steps. if it is acceptable we double the step.
40562
40563 if (this._evaluateStepQuality() === true) {
40564 this.timestep = factor * this.timestep;
40565 } else {
40566 // if not, we decrease the step to a minimum of the options timestep.
40567 // if the decreased timestep is smaller than the options step, we do not reset the counter
40568 // we assume that the options timestep is stable enough.
40569 if (this.timestep / factor < this.options.timestep) {
40570 this.timestep = this.options.timestep;
40571 } else {
40572 // if the timestep was larger than 2 times the option one we check the adaptivity again to ensure
40573 // that large instabilities do not form.
40574 this.adaptiveCounter = -1; // check again next iteration
40575
40576 this.timestep = Math.max(this.options.timestep, this.timestep / factor);
40577 }
40578 }
40579 }
40580 /**
40581 * A single simulation step (or 'tick') in the physics simulation
40582 *
40583 * @private
40584 */
40585
40586 }, {
40587 key: "physicsTick",
40588 value: function physicsTick() {
40589 this._startStabilizing(); // this ensures that there is no start event when the network is already stable.
40590
40591
40592 if (this.stabilized === true) return; // adaptivity means the timestep adapts to the situation, only applicable for stabilization
40593
40594 if (this.adaptiveTimestep === true && this.adaptiveTimestepEnabled === true) {
40595 // timestep remains stable for "interval" iterations.
40596 var doAdaptive = this.adaptiveCounter % this.adaptiveInterval === 0;
40597
40598 if (doAdaptive) {
40599 // first the big step and revert.
40600 this.timestep = 2 * this.timestep;
40601 this.physicsStep();
40602 this.revert(); // saves the reference state
40603 // now the normal step. Since this is the last step, it is the more stable one and we will take this.
40604
40605 this.timestep = 0.5 * this.timestep; // since it's half the step, we do it twice.
40606
40607 this.physicsStep();
40608 this.physicsStep();
40609 this.adjustTimeStep();
40610 } else {
40611 this.physicsStep(); // normal step, keeping timestep constant
40612 }
40613
40614 this.adaptiveCounter += 1;
40615 } else {
40616 // case for the static timestep, we reset it to the one in options and take a normal step.
40617 this.timestep = this.options.timestep;
40618 this.physicsStep();
40619 }
40620
40621 if (this.stabilized === true) this.revert();
40622 this.stabilizationIterations++;
40623 }
40624 /**
40625 * 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.
40626 *
40627 * @private
40628 */
40629
40630 }, {
40631 key: "updatePhysicsData",
40632 value: function updatePhysicsData() {
40633 this.physicsBody.forces = {};
40634 this.physicsBody.physicsNodeIndices = [];
40635 this.physicsBody.physicsEdgeIndices = [];
40636 var nodes = this.body.nodes;
40637 var edges = this.body.edges; // get node indices for physics
40638
40639 for (var nodeId in nodes) {
40640 if (nodes.hasOwnProperty(nodeId)) {
40641 if (nodes[nodeId].options.physics === true) {
40642 this.physicsBody.physicsNodeIndices.push(nodes[nodeId].id);
40643 }
40644 }
40645 } // get edge indices for physics
40646
40647
40648 for (var edgeId in edges) {
40649 if (edges.hasOwnProperty(edgeId)) {
40650 if (edges[edgeId].options.physics === true) {
40651 this.physicsBody.physicsEdgeIndices.push(edges[edgeId].id);
40652 }
40653 }
40654 } // get the velocity and the forces vector
40655
40656
40657 for (var i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) {
40658 var _nodeId = this.physicsBody.physicsNodeIndices[i];
40659 this.physicsBody.forces[_nodeId] = {
40660 x: 0,
40661 y: 0
40662 }; // forces can be reset because they are recalculated. Velocities have to persist.
40663
40664 if (this.physicsBody.velocities[_nodeId] === undefined) {
40665 this.physicsBody.velocities[_nodeId] = {
40666 x: 0,
40667 y: 0
40668 };
40669 }
40670 } // clean deleted nodes from the velocity vector
40671
40672
40673 for (var _nodeId2 in this.physicsBody.velocities) {
40674 if (nodes[_nodeId2] === undefined) {
40675 delete this.physicsBody.velocities[_nodeId2];
40676 }
40677 }
40678 }
40679 /**
40680 * Revert the simulation one step. This is done so after stabilization, every new start of the simulation will also say stabilized.
40681 */
40682
40683 }, {
40684 key: "revert",
40685 value: function revert() {
40686 var nodeIds = Object.keys(this.previousStates);
40687 var nodes = this.body.nodes;
40688 var velocities = this.physicsBody.velocities;
40689 this.referenceState = {};
40690
40691 for (var i = 0; i < nodeIds.length; i++) {
40692 var nodeId = nodeIds[i];
40693
40694 if (nodes[nodeId] !== undefined) {
40695 if (nodes[nodeId].options.physics === true) {
40696 this.referenceState[nodeId] = {
40697 positions: {
40698 x: nodes[nodeId].x,
40699 y: nodes[nodeId].y
40700 }
40701 };
40702 velocities[nodeId].x = this.previousStates[nodeId].vx;
40703 velocities[nodeId].y = this.previousStates[nodeId].vy;
40704 nodes[nodeId].x = this.previousStates[nodeId].x;
40705 nodes[nodeId].y = this.previousStates[nodeId].y;
40706 }
40707 } else {
40708 delete this.previousStates[nodeId];
40709 }
40710 }
40711 }
40712 /**
40713 * This compares the reference state to the current state
40714 *
40715 * @returns {boolean}
40716 * @private
40717 */
40718
40719 }, {
40720 key: "_evaluateStepQuality",
40721 value: function _evaluateStepQuality() {
40722 var dx, dy, dpos;
40723 var nodes = this.body.nodes;
40724 var reference = this.referenceState;
40725 var posThreshold = 0.3;
40726
40727 for (var nodeId in this.referenceState) {
40728 if (this.referenceState.hasOwnProperty(nodeId) && nodes[nodeId] !== undefined) {
40729 dx = nodes[nodeId].x - reference[nodeId].positions.x;
40730 dy = nodes[nodeId].y - reference[nodeId].positions.y;
40731 dpos = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
40732
40733 if (dpos > posThreshold) {
40734 return false;
40735 }
40736 }
40737 }
40738
40739 return true;
40740 }
40741 /**
40742 * move the nodes one timestep and check if they are stabilized
40743 */
40744
40745 }, {
40746 key: "moveNodes",
40747 value: function moveNodes() {
40748 var nodeIndices = this.physicsBody.physicsNodeIndices;
40749 var maxNodeVelocity = 0;
40750 var averageNodeVelocity = 0; // the velocity threshold (energy in the system) for the adaptivity toggle
40751
40752 var velocityAdaptiveThreshold = 5;
40753
40754 for (var i = 0; i < nodeIndices.length; i++) {
40755 var nodeId = nodeIndices[i];
40756
40757 var nodeVelocity = this._performStep(nodeId); // stabilized is true if stabilized is true and velocity is smaller than vmin --> all nodes must be stabilized
40758
40759
40760 maxNodeVelocity = Math.max(maxNodeVelocity, nodeVelocity);
40761 averageNodeVelocity += nodeVelocity;
40762 } // evaluating the stabilized and adaptiveTimestepEnabled conditions
40763
40764
40765 this.adaptiveTimestepEnabled = averageNodeVelocity / nodeIndices.length < velocityAdaptiveThreshold;
40766 this.stabilized = maxNodeVelocity < this.options.minVelocity;
40767 }
40768 /**
40769 * Calculate new velocity for a coordinate direction
40770 *
40771 * @param {number} v velocity for current coordinate
40772 * @param {number} f regular force for current coordinate
40773 * @param {number} m mass of current node
40774 * @returns {number} new velocity for current coordinate
40775 * @private
40776 */
40777
40778 }, {
40779 key: "calculateComponentVelocity",
40780 value: function calculateComponentVelocity(v, f, m) {
40781 var df = this.modelOptions.damping * v; // damping force
40782
40783 var a = (f - df) / m; // acceleration
40784
40785 v += a * this.timestep; // Put a limit on the velocities if it is really high
40786
40787 var maxV = this.options.maxVelocity || 1e9;
40788
40789 if (Math.abs(v) > maxV) {
40790 v = v > 0 ? maxV : -maxV;
40791 }
40792
40793 return v;
40794 }
40795 /**
40796 * Perform the actual step
40797 *
40798 * @param {Node.id} nodeId
40799 * @returns {number} the new velocity of given node
40800 * @private
40801 */
40802
40803 }, {
40804 key: "_performStep",
40805 value: function _performStep(nodeId) {
40806 var node = this.body.nodes[nodeId];
40807 var force = this.physicsBody.forces[nodeId];
40808 var velocity = this.physicsBody.velocities[nodeId]; // store the state so we can revert
40809
40810 this.previousStates[nodeId] = {
40811 x: node.x,
40812 y: node.y,
40813 vx: velocity.x,
40814 vy: velocity.y
40815 };
40816
40817 if (node.options.fixed.x === false) {
40818 velocity.x = this.calculateComponentVelocity(velocity.x, force.x, node.options.mass);
40819 node.x += velocity.x * this.timestep;
40820 } else {
40821 force.x = 0;
40822 velocity.x = 0;
40823 }
40824
40825 if (node.options.fixed.y === false) {
40826 velocity.y = this.calculateComponentVelocity(velocity.y, force.y, node.options.mass);
40827 node.y += velocity.y * this.timestep;
40828 } else {
40829 force.y = 0;
40830 velocity.y = 0;
40831 }
40832
40833 var totalVelocity = Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(velocity.y, 2));
40834 return totalVelocity;
40835 }
40836 /**
40837 * When initializing and stabilizing, we can freeze nodes with a predefined position.
40838 * This greatly speeds up stabilization because only the supportnodes for the smoothCurves have to settle.
40839 *
40840 * @private
40841 */
40842
40843 }, {
40844 key: "_freezeNodes",
40845 value: function _freezeNodes() {
40846 var nodes = this.body.nodes;
40847
40848 for (var id in nodes) {
40849 if (nodes.hasOwnProperty(id)) {
40850 if (nodes[id].x && nodes[id].y) {
40851 var fixed = nodes[id].options.fixed;
40852 this.freezeCache[id] = {
40853 x: fixed.x,
40854 y: fixed.y
40855 };
40856 fixed.x = true;
40857 fixed.y = true;
40858 }
40859 }
40860 }
40861 }
40862 /**
40863 * Unfreezes the nodes that have been frozen by _freezeDefinedNodes.
40864 *
40865 * @private
40866 */
40867
40868 }, {
40869 key: "_restoreFrozenNodes",
40870 value: function _restoreFrozenNodes() {
40871 var nodes = this.body.nodes;
40872
40873 for (var id in nodes) {
40874 if (nodes.hasOwnProperty(id)) {
40875 if (this.freezeCache[id] !== undefined) {
40876 nodes[id].options.fixed.x = this.freezeCache[id].x;
40877 nodes[id].options.fixed.y = this.freezeCache[id].y;
40878 }
40879 }
40880 }
40881
40882 this.freezeCache = {};
40883 }
40884 /**
40885 * Find a stable position for all nodes
40886 *
40887 * @param {number} [iterations=this.options.stabilization.iterations]
40888 */
40889
40890 }, {
40891 key: "stabilize",
40892 value: function stabilize() {
40893 var _this3 = this;
40894
40895 var iterations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.stabilization.iterations;
40896
40897 if (typeof iterations !== 'number') {
40898 iterations = this.options.stabilization.iterations;
40899 console.log('The stabilize method needs a numeric amount of iterations. Switching to default: ', iterations);
40900 }
40901
40902 if (this.physicsBody.physicsNodeIndices.length === 0) {
40903 this.ready = true;
40904 return;
40905 } // enable adaptive timesteps
40906
40907
40908 this.adaptiveTimestep = this.options.adaptiveTimestep; // this sets the width of all nodes initially which could be required for the avoidOverlap
40909
40910 this.body.emitter.emit("_resizeNodes");
40911 this.stopSimulation(); // stop the render loop
40912
40913 this.stabilized = false; // block redraw requests
40914
40915 this.body.emitter.emit('_blockRedraw');
40916 this.targetIterations = iterations; // start the stabilization
40917
40918 if (this.options.stabilization.onlyDynamicEdges === true) {
40919 this._freezeNodes();
40920 }
40921
40922 this.stabilizationIterations = 0;
40923 setTimeout(function () {
40924 return _this3._stabilizationBatch();
40925 }, 0);
40926 }
40927 /**
40928 * If not already stabilizing, start it and emit a start event.
40929 *
40930 * @returns {boolean} true if stabilization started with this call
40931 * @private
40932 */
40933
40934 }, {
40935 key: "_startStabilizing",
40936 value: function _startStabilizing() {
40937 if (this.startedStabilization === true) return false;
40938 this.body.emitter.emit('startStabilizing');
40939 this.startedStabilization = true;
40940 return true;
40941 }
40942 /**
40943 * One batch of stabilization
40944 * @private
40945 */
40946
40947 }, {
40948 key: "_stabilizationBatch",
40949 value: function _stabilizationBatch() {
40950 var _this4 = this;
40951
40952 var running = function running() {
40953 return _this4.stabilized === false && _this4.stabilizationIterations < _this4.targetIterations;
40954 };
40955
40956 var sendProgress = function sendProgress() {
40957 _this4.body.emitter.emit('stabilizationProgress', {
40958 iterations: _this4.stabilizationIterations,
40959 total: _this4.targetIterations
40960 });
40961 };
40962
40963 if (this._startStabilizing()) {
40964 sendProgress(); // Ensure that there is at least one start event.
40965 }
40966
40967 var count = 0;
40968
40969 while (running() && count < this.options.stabilization.updateInterval) {
40970 this.physicsTick();
40971 count++;
40972 }
40973
40974 sendProgress();
40975
40976 if (running()) {
40977 setTimeout(this._stabilizationBatch.bind(this), 0);
40978 } else {
40979 this._finalizeStabilization();
40980 }
40981 }
40982 /**
40983 * Wrap up the stabilization, fit and emit the events.
40984 * @private
40985 */
40986
40987 }, {
40988 key: "_finalizeStabilization",
40989 value: function _finalizeStabilization() {
40990 this.body.emitter.emit('_allowRedraw');
40991
40992 if (this.options.stabilization.fit === true) {
40993 this.body.emitter.emit('fit');
40994 }
40995
40996 if (this.options.stabilization.onlyDynamicEdges === true) {
40997 this._restoreFrozenNodes();
40998 }
40999
41000 this.body.emitter.emit('stabilizationIterationsDone');
41001 this.body.emitter.emit('_requestRedraw');
41002
41003 if (this.stabilized === true) {
41004 this._emitStabilized();
41005 } else {
41006 this.startSimulation();
41007 }
41008
41009 this.ready = true;
41010 } //--------------------------- DEBUGGING BELOW ---------------------------//
41011
41012 /**
41013 * Debug function that display arrows for the forces currently active in the network.
41014 *
41015 * Use this when debugging only.
41016 *
41017 * @param {CanvasRenderingContext2D} ctx
41018 * @private
41019 */
41020
41021 }, {
41022 key: "_drawForces",
41023 value: function _drawForces(ctx) {
41024 for (var i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) {
41025 var index = this.physicsBody.physicsNodeIndices[i];
41026 var node = this.body.nodes[index];
41027 var force = this.physicsBody.forces[index];
41028 var factor = 20;
41029 var colorFactor = 0.03;
41030 var forceSize = Math.sqrt(Math.pow(force.x, 2) + Math.pow(force.x, 2));
41031 var size = Math.min(Math.max(5, forceSize), 15);
41032 var arrowSize = 3 * size;
41033 var color = HSVToHex((180 - Math.min(1, Math.max(0, colorFactor * forceSize)) * 180) / 360, 1, 1);
41034 var point = {
41035 x: node.x + factor * force.x,
41036 y: node.y + factor * force.y
41037 };
41038 ctx.lineWidth = size;
41039 ctx.strokeStyle = color;
41040 ctx.beginPath();
41041 ctx.moveTo(node.x, node.y);
41042 ctx.lineTo(point.x, point.y);
41043 ctx.stroke();
41044 var angle = Math.atan2(force.y, force.x);
41045 ctx.fillStyle = color;
41046 EndPoints.draw(ctx, {
41047 type: 'arrow',
41048 point: point,
41049 angle: angle,
41050 length: arrowSize
41051 });
41052 ctx.fill();
41053 }
41054 }
41055 }]);
41056
41057 return PhysicsEngine;
41058 }();
41059
41060 /**
41061 * Utility Class
41062 */
41063
41064 var NetworkUtil =
41065 /*#__PURE__*/
41066 function () {
41067 /**
41068 * @ignore
41069 */
41070 function NetworkUtil() {
41071 _classCallCheck(this, NetworkUtil);
41072 }
41073 /**
41074 * Find the center position of the network considering the bounding boxes
41075 *
41076 * @param {Array.<Node>} allNodes
41077 * @param {Array.<Node>} [specificNodes=[]]
41078 * @returns {{minX: number, maxX: number, minY: number, maxY: number}}
41079 * @static
41080 */
41081
41082
41083 _createClass(NetworkUtil, null, [{
41084 key: "getRange",
41085 value: function getRange(allNodes) {
41086 var specificNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
41087 var minY = 1e9,
41088 maxY = -1e9,
41089 minX = 1e9,
41090 maxX = -1e9,
41091 node;
41092
41093 if (specificNodes.length > 0) {
41094 for (var i = 0; i < specificNodes.length; i++) {
41095 node = allNodes[specificNodes[i]];
41096
41097 if (minX > node.shape.boundingBox.left) {
41098 minX = node.shape.boundingBox.left;
41099 }
41100
41101 if (maxX < node.shape.boundingBox.right) {
41102 maxX = node.shape.boundingBox.right;
41103 }
41104
41105 if (minY > node.shape.boundingBox.top) {
41106 minY = node.shape.boundingBox.top;
41107 } // top is negative, bottom is positive
41108
41109
41110 if (maxY < node.shape.boundingBox.bottom) {
41111 maxY = node.shape.boundingBox.bottom;
41112 } // top is negative, bottom is positive
41113
41114 }
41115 }
41116
41117 if (minX === 1e9 && maxX === -1e9 && minY === 1e9 && maxY === -1e9) {
41118 minY = 0, maxY = 0, minX = 0, maxX = 0;
41119 }
41120
41121 return {
41122 minX: minX,
41123 maxX: maxX,
41124 minY: minY,
41125 maxY: maxY
41126 };
41127 }
41128 /**
41129 * Find the center position of the network
41130 *
41131 * @param {Array.<Node>} allNodes
41132 * @param {Array.<Node>} [specificNodes=[]]
41133 * @returns {{minX: number, maxX: number, minY: number, maxY: number}}
41134 * @static
41135 */
41136
41137 }, {
41138 key: "getRangeCore",
41139 value: function getRangeCore(allNodes) {
41140 var specificNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
41141 var minY = 1e9,
41142 maxY = -1e9,
41143 minX = 1e9,
41144 maxX = -1e9,
41145 node;
41146
41147 if (specificNodes.length > 0) {
41148 for (var i = 0; i < specificNodes.length; i++) {
41149 node = allNodes[specificNodes[i]];
41150
41151 if (minX > node.x) {
41152 minX = node.x;
41153 }
41154
41155 if (maxX < node.x) {
41156 maxX = node.x;
41157 }
41158
41159 if (minY > node.y) {
41160 minY = node.y;
41161 } // top is negative, bottom is positive
41162
41163
41164 if (maxY < node.y) {
41165 maxY = node.y;
41166 } // top is negative, bottom is positive
41167
41168 }
41169 }
41170
41171 if (minX === 1e9 && maxX === -1e9 && minY === 1e9 && maxY === -1e9) {
41172 minY = 0, maxY = 0, minX = 0, maxX = 0;
41173 }
41174
41175 return {
41176 minX: minX,
41177 maxX: maxX,
41178 minY: minY,
41179 maxY: maxY
41180 };
41181 }
41182 /**
41183 * @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY};
41184 * @returns {{x: number, y: number}}
41185 * @static
41186 */
41187
41188 }, {
41189 key: "findCenter",
41190 value: function findCenter(range) {
41191 return {
41192 x: 0.5 * (range.maxX + range.minX),
41193 y: 0.5 * (range.maxY + range.minY)
41194 };
41195 }
41196 /**
41197 * 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.
41198 * @param {vis.Item} item
41199 * @param {'node'|undefined} type
41200 * @returns {{}}
41201 * @static
41202 */
41203
41204 }, {
41205 key: "cloneOptions",
41206 value: function cloneOptions(item, type) {
41207 var clonedOptions = {};
41208
41209 if (type === undefined || type === 'node') {
41210 deepExtend(clonedOptions, item.options, true);
41211 clonedOptions.x = item.x;
41212 clonedOptions.y = item.y;
41213 clonedOptions.amountOfConnections = item.edges.length;
41214 } else {
41215 deepExtend(clonedOptions, item.options, true);
41216 }
41217
41218 return clonedOptions;
41219 }
41220 }]);
41221
41222 return NetworkUtil;
41223 }();
41224
41225 /**
41226 * A Cluster is a special Node that allows a group of Nodes positioned closely together
41227 * to be represented by a single Cluster Node.
41228 *
41229 * @extends Node
41230 */
41231
41232 var Cluster =
41233 /*#__PURE__*/
41234 function (_Node) {
41235 _inherits(Cluster, _Node);
41236
41237 /**
41238 * @param {Object} options
41239 * @param {Object} body
41240 * @param {Array.<HTMLImageElement>}imagelist
41241 * @param {Array} grouplist
41242 * @param {Object} globalOptions
41243 * @param {Object} defaultOptions Global default options for nodes
41244 */
41245 function Cluster(options, body, imagelist, grouplist, globalOptions, defaultOptions) {
41246 var _this;
41247
41248 _classCallCheck(this, Cluster);
41249
41250 _this = _possibleConstructorReturn(this, _getPrototypeOf(Cluster).call(this, options, body, imagelist, grouplist, globalOptions, defaultOptions));
41251 _this.isCluster = true;
41252 _this.containedNodes = {};
41253 _this.containedEdges = {};
41254 return _this;
41255 }
41256 /**
41257 * Transfer child cluster data to current and disconnect the child cluster.
41258 *
41259 * Please consult the header comment in 'Clustering.js' for the fields set here.
41260 *
41261 * @param {string|number} childClusterId id of child cluster to open
41262 */
41263
41264
41265 _createClass(Cluster, [{
41266 key: "_openChildCluster",
41267 value: function _openChildCluster(childClusterId) {
41268 var _this2 = this;
41269
41270 var childCluster = this.body.nodes[childClusterId];
41271
41272 if (this.containedNodes[childClusterId] === undefined) {
41273 throw new Error('node with id: ' + childClusterId + ' not in current cluster');
41274 }
41275
41276 if (!childCluster.isCluster) {
41277 throw new Error('node with id: ' + childClusterId + ' is not a cluster');
41278 } // Disconnect child cluster from current cluster
41279
41280
41281 delete this.containedNodes[childClusterId];
41282 forEach(childCluster.edges, function (edge) {
41283 delete _this2.containedEdges[edge.id];
41284 }); // Transfer nodes and edges
41285
41286 forEach(childCluster.containedNodes, function (node, nodeId) {
41287 _this2.containedNodes[nodeId] = node;
41288 });
41289 childCluster.containedNodes = {};
41290 forEach(childCluster.containedEdges, function (edge, edgeId) {
41291 _this2.containedEdges[edgeId] = edge;
41292 });
41293 childCluster.containedEdges = {}; // Transfer edges within cluster edges which are clustered
41294
41295 forEach(childCluster.edges, function (clusterEdge) {
41296 forEach(_this2.edges, function (parentClusterEdge) {
41297 // Assumption: a clustered edge can only be present in a single clustering edge
41298 // Not tested here
41299 var index = parentClusterEdge.clusteringEdgeReplacingIds.indexOf(clusterEdge.id);
41300 if (index === -1) return;
41301 forEach(clusterEdge.clusteringEdgeReplacingIds, function (srcId) {
41302 parentClusterEdge.clusteringEdgeReplacingIds.push(srcId); // Maintain correct bookkeeping for transferred edge
41303
41304 _this2.body.edges[srcId].edgeReplacedById = parentClusterEdge.id;
41305 }); // Remove cluster edge from parent cluster edge
41306
41307 parentClusterEdge.clusteringEdgeReplacingIds.splice(index, 1);
41308 });
41309 });
41310 childCluster.edges = [];
41311 }
41312 }]);
41313
41314 return Cluster;
41315 }(Node);
41316
41317 /**
41318 * The clustering engine
41319 */
41320
41321 var ClusterEngine =
41322 /*#__PURE__*/
41323 function () {
41324 /**
41325 * @param {Object} body
41326 */
41327 function ClusterEngine(body) {
41328 var _this = this;
41329
41330 _classCallCheck(this, ClusterEngine);
41331
41332 this.body = body;
41333 this.clusteredNodes = {}; // key: node id, value: { clusterId: <id of cluster>, node: <node instance>}
41334
41335 this.clusteredEdges = {}; // key: edge id, value: restore information for given edge
41336
41337 this.options = {};
41338 this.defaultOptions = {};
41339 extend(this.options, this.defaultOptions);
41340 this.body.emitter.on('_resetData', function () {
41341 _this.clusteredNodes = {};
41342 _this.clusteredEdges = {};
41343 });
41344 }
41345 /**
41346 *
41347 * @param {number} hubsize
41348 * @param {Object} options
41349 */
41350
41351
41352 _createClass(ClusterEngine, [{
41353 key: "clusterByHubsize",
41354 value: function clusterByHubsize(hubsize, options) {
41355 if (hubsize === undefined) {
41356 hubsize = this._getHubSize();
41357 } else if (_typeof(hubsize) === "object") {
41358 options = this._checkOptions(hubsize);
41359 hubsize = this._getHubSize();
41360 }
41361
41362 var nodesToCluster = [];
41363
41364 for (var i = 0; i < this.body.nodeIndices.length; i++) {
41365 var node = this.body.nodes[this.body.nodeIndices[i]];
41366
41367 if (node.edges.length >= hubsize) {
41368 nodesToCluster.push(node.id);
41369 }
41370 }
41371
41372 for (var _i = 0; _i < nodesToCluster.length; _i++) {
41373 this.clusterByConnection(nodesToCluster[_i], options, true);
41374 }
41375
41376 this.body.emitter.emit('_dataChanged');
41377 }
41378 /**
41379 * loop over all nodes, check if they adhere to the condition and cluster if needed.
41380 * @param {Object} options
41381 * @param {boolean} [refreshData=true]
41382 */
41383
41384 }, {
41385 key: "cluster",
41386 value: function cluster() {
41387 var _this2 = this;
41388
41389 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
41390 var refreshData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
41391
41392 if (options.joinCondition === undefined) {
41393 throw new Error("Cannot call clusterByNodeData without a joinCondition function in the options.");
41394 } // check if the options object is fine, append if needed
41395
41396
41397 options = this._checkOptions(options);
41398 var childNodesObj = {};
41399 var childEdgesObj = {}; // collect the nodes that will be in the cluster
41400
41401 forEach(this.body.nodes, function (node, nodeId) {
41402 if (node.options && options.joinCondition(node.options) === true) {
41403 childNodesObj[nodeId] = node; // collect the edges that will be in the cluster
41404
41405 forEach(node.edges, function (edge) {
41406 if (_this2.clusteredEdges[edge.id] === undefined) {
41407 childEdgesObj[edge.id] = edge;
41408 }
41409 });
41410 }
41411 });
41412
41413 this._cluster(childNodesObj, childEdgesObj, options, refreshData);
41414 }
41415 /**
41416 * Cluster all nodes in the network that have only X edges
41417 * @param {number} edgeCount
41418 * @param {Object} options
41419 * @param {boolean} [refreshData=true]
41420 */
41421
41422 }, {
41423 key: "clusterByEdgeCount",
41424 value: function clusterByEdgeCount(edgeCount, options) {
41425 var _this3 = this;
41426
41427 var refreshData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
41428 options = this._checkOptions(options);
41429 var clusters = [];
41430 var usedNodes = {};
41431 var edge, edges, relevantEdgeCount; // collect the nodes that will be in the cluster
41432
41433 var _loop = function _loop(i) {
41434 var childNodesObj = {};
41435 var childEdgesObj = {};
41436 var nodeId = _this3.body.nodeIndices[i];
41437 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.
41438
41439 if (usedNodes[nodeId] === undefined) {
41440 relevantEdgeCount = 0;
41441 edges = [];
41442
41443 for (var j = 0; j < node.edges.length; j++) {
41444 edge = node.edges[j];
41445
41446 if (_this3.clusteredEdges[edge.id] === undefined) {
41447 if (edge.toId !== edge.fromId) {
41448 relevantEdgeCount++;
41449 }
41450
41451 edges.push(edge);
41452 }
41453 } // this node qualifies, we collect its neighbours to start the clustering process.
41454
41455
41456 if (relevantEdgeCount === edgeCount) {
41457 checkJoinCondition = function checkJoinCondition(node) {
41458 if (options.joinCondition === undefined || options.joinCondition === null) {
41459 return true;
41460 }
41461
41462 var clonedOptions = NetworkUtil.cloneOptions(node);
41463 return options.joinCondition(clonedOptions);
41464 };
41465
41466 var gatheringSuccessful = true;
41467
41468 for (var _j = 0; _j < edges.length; _j++) {
41469 edge = edges[_j];
41470
41471 var childNodeId = _this3._getConnectedId(edge, nodeId); // add the nodes to the list by the join condition.
41472
41473
41474 if (checkJoinCondition(node)) {
41475 childEdgesObj[edge.id] = edge;
41476 childNodesObj[nodeId] = node;
41477 childNodesObj[childNodeId] = _this3.body.nodes[childNodeId];
41478 usedNodes[nodeId] = true;
41479 } else {
41480 // this node does not qualify after all.
41481 gatheringSuccessful = false;
41482 break;
41483 }
41484 } // add to the cluster queue
41485
41486
41487 if (Object.keys(childNodesObj).length > 0 && Object.keys(childEdgesObj).length > 0 && gatheringSuccessful === true) {
41488 /**
41489 * Search for cluster data that contains any of the node id's
41490 * @returns {Boolean} true if no joinCondition, otherwise return value of joinCondition
41491 */
41492 findClusterData = function findClusterData() {
41493 for (var n = 0; n < clusters.length; ++n) {
41494 // Search for a cluster containing any of the node id's
41495 for (var m in childNodesObj) {
41496 if (clusters[n].nodes[m] !== undefined) {
41497 return clusters[n];
41498 }
41499 }
41500 }
41501
41502 return undefined;
41503 }; // If any of the found nodes is part of a cluster found in this method,
41504 // add the current values to that cluster
41505
41506
41507 foundCluster = findClusterData();
41508
41509 if (foundCluster !== undefined) {
41510 // Add nodes to found cluster if not present
41511 for (var m in childNodesObj) {
41512 if (foundCluster.nodes[m] === undefined) {
41513 foundCluster.nodes[m] = childNodesObj[m];
41514 }
41515 } // Add edges to found cluster, if not present
41516
41517
41518 for (var _m in childEdgesObj) {
41519 if (foundCluster.edges[_m] === undefined) {
41520 foundCluster.edges[_m] = childEdgesObj[_m];
41521 }
41522 }
41523 } else {
41524 // Create a new cluster group
41525 clusters.push({
41526 nodes: childNodesObj,
41527 edges: childEdgesObj
41528 });
41529 }
41530 }
41531 }
41532 }
41533 };
41534
41535 for (var i = 0; i < this.body.nodeIndices.length; i++) {
41536 var checkJoinCondition;
41537 var findClusterData;
41538 var foundCluster;
41539
41540 _loop(i);
41541 }
41542
41543 for (var _i2 = 0; _i2 < clusters.length; _i2++) {
41544 this._cluster(clusters[_i2].nodes, clusters[_i2].edges, options, false);
41545 }
41546
41547 if (refreshData === true) {
41548 this.body.emitter.emit('_dataChanged');
41549 }
41550 }
41551 /**
41552 * Cluster all nodes in the network that have only 1 edge
41553 * @param {Object} options
41554 * @param {boolean} [refreshData=true]
41555 */
41556
41557 }, {
41558 key: "clusterOutliers",
41559 value: function clusterOutliers(options) {
41560 var refreshData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
41561 this.clusterByEdgeCount(1, options, refreshData);
41562 }
41563 /**
41564 * Cluster all nodes in the network that have only 2 edge
41565 * @param {Object} options
41566 * @param {boolean} [refreshData=true]
41567 */
41568
41569 }, {
41570 key: "clusterBridges",
41571 value: function clusterBridges(options) {
41572 var refreshData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
41573 this.clusterByEdgeCount(2, options, refreshData);
41574 }
41575 /**
41576 * suck all connected nodes of a node into the node.
41577 * @param {Node.id} nodeId
41578 * @param {Object} options
41579 * @param {boolean} [refreshData=true]
41580 */
41581
41582 }, {
41583 key: "clusterByConnection",
41584 value: function clusterByConnection(nodeId, options) {
41585 var refreshData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
41586
41587 // kill conditions
41588 if (nodeId === undefined) {
41589 throw new Error("No nodeId supplied to clusterByConnection!");
41590 }
41591
41592 if (this.body.nodes[nodeId] === undefined) {
41593 throw new Error("The nodeId given to clusterByConnection does not exist!");
41594 }
41595
41596 var node = this.body.nodes[nodeId];
41597 options = this._checkOptions(options, node);
41598
41599 if (options.clusterNodeProperties.x === undefined) {
41600 options.clusterNodeProperties.x = node.x;
41601 }
41602
41603 if (options.clusterNodeProperties.y === undefined) {
41604 options.clusterNodeProperties.y = node.y;
41605 }
41606
41607 if (options.clusterNodeProperties.fixed === undefined) {
41608 options.clusterNodeProperties.fixed = {};
41609 options.clusterNodeProperties.fixed.x = node.options.fixed.x;
41610 options.clusterNodeProperties.fixed.y = node.options.fixed.y;
41611 }
41612
41613 var childNodesObj = {};
41614 var childEdgesObj = {};
41615 var parentNodeId = node.id;
41616 var parentClonedOptions = NetworkUtil.cloneOptions(node);
41617 childNodesObj[parentNodeId] = node; // collect the nodes that will be in the cluster
41618
41619 for (var i = 0; i < node.edges.length; i++) {
41620 var edge = node.edges[i];
41621
41622 if (this.clusteredEdges[edge.id] === undefined) {
41623 var childNodeId = this._getConnectedId(edge, parentNodeId); // if the child node is not in a cluster
41624
41625
41626 if (this.clusteredNodes[childNodeId] === undefined) {
41627 if (childNodeId !== parentNodeId) {
41628 if (options.joinCondition === undefined) {
41629 childEdgesObj[edge.id] = edge;
41630 childNodesObj[childNodeId] = this.body.nodes[childNodeId];
41631 } else {
41632 // clone the options and insert some additional parameters that could be interesting.
41633 var childClonedOptions = NetworkUtil.cloneOptions(this.body.nodes[childNodeId]);
41634
41635 if (options.joinCondition(parentClonedOptions, childClonedOptions) === true) {
41636 childEdgesObj[edge.id] = edge;
41637 childNodesObj[childNodeId] = this.body.nodes[childNodeId];
41638 }
41639 }
41640 } else {
41641 // swallow the edge if it is self-referencing.
41642 childEdgesObj[edge.id] = edge;
41643 }
41644 }
41645 }
41646 }
41647
41648 var childNodeIDs = Object.keys(childNodesObj).map(function (childNode) {
41649 return childNodesObj[childNode].id;
41650 });
41651
41652 for (childNode in childNodesObj) {
41653 if (!childNodesObj.hasOwnProperty(childNode)) continue;
41654 var childNode = childNodesObj[childNode];
41655
41656 for (var y = 0; y < childNode.edges.length; y++) {
41657 var childEdge = childNode.edges[y];
41658
41659 if (childNodeIDs.indexOf(this._getConnectedId(childEdge, childNode.id)) > -1) {
41660 childEdgesObj[childEdge.id] = childEdge;
41661 }
41662 }
41663 }
41664
41665 this._cluster(childNodesObj, childEdgesObj, options, refreshData);
41666 }
41667 /**
41668 * This function creates the edges that will be attached to the cluster
41669 * It looks for edges that are connected to the nodes from the "outside' of the cluster.
41670 *
41671 * @param {{Node.id: vis.Node}} childNodesObj
41672 * @param {{vis.Edge.id: vis.Edge}} childEdgesObj
41673 * @param {Object} clusterNodeProperties
41674 * @param {Object} clusterEdgeProperties
41675 * @private
41676 */
41677
41678 }, {
41679 key: "_createClusterEdges",
41680 value: function _createClusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, clusterEdgeProperties) {
41681 var edge, childNodeId, childNode, toId, fromId, otherNodeId; // loop over all child nodes and their edges to find edges going out of the cluster
41682 // these edges will be replaced by clusterEdges.
41683
41684 var childKeys = Object.keys(childNodesObj);
41685 var createEdges = [];
41686
41687 for (var i = 0; i < childKeys.length; i++) {
41688 childNodeId = childKeys[i];
41689 childNode = childNodesObj[childNodeId]; // construct new edges from the cluster to others
41690
41691 for (var j = 0; j < childNode.edges.length; j++) {
41692 edge = childNode.edges[j]; // we only handle edges that are visible to the system, not the disabled ones from the clustering process.
41693
41694 if (this.clusteredEdges[edge.id] === undefined) {
41695 // self-referencing edges will be added to the "hidden" list
41696 if (edge.toId == edge.fromId) {
41697 childEdgesObj[edge.id] = edge;
41698 } else {
41699 // set up the from and to.
41700 if (edge.toId == childNodeId) {
41701 // this is a double equals because ints and strings can be interchanged here.
41702 toId = clusterNodeProperties.id;
41703 fromId = edge.fromId;
41704 otherNodeId = fromId;
41705 } else {
41706 toId = edge.toId;
41707 fromId = clusterNodeProperties.id;
41708 otherNodeId = toId;
41709 }
41710 } // Only edges from the cluster outwards are being replaced.
41711
41712
41713 if (childNodesObj[otherNodeId] === undefined) {
41714 createEdges.push({
41715 edge: edge,
41716 fromId: fromId,
41717 toId: toId
41718 });
41719 }
41720 }
41721 }
41722 } //
41723 // Here we actually create the replacement edges.
41724 //
41725 // We could not do this in the loop above as the creation process
41726 // would add an edge to the edges array we are iterating over.
41727 //
41728 // NOTE: a clustered edge can have multiple base edges!
41729 //
41730
41731
41732 var newEdges = [];
41733 /**
41734 * Find a cluster edge which matches the given created edge.
41735 * @param {vis.Edge} createdEdge
41736 * @returns {vis.Edge}
41737 */
41738
41739 var getNewEdge = function getNewEdge(createdEdge) {
41740 for (var _j2 = 0; _j2 < newEdges.length; _j2++) {
41741 var newEdge = newEdges[_j2]; // We replace both to and from edges with a single cluster edge
41742
41743 var matchToDirection = createdEdge.fromId === newEdge.fromId && createdEdge.toId === newEdge.toId;
41744 var matchFromDirection = createdEdge.fromId === newEdge.toId && createdEdge.toId === newEdge.fromId;
41745
41746 if (matchToDirection || matchFromDirection) {
41747 return newEdge;
41748 }
41749 }
41750
41751 return null;
41752 };
41753
41754 for (var _j3 = 0; _j3 < createEdges.length; _j3++) {
41755 var createdEdge = createEdges[_j3];
41756 var _edge = createdEdge.edge;
41757 var newEdge = getNewEdge(createdEdge);
41758
41759 if (newEdge === null) {
41760 // Create a clustered edge for this connection
41761 newEdge = this._createClusteredEdge(createdEdge.fromId, createdEdge.toId, _edge, clusterEdgeProperties);
41762 newEdges.push(newEdge);
41763 } else {
41764 newEdge.clusteringEdgeReplacingIds.push(_edge.id);
41765 } // also reference the new edge in the old edge
41766
41767
41768 this.body.edges[_edge.id].edgeReplacedById = newEdge.id; // hide the replaced edge
41769
41770 this._backupEdgeOptions(_edge);
41771
41772 _edge.setOptions({
41773 physics: false
41774 });
41775 }
41776 }
41777 /**
41778 * This function checks the options that can be supplied to the different cluster functions
41779 * for certain fields and inserts defaults if needed
41780 * @param {Object} options
41781 * @returns {*}
41782 * @private
41783 */
41784
41785 }, {
41786 key: "_checkOptions",
41787 value: function _checkOptions() {
41788 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
41789
41790 if (options.clusterEdgeProperties === undefined) {
41791 options.clusterEdgeProperties = {};
41792 }
41793
41794 if (options.clusterNodeProperties === undefined) {
41795 options.clusterNodeProperties = {};
41796 }
41797
41798 return options;
41799 }
41800 /**
41801 *
41802 * @param {Object} childNodesObj | object with node objects, id as keys, same as childNodes except it also contains a source node
41803 * @param {Object} childEdgesObj | object with edge objects, id as keys
41804 * @param {Array} options | object with {clusterNodeProperties, clusterEdgeProperties, processProperties}
41805 * @param {boolean} refreshData | when true, do not wrap up
41806 * @private
41807 */
41808
41809 }, {
41810 key: "_cluster",
41811 value: function _cluster(childNodesObj, childEdgesObj, options) {
41812 var refreshData = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
41813 // Remove nodes which are already clustered
41814 var tmpNodesToRemove = [];
41815
41816 for (var nodeId in childNodesObj) {
41817 if (childNodesObj.hasOwnProperty(nodeId)) {
41818 if (this.clusteredNodes[nodeId] !== undefined) {
41819 tmpNodesToRemove.push(nodeId);
41820 }
41821 }
41822 }
41823
41824 for (var n = 0; n < tmpNodesToRemove.length; ++n) {
41825 delete childNodesObj[tmpNodesToRemove[n]];
41826 } // kill condition: no nodes don't bother
41827
41828
41829 if (Object.keys(childNodesObj).length == 0) {
41830 return;
41831 } // allow clusters of 1 if options allow
41832
41833
41834 if (Object.keys(childNodesObj).length == 1 && options.clusterNodeProperties.allowSingleNodeCluster != true) {
41835 return;
41836 }
41837
41838 var clusterNodeProperties = deepExtend({}, options.clusterNodeProperties); // construct the clusterNodeProperties
41839
41840 if (options.processProperties !== undefined) {
41841 // get the childNode options
41842 var childNodesOptions = [];
41843
41844 for (var _nodeId in childNodesObj) {
41845 if (childNodesObj.hasOwnProperty(_nodeId)) {
41846 var clonedOptions = NetworkUtil.cloneOptions(childNodesObj[_nodeId]);
41847 childNodesOptions.push(clonedOptions);
41848 }
41849 } // get cluster properties based on childNodes
41850
41851
41852 var childEdgesOptions = [];
41853
41854 for (var edgeId in childEdgesObj) {
41855 if (childEdgesObj.hasOwnProperty(edgeId)) {
41856 // these cluster edges will be removed on creation of the cluster.
41857 if (edgeId.substr(0, 12) !== "clusterEdge:") {
41858 var _clonedOptions = NetworkUtil.cloneOptions(childEdgesObj[edgeId], 'edge');
41859
41860 childEdgesOptions.push(_clonedOptions);
41861 }
41862 }
41863 }
41864
41865 clusterNodeProperties = options.processProperties(clusterNodeProperties, childNodesOptions, childEdgesOptions);
41866
41867 if (!clusterNodeProperties) {
41868 throw new Error("The processProperties function does not return properties!");
41869 }
41870 } // check if we have an unique id;
41871
41872
41873 if (clusterNodeProperties.id === undefined) {
41874 clusterNodeProperties.id = 'cluster:' + uuid4();
41875 }
41876
41877 var clusterId = clusterNodeProperties.id;
41878
41879 if (clusterNodeProperties.label === undefined) {
41880 clusterNodeProperties.label = 'cluster';
41881 } // give the clusterNode a position if it does not have one.
41882
41883
41884 var pos = undefined;
41885
41886 if (clusterNodeProperties.x === undefined) {
41887 pos = this._getClusterPosition(childNodesObj);
41888 clusterNodeProperties.x = pos.x;
41889 }
41890
41891 if (clusterNodeProperties.y === undefined) {
41892 if (pos === undefined) {
41893 pos = this._getClusterPosition(childNodesObj);
41894 }
41895
41896 clusterNodeProperties.y = pos.y;
41897 } // force the ID to remain the same
41898
41899
41900 clusterNodeProperties.id = clusterId; // create the cluster Node
41901 // Note that allowSingleNodeCluster, if present, is stored in the options as well
41902
41903 var clusterNode = this.body.functions.createNode(clusterNodeProperties, Cluster);
41904 clusterNode.containedNodes = childNodesObj;
41905 clusterNode.containedEdges = childEdgesObj; // cache a copy from the cluster edge properties if we have to reconnect others later on
41906
41907 clusterNode.clusterEdgeProperties = options.clusterEdgeProperties; // finally put the cluster node into global
41908
41909 this.body.nodes[clusterNodeProperties.id] = clusterNode;
41910
41911 this._clusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, options.clusterEdgeProperties); // set ID to undefined so no duplicates arise
41912
41913
41914 clusterNodeProperties.id = undefined; // wrap up
41915
41916 if (refreshData === true) {
41917 this.body.emitter.emit('_dataChanged');
41918 }
41919 }
41920 /**
41921 *
41922 * @param {Edge} edge
41923 * @private
41924 */
41925
41926 }, {
41927 key: "_backupEdgeOptions",
41928 value: function _backupEdgeOptions(edge) {
41929 if (this.clusteredEdges[edge.id] === undefined) {
41930 this.clusteredEdges[edge.id] = {
41931 physics: edge.options.physics
41932 };
41933 }
41934 }
41935 /**
41936 *
41937 * @param {Edge} edge
41938 * @private
41939 */
41940
41941 }, {
41942 key: "_restoreEdge",
41943 value: function _restoreEdge(edge) {
41944 var originalOptions = this.clusteredEdges[edge.id];
41945
41946 if (originalOptions !== undefined) {
41947 edge.setOptions({
41948 physics: originalOptions.physics
41949 });
41950 delete this.clusteredEdges[edge.id];
41951 }
41952 }
41953 /**
41954 * Check if a node is a cluster.
41955 * @param {Node.id} nodeId
41956 * @returns {*}
41957 */
41958
41959 }, {
41960 key: "isCluster",
41961 value: function isCluster(nodeId) {
41962 if (this.body.nodes[nodeId] !== undefined) {
41963 return this.body.nodes[nodeId].isCluster === true;
41964 } else {
41965 console.log("Node does not exist.");
41966 return false;
41967 }
41968 }
41969 /**
41970 * get the position of the cluster node based on what's inside
41971 * @param {object} childNodesObj | object with node objects, id as keys
41972 * @returns {{x: number, y: number}}
41973 * @private
41974 */
41975
41976 }, {
41977 key: "_getClusterPosition",
41978 value: function _getClusterPosition(childNodesObj) {
41979 var childKeys = Object.keys(childNodesObj);
41980 var minX = childNodesObj[childKeys[0]].x;
41981 var maxX = childNodesObj[childKeys[0]].x;
41982 var minY = childNodesObj[childKeys[0]].y;
41983 var maxY = childNodesObj[childKeys[0]].y;
41984 var node;
41985
41986 for (var i = 1; i < childKeys.length; i++) {
41987 node = childNodesObj[childKeys[i]];
41988 minX = node.x < minX ? node.x : minX;
41989 maxX = node.x > maxX ? node.x : maxX;
41990 minY = node.y < minY ? node.y : minY;
41991 maxY = node.y > maxY ? node.y : maxY;
41992 }
41993
41994 return {
41995 x: 0.5 * (minX + maxX),
41996 y: 0.5 * (minY + maxY)
41997 };
41998 }
41999 /**
42000 * Open a cluster by calling this function.
42001 * @param {vis.Edge.id} clusterNodeId | the ID of the cluster node
42002 * @param {Object} options
42003 * @param {boolean} refreshData | wrap up afterwards if not true
42004 */
42005
42006 }, {
42007 key: "openCluster",
42008 value: function openCluster(clusterNodeId, options) {
42009 var refreshData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
42010
42011 // kill conditions
42012 if (clusterNodeId === undefined) {
42013 throw new Error("No clusterNodeId supplied to openCluster.");
42014 }
42015
42016 var clusterNode = this.body.nodes[clusterNodeId];
42017
42018 if (clusterNode === undefined) {
42019 throw new Error("The clusterNodeId supplied to openCluster does not exist.");
42020 }
42021
42022 if (clusterNode.isCluster !== true || clusterNode.containedNodes === undefined || clusterNode.containedEdges === undefined) {
42023 throw new Error("The node:" + clusterNodeId + " is not a valid cluster.");
42024 } // Check if current cluster is clustered itself
42025
42026
42027 var stack = this.findNode(clusterNodeId);
42028 var parentIndex = stack.indexOf(clusterNodeId) - 1;
42029
42030 if (parentIndex >= 0) {
42031 // Current cluster is clustered; transfer contained nodes and edges to parent
42032 var parentClusterNodeId = stack[parentIndex];
42033 var parentClusterNode = this.body.nodes[parentClusterNodeId]; // clustering.clusteredNodes and clustering.clusteredEdges remain unchanged
42034
42035 parentClusterNode._openChildCluster(clusterNodeId); // All components of child cluster node have been transferred. It can die now.
42036
42037
42038 delete this.body.nodes[clusterNodeId];
42039
42040 if (refreshData === true) {
42041 this.body.emitter.emit('_dataChanged');
42042 }
42043
42044 return;
42045 } // main body
42046
42047
42048 var containedNodes = clusterNode.containedNodes;
42049 var containedEdges = clusterNode.containedEdges; // allow the user to position the nodes after release.
42050
42051 if (options !== undefined && options.releaseFunction !== undefined && typeof options.releaseFunction === 'function') {
42052 var positions = {};
42053 var clusterPosition = {
42054 x: clusterNode.x,
42055 y: clusterNode.y
42056 };
42057
42058 for (var nodeId in containedNodes) {
42059 if (containedNodes.hasOwnProperty(nodeId)) {
42060 var containedNode = this.body.nodes[nodeId];
42061 positions[nodeId] = {
42062 x: containedNode.x,
42063 y: containedNode.y
42064 };
42065 }
42066 }
42067
42068 var newPositions = options.releaseFunction(clusterPosition, positions);
42069
42070 for (var _nodeId2 in containedNodes) {
42071 if (containedNodes.hasOwnProperty(_nodeId2)) {
42072 var _containedNode = this.body.nodes[_nodeId2];
42073
42074 if (newPositions[_nodeId2] !== undefined) {
42075 _containedNode.x = newPositions[_nodeId2].x === undefined ? clusterNode.x : newPositions[_nodeId2].x;
42076 _containedNode.y = newPositions[_nodeId2].y === undefined ? clusterNode.y : newPositions[_nodeId2].y;
42077 }
42078 }
42079 }
42080 } else {
42081 // copy the position from the cluster
42082 forEach(containedNodes, function (containedNode) {
42083 // inherit position
42084 if (containedNode.options.fixed.x === false) {
42085 containedNode.x = clusterNode.x;
42086 }
42087
42088 if (containedNode.options.fixed.y === false) {
42089 containedNode.y = clusterNode.y;
42090 }
42091 });
42092 } // release nodes
42093
42094
42095 for (var _nodeId3 in containedNodes) {
42096 if (containedNodes.hasOwnProperty(_nodeId3)) {
42097 var _containedNode2 = this.body.nodes[_nodeId3]; // inherit speed
42098
42099 _containedNode2.vx = clusterNode.vx;
42100 _containedNode2.vy = clusterNode.vy;
42101
42102 _containedNode2.setOptions({
42103 physics: true
42104 });
42105
42106 delete this.clusteredNodes[_nodeId3];
42107 }
42108 } // copy the clusterNode edges because we cannot iterate over an object that we add or remove from.
42109
42110
42111 var edgesToBeDeleted = [];
42112
42113 for (var i = 0; i < clusterNode.edges.length; i++) {
42114 edgesToBeDeleted.push(clusterNode.edges[i]);
42115 } // actually handling the deleting.
42116
42117
42118 for (var _i3 = 0; _i3 < edgesToBeDeleted.length; _i3++) {
42119 var edge = edgesToBeDeleted[_i3];
42120
42121 var otherNodeId = this._getConnectedId(edge, clusterNodeId);
42122
42123 var otherNode = this.clusteredNodes[otherNodeId];
42124
42125 for (var j = 0; j < edge.clusteringEdgeReplacingIds.length; j++) {
42126 var transferId = edge.clusteringEdgeReplacingIds[j];
42127 var transferEdge = this.body.edges[transferId];
42128 if (transferEdge === undefined) continue; // if the other node is in another cluster, we transfer ownership of this edge to the other cluster
42129
42130 if (otherNode !== undefined) {
42131 // transfer ownership:
42132 var otherCluster = this.body.nodes[otherNode.clusterId];
42133 otherCluster.containedEdges[transferEdge.id] = transferEdge; // delete local reference
42134
42135 delete containedEdges[transferEdge.id]; // get to and from
42136
42137 var fromId = transferEdge.fromId;
42138 var toId = transferEdge.toId;
42139
42140 if (transferEdge.toId == otherNodeId) {
42141 toId = otherNode.clusterId;
42142 } else {
42143 fromId = otherNode.clusterId;
42144 } // create new cluster edge from the otherCluster
42145
42146
42147 this._createClusteredEdge(fromId, toId, transferEdge, otherCluster.clusterEdgeProperties, {
42148 hidden: false,
42149 physics: true
42150 });
42151 } else {
42152 this._restoreEdge(transferEdge);
42153 }
42154 }
42155
42156 edge.remove();
42157 } // handle the releasing of the edges
42158
42159
42160 for (var edgeId in containedEdges) {
42161 if (containedEdges.hasOwnProperty(edgeId)) {
42162 this._restoreEdge(containedEdges[edgeId]);
42163 }
42164 } // remove clusterNode
42165
42166
42167 delete this.body.nodes[clusterNodeId];
42168
42169 if (refreshData === true) {
42170 this.body.emitter.emit('_dataChanged');
42171 }
42172 }
42173 /**
42174 *
42175 * @param {Cluster.id} clusterId
42176 * @returns {Array.<Node.id>}
42177 */
42178
42179 }, {
42180 key: "getNodesInCluster",
42181 value: function getNodesInCluster(clusterId) {
42182 var nodesArray = [];
42183
42184 if (this.isCluster(clusterId) === true) {
42185 var containedNodes = this.body.nodes[clusterId].containedNodes;
42186
42187 for (var nodeId in containedNodes) {
42188 if (containedNodes.hasOwnProperty(nodeId)) {
42189 nodesArray.push(this.body.nodes[nodeId].id);
42190 }
42191 }
42192 }
42193
42194 return nodesArray;
42195 }
42196 /**
42197 * Get the stack clusterId's that a certain node resides in. cluster A -> cluster B -> cluster C -> node
42198 *
42199 * If a node can't be found in the chain, return an empty array.
42200 *
42201 * @param {string|number} nodeId
42202 * @returns {Array}
42203 */
42204
42205 }, {
42206 key: "findNode",
42207 value: function findNode(nodeId) {
42208 var stack = [];
42209 var max = 100;
42210 var counter = 0;
42211 var node;
42212
42213 while (this.clusteredNodes[nodeId] !== undefined && counter < max) {
42214 node = this.body.nodes[nodeId];
42215 if (node === undefined) return [];
42216 stack.push(node.id);
42217 nodeId = this.clusteredNodes[nodeId].clusterId;
42218 counter++;
42219 }
42220
42221 node = this.body.nodes[nodeId];
42222 if (node === undefined) return [];
42223 stack.push(node.id);
42224 stack.reverse();
42225 return stack;
42226 }
42227 /**
42228 * Using a clustered nodeId, update with the new options
42229 * @param {vis.Edge.id} clusteredNodeId
42230 * @param {object} newOptions
42231 */
42232
42233 }, {
42234 key: "updateClusteredNode",
42235 value: function updateClusteredNode(clusteredNodeId, newOptions) {
42236 if (clusteredNodeId === undefined) {
42237 throw new Error("No clusteredNodeId supplied to updateClusteredNode.");
42238 }
42239
42240 if (newOptions === undefined) {
42241 throw new Error("No newOptions supplied to updateClusteredNode.");
42242 }
42243
42244 if (this.body.nodes[clusteredNodeId] === undefined) {
42245 throw new Error("The clusteredNodeId supplied to updateClusteredNode does not exist.");
42246 }
42247
42248 this.body.nodes[clusteredNodeId].setOptions(newOptions);
42249 this.body.emitter.emit('_dataChanged');
42250 }
42251 /**
42252 * Using a base edgeId, update all related clustered edges with the new options
42253 * @param {vis.Edge.id} startEdgeId
42254 * @param {object} newOptions
42255 */
42256
42257 }, {
42258 key: "updateEdge",
42259 value: function updateEdge(startEdgeId, newOptions) {
42260 if (startEdgeId === undefined) {
42261 throw new Error("No startEdgeId supplied to updateEdge.");
42262 }
42263
42264 if (newOptions === undefined) {
42265 throw new Error("No newOptions supplied to updateEdge.");
42266 }
42267
42268 if (this.body.edges[startEdgeId] === undefined) {
42269 throw new Error("The startEdgeId supplied to updateEdge does not exist.");
42270 }
42271
42272 var allEdgeIds = this.getClusteredEdges(startEdgeId);
42273
42274 for (var i = 0; i < allEdgeIds.length; i++) {
42275 var edge = this.body.edges[allEdgeIds[i]];
42276 edge.setOptions(newOptions);
42277 }
42278
42279 this.body.emitter.emit('_dataChanged');
42280 }
42281 /**
42282 * 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)
42283 * @param {vis.Edge.id} edgeId
42284 * @returns {Array.<vis.Edge.id>}
42285 */
42286
42287 }, {
42288 key: "getClusteredEdges",
42289 value: function getClusteredEdges(edgeId) {
42290 var stack = [];
42291 var max = 100;
42292 var counter = 0;
42293
42294 while (edgeId !== undefined && this.body.edges[edgeId] !== undefined && counter < max) {
42295 stack.push(this.body.edges[edgeId].id);
42296 edgeId = this.body.edges[edgeId].edgeReplacedById;
42297 counter++;
42298 }
42299
42300 stack.reverse();
42301 return stack;
42302 }
42303 /**
42304 * Get the base edge id of clusterEdgeId. cluster edge (clusteredEdgeId) -> cluster edge B -> cluster edge C -> base edge
42305 * @param {vis.Edge.id} clusteredEdgeId
42306 * @returns {vis.Edge.id} baseEdgeId
42307 *
42308 * TODO: deprecate in 5.0.0. Method getBaseEdges() is the correct one to use.
42309 */
42310
42311 }, {
42312 key: "getBaseEdge",
42313 value: function getBaseEdge(clusteredEdgeId) {
42314 // Just kludge this by returning the first base edge id found
42315 return this.getBaseEdges(clusteredEdgeId)[0];
42316 }
42317 /**
42318 * Get all regular edges for this clustered edge id.
42319 *
42320 * @param {vis.Edge.id} clusteredEdgeId
42321 * @returns {Array.<vis.Edge.id>} all baseEdgeId's under this clustered edge
42322 */
42323
42324 }, {
42325 key: "getBaseEdges",
42326 value: function getBaseEdges(clusteredEdgeId) {
42327 var IdsToHandle = [clusteredEdgeId];
42328 var doneIds = [];
42329 var foundIds = [];
42330 var max = 100;
42331 var counter = 0;
42332
42333 while (IdsToHandle.length > 0 && counter < max) {
42334 var nextId = IdsToHandle.pop();
42335 if (nextId === undefined) continue; // Paranoia here and onwards
42336
42337 var nextEdge = this.body.edges[nextId];
42338 if (nextEdge === undefined) continue;
42339 counter++;
42340 var replacingIds = nextEdge.clusteringEdgeReplacingIds;
42341
42342 if (replacingIds === undefined) {
42343 // nextId is a base id
42344 foundIds.push(nextId);
42345 } else {
42346 // Another cluster edge, unravel this one as well
42347 for (var i = 0; i < replacingIds.length; ++i) {
42348 var replacingId = replacingIds[i]; // Don't add if already handled
42349 // TODO: never triggers; find a test-case which does
42350
42351 if (IdsToHandle.indexOf(replacingIds) !== -1 || doneIds.indexOf(replacingIds) !== -1) {
42352 continue;
42353 }
42354
42355 IdsToHandle.push(replacingId);
42356 }
42357 }
42358
42359 doneIds.push(nextId);
42360 }
42361
42362 return foundIds;
42363 }
42364 /**
42365 * Get the Id the node is connected to
42366 * @param {vis.Edge} edge
42367 * @param {Node.id} nodeId
42368 * @returns {*}
42369 * @private
42370 */
42371
42372 }, {
42373 key: "_getConnectedId",
42374 value: function _getConnectedId(edge, nodeId) {
42375 if (edge.toId != nodeId) {
42376 return edge.toId;
42377 } else if (edge.fromId != nodeId) {
42378 return edge.fromId;
42379 } else {
42380 return edge.fromId;
42381 }
42382 }
42383 /**
42384 * We determine how many connections denote an important hub.
42385 * We take the mean + 2*std as the important hub size. (Assuming a normal distribution of data, ~2.2%)
42386 *
42387 * @returns {number}
42388 * @private
42389 */
42390
42391 }, {
42392 key: "_getHubSize",
42393 value: function _getHubSize() {
42394 var average = 0;
42395 var averageSquared = 0;
42396 var hubCounter = 0;
42397 var largestHub = 0;
42398
42399 for (var i = 0; i < this.body.nodeIndices.length; i++) {
42400 var node = this.body.nodes[this.body.nodeIndices[i]];
42401
42402 if (node.edges.length > largestHub) {
42403 largestHub = node.edges.length;
42404 }
42405
42406 average += node.edges.length;
42407 averageSquared += Math.pow(node.edges.length, 2);
42408 hubCounter += 1;
42409 }
42410
42411 average = average / hubCounter;
42412 averageSquared = averageSquared / hubCounter;
42413 var variance = averageSquared - Math.pow(average, 2);
42414 var standardDeviation = Math.sqrt(variance);
42415 var hubThreshold = Math.floor(average + 2 * standardDeviation); // always have at least one to cluster
42416
42417 if (hubThreshold > largestHub) {
42418 hubThreshold = largestHub;
42419 }
42420
42421 return hubThreshold;
42422 }
42423 /**
42424 * Create an edge for the cluster representation.
42425 *
42426 * @param {Node.id} fromId
42427 * @param {Node.id} toId
42428 * @param {vis.Edge} baseEdge
42429 * @param {Object} clusterEdgeProperties
42430 * @param {Object} extraOptions
42431 * @returns {Edge} newly created clustered edge
42432 * @private
42433 */
42434
42435 }, {
42436 key: "_createClusteredEdge",
42437 value: function _createClusteredEdge(fromId, toId, baseEdge, clusterEdgeProperties, extraOptions) {
42438 // copy the options of the edge we will replace
42439 var clonedOptions = NetworkUtil.cloneOptions(baseEdge, 'edge'); // make sure the properties of clusterEdges are superimposed on it
42440
42441 deepExtend(clonedOptions, clusterEdgeProperties); // set up the edge
42442
42443 clonedOptions.from = fromId;
42444 clonedOptions.to = toId;
42445 clonedOptions.id = 'clusterEdge:' + uuid4(); // apply the edge specific options to it if specified
42446
42447 if (extraOptions !== undefined) {
42448 deepExtend(clonedOptions, extraOptions);
42449 }
42450
42451 var newEdge = this.body.functions.createEdge(clonedOptions);
42452 newEdge.clusteringEdgeReplacingIds = [baseEdge.id];
42453 newEdge.connect(); // Register the new edge
42454
42455 this.body.edges[newEdge.id] = newEdge;
42456 return newEdge;
42457 }
42458 /**
42459 * Add the passed child nodes and edges to the given cluster node.
42460 *
42461 * @param {Object|Node} childNodes hash of nodes or single node to add in cluster
42462 * @param {Object|Edge} childEdges hash of edges or single edge to take into account when clustering
42463 * @param {Node} clusterNode cluster node to add nodes and edges to
42464 * @param {Object} [clusterEdgeProperties]
42465 * @private
42466 */
42467
42468 }, {
42469 key: "_clusterEdges",
42470 value: function _clusterEdges(childNodes, childEdges, clusterNode, clusterEdgeProperties) {
42471 if (childEdges instanceof Edge) {
42472 var edge = childEdges;
42473 var obj = {};
42474 obj[edge.id] = edge;
42475 childEdges = obj;
42476 }
42477
42478 if (childNodes instanceof Node) {
42479 var node = childNodes;
42480 var _obj = {};
42481 _obj[node.id] = node;
42482 childNodes = _obj;
42483 }
42484
42485 if (clusterNode === undefined || clusterNode === null) {
42486 throw new Error("_clusterEdges: parameter clusterNode required");
42487 }
42488
42489 if (clusterEdgeProperties === undefined) {
42490 // Take the required properties from the cluster node
42491 clusterEdgeProperties = clusterNode.clusterEdgeProperties;
42492 } // create the new edges that will connect to the cluster.
42493 // All self-referencing edges will be added to childEdges here.
42494
42495
42496 this._createClusterEdges(childNodes, childEdges, clusterNode, clusterEdgeProperties); // disable the childEdges
42497
42498
42499 for (var edgeId in childEdges) {
42500 if (childEdges.hasOwnProperty(edgeId)) {
42501 if (this.body.edges[edgeId] !== undefined) {
42502 var _edge2 = this.body.edges[edgeId]; // cache the options before changing
42503
42504 this._backupEdgeOptions(_edge2); // disable physics and hide the edge
42505
42506
42507 _edge2.setOptions({
42508 physics: false
42509 });
42510 }
42511 }
42512 } // disable the childNodes
42513
42514
42515 for (var nodeId in childNodes) {
42516 if (childNodes.hasOwnProperty(nodeId)) {
42517 this.clusteredNodes[nodeId] = {
42518 clusterId: clusterNode.id,
42519 node: this.body.nodes[nodeId]
42520 };
42521 this.body.nodes[nodeId].setOptions({
42522 physics: false
42523 });
42524 }
42525 }
42526 }
42527 /**
42528 * Determine in which cluster given nodeId resides.
42529 *
42530 * If not in cluster, return undefined.
42531 *
42532 * NOTE: If you know a cleaner way to do this, please enlighten me (wimrijnders).
42533 *
42534 * @param {Node.id} nodeId
42535 * @returns {Node|undefined} Node instance for cluster, if present
42536 * @private
42537 */
42538
42539 }, {
42540 key: "_getClusterNodeForNode",
42541 value: function _getClusterNodeForNode(nodeId) {
42542 if (nodeId === undefined) return undefined;
42543 var clusteredNode = this.clusteredNodes[nodeId]; // NOTE: If no cluster info found, it should actually be an error
42544
42545 if (clusteredNode === undefined) return undefined;
42546 var clusterId = clusteredNode.clusterId;
42547 if (clusterId === undefined) return undefined;
42548 return this.body.nodes[clusterId];
42549 }
42550 /**
42551 * Internal helper function for conditionally removing items in array
42552 *
42553 * Done like this because Array.filter() is not fully supported by all IE's.
42554 *
42555 * @param {Array} arr
42556 * @param {function} callback
42557 * @returns {Array}
42558 * @private
42559 */
42560
42561 }, {
42562 key: "_filter",
42563 value: function _filter(arr, callback) {
42564 var ret = [];
42565 forEach(arr, function (item) {
42566 if (callback(item)) {
42567 ret.push(item);
42568 }
42569 });
42570 return ret;
42571 }
42572 /**
42573 * Scan all edges for changes in clustering and adjust this if necessary.
42574 *
42575 * Call this (internally) after there has been a change in node or edge data.
42576 *
42577 * Pre: States of this.body.nodes and this.body.edges consistent
42578 * Pre: this.clusteredNodes and this.clusteredEdge consistent with containedNodes and containedEdges
42579 * of cluster nodes.
42580 */
42581
42582 }, {
42583 key: "_updateState",
42584 value: function _updateState() {
42585 var _this4 = this;
42586
42587 var nodeId;
42588 var deletedNodeIds = [];
42589 var deletedEdgeIds = {};
42590 /**
42591 * Utility function to iterate over clustering nodes only
42592 *
42593 * @param {Function} callback function to call for each cluster node
42594 */
42595
42596 var eachClusterNode = function eachClusterNode(callback) {
42597 forEach(_this4.body.nodes, function (node) {
42598 if (node.isCluster === true) {
42599 callback(node);
42600 }
42601 });
42602 }; //
42603 // Remove deleted regular nodes from clustering
42604 //
42605 // Determine the deleted nodes
42606
42607
42608 for (nodeId in this.clusteredNodes) {
42609 if (!this.clusteredNodes.hasOwnProperty(nodeId)) continue;
42610 var node = this.body.nodes[nodeId];
42611
42612 if (node === undefined) {
42613 deletedNodeIds.push(nodeId);
42614 }
42615 } // Remove nodes from cluster nodes
42616
42617
42618 eachClusterNode(function (clusterNode) {
42619 for (var n = 0; n < deletedNodeIds.length; n++) {
42620 delete clusterNode.containedNodes[deletedNodeIds[n]];
42621 }
42622 }); // Remove nodes from cluster list
42623
42624 for (var n = 0; n < deletedNodeIds.length; n++) {
42625 delete this.clusteredNodes[deletedNodeIds[n]];
42626 } //
42627 // Remove deleted edges from clustering
42628 //
42629 // Add the deleted clustered edges to the list
42630
42631
42632 forEach(this.clusteredEdges, function (edgeId) {
42633 var edge = _this4.body.edges[edgeId];
42634
42635 if (edge === undefined || !edge.endPointsValid()) {
42636 deletedEdgeIds[edgeId] = edgeId;
42637 }
42638 }); // Cluster nodes can also contain edges which are not clustered,
42639 // i.e. nodes 1-2 within cluster with an edge in between.
42640 // So the cluster nodes also need to be scanned for invalid edges
42641
42642 eachClusterNode(function (clusterNode) {
42643 forEach(clusterNode.containedEdges, function (edge, edgeId) {
42644 if (!edge.endPointsValid() && !deletedEdgeIds[edgeId]) {
42645 deletedEdgeIds[edgeId] = edgeId;
42646 }
42647 });
42648 }); // Also scan for cluster edges which need to be removed in the active list.
42649 // Regular edges have been removed beforehand, so this only picks up the cluster edges.
42650
42651 forEach(this.body.edges, function (edge, edgeId) {
42652 // Explicitly scan the contained edges for validity
42653 var isValid = true;
42654 var replacedIds = edge.clusteringEdgeReplacingIds;
42655
42656 if (replacedIds !== undefined) {
42657 var numValid = 0;
42658 forEach(replacedIds, function (containedEdgeId) {
42659 var containedEdge = _this4.body.edges[containedEdgeId];
42660
42661 if (containedEdge !== undefined && containedEdge.endPointsValid()) {
42662 numValid += 1;
42663 }
42664 });
42665 isValid = numValid > 0;
42666 }
42667
42668 if (!edge.endPointsValid() || !isValid) {
42669 deletedEdgeIds[edgeId] = edgeId;
42670 }
42671 }); // Remove edges from cluster nodes
42672
42673 eachClusterNode(function (clusterNode) {
42674 forEach(deletedEdgeIds, function (deletedEdgeId) {
42675 delete clusterNode.containedEdges[deletedEdgeId];
42676 forEach(clusterNode.edges, function (edge, m) {
42677 if (edge.id === deletedEdgeId) {
42678 clusterNode.edges[m] = null; // Don't want to directly delete here, because in the loop
42679
42680 return;
42681 }
42682
42683 edge.clusteringEdgeReplacingIds = _this4._filter(edge.clusteringEdgeReplacingIds, function (id) {
42684 return !deletedEdgeIds[id];
42685 });
42686 }); // Clean up the nulls
42687
42688 clusterNode.edges = _this4._filter(clusterNode.edges, function (item) {
42689 return item !== null;
42690 });
42691 });
42692 }); // Remove from cluster list
42693
42694 forEach(deletedEdgeIds, function (edgeId) {
42695 delete _this4.clusteredEdges[edgeId];
42696 }); // Remove cluster edges from active list (this.body.edges).
42697 // deletedEdgeIds still contains id of regular edges, but these should all
42698 // be gone when you reach here.
42699
42700 forEach(deletedEdgeIds, function (edgeId) {
42701 delete _this4.body.edges[edgeId];
42702 }); //
42703 // Check changed cluster state of edges
42704 //
42705 // Iterating over keys here, because edges may be removed in the loop
42706
42707 var ids = Object.keys(this.body.edges);
42708 forEach(ids, function (edgeId) {
42709 var edge = _this4.body.edges[edgeId];
42710
42711 var shouldBeClustered = _this4._isClusteredNode(edge.fromId) || _this4._isClusteredNode(edge.toId);
42712
42713 if (shouldBeClustered === _this4._isClusteredEdge(edge.id)) {
42714 return; // all is well
42715 }
42716
42717 if (shouldBeClustered) {
42718 // add edge to clustering
42719 var clusterFrom = _this4._getClusterNodeForNode(edge.fromId);
42720
42721 if (clusterFrom !== undefined) {
42722 _this4._clusterEdges(_this4.body.nodes[edge.fromId], edge, clusterFrom);
42723 }
42724
42725 var clusterTo = _this4._getClusterNodeForNode(edge.toId);
42726
42727 if (clusterTo !== undefined) {
42728 _this4._clusterEdges(_this4.body.nodes[edge.toId], edge, clusterTo);
42729 } // TODO: check that it works for both edges clustered
42730 // (This might be paranoia)
42731
42732 } else {
42733 delete _this4._clusterEdges[edgeId];
42734
42735 _this4._restoreEdge(edge); // This should not be happening, the state should
42736 // be properly updated at this point.
42737 //
42738 // If it *is* reached during normal operation, then we have to implement
42739 // undo clustering for this edge here.
42740 // throw new Error('remove edge from clustering not implemented!')
42741
42742 }
42743 }); // Clusters may be nested to any level. Keep on opening until nothing to open
42744
42745 var changed = false;
42746 var continueLoop = true;
42747
42748 var _loop2 = function _loop2() {
42749 var clustersToOpen = []; // Determine the id's of clusters that need opening
42750
42751 eachClusterNode(function (clusterNode) {
42752 var numNodes = Object.keys(clusterNode.containedNodes).length;
42753 var allowSingle = clusterNode.options.allowSingleNodeCluster === true;
42754
42755 if (allowSingle && numNodes < 1 || !allowSingle && numNodes < 2) {
42756 clustersToOpen.push(clusterNode.id);
42757 }
42758 }); // Open them
42759
42760 for (var _n = 0; _n < clustersToOpen.length; ++_n) {
42761 _this4.openCluster(clustersToOpen[_n], {}, false
42762 /* Don't refresh, we're in an refresh/update already */
42763 );
42764 }
42765
42766 continueLoop = clustersToOpen.length > 0;
42767 changed = changed || continueLoop;
42768 };
42769
42770 while (continueLoop) {
42771 _loop2();
42772 }
42773
42774 if (changed) {
42775 this._updateState(); // Redo this method (recursion possible! should be safe)
42776
42777 }
42778 }
42779 /**
42780 * Determine if node with given id is part of a cluster.
42781 *
42782 * @param {Node.id} nodeId
42783 * @return {boolean} true if part of a cluster.
42784 */
42785
42786 }, {
42787 key: "_isClusteredNode",
42788 value: function _isClusteredNode(nodeId) {
42789 return this.clusteredNodes[nodeId] !== undefined;
42790 }
42791 /**
42792 * Determine if edge with given id is not visible due to clustering.
42793 *
42794 * An edge is considered clustered if:
42795 * - it is directly replaced by a clustering edge
42796 * - any of its connecting nodes is in a cluster
42797 *
42798 * @param {vis.Edge.id} edgeId
42799 * @return {boolean} true if part of a cluster.
42800 */
42801
42802 }, {
42803 key: "_isClusteredEdge",
42804 value: function _isClusteredEdge(edgeId) {
42805 return this.clusteredEdges[edgeId] !== undefined;
42806 }
42807 }]);
42808
42809 return ClusterEngine;
42810 }();
42811
42812 /**
42813 * Initializes window.requestAnimationFrame() to a usable form.
42814 *
42815 * Specifically, set up this method for the case of running on node.js with jsdom enabled.
42816 *
42817 * NOTES:
42818 *
42819 * * On node.js, when calling this directly outside of this class, `window` is not defined.
42820 * This happens even if jsdom is used.
42821 * * For node.js + jsdom, `window` is available at the moment the constructor is called.
42822 * For this reason, the called is placed within the constructor.
42823 * * Even then, `window.requestAnimationFrame()` is not defined, so it still needs to be added.
42824 * * During unit testing, it happens that the window object is reset during execution, causing
42825 * a runtime error due to missing `requestAnimationFrame()`. This needs to be compensated for,
42826 * see `_requestNextFrame()`.
42827 * * Since this is a global object, it may affect other modules besides `Network`. With normal
42828 * usage, this does not cause any problems. During unit testing, errors may occur. These have
42829 * been compensated for, see comment block in _requestNextFrame().
42830 *
42831 * @private
42832 */
42833 function _initRequestAnimationFrame() {
42834 var func;
42835
42836 if (window !== undefined) {
42837 func = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
42838 }
42839
42840 if (func === undefined) {
42841 // window or method not present, setting mock requestAnimationFrame
42842 window.requestAnimationFrame = function (callback) {
42843 //console.log("Called mock requestAnimationFrame");
42844 callback();
42845 };
42846 } else {
42847 window.requestAnimationFrame = func;
42848 }
42849 }
42850 /**
42851 * The canvas renderer
42852 */
42853
42854 var CanvasRenderer =
42855 /*#__PURE__*/
42856 function () {
42857 /**
42858 * @param {Object} body
42859 * @param {Canvas} canvas
42860 */
42861 function CanvasRenderer(body, canvas) {
42862 _classCallCheck(this, CanvasRenderer);
42863
42864 _initRequestAnimationFrame();
42865
42866 this.body = body;
42867 this.canvas = canvas;
42868 this.redrawRequested = false;
42869 this.renderTimer = undefined;
42870 this.requiresTimeout = true;
42871 this.renderingActive = false;
42872 this.renderRequests = 0;
42873 this.allowRedraw = true;
42874 this.dragging = false;
42875 this.zooming = false;
42876 this.options = {};
42877 this.defaultOptions = {
42878 hideEdgesOnDrag: false,
42879 hideEdgesOnZoom: false,
42880 hideNodesOnDrag: false
42881 };
42882 extend(this.options, this.defaultOptions);
42883
42884 this._determineBrowserMethod();
42885
42886 this.bindEventListeners();
42887 }
42888 /**
42889 * Binds event listeners
42890 */
42891
42892
42893 _createClass(CanvasRenderer, [{
42894 key: "bindEventListeners",
42895 value: function bindEventListeners() {
42896 var _this = this;
42897
42898 this.body.emitter.on("dragStart", function () {
42899 _this.dragging = true;
42900 });
42901 this.body.emitter.on("dragEnd", function () {
42902 _this.dragging = false;
42903 });
42904 this.body.emitter.on("zoom", function () {
42905 _this.zooming = true;
42906 window.clearTimeout(_this.zoomTimeoutId);
42907 _this.zoomTimeoutId = window.setTimeout(function () {
42908 _this.zooming = false;
42909
42910 _this._requestRedraw.bind(_this)();
42911 }, 250);
42912 });
42913 this.body.emitter.on("_resizeNodes", function () {
42914 _this._resizeNodes();
42915 });
42916 this.body.emitter.on("_redraw", function () {
42917 if (_this.renderingActive === false) {
42918 _this._redraw();
42919 }
42920 });
42921 this.body.emitter.on("_blockRedraw", function () {
42922 _this.allowRedraw = false;
42923 });
42924 this.body.emitter.on("_allowRedraw", function () {
42925 _this.allowRedraw = true;
42926 _this.redrawRequested = false;
42927 });
42928 this.body.emitter.on("_requestRedraw", this._requestRedraw.bind(this));
42929 this.body.emitter.on("_startRendering", function () {
42930 _this.renderRequests += 1;
42931 _this.renderingActive = true;
42932
42933 _this._startRendering();
42934 });
42935 this.body.emitter.on("_stopRendering", function () {
42936 _this.renderRequests -= 1;
42937 _this.renderingActive = _this.renderRequests > 0;
42938 _this.renderTimer = undefined;
42939 });
42940 this.body.emitter.on('destroy', function () {
42941 _this.renderRequests = 0;
42942 _this.allowRedraw = false;
42943 _this.renderingActive = false;
42944
42945 if (_this.requiresTimeout === true) {
42946 clearTimeout(_this.renderTimer);
42947 } else {
42948 window.cancelAnimationFrame(_this.renderTimer);
42949 }
42950
42951 _this.body.emitter.off();
42952 });
42953 }
42954 /**
42955 *
42956 * @param {Object} options
42957 */
42958
42959 }, {
42960 key: "setOptions",
42961 value: function setOptions(options) {
42962 if (options !== undefined) {
42963 var fields = ['hideEdgesOnDrag', 'hideEdgesOnZoom', 'hideNodesOnDrag'];
42964 selectiveDeepExtend(fields, this.options, options);
42965 }
42966 }
42967 /**
42968 * Prepare the drawing of the next frame.
42969 *
42970 * Calls the callback when the next frame can or will be drawn.
42971 *
42972 * @param {function} callback
42973 * @param {number} delay - timeout case only, wait this number of milliseconds
42974 * @returns {function|undefined}
42975 * @private
42976 */
42977
42978 }, {
42979 key: "_requestNextFrame",
42980 value: function _requestNextFrame(callback, delay) {
42981 // During unit testing, it happens that the mock window object is reset while
42982 // the next frame is still pending. Then, either 'window' is not present, or
42983 // 'requestAnimationFrame()' is not present because it is not defined on the
42984 // mock window object.
42985 //
42986 // As a consequence, unrelated unit tests may appear to fail, even if the problem
42987 // described happens in the current unit test.
42988 //
42989 // This is not something that will happen in normal operation, but we still need
42990 // to take it into account.
42991 //
42992 if (typeof window === 'undefined') return; // Doing `if (window === undefined)` does not work here!
42993
42994 var timer;
42995 var myWindow = window; // Grab a reference to reduce the possibility that 'window' is reset
42996 // while running this method.
42997
42998 if (this.requiresTimeout === true) {
42999 // wait given number of milliseconds and perform the animation step function
43000 timer = myWindow.setTimeout(callback, delay);
43001 } else {
43002 if (myWindow.requestAnimationFrame) {
43003 timer = myWindow.requestAnimationFrame(callback);
43004 }
43005 }
43006
43007 return timer;
43008 }
43009 /**
43010 *
43011 * @private
43012 */
43013
43014 }, {
43015 key: "_startRendering",
43016 value: function _startRendering() {
43017 if (this.renderingActive === true) {
43018 if (this.renderTimer === undefined) {
43019 this.renderTimer = this._requestNextFrame(this._renderStep.bind(this), this.simulationInterval);
43020 }
43021 }
43022 }
43023 /**
43024 *
43025 * @private
43026 */
43027
43028 }, {
43029 key: "_renderStep",
43030 value: function _renderStep() {
43031 if (this.renderingActive === true) {
43032 // reset the renderTimer so a new scheduled animation step can be set
43033 this.renderTimer = undefined;
43034
43035 if (this.requiresTimeout === true) {
43036 // this schedules a new simulation step
43037 this._startRendering();
43038 }
43039
43040 this._redraw();
43041
43042 if (this.requiresTimeout === false) {
43043 // this schedules a new simulation step
43044 this._startRendering();
43045 }
43046 }
43047 }
43048 /**
43049 * Redraw the network with the current data
43050 * chart will be resized too.
43051 */
43052
43053 }, {
43054 key: "redraw",
43055 value: function redraw() {
43056 this.body.emitter.emit('setSize');
43057
43058 this._redraw();
43059 }
43060 /**
43061 * Redraw the network with the current data
43062 * @private
43063 */
43064
43065 }, {
43066 key: "_requestRedraw",
43067 value: function _requestRedraw() {
43068 var _this2 = this;
43069
43070 if (this.redrawRequested !== true && this.renderingActive === false && this.allowRedraw === true) {
43071 this.redrawRequested = true;
43072
43073 this._requestNextFrame(function () {
43074 _this2._redraw(false);
43075 }, 0);
43076 }
43077 }
43078 /**
43079 * Redraw the network with the current data
43080 * @param {boolean} [hidden=false] | Used to get the first estimate of the node sizes.
43081 * Only the nodes are drawn after which they are quickly drawn over.
43082 * @private
43083 */
43084
43085 }, {
43086 key: "_redraw",
43087 value: function _redraw() {
43088 var hidden = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
43089
43090 if (this.allowRedraw === true) {
43091 this.body.emitter.emit("initRedraw");
43092 this.redrawRequested = false; // when the container div was hidden, this fixes it back up!
43093
43094 if (this.canvas.frame.canvas.width === 0 || this.canvas.frame.canvas.height === 0) {
43095 this.canvas.setSize();
43096 }
43097
43098 this.canvas.setTransform();
43099 var ctx = this.canvas.getContext(); // clear the canvas
43100
43101 var w = this.canvas.frame.canvas.clientWidth;
43102 var h = this.canvas.frame.canvas.clientHeight;
43103 ctx.clearRect(0, 0, w, h); // if the div is hidden, we stop the redraw here for performance.
43104
43105 if (this.canvas.frame.clientWidth === 0) {
43106 return;
43107 } // set scaling and translation
43108
43109
43110 ctx.save();
43111 ctx.translate(this.body.view.translation.x, this.body.view.translation.y);
43112 ctx.scale(this.body.view.scale, this.body.view.scale);
43113 ctx.beginPath();
43114 this.body.emitter.emit("beforeDrawing", ctx);
43115 ctx.closePath();
43116
43117 if (hidden === false) {
43118 if ((this.dragging === false || this.dragging === true && this.options.hideEdgesOnDrag === false) && (this.zooming === false || this.zooming === true && this.options.hideEdgesOnZoom === false)) {
43119 this._drawEdges(ctx);
43120 }
43121 }
43122
43123 if (this.dragging === false || this.dragging === true && this.options.hideNodesOnDrag === false) {
43124 this._drawNodes(ctx, hidden);
43125 }
43126
43127 ctx.beginPath();
43128 this.body.emitter.emit("afterDrawing", ctx);
43129 ctx.closePath(); // restore original scaling and translation
43130
43131 ctx.restore();
43132
43133 if (hidden === true) {
43134 ctx.clearRect(0, 0, w, h);
43135 }
43136 }
43137 }
43138 /**
43139 * Redraw all nodes
43140 *
43141 * @param {CanvasRenderingContext2D} ctx
43142 * @param {boolean} [alwaysShow]
43143 * @private
43144 */
43145
43146 }, {
43147 key: "_resizeNodes",
43148 value: function _resizeNodes() {
43149 this.canvas.setTransform();
43150 var ctx = this.canvas.getContext();
43151 ctx.save();
43152 ctx.translate(this.body.view.translation.x, this.body.view.translation.y);
43153 ctx.scale(this.body.view.scale, this.body.view.scale);
43154 var nodes = this.body.nodes;
43155 var node; // resize all nodes
43156
43157 for (var nodeId in nodes) {
43158 if (nodes.hasOwnProperty(nodeId)) {
43159 node = nodes[nodeId];
43160 node.resize(ctx);
43161 node.updateBoundingBox(ctx, node.selected);
43162 }
43163 } // restore original scaling and translation
43164
43165
43166 ctx.restore();
43167 }
43168 /**
43169 * Redraw all nodes
43170 *
43171 * @param {CanvasRenderingContext2D} ctx 2D context of a HTML canvas
43172 * @param {boolean} [alwaysShow]
43173 * @private
43174 */
43175
43176 }, {
43177 key: "_drawNodes",
43178 value: function _drawNodes(ctx) {
43179 var alwaysShow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
43180 var nodes = this.body.nodes;
43181 var nodeIndices = this.body.nodeIndices;
43182 var node;
43183 var selected = [];
43184 var margin = 20;
43185 var topLeft = this.canvas.DOMtoCanvas({
43186 x: -margin,
43187 y: -margin
43188 });
43189 var bottomRight = this.canvas.DOMtoCanvas({
43190 x: this.canvas.frame.canvas.clientWidth + margin,
43191 y: this.canvas.frame.canvas.clientHeight + margin
43192 });
43193 var viewableArea = {
43194 top: topLeft.y,
43195 left: topLeft.x,
43196 bottom: bottomRight.y,
43197 right: bottomRight.x
43198 }; // draw unselected nodes;
43199
43200 for (var i = 0; i < nodeIndices.length; i++) {
43201 node = nodes[nodeIndices[i]]; // set selected nodes aside
43202
43203 if (node.isSelected()) {
43204 selected.push(nodeIndices[i]);
43205 } else {
43206 if (alwaysShow === true) {
43207 node.draw(ctx);
43208 } else if (node.isBoundingBoxOverlappingWith(viewableArea) === true) {
43209 node.draw(ctx);
43210 } else {
43211 node.updateBoundingBox(ctx, node.selected);
43212 }
43213 }
43214 } // draw the selected nodes on top
43215
43216
43217 for (var _i = 0; _i < selected.length; _i++) {
43218 node = nodes[selected[_i]];
43219 node.draw(ctx);
43220 }
43221 }
43222 /**
43223 * Redraw all edges
43224 * @param {CanvasRenderingContext2D} ctx 2D context of a HTML canvas
43225 * @private
43226 */
43227
43228 }, {
43229 key: "_drawEdges",
43230 value: function _drawEdges(ctx) {
43231 var edges = this.body.edges;
43232 var edgeIndices = this.body.edgeIndices;
43233 var edge;
43234
43235 for (var i = 0; i < edgeIndices.length; i++) {
43236 edge = edges[edgeIndices[i]];
43237
43238 if (edge.connected === true) {
43239 edge.draw(ctx);
43240 }
43241 }
43242 }
43243 /**
43244 * Determine if the browser requires a setTimeout or a requestAnimationFrame. This was required because
43245 * some implementations (safari and IE9) did not support requestAnimationFrame
43246 * @private
43247 */
43248
43249 }, {
43250 key: "_determineBrowserMethod",
43251 value: function _determineBrowserMethod() {
43252 if (typeof window !== 'undefined') {
43253 var browserType = navigator.userAgent.toLowerCase();
43254 this.requiresTimeout = false;
43255
43256 if (browserType.indexOf('msie 9.0') != -1) {
43257 // IE 9
43258 this.requiresTimeout = true;
43259 } else if (browserType.indexOf('safari') != -1) {
43260 // safari
43261 if (browserType.indexOf('chrome') <= -1) {
43262 this.requiresTimeout = true;
43263 }
43264 }
43265 } else {
43266 this.requiresTimeout = true;
43267 }
43268 }
43269 }]);
43270
43271 return CanvasRenderer;
43272 }();
43273
43274 var hammerUtil = createCommonjsModule(function (module, exports) {
43275 /**
43276 * Register a touch event, taking place before a gesture
43277 * @param {Hammer} hammer A hammer instance
43278 * @param {function} callback Callback, called as callback(event)
43279 */
43280 exports.onTouch = function (hammer, callback) {
43281 callback.inputHandler = function (event) {
43282 if (event.isFirst) {
43283 callback(event);
43284 }
43285 };
43286
43287 hammer.on('hammer.input', callback.inputHandler);
43288 };
43289 /**
43290 * Register a release event, taking place after a gesture
43291 * @param {Hammer} hammer A hammer instance
43292 * @param {function} callback Callback, called as callback(event)
43293 * @returns {*}
43294 */
43295
43296
43297 exports.onRelease = function (hammer, callback) {
43298 callback.inputHandler = function (event) {
43299 if (event.isFinal) {
43300 callback(event);
43301 }
43302 };
43303
43304 return hammer.on('hammer.input', callback.inputHandler);
43305 };
43306 /**
43307 * Unregister a touch event, taking place before a gesture
43308 * @param {Hammer} hammer A hammer instance
43309 * @param {function} callback Callback, called as callback(event)
43310 */
43311
43312
43313 exports.offTouch = function (hammer, callback) {
43314 hammer.off('hammer.input', callback.inputHandler);
43315 };
43316 /**
43317 * Unregister a release event, taking place before a gesture
43318 * @param {Hammer} hammer A hammer instance
43319 * @param {function} callback Callback, called as callback(event)
43320 */
43321
43322
43323 exports.offRelease = exports.offTouch;
43324 /**
43325 * Hack the PinchRecognizer such that it doesn't prevent default behavior
43326 * for vertical panning.
43327 *
43328 * Yeah ... this is quite a hack ... see https://github.com/hammerjs/hammer.js/issues/932
43329 *
43330 * @param {Hammer.Pinch} pinchRecognizer
43331 * @return {Hammer.Pinch} returns the pinchRecognizer
43332 */
43333
43334 exports.disablePreventDefaultVertically = function (pinchRecognizer) {
43335 var TOUCH_ACTION_PAN_Y = 'pan-y';
43336
43337 pinchRecognizer.getTouchAction = function () {
43338 // default method returns [TOUCH_ACTION_NONE]
43339 return [TOUCH_ACTION_PAN_Y];
43340 };
43341
43342 return pinchRecognizer;
43343 };
43344 });
43345 var hammerUtil_1 = hammerUtil.onTouch;
43346 var hammerUtil_2 = hammerUtil.onRelease;
43347 var hammerUtil_3 = hammerUtil.offTouch;
43348 var hammerUtil_4 = hammerUtil.offRelease;
43349 var hammerUtil_5 = hammerUtil.disablePreventDefaultVertically;
43350
43351 /**
43352 * Create the main frame for the Network.
43353 * This function is executed once when a Network object is created. The frame
43354 * contains a canvas, and this canvas contains all objects like the axis and
43355 * nodes.
43356 */
43357
43358 var Canvas =
43359 /*#__PURE__*/
43360 function () {
43361 /**
43362 * @param {Object} body
43363 */
43364 function Canvas(body) {
43365 _classCallCheck(this, Canvas);
43366
43367 this.body = body;
43368 this.pixelRatio = 1;
43369 this.resizeTimer = undefined;
43370 this.resizeFunction = this._onResize.bind(this);
43371 this.cameraState = {};
43372 this.initialized = false;
43373 this.canvasViewCenter = {};
43374 this.options = {};
43375 this.defaultOptions = {
43376 autoResize: true,
43377 height: '100%',
43378 width: '100%'
43379 };
43380 extend(this.options, this.defaultOptions);
43381 this.bindEventListeners();
43382 }
43383 /**
43384 * Binds event listeners
43385 */
43386
43387
43388 _createClass(Canvas, [{
43389 key: "bindEventListeners",
43390 value: function bindEventListeners() {
43391 var _this = this;
43392
43393 // bind the events
43394 this.body.emitter.once("resize", function (obj) {
43395 if (obj.width !== 0) {
43396 _this.body.view.translation.x = obj.width * 0.5;
43397 }
43398
43399 if (obj.height !== 0) {
43400 _this.body.view.translation.y = obj.height * 0.5;
43401 }
43402 });
43403 this.body.emitter.on("setSize", this.setSize.bind(this));
43404 this.body.emitter.on("destroy", function () {
43405 _this.hammerFrame.destroy();
43406
43407 _this.hammer.destroy();
43408
43409 _this._cleanUp();
43410 });
43411 }
43412 /**
43413 * @param {Object} options
43414 */
43415
43416 }, {
43417 key: "setOptions",
43418 value: function setOptions(options) {
43419 var _this2 = this;
43420
43421 if (options !== undefined) {
43422 var fields = ['width', 'height', 'autoResize'];
43423 selectiveDeepExtend(fields, this.options, options);
43424 }
43425
43426 if (this.options.autoResize === true) {
43427 // automatically adapt to a changing size of the browser.
43428 this._cleanUp();
43429
43430 this.resizeTimer = setInterval(function () {
43431 var changed = _this2.setSize();
43432
43433 if (changed === true) {
43434 _this2.body.emitter.emit("_requestRedraw");
43435 }
43436 }, 1000);
43437 this.resizeFunction = this._onResize.bind(this);
43438 addEventListener(window, 'resize', this.resizeFunction);
43439 }
43440 }
43441 /**
43442 * @private
43443 */
43444
43445 }, {
43446 key: "_cleanUp",
43447 value: function _cleanUp() {
43448 // automatically adapt to a changing size of the browser.
43449 if (this.resizeTimer !== undefined) {
43450 clearInterval(this.resizeTimer);
43451 }
43452
43453 removeEventListener(window, 'resize', this.resizeFunction);
43454 this.resizeFunction = undefined;
43455 }
43456 /**
43457 * @private
43458 */
43459
43460 }, {
43461 key: "_onResize",
43462 value: function _onResize() {
43463 this.setSize();
43464 this.body.emitter.emit("_redraw");
43465 }
43466 /**
43467 * Get and store the cameraState
43468 *
43469 * @param {number} [pixelRatio=this.pixelRatio]
43470 * @private
43471 */
43472
43473 }, {
43474 key: "_getCameraState",
43475 value: function _getCameraState() {
43476 var pixelRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.pixelRatio;
43477
43478 if (this.initialized === true) {
43479 this.cameraState.previousWidth = this.frame.canvas.width / pixelRatio;
43480 this.cameraState.previousHeight = this.frame.canvas.height / pixelRatio;
43481 this.cameraState.scale = this.body.view.scale;
43482 this.cameraState.position = this.DOMtoCanvas({
43483 x: 0.5 * this.frame.canvas.width / pixelRatio,
43484 y: 0.5 * this.frame.canvas.height / pixelRatio
43485 });
43486 }
43487 }
43488 /**
43489 * Set the cameraState
43490 * @private
43491 */
43492
43493 }, {
43494 key: "_setCameraState",
43495 value: function _setCameraState() {
43496 if (this.cameraState.scale !== undefined && this.frame.canvas.clientWidth !== 0 && this.frame.canvas.clientHeight !== 0 && this.pixelRatio !== 0 && this.cameraState.previousWidth > 0) {
43497 var widthRatio = this.frame.canvas.width / this.pixelRatio / this.cameraState.previousWidth;
43498 var heightRatio = this.frame.canvas.height / this.pixelRatio / this.cameraState.previousHeight;
43499 var newScale = this.cameraState.scale;
43500
43501 if (widthRatio != 1 && heightRatio != 1) {
43502 newScale = this.cameraState.scale * 0.5 * (widthRatio + heightRatio);
43503 } else if (widthRatio != 1) {
43504 newScale = this.cameraState.scale * widthRatio;
43505 } else if (heightRatio != 1) {
43506 newScale = this.cameraState.scale * heightRatio;
43507 }
43508
43509 this.body.view.scale = newScale; // this comes from the view module.
43510
43511 var currentViewCenter = this.DOMtoCanvas({
43512 x: 0.5 * this.frame.canvas.clientWidth,
43513 y: 0.5 * this.frame.canvas.clientHeight
43514 });
43515 var distanceFromCenter = {
43516 // offset from view, distance view has to change by these x and y to center the node
43517 x: currentViewCenter.x - this.cameraState.position.x,
43518 y: currentViewCenter.y - this.cameraState.position.y
43519 };
43520 this.body.view.translation.x += distanceFromCenter.x * this.body.view.scale;
43521 this.body.view.translation.y += distanceFromCenter.y * this.body.view.scale;
43522 }
43523 }
43524 /**
43525 *
43526 * @param {number|string} value
43527 * @returns {string}
43528 * @private
43529 */
43530
43531 }, {
43532 key: "_prepareValue",
43533 value: function _prepareValue(value) {
43534 if (typeof value === 'number') {
43535 return value + 'px';
43536 } else if (typeof value === 'string') {
43537 if (value.indexOf('%') !== -1 || value.indexOf('px') !== -1) {
43538 return value;
43539 } else if (value.indexOf('%') === -1) {
43540 return value + 'px';
43541 }
43542 }
43543
43544 throw new Error('Could not use the value supplied for width or height:' + value);
43545 }
43546 /**
43547 * Create the HTML
43548 */
43549
43550 }, {
43551 key: "_create",
43552 value: function _create() {
43553 // remove all elements from the container element.
43554 while (this.body.container.hasChildNodes()) {
43555 this.body.container.removeChild(this.body.container.firstChild);
43556 }
43557
43558 this.frame = document.createElement('div');
43559 this.frame.className = 'vis-network';
43560 this.frame.style.position = 'relative';
43561 this.frame.style.overflow = 'hidden';
43562 this.frame.tabIndex = 900; // tab index is required for keycharm to bind keystrokes to the div instead of the window
43563 //////////////////////////////////////////////////////////////////
43564
43565 this.frame.canvas = document.createElement("canvas");
43566 this.frame.canvas.style.position = 'relative';
43567 this.frame.appendChild(this.frame.canvas);
43568
43569 if (!this.frame.canvas.getContext) {
43570 var noCanvas = document.createElement('DIV');
43571 noCanvas.style.color = 'red';
43572 noCanvas.style.fontWeight = 'bold';
43573 noCanvas.style.padding = '10px';
43574 noCanvas.innerHTML = 'Error: your browser does not support HTML canvas';
43575 this.frame.canvas.appendChild(noCanvas);
43576 } else {
43577 this._setPixelRatio();
43578
43579 this.setTransform();
43580 } // add the frame to the container element
43581
43582
43583 this.body.container.appendChild(this.frame);
43584 this.body.view.scale = 1;
43585 this.body.view.translation = {
43586 x: 0.5 * this.frame.canvas.clientWidth,
43587 y: 0.5 * this.frame.canvas.clientHeight
43588 };
43589
43590 this._bindHammer();
43591 }
43592 /**
43593 * This function binds hammer, it can be repeated over and over due to the uniqueness check.
43594 * @private
43595 */
43596
43597 }, {
43598 key: "_bindHammer",
43599 value: function _bindHammer() {
43600 var _this3 = this;
43601
43602 if (this.hammer !== undefined) {
43603 this.hammer.destroy();
43604 }
43605
43606 this.drag = {};
43607 this.pinch = {}; // init hammer
43608
43609 this.hammer = new hammer(this.frame.canvas);
43610 this.hammer.get('pinch').set({
43611 enable: true
43612 }); // enable to get better response, todo: test on mobile.
43613
43614 this.hammer.get('pan').set({
43615 threshold: 5,
43616 direction: hammer.DIRECTION_ALL
43617 });
43618 hammerUtil.onTouch(this.hammer, function (event) {
43619 _this3.body.eventListeners.onTouch(event);
43620 });
43621 this.hammer.on('tap', function (event) {
43622 _this3.body.eventListeners.onTap(event);
43623 });
43624 this.hammer.on('doubletap', function (event) {
43625 _this3.body.eventListeners.onDoubleTap(event);
43626 });
43627 this.hammer.on('press', function (event) {
43628 _this3.body.eventListeners.onHold(event);
43629 });
43630 this.hammer.on('panstart', function (event) {
43631 _this3.body.eventListeners.onDragStart(event);
43632 });
43633 this.hammer.on('panmove', function (event) {
43634 _this3.body.eventListeners.onDrag(event);
43635 });
43636 this.hammer.on('panend', function (event) {
43637 _this3.body.eventListeners.onDragEnd(event);
43638 });
43639 this.hammer.on('pinch', function (event) {
43640 _this3.body.eventListeners.onPinch(event);
43641 }); // TODO: neatly cleanup these handlers when re-creating the Canvas, IF these are done with hammer, event.stopPropagation will not work?
43642
43643 this.frame.canvas.addEventListener('wheel', function (event) {
43644 _this3.body.eventListeners.onMouseWheel(event);
43645 });
43646 this.frame.canvas.addEventListener('mousemove', function (event) {
43647 _this3.body.eventListeners.onMouseMove(event);
43648 });
43649 this.frame.canvas.addEventListener('contextmenu', function (event) {
43650 _this3.body.eventListeners.onContext(event);
43651 });
43652 this.hammerFrame = new hammer(this.frame);
43653 hammerUtil.onRelease(this.hammerFrame, function (event) {
43654 _this3.body.eventListeners.onRelease(event);
43655 });
43656 }
43657 /**
43658 * Set a new size for the network
43659 * @param {string} width Width in pixels or percentage (for example '800px'
43660 * or '50%')
43661 * @param {string} height Height in pixels or percentage (for example '400px'
43662 * or '30%')
43663 * @returns {boolean}
43664 */
43665
43666 }, {
43667 key: "setSize",
43668 value: function setSize() {
43669 var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.width;
43670 var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.height;
43671 width = this._prepareValue(width);
43672 height = this._prepareValue(height);
43673 var emitEvent = false;
43674 var oldWidth = this.frame.canvas.width;
43675 var oldHeight = this.frame.canvas.height; // update the pixel ratio
43676 //
43677 // NOTE: Comment in following is rather inconsistent; this is the ONLY place in the code
43678 // where it is assumed that the pixel ratio could change at runtime.
43679 // The only way I can think of this happening is a rotating screen or tablet; but then
43680 // there should be a mechanism for reloading the data (TODO: check if this is present).
43681 //
43682 // If the assumption is true (i.e. pixel ratio can change at runtime), then *all* usage
43683 // of pixel ratio must be overhauled for this.
43684 //
43685 // For the time being, I will humor the assumption here, and in the rest of the code assume it is
43686 // constant.
43687
43688 var previousRatio = this.pixelRatio; // we cache this because the camera state storage needs the old value
43689
43690 this._setPixelRatio();
43691
43692 if (width != this.options.width || height != this.options.height || this.frame.style.width != width || this.frame.style.height != height) {
43693 this._getCameraState(previousRatio);
43694
43695 this.frame.style.width = width;
43696 this.frame.style.height = height;
43697 this.frame.canvas.style.width = '100%';
43698 this.frame.canvas.style.height = '100%';
43699 this.frame.canvas.width = Math.round(this.frame.canvas.clientWidth * this.pixelRatio);
43700 this.frame.canvas.height = Math.round(this.frame.canvas.clientHeight * this.pixelRatio);
43701 this.options.width = width;
43702 this.options.height = height;
43703 this.canvasViewCenter = {
43704 x: 0.5 * this.frame.clientWidth,
43705 y: 0.5 * this.frame.clientHeight
43706 };
43707 emitEvent = true;
43708 } else {
43709 // this would adapt the width of the canvas to the width from 100% if and only if
43710 // there is a change.
43711 var newWidth = Math.round(this.frame.canvas.clientWidth * this.pixelRatio);
43712 var newHeight = Math.round(this.frame.canvas.clientHeight * this.pixelRatio); // store the camera if there is a change in size.
43713
43714 if (this.frame.canvas.width !== newWidth || this.frame.canvas.height !== newHeight) {
43715 this._getCameraState(previousRatio);
43716 }
43717
43718 if (this.frame.canvas.width !== newWidth) {
43719 this.frame.canvas.width = newWidth;
43720 emitEvent = true;
43721 }
43722
43723 if (this.frame.canvas.height !== newHeight) {
43724 this.frame.canvas.height = newHeight;
43725 emitEvent = true;
43726 }
43727 }
43728
43729 if (emitEvent === true) {
43730 this.body.emitter.emit('resize', {
43731 width: Math.round(this.frame.canvas.width / this.pixelRatio),
43732 height: Math.round(this.frame.canvas.height / this.pixelRatio),
43733 oldWidth: Math.round(oldWidth / this.pixelRatio),
43734 oldHeight: Math.round(oldHeight / this.pixelRatio)
43735 }); // restore the camera on change.
43736
43737 this._setCameraState();
43738 } // set initialized so the get and set camera will work from now on.
43739
43740
43741 this.initialized = true;
43742 return emitEvent;
43743 }
43744 /**
43745 *
43746 * @returns {CanvasRenderingContext2D}
43747 */
43748
43749 }, {
43750 key: "getContext",
43751 value: function getContext() {
43752 return this.frame.canvas.getContext("2d");
43753 }
43754 /**
43755 * Determine the pixel ratio for various browsers.
43756 *
43757 * @returns {number}
43758 * @private
43759 */
43760
43761 }, {
43762 key: "_determinePixelRatio",
43763 value: function _determinePixelRatio() {
43764 var ctx = this.getContext();
43765
43766 if (ctx === undefined) {
43767 throw new Error("Could not get canvax context");
43768 }
43769
43770 var numerator = 1;
43771
43772 if (typeof window !== 'undefined') {
43773 // (window !== undefined) doesn't work here!
43774 // Protection during unit tests, where 'window' can be missing
43775 numerator = window.devicePixelRatio || 1;
43776 }
43777
43778 var denominator = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
43779 return numerator / denominator;
43780 }
43781 /**
43782 * Lazy determination of pixel ratio.
43783 *
43784 * @private
43785 */
43786
43787 }, {
43788 key: "_setPixelRatio",
43789 value: function _setPixelRatio() {
43790 this.pixelRatio = this._determinePixelRatio();
43791 }
43792 /**
43793 * Set the transform in the contained context, based on its pixelRatio
43794 */
43795
43796 }, {
43797 key: "setTransform",
43798 value: function setTransform() {
43799 var ctx = this.getContext();
43800
43801 if (ctx === undefined) {
43802 throw new Error("Could not get canvax context");
43803 }
43804
43805 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
43806 }
43807 /**
43808 * Convert the X coordinate in DOM-space (coordinate point in browser relative to the container div) to
43809 * the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon)
43810 * @param {number} x
43811 * @returns {number}
43812 * @private
43813 */
43814
43815 }, {
43816 key: "_XconvertDOMtoCanvas",
43817 value: function _XconvertDOMtoCanvas(x) {
43818 return (x - this.body.view.translation.x) / this.body.view.scale;
43819 }
43820 /**
43821 * Convert the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to
43822 * the X coordinate in DOM-space (coordinate point in browser relative to the container div)
43823 * @param {number} x
43824 * @returns {number}
43825 * @private
43826 */
43827
43828 }, {
43829 key: "_XconvertCanvasToDOM",
43830 value: function _XconvertCanvasToDOM(x) {
43831 return x * this.body.view.scale + this.body.view.translation.x;
43832 }
43833 /**
43834 * Convert the Y coordinate in DOM-space (coordinate point in browser relative to the container div) to
43835 * the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon)
43836 * @param {number} y
43837 * @returns {number}
43838 * @private
43839 */
43840
43841 }, {
43842 key: "_YconvertDOMtoCanvas",
43843 value: function _YconvertDOMtoCanvas(y) {
43844 return (y - this.body.view.translation.y) / this.body.view.scale;
43845 }
43846 /**
43847 * Convert the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to
43848 * the Y coordinate in DOM-space (coordinate point in browser relative to the container div)
43849 * @param {number} y
43850 * @returns {number}
43851 * @private
43852 */
43853
43854 }, {
43855 key: "_YconvertCanvasToDOM",
43856 value: function _YconvertCanvasToDOM(y) {
43857 return y * this.body.view.scale + this.body.view.translation.y;
43858 }
43859 /**
43860 * @param {point} pos
43861 * @returns {point}
43862 */
43863
43864 }, {
43865 key: "canvasToDOM",
43866 value: function canvasToDOM(pos) {
43867 return {
43868 x: this._XconvertCanvasToDOM(pos.x),
43869 y: this._YconvertCanvasToDOM(pos.y)
43870 };
43871 }
43872 /**
43873 *
43874 * @param {point} pos
43875 * @returns {point}
43876 */
43877
43878 }, {
43879 key: "DOMtoCanvas",
43880 value: function DOMtoCanvas(pos) {
43881 return {
43882 x: this._XconvertDOMtoCanvas(pos.x),
43883 y: this._YconvertDOMtoCanvas(pos.y)
43884 };
43885 }
43886 }]);
43887
43888 return Canvas;
43889 }();
43890
43891 var globalIsFinite = global_1.isFinite;
43892
43893 // `Number.isFinite` method
43894 // https://tc39.github.io/ecma262/#sec-number.isfinite
43895 var numberIsFinite = Number.isFinite || function isFinite(it) {
43896 return typeof it == 'number' && globalIsFinite(it);
43897 };
43898
43899 // `Number.isFinite` method
43900 // https://tc39.github.io/ecma262/#sec-number.isfinite
43901 _export({ target: 'Number', stat: true }, { isFinite: numberIsFinite });
43902
43903 /**
43904 * The view
43905 */
43906
43907 var View =
43908 /*#__PURE__*/
43909 function () {
43910 /**
43911 * @param {Object} body
43912 * @param {Canvas} canvas
43913 */
43914 function View(body, canvas) {
43915 var _this = this;
43916
43917 _classCallCheck(this, View);
43918
43919 this.body = body;
43920 this.canvas = canvas;
43921 this.animationSpeed = 1 / this.renderRefreshRate;
43922 this.animationEasingFunction = "easeInOutQuint";
43923 this.easingTime = 0;
43924 this.sourceScale = 0;
43925 this.targetScale = 0;
43926 this.sourceTranslation = 0;
43927 this.targetTranslation = 0;
43928 this.lockedOnNodeId = undefined;
43929 this.lockedOnNodeOffset = undefined;
43930 this.touchTime = 0;
43931 this.viewFunction = undefined;
43932 this.body.emitter.on("fit", this.fit.bind(this));
43933 this.body.emitter.on("animationFinished", function () {
43934 _this.body.emitter.emit("_stopRendering");
43935 });
43936 this.body.emitter.on("unlockNode", this.releaseNode.bind(this));
43937 }
43938 /**
43939 *
43940 * @param {Object} [options={}]
43941 */
43942
43943
43944 _createClass(View, [{
43945 key: "setOptions",
43946 value: function setOptions() {
43947 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
43948 this.options = options;
43949 }
43950 /**
43951 * This function zooms out to fit all data on screen based on amount of nodes
43952 * @param {Object} [options={{nodes=Array}}]
43953 * @param {boolean} [initialZoom=false] | zoom based on fitted formula or range, true = fitted, default = false;
43954 */
43955
43956 }, {
43957 key: "fit",
43958 value: function fit() {
43959 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
43960 nodes: []
43961 };
43962 var initialZoom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
43963 var range;
43964 var zoomLevel;
43965 options = Object.assign({}, options);
43966
43967 if (options.nodes === undefined || options.nodes.length === 0) {
43968 options.nodes = this.body.nodeIndices;
43969 }
43970
43971 if (initialZoom === true) {
43972 // check if more than half of the nodes have a predefined position. If so, we use the range, not the approximation.
43973 var positionDefined = 0;
43974
43975 for (var nodeId in this.body.nodes) {
43976 if (this.body.nodes.hasOwnProperty(nodeId)) {
43977 var node = this.body.nodes[nodeId];
43978
43979 if (node.predefinedPosition === true) {
43980 positionDefined += 1;
43981 }
43982 }
43983 }
43984
43985 if (positionDefined > 0.5 * this.body.nodeIndices.length) {
43986 this.fit(options, false);
43987 return;
43988 }
43989
43990 range = NetworkUtil.getRange(this.body.nodes, options.nodes);
43991 var numberOfNodes = this.body.nodeIndices.length;
43992 zoomLevel = 12.662 / (numberOfNodes + 7.4147) + 0.0964822; // this is obtained from fitting a dataset from 5 points with scale levels that looked good.
43993 // correct for larger canvasses.
43994
43995 var factor = Math.min(this.canvas.frame.canvas.clientWidth / 600, this.canvas.frame.canvas.clientHeight / 600);
43996 zoomLevel *= factor;
43997 } else {
43998 this.body.emitter.emit("_resizeNodes");
43999 range = NetworkUtil.getRange(this.body.nodes, options.nodes);
44000 var xDistance = Math.abs(range.maxX - range.minX) * 1.1;
44001 var yDistance = Math.abs(range.maxY - range.minY) * 1.1;
44002 var xZoomLevel = this.canvas.frame.canvas.clientWidth / xDistance;
44003 var yZoomLevel = this.canvas.frame.canvas.clientHeight / yDistance;
44004 zoomLevel = xZoomLevel <= yZoomLevel ? xZoomLevel : yZoomLevel;
44005 }
44006
44007 if (zoomLevel > 1.0) {
44008 zoomLevel = 1.0;
44009 } else if (zoomLevel === 0) {
44010 zoomLevel = 1.0;
44011 }
44012
44013 var center = NetworkUtil.findCenter(range);
44014 var animationOptions = {
44015 position: center,
44016 scale: zoomLevel,
44017 animation: options.animation
44018 };
44019 this.moveTo(animationOptions);
44020 } // animation
44021
44022 /**
44023 * Center a node in view.
44024 *
44025 * @param {number} nodeId
44026 * @param {number} [options]
44027 */
44028
44029 }, {
44030 key: "focus",
44031 value: function focus(nodeId) {
44032 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
44033
44034 if (this.body.nodes[nodeId] !== undefined) {
44035 var nodePosition = {
44036 x: this.body.nodes[nodeId].x,
44037 y: this.body.nodes[nodeId].y
44038 };
44039 options.position = nodePosition;
44040 options.lockedOnNode = nodeId;
44041 this.moveTo(options);
44042 } else {
44043 console.log("Node: " + nodeId + " cannot be found.");
44044 }
44045 }
44046 /**
44047 *
44048 * @param {Object} options | options.offset = {x:number, y:number} // offset from the center in DOM pixels
44049 * | options.scale = number // scale to move to
44050 * | options.position = {x:number, y:number} // position to move to
44051 * | options.animation = {duration:number, easingFunction:String} || Boolean // position to move to
44052 */
44053
44054 }, {
44055 key: "moveTo",
44056 value: function moveTo(options) {
44057 if (options === undefined) {
44058 options = {};
44059 return;
44060 }
44061
44062 if (options.offset != null) {
44063 if (options.offset.x != null) {
44064 // Coerce and verify that x is valid.
44065 options.offset.x = +options.offset.x;
44066
44067 if (!Number.isFinite(options.offset.x)) {
44068 throw new TypeError('The option "offset.x" has to be a finite number.');
44069 }
44070 } else {
44071 options.offset.x = 0;
44072 }
44073
44074 if (options.offset.y != null) {
44075 // Coerce and verify that y is valid.
44076 options.offset.y = +options.offset.y;
44077
44078 if (!Number.isFinite(options.offset.y)) {
44079 throw new TypeError('The option "offset.y" has to be a finite number.');
44080 }
44081 } else {
44082 options.offset.x = 0;
44083 }
44084 } else {
44085 options.offset = {
44086 x: 0,
44087 y: 0
44088 };
44089 }
44090
44091 if (options.position != null) {
44092 if (options.position.x != null) {
44093 // Coerce and verify that x is valid.
44094 options.position.x = +options.position.x;
44095
44096 if (!Number.isFinite(options.position.x)) {
44097 throw new TypeError('The option "position.x" has to be a finite number.');
44098 }
44099 } else {
44100 options.position.x = 0;
44101 }
44102
44103 if (options.position.y != null) {
44104 // Coerce and verify that y is valid.
44105 options.position.y = +options.position.y;
44106
44107 if (!Number.isFinite(options.position.y)) {
44108 throw new TypeError('The option "position.y" has to be a finite number.');
44109 }
44110 } else {
44111 options.position.x = 0;
44112 }
44113 } else {
44114 options.position = this.getViewPosition();
44115 }
44116
44117 if (options.scale != null) {
44118 // Coerce and verify that the scale is valid.
44119 options.scale = +options.scale;
44120
44121 if (!(options.scale > 0)) {
44122 throw new TypeError('The option "scale" has to be a number greater than zero.');
44123 }
44124 } else {
44125 options.scale = this.body.view.scale;
44126 }
44127
44128 if (options.animation === undefined) {
44129 options.animation = {
44130 duration: 0
44131 };
44132 }
44133
44134 if (options.animation === false) {
44135 options.animation = {
44136 duration: 0
44137 };
44138 }
44139
44140 if (options.animation === true) {
44141 options.animation = {};
44142 }
44143
44144 if (options.animation.duration === undefined) {
44145 options.animation.duration = 1000;
44146 } // default duration
44147
44148
44149 if (options.animation.easingFunction === undefined) {
44150 options.animation.easingFunction = "easeInOutQuad";
44151 } // default easing function
44152
44153
44154 this.animateView(options);
44155 }
44156 /**
44157 *
44158 * @param {Object} options | options.offset = {x:number, y:number} // offset from the center in DOM pixels
44159 * | options.time = number // animation time in milliseconds
44160 * | options.scale = number // scale to animate to
44161 * | options.position = {x:number, y:number} // position to animate to
44162 * | options.easingFunction = String // linear, easeInQuad, easeOutQuad, easeInOutQuad,
44163 * // easeInCubic, easeOutCubic, easeInOutCubic,
44164 * // easeInQuart, easeOutQuart, easeInOutQuart,
44165 * // easeInQuint, easeOutQuint, easeInOutQuint
44166 */
44167
44168 }, {
44169 key: "animateView",
44170 value: function animateView(options) {
44171 if (options === undefined) {
44172 return;
44173 }
44174
44175 this.animationEasingFunction = options.animation.easingFunction; // release if something focussed on the node
44176
44177 this.releaseNode();
44178
44179 if (options.locked === true) {
44180 this.lockedOnNodeId = options.lockedOnNode;
44181 this.lockedOnNodeOffset = options.offset;
44182 } // forcefully complete the old animation if it was still running
44183
44184
44185 if (this.easingTime != 0) {
44186 this._transitionRedraw(true); // by setting easingtime to 1, we finish the animation.
44187
44188 }
44189
44190 this.sourceScale = this.body.view.scale;
44191 this.sourceTranslation = this.body.view.translation;
44192 this.targetScale = options.scale; // set the scale so the viewCenter is based on the correct zoom level. This is overridden in the transitionRedraw
44193 // but at least then we'll have the target transition
44194
44195 this.body.view.scale = this.targetScale;
44196 var viewCenter = this.canvas.DOMtoCanvas({
44197 x: 0.5 * this.canvas.frame.canvas.clientWidth,
44198 y: 0.5 * this.canvas.frame.canvas.clientHeight
44199 });
44200 var distanceFromCenter = {
44201 // offset from view, distance view has to change by these x and y to center the node
44202 x: viewCenter.x - options.position.x,
44203 y: viewCenter.y - options.position.y
44204 };
44205 this.targetTranslation = {
44206 x: this.sourceTranslation.x + distanceFromCenter.x * this.targetScale + options.offset.x,
44207 y: this.sourceTranslation.y + distanceFromCenter.y * this.targetScale + options.offset.y
44208 }; // if the time is set to 0, don't do an animation
44209
44210 if (options.animation.duration === 0) {
44211 if (this.lockedOnNodeId != undefined) {
44212 this.viewFunction = this._lockedRedraw.bind(this);
44213 this.body.emitter.on("initRedraw", this.viewFunction);
44214 } else {
44215 this.body.view.scale = this.targetScale;
44216 this.body.view.translation = this.targetTranslation;
44217 this.body.emitter.emit("_requestRedraw");
44218 }
44219 } else {
44220 this.animationSpeed = 1 / (60 * options.animation.duration * 0.001) || 1 / 60; // 60 for 60 seconds, 0.001 for milli's
44221
44222 this.animationEasingFunction = options.animation.easingFunction;
44223 this.viewFunction = this._transitionRedraw.bind(this);
44224 this.body.emitter.on("initRedraw", this.viewFunction);
44225 this.body.emitter.emit("_startRendering");
44226 }
44227 }
44228 /**
44229 * used to animate smoothly by hijacking the redraw function.
44230 * @private
44231 */
44232
44233 }, {
44234 key: "_lockedRedraw",
44235 value: function _lockedRedraw() {
44236 var nodePosition = {
44237 x: this.body.nodes[this.lockedOnNodeId].x,
44238 y: this.body.nodes[this.lockedOnNodeId].y
44239 };
44240 var viewCenter = this.canvas.DOMtoCanvas({
44241 x: 0.5 * this.canvas.frame.canvas.clientWidth,
44242 y: 0.5 * this.canvas.frame.canvas.clientHeight
44243 });
44244 var distanceFromCenter = {
44245 // offset from view, distance view has to change by these x and y to center the node
44246 x: viewCenter.x - nodePosition.x,
44247 y: viewCenter.y - nodePosition.y
44248 };
44249 var sourceTranslation = this.body.view.translation;
44250 var targetTranslation = {
44251 x: sourceTranslation.x + distanceFromCenter.x * this.body.view.scale + this.lockedOnNodeOffset.x,
44252 y: sourceTranslation.y + distanceFromCenter.y * this.body.view.scale + this.lockedOnNodeOffset.y
44253 };
44254 this.body.view.translation = targetTranslation;
44255 }
44256 /**
44257 * Resets state of a locked on Node
44258 */
44259
44260 }, {
44261 key: "releaseNode",
44262 value: function releaseNode() {
44263 if (this.lockedOnNodeId !== undefined && this.viewFunction !== undefined) {
44264 this.body.emitter.off("initRedraw", this.viewFunction);
44265 this.lockedOnNodeId = undefined;
44266 this.lockedOnNodeOffset = undefined;
44267 }
44268 }
44269 /**
44270 * @param {boolean} [finished=false]
44271 * @private
44272 */
44273
44274 }, {
44275 key: "_transitionRedraw",
44276 value: function _transitionRedraw() {
44277 var finished = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
44278 this.easingTime += this.animationSpeed;
44279 this.easingTime = finished === true ? 1.0 : this.easingTime;
44280 var progress = easingFunctions[this.animationEasingFunction](this.easingTime);
44281 this.body.view.scale = this.sourceScale + (this.targetScale - this.sourceScale) * progress;
44282 this.body.view.translation = {
44283 x: this.sourceTranslation.x + (this.targetTranslation.x - this.sourceTranslation.x) * progress,
44284 y: this.sourceTranslation.y + (this.targetTranslation.y - this.sourceTranslation.y) * progress
44285 }; // cleanup
44286
44287 if (this.easingTime >= 1.0) {
44288 this.body.emitter.off("initRedraw", this.viewFunction);
44289 this.easingTime = 0;
44290
44291 if (this.lockedOnNodeId != undefined) {
44292 this.viewFunction = this._lockedRedraw.bind(this);
44293 this.body.emitter.on("initRedraw", this.viewFunction);
44294 }
44295
44296 this.body.emitter.emit("animationFinished");
44297 }
44298 }
44299 /**
44300 *
44301 * @returns {number}
44302 */
44303
44304 }, {
44305 key: "getScale",
44306 value: function getScale() {
44307 return this.body.view.scale;
44308 }
44309 /**
44310 *
44311 * @returns {{x: number, y: number}}
44312 */
44313
44314 }, {
44315 key: "getViewPosition",
44316 value: function getViewPosition() {
44317 return this.canvas.DOMtoCanvas({
44318 x: 0.5 * this.canvas.frame.canvas.clientWidth,
44319 y: 0.5 * this.canvas.frame.canvas.clientHeight
44320 });
44321 }
44322 }]);
44323
44324 return View;
44325 }();
44326
44327 var css$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.30);\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\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk5hdmlnYXRpb25IYW5kbGVyLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtJQUNJLFVBQVU7SUFDVixXQUFXO0lBQ1gsd0JBQXdCO0lBQ3hCLG1CQUFtQjtJQUNuQixpQkFBaUI7SUFDakIsb0JBQW9CO0lBQ3BCLDRCQUE0QjtJQUM1QiwyQkFBMkI7SUFDM0IsZUFBZTtJQUNmLDJCQUEyQjtJQUMzQix5QkFBeUI7SUFDekIsd0JBQXdCO0lBQ3hCLHNCQUFzQjtJQUN0QixxQkFBcUI7SUFDckIsaUJBQWlCO0FBQ3JCOztBQUVBO0lBQ0ksK0NBQStDO0FBQ25EOztBQUVBO0lBQ0ksK0NBQStDO0FBQ25EOztBQUVBO0lBQ0ksMjJMQUF1QztJQUN2QyxXQUFXO0lBQ1gsU0FBUztBQUNiO0FBQ0E7SUFDSSwyMkxBQXlDO0lBQ3pDLFdBQVc7SUFDWCxTQUFTO0FBQ2I7QUFDQTtJQUNJLDI4TEFBeUM7SUFDekMsV0FBVztJQUNYLFNBQVM7QUFDYjtBQUNBO0lBQ0ksbTdMQUEwQztJQUMxQyxXQUFXO0lBQ1gsU0FBUztBQUNiO0FBQ0E7SUFDSSwyc0xBQW9DO0lBQ3BDLFdBQVc7SUFDWCxVQUFVO0FBQ2Q7QUFDQTtJQUNJLDI4S0FBcUM7SUFDckMsV0FBVztJQUNYLFVBQVU7QUFDZDtBQUNBO0lBQ0ksKzJMQUEyQztJQUMzQyxXQUFXO0lBQ1gsVUFBVTtBQUNkIiwiZmlsZSI6Ik5hdmlnYXRpb25IYW5kbGVyLmNzcyIsInNvdXJjZXNDb250ZW50IjpbImRpdi52aXMtbmV0d29yayBkaXYudmlzLW5hdmlnYXRpb24gZGl2LnZpcy1idXR0b24ge1xuICAgIHdpZHRoOjM0cHg7XG4gICAgaGVpZ2h0OjM0cHg7XG4gICAgLW1vei1ib3JkZXItcmFkaXVzOiAxN3B4O1xuICAgIGJvcmRlci1yYWRpdXM6IDE3cHg7XG4gICAgcG9zaXRpb246YWJzb2x1dGU7XG4gICAgZGlzcGxheTppbmxpbmUtYmxvY2s7XG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogMnB4IDJweDtcbiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTtcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xuICAgIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xuICAgIC1tcy11c2VyLXNlbGVjdDogbm9uZTtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcbn1cblxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbmF2aWdhdGlvbiBkaXYudmlzLWJ1dHRvbjpob3ZlciB7XG4gICAgYm94LXNoYWRvdzogMCAwIDNweCAzcHggcmdiYSg1NiwgMjA3LCAyMSwgMC4zMCk7XG59XG5cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLW5hdmlnYXRpb24gZGl2LnZpcy1idXR0b246YWN0aXZlIHtcbiAgICBib3gtc2hhZG93OiAwIDAgMXB4IDNweCByZ2JhKDU2LCAyMDcsIDIxLCAwLjk1KTtcbn1cblxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbmF2aWdhdGlvbiBkaXYudmlzLWJ1dHRvbi52aXMtdXAge1xuICAgIGJhY2tncm91bmQtaW1hZ2U6IGlubGluZShcInVwQXJyb3cucG5nXCIpO1xuICAgIGJvdHRvbTo1MHB4O1xuICAgIGxlZnQ6NTVweDtcbn1cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLW5hdmlnYXRpb24gZGl2LnZpcy1idXR0b24udmlzLWRvd24ge1xuICAgIGJhY2tncm91bmQtaW1hZ2U6IGlubGluZShcImRvd25BcnJvdy5wbmdcIik7XG4gICAgYm90dG9tOjEwcHg7XG4gICAgbGVmdDo1NXB4O1xufVxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbmF2aWdhdGlvbiBkaXYudmlzLWJ1dHRvbi52aXMtbGVmdCB7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwibGVmdEFycm93LnBuZ1wiKTtcbiAgICBib3R0b206MTBweDtcbiAgICBsZWZ0OjE1cHg7XG59XG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1uYXZpZ2F0aW9uIGRpdi52aXMtYnV0dG9uLnZpcy1yaWdodCB7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwicmlnaHRBcnJvdy5wbmdcIik7XG4gICAgYm90dG9tOjEwcHg7XG4gICAgbGVmdDo5NXB4O1xufVxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbmF2aWdhdGlvbiBkaXYudmlzLWJ1dHRvbi52aXMtem9vbUluIHtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiBpbmxpbmUoXCJwbHVzLnBuZ1wiKTtcbiAgICBib3R0b206MTBweDtcbiAgICByaWdodDoxNXB4O1xufVxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbmF2aWdhdGlvbiBkaXYudmlzLWJ1dHRvbi52aXMtem9vbU91dCB7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwibWludXMucG5nXCIpO1xuICAgIGJvdHRvbToxMHB4O1xuICAgIHJpZ2h0OjU1cHg7XG59XG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1uYXZpZ2F0aW9uIGRpdi52aXMtYnV0dG9uLnZpcy16b29tRXh0ZW5kcyB7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwiem9vbUV4dGVuZHMucG5nXCIpO1xuICAgIGJvdHRvbTo1MHB4O1xuICAgIHJpZ2h0OjE1cHg7XG59XG4iXX0= */";
44328 styleInject(css$1);
44329
44330 /**
44331 * Navigation Handler
44332 */
44333
44334 var NavigationHandler =
44335 /*#__PURE__*/
44336 function () {
44337 /**
44338 * @param {Object} body
44339 * @param {Canvas} canvas
44340 */
44341 function NavigationHandler(body, canvas) {
44342 var _this = this;
44343
44344 _classCallCheck(this, NavigationHandler);
44345
44346 this.body = body;
44347 this.canvas = canvas;
44348 this.iconsCreated = false;
44349 this.navigationHammers = [];
44350 this.boundFunctions = {};
44351 this.touchTime = 0;
44352 this.activated = false;
44353 this.body.emitter.on("activate", function () {
44354 _this.activated = true;
44355
44356 _this.configureKeyboardBindings();
44357 });
44358 this.body.emitter.on("deactivate", function () {
44359 _this.activated = false;
44360
44361 _this.configureKeyboardBindings();
44362 });
44363 this.body.emitter.on("destroy", function () {
44364 if (_this.keycharm !== undefined) {
44365 _this.keycharm.destroy();
44366 }
44367 });
44368 this.options = {};
44369 }
44370 /**
44371 *
44372 * @param {Object} options
44373 */
44374
44375
44376 _createClass(NavigationHandler, [{
44377 key: "setOptions",
44378 value: function setOptions(options) {
44379 if (options !== undefined) {
44380 this.options = options;
44381 this.create();
44382 }
44383 }
44384 /**
44385 * Creates or refreshes navigation and sets key bindings
44386 */
44387
44388 }, {
44389 key: "create",
44390 value: function create() {
44391 if (this.options.navigationButtons === true) {
44392 if (this.iconsCreated === false) {
44393 this.loadNavigationElements();
44394 }
44395 } else if (this.iconsCreated === true) {
44396 this.cleanNavigation();
44397 }
44398
44399 this.configureKeyboardBindings();
44400 }
44401 /**
44402 * Cleans up previous navigation items
44403 */
44404
44405 }, {
44406 key: "cleanNavigation",
44407 value: function cleanNavigation() {
44408 // clean hammer bindings
44409 if (this.navigationHammers.length != 0) {
44410 for (var i = 0; i < this.navigationHammers.length; i++) {
44411 this.navigationHammers[i].destroy();
44412 }
44413
44414 this.navigationHammers = [];
44415 } // clean up previous navigation items
44416
44417
44418 if (this.navigationDOM && this.navigationDOM['wrapper'] && this.navigationDOM['wrapper'].parentNode) {
44419 this.navigationDOM['wrapper'].parentNode.removeChild(this.navigationDOM['wrapper']);
44420 }
44421
44422 this.iconsCreated = false;
44423 }
44424 /**
44425 * Creation of the navigation controls nodes. They are drawn over the rest of the nodes and are not affected by scale and translation
44426 * they have a triggerFunction which is called on click. If the position of the navigation controls is dependent
44427 * on this.frame.canvas.clientWidth or this.frame.canvas.clientHeight, we flag horizontalAlignLeft and verticalAlignTop false.
44428 * This means that the location will be corrected by the _relocateNavigation function on a size change of the canvas.
44429 *
44430 * @private
44431 */
44432
44433 }, {
44434 key: "loadNavigationElements",
44435 value: function loadNavigationElements() {
44436 var _this2 = this;
44437
44438 this.cleanNavigation();
44439 this.navigationDOM = {};
44440 var navigationDivs = ['up', 'down', 'left', 'right', 'zoomIn', 'zoomOut', 'zoomExtends'];
44441 var navigationDivActions = ['_moveUp', '_moveDown', '_moveLeft', '_moveRight', '_zoomIn', '_zoomOut', '_fit'];
44442 this.navigationDOM['wrapper'] = document.createElement('div');
44443 this.navigationDOM['wrapper'].className = 'vis-navigation';
44444 this.canvas.frame.appendChild(this.navigationDOM['wrapper']);
44445
44446 for (var i = 0; i < navigationDivs.length; i++) {
44447 this.navigationDOM[navigationDivs[i]] = document.createElement('div');
44448 this.navigationDOM[navigationDivs[i]].className = 'vis-button vis-' + navigationDivs[i];
44449 this.navigationDOM['wrapper'].appendChild(this.navigationDOM[navigationDivs[i]]);
44450 var hammer$1 = new hammer(this.navigationDOM[navigationDivs[i]]);
44451
44452 if (navigationDivActions[i] === "_fit") {
44453 hammerUtil.onTouch(hammer$1, this._fit.bind(this));
44454 } else {
44455 hammerUtil.onTouch(hammer$1, this.bindToRedraw.bind(this, navigationDivActions[i]));
44456 }
44457
44458 this.navigationHammers.push(hammer$1);
44459 } // use a hammer for the release so we do not require the one used in the rest of the network
44460 // the one the rest uses can be overloaded by the manipulation system.
44461
44462
44463 var hammerFrame = new hammer(this.canvas.frame);
44464 hammerUtil.onRelease(hammerFrame, function () {
44465 _this2._stopMovement();
44466 });
44467 this.navigationHammers.push(hammerFrame);
44468 this.iconsCreated = true;
44469 }
44470 /**
44471 *
44472 * @param {string} action
44473 */
44474
44475 }, {
44476 key: "bindToRedraw",
44477 value: function bindToRedraw(action) {
44478 if (this.boundFunctions[action] === undefined) {
44479 this.boundFunctions[action] = this[action].bind(this);
44480 this.body.emitter.on("initRedraw", this.boundFunctions[action]);
44481 this.body.emitter.emit("_startRendering");
44482 }
44483 }
44484 /**
44485 *
44486 * @param {string} action
44487 */
44488
44489 }, {
44490 key: "unbindFromRedraw",
44491 value: function unbindFromRedraw(action) {
44492 if (this.boundFunctions[action] !== undefined) {
44493 this.body.emitter.off("initRedraw", this.boundFunctions[action]);
44494 this.body.emitter.emit("_stopRendering");
44495 delete this.boundFunctions[action];
44496 }
44497 }
44498 /**
44499 * this stops all movement induced by the navigation buttons
44500 *
44501 * @private
44502 */
44503
44504 }, {
44505 key: "_fit",
44506 value: function _fit() {
44507 if (new Date().valueOf() - this.touchTime > 700) {
44508 // TODO: fix ugly hack to avoid hammer's double fireing of event (because we use release?)
44509 this.body.emitter.emit("fit", {
44510 duration: 700
44511 });
44512 this.touchTime = new Date().valueOf();
44513 }
44514 }
44515 /**
44516 * this stops all movement induced by the navigation buttons
44517 *
44518 * @private
44519 */
44520
44521 }, {
44522 key: "_stopMovement",
44523 value: function _stopMovement() {
44524 for (var boundAction in this.boundFunctions) {
44525 if (this.boundFunctions.hasOwnProperty(boundAction)) {
44526 this.body.emitter.off("initRedraw", this.boundFunctions[boundAction]);
44527 this.body.emitter.emit("_stopRendering");
44528 }
44529 }
44530
44531 this.boundFunctions = {};
44532 }
44533 /**
44534 *
44535 * @private
44536 */
44537
44538 }, {
44539 key: "_moveUp",
44540 value: function _moveUp() {
44541 this.body.view.translation.y += this.options.keyboard.speed.y;
44542 }
44543 /**
44544 *
44545 * @private
44546 */
44547
44548 }, {
44549 key: "_moveDown",
44550 value: function _moveDown() {
44551 this.body.view.translation.y -= this.options.keyboard.speed.y;
44552 }
44553 /**
44554 *
44555 * @private
44556 */
44557
44558 }, {
44559 key: "_moveLeft",
44560 value: function _moveLeft() {
44561 this.body.view.translation.x += this.options.keyboard.speed.x;
44562 }
44563 /**
44564 *
44565 * @private
44566 */
44567
44568 }, {
44569 key: "_moveRight",
44570 value: function _moveRight() {
44571 this.body.view.translation.x -= this.options.keyboard.speed.x;
44572 }
44573 /**
44574 *
44575 * @private
44576 */
44577
44578 }, {
44579 key: "_zoomIn",
44580 value: function _zoomIn() {
44581 var scaleOld = this.body.view.scale;
44582 var scale = this.body.view.scale * (1 + this.options.keyboard.speed.zoom);
44583 var translation = this.body.view.translation;
44584 var scaleFrac = scale / scaleOld;
44585 var tx = (1 - scaleFrac) * this.canvas.canvasViewCenter.x + translation.x * scaleFrac;
44586 var ty = (1 - scaleFrac) * this.canvas.canvasViewCenter.y + translation.y * scaleFrac;
44587 this.body.view.scale = scale;
44588 this.body.view.translation = {
44589 x: tx,
44590 y: ty
44591 };
44592 this.body.emitter.emit('zoom', {
44593 direction: '+',
44594 scale: this.body.view.scale,
44595 pointer: null
44596 });
44597 }
44598 /**
44599 *
44600 * @private
44601 */
44602
44603 }, {
44604 key: "_zoomOut",
44605 value: function _zoomOut() {
44606 var scaleOld = this.body.view.scale;
44607 var scale = this.body.view.scale / (1 + this.options.keyboard.speed.zoom);
44608 var translation = this.body.view.translation;
44609 var scaleFrac = scale / scaleOld;
44610 var tx = (1 - scaleFrac) * this.canvas.canvasViewCenter.x + translation.x * scaleFrac;
44611 var ty = (1 - scaleFrac) * this.canvas.canvasViewCenter.y + translation.y * scaleFrac;
44612 this.body.view.scale = scale;
44613 this.body.view.translation = {
44614 x: tx,
44615 y: ty
44616 };
44617 this.body.emitter.emit('zoom', {
44618 direction: '-',
44619 scale: this.body.view.scale,
44620 pointer: null
44621 });
44622 }
44623 /**
44624 * bind all keys using keycharm.
44625 */
44626
44627 }, {
44628 key: "configureKeyboardBindings",
44629 value: function configureKeyboardBindings() {
44630 var _this3 = this;
44631
44632 if (this.keycharm !== undefined) {
44633 this.keycharm.destroy();
44634 }
44635
44636 if (this.options.keyboard.enabled === true) {
44637 if (this.options.keyboard.bindToWindow === true) {
44638 this.keycharm = keycharm({
44639 container: window,
44640 preventDefault: true
44641 });
44642 } else {
44643 this.keycharm = keycharm({
44644 container: this.canvas.frame,
44645 preventDefault: true
44646 });
44647 }
44648
44649 this.keycharm.reset();
44650
44651 if (this.activated === true) {
44652 this.keycharm.bind("up", function () {
44653 _this3.bindToRedraw("_moveUp");
44654 }, "keydown");
44655 this.keycharm.bind("down", function () {
44656 _this3.bindToRedraw("_moveDown");
44657 }, "keydown");
44658 this.keycharm.bind("left", function () {
44659 _this3.bindToRedraw("_moveLeft");
44660 }, "keydown");
44661 this.keycharm.bind("right", function () {
44662 _this3.bindToRedraw("_moveRight");
44663 }, "keydown");
44664 this.keycharm.bind("=", function () {
44665 _this3.bindToRedraw("_zoomIn");
44666 }, "keydown");
44667 this.keycharm.bind("num+", function () {
44668 _this3.bindToRedraw("_zoomIn");
44669 }, "keydown");
44670 this.keycharm.bind("num-", function () {
44671 _this3.bindToRedraw("_zoomOut");
44672 }, "keydown");
44673 this.keycharm.bind("-", function () {
44674 _this3.bindToRedraw("_zoomOut");
44675 }, "keydown");
44676 this.keycharm.bind("[", function () {
44677 _this3.bindToRedraw("_zoomOut");
44678 }, "keydown");
44679 this.keycharm.bind("]", function () {
44680 _this3.bindToRedraw("_zoomIn");
44681 }, "keydown");
44682 this.keycharm.bind("pageup", function () {
44683 _this3.bindToRedraw("_zoomIn");
44684 }, "keydown");
44685 this.keycharm.bind("pagedown", function () {
44686 _this3.bindToRedraw("_zoomOut");
44687 }, "keydown");
44688 this.keycharm.bind("up", function () {
44689 _this3.unbindFromRedraw("_moveUp");
44690 }, "keyup");
44691 this.keycharm.bind("down", function () {
44692 _this3.unbindFromRedraw("_moveDown");
44693 }, "keyup");
44694 this.keycharm.bind("left", function () {
44695 _this3.unbindFromRedraw("_moveLeft");
44696 }, "keyup");
44697 this.keycharm.bind("right", function () {
44698 _this3.unbindFromRedraw("_moveRight");
44699 }, "keyup");
44700 this.keycharm.bind("=", function () {
44701 _this3.unbindFromRedraw("_zoomIn");
44702 }, "keyup");
44703 this.keycharm.bind("num+", function () {
44704 _this3.unbindFromRedraw("_zoomIn");
44705 }, "keyup");
44706 this.keycharm.bind("num-", function () {
44707 _this3.unbindFromRedraw("_zoomOut");
44708 }, "keyup");
44709 this.keycharm.bind("-", function () {
44710 _this3.unbindFromRedraw("_zoomOut");
44711 }, "keyup");
44712 this.keycharm.bind("[", function () {
44713 _this3.unbindFromRedraw("_zoomOut");
44714 }, "keyup");
44715 this.keycharm.bind("]", function () {
44716 _this3.unbindFromRedraw("_zoomIn");
44717 }, "keyup");
44718 this.keycharm.bind("pageup", function () {
44719 _this3.unbindFromRedraw("_zoomIn");
44720 }, "keyup");
44721 this.keycharm.bind("pagedown", function () {
44722 _this3.unbindFromRedraw("_zoomOut");
44723 }, "keyup");
44724 }
44725 }
44726 }
44727 }]);
44728
44729 return NavigationHandler;
44730 }();
44731
44732 var css$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\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlBvcHVwLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLGtCQUFrQjtFQUNsQixrQkFBa0I7RUFDbEIsWUFBWTtFQUNaLG1CQUFtQjs7RUFFbkIsb0JBQW9CO0VBQ3BCLGNBQWM7RUFDZCxhQUFhO0VBQ2IseUJBQXlCOztFQUV6Qix1QkFBdUI7RUFDdkIsMEJBQTBCO0VBQzFCLGtCQUFrQjtFQUNsQix5QkFBeUI7O0VBRXpCLDJDQUEyQztFQUMzQyxvQkFBb0I7O0VBRXBCLFVBQVU7QUFDWiIsImZpbGUiOiJQb3B1cC5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJkaXYudmlzLXRvb2x0aXAge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHZpc2liaWxpdHk6IGhpZGRlbjtcbiAgcGFkZGluZzogNXB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuXG4gIGZvbnQtZmFtaWx5OiB2ZXJkYW5hO1xuICBmb250LXNpemU6MTRweDtcbiAgY29sb3I6IzAwMDAwMDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjRlZDtcblxuICAtbW96LWJvcmRlci1yYWRpdXM6IDNweDtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAzcHg7XG4gIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgYm9yZGVyOiAxcHggc29saWQgIzgwODA3NDtcblxuICBib3gtc2hhZG93OiAzcHggM3B4IDEwcHggcmdiYSgwLCAwLCAwLCAwLjIpO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcblxuICB6LWluZGV4OiA1O1xufVxuIl19 */";
44733 styleInject(css$2);
44734
44735 /**
44736 * Popup is a class to create a popup window with some text
44737 */
44738
44739 var Popup =
44740 /*#__PURE__*/
44741 function () {
44742 /**
44743 * @param {Element} container The container object.
44744 * @param {string} overflowMethod How the popup should act to overflowing ('flip' or 'cap')
44745 */
44746 function Popup(container, overflowMethod) {
44747 _classCallCheck(this, Popup);
44748
44749 this.container = container;
44750 this.overflowMethod = overflowMethod || 'cap';
44751 this.x = 0;
44752 this.y = 0;
44753 this.padding = 5;
44754 this.hidden = false; // create the frame
44755
44756 this.frame = document.createElement('div');
44757 this.frame.className = 'vis-tooltip';
44758 this.container.appendChild(this.frame);
44759 }
44760 /**
44761 * @param {number} x Horizontal position of the popup window
44762 * @param {number} y Vertical position of the popup window
44763 */
44764
44765
44766 _createClass(Popup, [{
44767 key: "setPosition",
44768 value: function setPosition(x, y) {
44769 this.x = parseInt(x);
44770 this.y = parseInt(y);
44771 }
44772 /**
44773 * Set the content for the popup window. This can be HTML code or text.
44774 * @param {string | Element} content
44775 */
44776
44777 }, {
44778 key: "setText",
44779 value: function setText(content) {
44780 if (content instanceof Element) {
44781 this.frame.innerHTML = '';
44782 this.frame.appendChild(content);
44783 } else {
44784 this.frame.innerHTML = content; // string containing text or HTML
44785 }
44786 }
44787 /**
44788 * Show the popup window
44789 * @param {boolean} [doShow] Show or hide the window
44790 */
44791
44792 }, {
44793 key: "show",
44794 value: function show(doShow) {
44795 if (doShow === undefined) {
44796 doShow = true;
44797 }
44798
44799 if (doShow === true) {
44800 var height = this.frame.clientHeight;
44801 var width = this.frame.clientWidth;
44802 var maxHeight = this.frame.parentNode.clientHeight;
44803 var maxWidth = this.frame.parentNode.clientWidth;
44804 var left = 0,
44805 top = 0;
44806
44807 if (this.overflowMethod == 'flip') {
44808 var isLeft = false,
44809 isTop = true; // Where around the position it's located
44810
44811 if (this.y - height < this.padding) {
44812 isTop = false;
44813 }
44814
44815 if (this.x + width > maxWidth - this.padding) {
44816 isLeft = true;
44817 }
44818
44819 if (isLeft) {
44820 left = this.x - width;
44821 } else {
44822 left = this.x;
44823 }
44824
44825 if (isTop) {
44826 top = this.y - height;
44827 } else {
44828 top = this.y;
44829 }
44830 } else {
44831 top = this.y - height;
44832
44833 if (top + height + this.padding > maxHeight) {
44834 top = maxHeight - height - this.padding;
44835 }
44836
44837 if (top < this.padding) {
44838 top = this.padding;
44839 }
44840
44841 left = this.x;
44842
44843 if (left + width + this.padding > maxWidth) {
44844 left = maxWidth - width - this.padding;
44845 }
44846
44847 if (left < this.padding) {
44848 left = this.padding;
44849 }
44850 }
44851
44852 this.frame.style.left = left + "px";
44853 this.frame.style.top = top + "px";
44854 this.frame.style.visibility = "visible";
44855 this.hidden = false;
44856 } else {
44857 this.hide();
44858 }
44859 }
44860 /**
44861 * Hide the popup window
44862 */
44863
44864 }, {
44865 key: "hide",
44866 value: function hide() {
44867 this.hidden = true;
44868 this.frame.style.left = "0";
44869 this.frame.style.top = "0";
44870 this.frame.style.visibility = "hidden";
44871 }
44872 /**
44873 * Remove the popup window
44874 */
44875
44876 }, {
44877 key: "destroy",
44878 value: function destroy() {
44879 this.frame.parentNode.removeChild(this.frame); // Remove element from DOM
44880 }
44881 }]);
44882
44883 return Popup;
44884 }();
44885
44886 /**
44887 * Handler for interactions
44888 */
44889
44890 var InteractionHandler =
44891 /*#__PURE__*/
44892 function () {
44893 /**
44894 * @param {Object} body
44895 * @param {Canvas} canvas
44896 * @param {SelectionHandler} selectionHandler
44897 */
44898 function InteractionHandler(body, canvas, selectionHandler) {
44899 _classCallCheck(this, InteractionHandler);
44900
44901 this.body = body;
44902 this.canvas = canvas;
44903 this.selectionHandler = selectionHandler;
44904 this.navigationHandler = new NavigationHandler(body, canvas); // bind the events from hammer to functions in this object
44905
44906 this.body.eventListeners.onTap = this.onTap.bind(this);
44907 this.body.eventListeners.onTouch = this.onTouch.bind(this);
44908 this.body.eventListeners.onDoubleTap = this.onDoubleTap.bind(this);
44909 this.body.eventListeners.onHold = this.onHold.bind(this);
44910 this.body.eventListeners.onDragStart = this.onDragStart.bind(this);
44911 this.body.eventListeners.onDrag = this.onDrag.bind(this);
44912 this.body.eventListeners.onDragEnd = this.onDragEnd.bind(this);
44913 this.body.eventListeners.onMouseWheel = this.onMouseWheel.bind(this);
44914 this.body.eventListeners.onPinch = this.onPinch.bind(this);
44915 this.body.eventListeners.onMouseMove = this.onMouseMove.bind(this);
44916 this.body.eventListeners.onRelease = this.onRelease.bind(this);
44917 this.body.eventListeners.onContext = this.onContext.bind(this);
44918 this.touchTime = 0;
44919 this.drag = {};
44920 this.pinch = {};
44921 this.popup = undefined;
44922 this.popupObj = undefined;
44923 this.popupTimer = undefined;
44924 this.body.functions.getPointer = this.getPointer.bind(this);
44925 this.options = {};
44926 this.defaultOptions = {
44927 dragNodes: true,
44928 dragView: true,
44929 hover: false,
44930 keyboard: {
44931 enabled: false,
44932 speed: {
44933 x: 10,
44934 y: 10,
44935 zoom: 0.02
44936 },
44937 bindToWindow: true
44938 },
44939 navigationButtons: false,
44940 tooltipDelay: 300,
44941 zoomView: true,
44942 zoomSpeed: 1
44943 };
44944 extend(this.options, this.defaultOptions);
44945 this.bindEventListeners();
44946 }
44947 /**
44948 * Binds event listeners
44949 */
44950
44951
44952 _createClass(InteractionHandler, [{
44953 key: "bindEventListeners",
44954 value: function bindEventListeners() {
44955 var _this = this;
44956
44957 this.body.emitter.on('destroy', function () {
44958 clearTimeout(_this.popupTimer);
44959 delete _this.body.functions.getPointer;
44960 });
44961 }
44962 /**
44963 *
44964 * @param {Object} options
44965 */
44966
44967 }, {
44968 key: "setOptions",
44969 value: function setOptions(options) {
44970 if (options !== undefined) {
44971 // extend all but the values in fields
44972 var fields = ['hideEdgesOnDrag', 'hideEdgesOnZoom', 'hideNodesOnDrag', 'keyboard', 'multiselect', 'selectable', 'selectConnectedEdges'];
44973 selectiveNotDeepExtend(fields, this.options, options); // merge the keyboard options in.
44974
44975 mergeOptions(this.options, options, 'keyboard');
44976
44977 if (options.tooltip) {
44978 extend(this.options.tooltip, options.tooltip);
44979
44980 if (options.tooltip.color) {
44981 this.options.tooltip.color = parseColor(options.tooltip.color);
44982 }
44983 }
44984 }
44985
44986 this.navigationHandler.setOptions(this.options);
44987 }
44988 /**
44989 * Get the pointer location from a touch location
44990 * @param {{x: number, y: number}} touch
44991 * @return {{x: number, y: number}} pointer
44992 * @private
44993 */
44994
44995 }, {
44996 key: "getPointer",
44997 value: function getPointer(touch) {
44998 return {
44999 x: touch.x - getAbsoluteLeft(this.canvas.frame.canvas),
45000 y: touch.y - getAbsoluteTop(this.canvas.frame.canvas)
45001 };
45002 }
45003 /**
45004 * On start of a touch gesture, store the pointer
45005 * @param {Event} event The event
45006 * @private
45007 */
45008
45009 }, {
45010 key: "onTouch",
45011 value: function onTouch(event) {
45012 if (new Date().valueOf() - this.touchTime > 50) {
45013 this.drag.pointer = this.getPointer(event.center);
45014 this.drag.pinched = false;
45015 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)
45016
45017 this.touchTime = new Date().valueOf();
45018 }
45019 }
45020 /**
45021 * handle tap/click event: select/unselect a node
45022 * @param {Event} event
45023 * @private
45024 */
45025
45026 }, {
45027 key: "onTap",
45028 value: function onTap(event) {
45029 var pointer = this.getPointer(event.center);
45030 var multiselect = this.selectionHandler.options.multiselect && (event.changedPointers[0].ctrlKey || event.changedPointers[0].metaKey);
45031 this.checkSelectionChanges(pointer, event, multiselect);
45032
45033 this.selectionHandler._generateClickEvent('click', event, pointer);
45034 }
45035 /**
45036 * handle doubletap event
45037 * @param {Event} event
45038 * @private
45039 */
45040
45041 }, {
45042 key: "onDoubleTap",
45043 value: function onDoubleTap(event) {
45044 var pointer = this.getPointer(event.center);
45045
45046 this.selectionHandler._generateClickEvent('doubleClick', event, pointer);
45047 }
45048 /**
45049 * handle long tap event: multi select nodes
45050 * @param {Event} event
45051 * @private
45052 */
45053
45054 }, {
45055 key: "onHold",
45056 value: function onHold(event) {
45057 var pointer = this.getPointer(event.center);
45058 var multiselect = this.selectionHandler.options.multiselect;
45059 this.checkSelectionChanges(pointer, event, multiselect);
45060
45061 this.selectionHandler._generateClickEvent('click', event, pointer);
45062
45063 this.selectionHandler._generateClickEvent('hold', event, pointer);
45064 }
45065 /**
45066 * handle the release of the screen
45067 *
45068 * @param {Event} event
45069 * @private
45070 */
45071
45072 }, {
45073 key: "onRelease",
45074 value: function onRelease(event) {
45075 if (new Date().valueOf() - this.touchTime > 10) {
45076 var pointer = this.getPointer(event.center);
45077
45078 this.selectionHandler._generateClickEvent('release', event, pointer); // to avoid double fireing of this event because we have two hammer instances. (on canvas and on frame)
45079
45080
45081 this.touchTime = new Date().valueOf();
45082 }
45083 }
45084 /**
45085 *
45086 * @param {Event} event
45087 */
45088
45089 }, {
45090 key: "onContext",
45091 value: function onContext(event) {
45092 var pointer = this.getPointer({
45093 x: event.clientX,
45094 y: event.clientY
45095 });
45096
45097 this.selectionHandler._generateClickEvent('oncontext', event, pointer);
45098 }
45099 /**
45100 * Select and deselect nodes depending current selection change.
45101 *
45102 * For changing nodes, select/deselect events are fired.
45103 *
45104 * NOTE: For a given edge, if one connecting node is deselected and with the same
45105 * click the other node is selected, no events for the edge will fire.
45106 * It was selected and it will remain selected.
45107 *
45108 * TODO: This is all SelectionHandler calls; the method should be moved to there.
45109 *
45110 * @param {{x: number, y: number}} pointer
45111 * @param {Event} event
45112 * @param {boolean} [add=false]
45113 */
45114
45115 }, {
45116 key: "checkSelectionChanges",
45117 value: function checkSelectionChanges(pointer, event) {
45118 var add = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
45119 var previousSelection = this.selectionHandler.getSelection();
45120 var selected = false;
45121
45122 if (add === true) {
45123 selected = this.selectionHandler.selectAdditionalOnPoint(pointer);
45124 } else {
45125 selected = this.selectionHandler.selectOnPoint(pointer);
45126 }
45127
45128 var currentSelection = this.selectionHandler.getSelection(); // See NOTE in method comment for the reason to do it like this
45129
45130 var deselectedItems = this._determineDifference(previousSelection, currentSelection);
45131
45132 var selectedItems = this._determineDifference(currentSelection, previousSelection);
45133
45134 if (deselectedItems.edges.length > 0) {
45135 this.selectionHandler._generateClickEvent('deselectEdge', event, pointer, previousSelection);
45136
45137 selected = true;
45138 }
45139
45140 if (deselectedItems.nodes.length > 0) {
45141 this.selectionHandler._generateClickEvent('deselectNode', event, pointer, previousSelection);
45142
45143 selected = true;
45144 }
45145
45146 if (selectedItems.nodes.length > 0) {
45147 this.selectionHandler._generateClickEvent('selectNode', event, pointer);
45148
45149 selected = true;
45150 }
45151
45152 if (selectedItems.edges.length > 0) {
45153 this.selectionHandler._generateClickEvent('selectEdge', event, pointer);
45154
45155 selected = true;
45156 } // fire the select event if anything has been selected or deselected
45157
45158
45159 if (selected === true) {
45160 // select or unselect
45161 this.selectionHandler._generateClickEvent('select', event, pointer);
45162 }
45163 }
45164 /**
45165 * Remove all node and edge id's from the first set that are present in the second one.
45166 *
45167 * @param {{nodes: Array.<Node>, edges: Array.<vis.Edge>}} firstSet
45168 * @param {{nodes: Array.<Node>, edges: Array.<vis.Edge>}} secondSet
45169 * @returns {{nodes: Array.<Node>, edges: Array.<vis.Edge>}}
45170 * @private
45171 */
45172
45173 }, {
45174 key: "_determineDifference",
45175 value: function _determineDifference(firstSet, secondSet) {
45176 var arrayDiff = function arrayDiff(firstArr, secondArr) {
45177 var result = [];
45178
45179 for (var i = 0; i < firstArr.length; i++) {
45180 var value = firstArr[i];
45181
45182 if (secondArr.indexOf(value) === -1) {
45183 result.push(value);
45184 }
45185 }
45186
45187 return result;
45188 };
45189
45190 return {
45191 nodes: arrayDiff(firstSet.nodes, secondSet.nodes),
45192 edges: arrayDiff(firstSet.edges, secondSet.edges)
45193 };
45194 }
45195 /**
45196 * This function is called by onDragStart.
45197 * It is separated out because we can then overload it for the datamanipulation system.
45198 *
45199 * @param {Event} event
45200 * @private
45201 */
45202
45203 }, {
45204 key: "onDragStart",
45205 value: function onDragStart(event) {
45206 //in case the touch event was triggered on an external div, do the initial touch now.
45207 if (this.drag.pointer === undefined) {
45208 this.onTouch(event);
45209 } // note: drag.pointer is set in onTouch to get the initial touch location
45210
45211
45212 var node = this.selectionHandler.getNodeAt(this.drag.pointer);
45213 this.drag.dragging = true;
45214 this.drag.selection = [];
45215 this.drag.translation = extend({}, this.body.view.translation); // copy the object
45216
45217 this.drag.nodeId = undefined;
45218
45219 if (node !== undefined && this.options.dragNodes === true) {
45220 this.drag.nodeId = node.id; // select the clicked node if not yet selected
45221
45222 if (node.isSelected() === false) {
45223 this.selectionHandler.unselectAll();
45224 this.selectionHandler.selectObject(node);
45225 } // after select to contain the node
45226
45227
45228 this.selectionHandler._generateClickEvent('dragStart', event, this.drag.pointer);
45229
45230 var selection = this.selectionHandler.selectionObj.nodes; // create an array with the selected nodes and their original location and status
45231
45232 for (var nodeId in selection) {
45233 if (selection.hasOwnProperty(nodeId)) {
45234 var object = selection[nodeId];
45235 var s = {
45236 id: object.id,
45237 node: object,
45238 // store original x, y, xFixed and yFixed, make the node temporarily Fixed
45239 x: object.x,
45240 y: object.y,
45241 xFixed: object.options.fixed.x,
45242 yFixed: object.options.fixed.y
45243 };
45244 object.options.fixed.x = true;
45245 object.options.fixed.y = true;
45246 this.drag.selection.push(s);
45247 }
45248 }
45249 } else {
45250 // fallback if no node is selected and thus the view is dragged.
45251 this.selectionHandler._generateClickEvent('dragStart', event, this.drag.pointer, undefined, true);
45252 }
45253 }
45254 /**
45255 * handle drag event
45256 * @param {Event} event
45257 * @private
45258 */
45259
45260 }, {
45261 key: "onDrag",
45262 value: function onDrag(event) {
45263 var _this2 = this;
45264
45265 if (this.drag.pinched === true) {
45266 return;
45267 } // remove the focus on node if it is focussed on by the focusOnNode
45268
45269
45270 this.body.emitter.emit('unlockNode');
45271 var pointer = this.getPointer(event.center);
45272 var selection = this.drag.selection;
45273
45274 if (selection && selection.length && this.options.dragNodes === true) {
45275 this.selectionHandler._generateClickEvent('dragging', event, pointer); // calculate delta's and new location
45276
45277
45278 var deltaX = pointer.x - this.drag.pointer.x;
45279 var deltaY = pointer.y - this.drag.pointer.y; // update position of all selected nodes
45280
45281 selection.forEach(function (selection) {
45282 var node = selection.node; // only move the node if it was not fixed initially
45283
45284 if (selection.xFixed === false) {
45285 node.x = _this2.canvas._XconvertDOMtoCanvas(_this2.canvas._XconvertCanvasToDOM(selection.x) + deltaX);
45286 } // only move the node if it was not fixed initially
45287
45288
45289 if (selection.yFixed === false) {
45290 node.y = _this2.canvas._YconvertDOMtoCanvas(_this2.canvas._YconvertCanvasToDOM(selection.y) + deltaY);
45291 }
45292 }); // start the simulation of the physics
45293
45294 this.body.emitter.emit('startSimulation');
45295 } else {
45296 // move the network
45297 if (this.options.dragView === true) {
45298 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.
45299
45300
45301 if (this.drag.pointer === undefined) {
45302 this.onDragStart(event);
45303 return;
45304 }
45305
45306 var diffX = pointer.x - this.drag.pointer.x;
45307 var diffY = pointer.y - this.drag.pointer.y;
45308 this.body.view.translation = {
45309 x: this.drag.translation.x + diffX,
45310 y: this.drag.translation.y + diffY
45311 };
45312 this.body.emitter.emit('_requestRedraw');
45313 }
45314 }
45315 }
45316 /**
45317 * handle drag start event
45318 * @param {Event} event
45319 * @private
45320 */
45321
45322 }, {
45323 key: "onDragEnd",
45324 value: function onDragEnd(event) {
45325 this.drag.dragging = false;
45326 var selection = this.drag.selection;
45327
45328 if (selection && selection.length) {
45329 selection.forEach(function (s) {
45330 // restore original xFixed and yFixed
45331 s.node.options.fixed.x = s.xFixed;
45332 s.node.options.fixed.y = s.yFixed;
45333 });
45334
45335 this.selectionHandler._generateClickEvent('dragEnd', event, this.getPointer(event.center));
45336
45337 this.body.emitter.emit('startSimulation');
45338 } else {
45339 this.selectionHandler._generateClickEvent('dragEnd', event, this.getPointer(event.center), undefined, true);
45340
45341 this.body.emitter.emit('_requestRedraw');
45342 }
45343 }
45344 /**
45345 * Handle pinch event
45346 * @param {Event} event The event
45347 * @private
45348 */
45349
45350 }, {
45351 key: "onPinch",
45352 value: function onPinch(event) {
45353 var pointer = this.getPointer(event.center);
45354 this.drag.pinched = true;
45355
45356 if (this.pinch['scale'] === undefined) {
45357 this.pinch.scale = 1;
45358 } // TODO: enabled moving while pinching?
45359
45360
45361 var scale = this.pinch.scale * event.scale;
45362 this.zoom(scale, pointer);
45363 }
45364 /**
45365 * Zoom the network in or out
45366 * @param {number} scale a number around 1, and between 0.01 and 10
45367 * @param {{x: number, y: number}} pointer Position on screen
45368 * @private
45369 */
45370
45371 }, {
45372 key: "zoom",
45373 value: function zoom(scale, pointer) {
45374 if (this.options.zoomView === true) {
45375 var scaleOld = this.body.view.scale;
45376
45377 if (scale < 0.00001) {
45378 scale = 0.00001;
45379 }
45380
45381 if (scale > 10) {
45382 scale = 10;
45383 }
45384
45385 var preScaleDragPointer = undefined;
45386
45387 if (this.drag !== undefined) {
45388 if (this.drag.dragging === true) {
45389 preScaleDragPointer = this.canvas.DOMtoCanvas(this.drag.pointer);
45390 }
45391 } // + this.canvas.frame.canvas.clientHeight / 2
45392
45393
45394 var translation = this.body.view.translation;
45395 var scaleFrac = scale / scaleOld;
45396 var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac;
45397 var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac;
45398 this.body.view.scale = scale;
45399 this.body.view.translation = {
45400 x: tx,
45401 y: ty
45402 };
45403
45404 if (preScaleDragPointer != undefined) {
45405 var postScaleDragPointer = this.canvas.canvasToDOM(preScaleDragPointer);
45406 this.drag.pointer.x = postScaleDragPointer.x;
45407 this.drag.pointer.y = postScaleDragPointer.y;
45408 }
45409
45410 this.body.emitter.emit('_requestRedraw');
45411
45412 if (scaleOld < scale) {
45413 this.body.emitter.emit('zoom', {
45414 direction: '+',
45415 scale: this.body.view.scale,
45416 pointer: pointer
45417 });
45418 } else {
45419 this.body.emitter.emit('zoom', {
45420 direction: '-',
45421 scale: this.body.view.scale,
45422 pointer: pointer
45423 });
45424 }
45425 }
45426 }
45427 /**
45428 * Event handler for mouse wheel event, used to zoom the timeline
45429 * See http://adomas.org/javascript-mouse-wheel/
45430 * https://github.com/EightMedia/hammer.js/issues/256
45431 * @param {MouseEvent} event
45432 * @private
45433 */
45434
45435 }, {
45436 key: "onMouseWheel",
45437 value: function onMouseWheel(event) {
45438 if (this.options.zoomView === true) {
45439 // If delta is nonzero, handle it.
45440 // Basically, delta is now positive if wheel was scrolled up,
45441 // and negative, if wheel was scrolled down.
45442 if (event.deltaY !== 0) {
45443 // calculate the new scale
45444 var scale = this.body.view.scale;
45445 scale *= 1 + (event.deltaY < 0 ? 1 : -1) * (this.options.zoomSpeed * 0.1); // calculate the pointer location
45446
45447 var pointer = this.getPointer({
45448 x: event.clientX,
45449 y: event.clientY
45450 }); // apply the new scale
45451
45452 this.zoom(scale, pointer);
45453 } // Prevent default actions caused by mouse wheel.
45454
45455
45456 event.preventDefault();
45457 }
45458 }
45459 /**
45460 * Mouse move handler for checking whether the title moves over a node with a title.
45461 * @param {Event} event
45462 * @private
45463 */
45464
45465 }, {
45466 key: "onMouseMove",
45467 value: function onMouseMove(event) {
45468 var _this3 = this;
45469
45470 var pointer = this.getPointer({
45471 x: event.clientX,
45472 y: event.clientY
45473 });
45474 var popupVisible = false; // check if the previously selected node is still selected
45475
45476 if (this.popup !== undefined) {
45477 if (this.popup.hidden === false) {
45478 this._checkHidePopup(pointer);
45479 } // if the popup was not hidden above
45480
45481
45482 if (this.popup.hidden === false) {
45483 popupVisible = true;
45484 this.popup.setPosition(pointer.x + 3, pointer.y - 5);
45485 this.popup.show();
45486 }
45487 } // if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over.
45488
45489
45490 if (this.options.keyboard.bindToWindow === false && this.options.keyboard.enabled === true) {
45491 this.canvas.frame.focus();
45492 } // start a timeout that will check if the mouse is positioned above an element
45493
45494
45495 if (popupVisible === false) {
45496 if (this.popupTimer !== undefined) {
45497 clearInterval(this.popupTimer); // stop any running calculationTimer
45498
45499 this.popupTimer = undefined;
45500 }
45501
45502 if (!this.drag.dragging) {
45503 this.popupTimer = setTimeout(function () {
45504 return _this3._checkShowPopup(pointer);
45505 }, this.options.tooltipDelay);
45506 }
45507 } // adding hover highlights
45508
45509
45510 if (this.options.hover === true) {
45511 this.selectionHandler.hoverObject(event, pointer);
45512 }
45513 }
45514 /**
45515 * Check if there is an element on the given position in the network
45516 * (a node or edge). If so, and if this element has a title,
45517 * show a popup window with its title.
45518 *
45519 * @param {{x:number, y:number}} pointer
45520 * @private
45521 */
45522
45523 }, {
45524 key: "_checkShowPopup",
45525 value: function _checkShowPopup(pointer) {
45526 var x = this.canvas._XconvertDOMtoCanvas(pointer.x);
45527
45528 var y = this.canvas._YconvertDOMtoCanvas(pointer.y);
45529
45530 var pointerObj = {
45531 left: x,
45532 top: y,
45533 right: x,
45534 bottom: y
45535 };
45536 var previousPopupObjId = this.popupObj === undefined ? undefined : this.popupObj.id;
45537 var nodeUnderCursor = false;
45538 var popupType = 'node'; // check if a node is under the cursor.
45539
45540 if (this.popupObj === undefined) {
45541 // search the nodes for overlap, select the top one in case of multiple nodes
45542 var nodeIndices = this.body.nodeIndices;
45543 var nodes = this.body.nodes;
45544 var node;
45545 var overlappingNodes = [];
45546
45547 for (var i = 0; i < nodeIndices.length; i++) {
45548 node = nodes[nodeIndices[i]];
45549
45550 if (node.isOverlappingWith(pointerObj) === true) {
45551 nodeUnderCursor = true;
45552
45553 if (node.getTitle() !== undefined) {
45554 overlappingNodes.push(nodeIndices[i]);
45555 }
45556 }
45557 }
45558
45559 if (overlappingNodes.length > 0) {
45560 // if there are overlapping nodes, select the last one, this is the one which is drawn on top of the others
45561 this.popupObj = nodes[overlappingNodes[overlappingNodes.length - 1]]; // if you hover over a node, the title of the edge is not supposed to be shown.
45562
45563 nodeUnderCursor = true;
45564 }
45565 }
45566
45567 if (this.popupObj === undefined && nodeUnderCursor === false) {
45568 // search the edges for overlap
45569 var edgeIndices = this.body.edgeIndices;
45570 var edges = this.body.edges;
45571 var edge;
45572 var overlappingEdges = [];
45573
45574 for (var _i = 0; _i < edgeIndices.length; _i++) {
45575 edge = edges[edgeIndices[_i]];
45576
45577 if (edge.isOverlappingWith(pointerObj) === true) {
45578 if (edge.connected === true && edge.getTitle() !== undefined) {
45579 overlappingEdges.push(edgeIndices[_i]);
45580 }
45581 }
45582 }
45583
45584 if (overlappingEdges.length > 0) {
45585 this.popupObj = edges[overlappingEdges[overlappingEdges.length - 1]];
45586 popupType = 'edge';
45587 }
45588 }
45589
45590 if (this.popupObj !== undefined) {
45591 // show popup message window
45592 if (this.popupObj.id !== previousPopupObjId) {
45593 if (this.popup === undefined) {
45594 this.popup = new Popup(this.canvas.frame);
45595 }
45596
45597 this.popup.popupTargetType = popupType;
45598 this.popup.popupTargetId = this.popupObj.id; // adjust a small offset such that the mouse cursor is located in the
45599 // bottom left location of the popup, and you can easily move over the
45600 // popup area
45601
45602 this.popup.setPosition(pointer.x + 3, pointer.y - 5);
45603 this.popup.setText(this.popupObj.getTitle());
45604 this.popup.show();
45605 this.body.emitter.emit('showPopup', this.popupObj.id);
45606 }
45607 } else {
45608 if (this.popup !== undefined) {
45609 this.popup.hide();
45610 this.body.emitter.emit('hidePopup');
45611 }
45612 }
45613 }
45614 /**
45615 * Check if the popup must be hidden, which is the case when the mouse is no
45616 * longer hovering on the object
45617 * @param {{x:number, y:number}} pointer
45618 * @private
45619 */
45620
45621 }, {
45622 key: "_checkHidePopup",
45623 value: function _checkHidePopup(pointer) {
45624 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer);
45625
45626 var stillOnObj = false;
45627
45628 if (this.popup.popupTargetType === 'node') {
45629 if (this.body.nodes[this.popup.popupTargetId] !== undefined) {
45630 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.
45631 // we initially only check stillOnObj because this is much faster.
45632
45633 if (stillOnObj === true) {
45634 var overNode = this.selectionHandler.getNodeAt(pointer);
45635 stillOnObj = overNode === undefined ? false : overNode.id === this.popup.popupTargetId;
45636 }
45637 }
45638 } else {
45639 if (this.selectionHandler.getNodeAt(pointer) === undefined) {
45640 if (this.body.edges[this.popup.popupTargetId] !== undefined) {
45641 stillOnObj = this.body.edges[this.popup.popupTargetId].isOverlappingWith(pointerObj);
45642 }
45643 }
45644 }
45645
45646 if (stillOnObj === false) {
45647 this.popupObj = undefined;
45648 this.popup.hide();
45649 this.body.emitter.emit('hidePopup');
45650 }
45651 }
45652 }]);
45653
45654 return InteractionHandler;
45655 }();
45656
45657 /**
45658 * The handler for selections
45659 */
45660
45661 var SelectionHandler =
45662 /*#__PURE__*/
45663 function () {
45664 /**
45665 * @param {Object} body
45666 * @param {Canvas} canvas
45667 */
45668 function SelectionHandler(body, canvas) {
45669 var _this = this;
45670
45671 _classCallCheck(this, SelectionHandler);
45672
45673 this.body = body;
45674 this.canvas = canvas;
45675 this.selectionObj = {
45676 nodes: [],
45677 edges: []
45678 };
45679 this.hoverObj = {
45680 nodes: {},
45681 edges: {}
45682 };
45683 this.options = {};
45684 this.defaultOptions = {
45685 multiselect: false,
45686 selectable: true,
45687 selectConnectedEdges: true,
45688 hoverConnectedEdges: true
45689 };
45690 extend(this.options, this.defaultOptions);
45691 this.body.emitter.on("_dataChanged", function () {
45692 _this.updateSelection();
45693 });
45694 }
45695 /**
45696 *
45697 * @param {Object} [options]
45698 */
45699
45700
45701 _createClass(SelectionHandler, [{
45702 key: "setOptions",
45703 value: function setOptions(options) {
45704 if (options !== undefined) {
45705 var fields = ['multiselect', 'hoverConnectedEdges', 'selectable', 'selectConnectedEdges'];
45706 selectiveDeepExtend(fields, this.options, options);
45707 }
45708 }
45709 /**
45710 * handles the selection part of the tap;
45711 *
45712 * @param {{x: number, y: number}} pointer
45713 * @returns {boolean}
45714 */
45715
45716 }, {
45717 key: "selectOnPoint",
45718 value: function selectOnPoint(pointer) {
45719 var selected = false;
45720
45721 if (this.options.selectable === true) {
45722 var obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer); // unselect after getting the objects in order to restore width and height.
45723
45724 this.unselectAll();
45725
45726 if (obj !== undefined) {
45727 selected = this.selectObject(obj);
45728 }
45729
45730 this.body.emitter.emit("_requestRedraw");
45731 }
45732
45733 return selected;
45734 }
45735 /**
45736 *
45737 * @param {{x: number, y: number}} pointer
45738 * @returns {boolean}
45739 */
45740
45741 }, {
45742 key: "selectAdditionalOnPoint",
45743 value: function selectAdditionalOnPoint(pointer) {
45744 var selectionChanged = false;
45745
45746 if (this.options.selectable === true) {
45747 var obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer);
45748
45749 if (obj !== undefined) {
45750 selectionChanged = true;
45751
45752 if (obj.isSelected() === true) {
45753 this.deselectObject(obj);
45754 } else {
45755 this.selectObject(obj);
45756 }
45757
45758 this.body.emitter.emit("_requestRedraw");
45759 }
45760 }
45761
45762 return selectionChanged;
45763 }
45764 /**
45765 * Create an object containing the standard fields for an event.
45766 *
45767 * @param {Event} event
45768 * @param {{x: number, y: number}} pointer Object with the x and y screen coordinates of the mouse
45769 * @returns {{}}
45770 * @private
45771 */
45772
45773 }, {
45774 key: "_initBaseEvent",
45775 value: function _initBaseEvent(event, pointer) {
45776 var properties = {};
45777 properties['pointer'] = {
45778 DOM: {
45779 x: pointer.x,
45780 y: pointer.y
45781 },
45782 canvas: this.canvas.DOMtoCanvas(pointer)
45783 };
45784 properties['event'] = event;
45785 return properties;
45786 }
45787 /**
45788 * Generate an event which the user can catch.
45789 *
45790 * This adds some extra data to the event with respect to cursor position and
45791 * selected nodes and edges.
45792 *
45793 * @param {string} eventType Name of event to send
45794 * @param {Event} event
45795 * @param {{x: number, y: number}} pointer Object with the x and y screen coordinates of the mouse
45796 * @param {Object|undefined} oldSelection If present, selection state before event occured
45797 * @param {boolean|undefined} [emptySelection=false] Indicate if selection data should be passed
45798 */
45799
45800 }, {
45801 key: "_generateClickEvent",
45802 value: function _generateClickEvent(eventType, event, pointer, oldSelection) {
45803 var emptySelection = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
45804
45805 var properties = this._initBaseEvent(event, pointer);
45806
45807 if (emptySelection === true) {
45808 properties.nodes = [];
45809 properties.edges = [];
45810 } else {
45811 var tmp = this.getSelection();
45812 properties.nodes = tmp.nodes;
45813 properties.edges = tmp.edges;
45814 }
45815
45816 if (oldSelection !== undefined) {
45817 properties['previousSelection'] = oldSelection;
45818 }
45819
45820 if (eventType == 'click') {
45821 // For the time being, restrict this functionality to
45822 // just the click event.
45823 properties.items = this.getClickedItems(pointer);
45824 }
45825
45826 if (event.controlEdge !== undefined) {
45827 properties.controlEdge = event.controlEdge;
45828 }
45829
45830 this.body.emitter.emit(eventType, properties);
45831 }
45832 /**
45833 *
45834 * @param {Object} obj
45835 * @param {boolean} [highlightEdges=this.options.selectConnectedEdges]
45836 * @returns {boolean}
45837 */
45838
45839 }, {
45840 key: "selectObject",
45841 value: function selectObject(obj) {
45842 var highlightEdges = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.options.selectConnectedEdges;
45843
45844 if (obj !== undefined) {
45845 if (obj instanceof Node) {
45846 if (highlightEdges === true) {
45847 this._selectConnectedEdges(obj);
45848 }
45849 }
45850
45851 obj.select();
45852
45853 this._addToSelection(obj);
45854
45855 return true;
45856 }
45857
45858 return false;
45859 }
45860 /**
45861 *
45862 * @param {Object} obj
45863 */
45864
45865 }, {
45866 key: "deselectObject",
45867 value: function deselectObject(obj) {
45868 if (obj.isSelected() === true) {
45869 obj.selected = false;
45870
45871 this._removeFromSelection(obj);
45872 }
45873 }
45874 /**
45875 * retrieve all nodes overlapping with given object
45876 * @param {Object} object An object with parameters left, top, right, bottom
45877 * @return {number[]} An array with id's of the overlapping nodes
45878 * @private
45879 */
45880
45881 }, {
45882 key: "_getAllNodesOverlappingWith",
45883 value: function _getAllNodesOverlappingWith(object) {
45884 var overlappingNodes = [];
45885 var nodes = this.body.nodes;
45886
45887 for (var i = 0; i < this.body.nodeIndices.length; i++) {
45888 var nodeId = this.body.nodeIndices[i];
45889
45890 if (nodes[nodeId].isOverlappingWith(object)) {
45891 overlappingNodes.push(nodeId);
45892 }
45893 }
45894
45895 return overlappingNodes;
45896 }
45897 /**
45898 * Return a position object in canvasspace from a single point in screenspace
45899 *
45900 * @param {{x: number, y: number}} pointer
45901 * @returns {{left: number, top: number, right: number, bottom: number}}
45902 * @private
45903 */
45904
45905 }, {
45906 key: "_pointerToPositionObject",
45907 value: function _pointerToPositionObject(pointer) {
45908 var canvasPos = this.canvas.DOMtoCanvas(pointer);
45909 return {
45910 left: canvasPos.x - 1,
45911 top: canvasPos.y + 1,
45912 right: canvasPos.x + 1,
45913 bottom: canvasPos.y - 1
45914 };
45915 }
45916 /**
45917 * Get the top node at the passed point (like a click)
45918 *
45919 * @param {{x: number, y: number}} pointer
45920 * @param {boolean} [returnNode=true]
45921 * @return {Node | undefined} node
45922 */
45923
45924 }, {
45925 key: "getNodeAt",
45926 value: function getNodeAt(pointer) {
45927 var returnNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
45928
45929 // we first check if this is an navigation controls element
45930 var positionObject = this._pointerToPositionObject(pointer);
45931
45932 var overlappingNodes = this._getAllNodesOverlappingWith(positionObject); // if there are overlapping nodes, select the last one, this is the
45933 // one which is drawn on top of the others
45934
45935
45936 if (overlappingNodes.length > 0) {
45937 if (returnNode === true) {
45938 return this.body.nodes[overlappingNodes[overlappingNodes.length - 1]];
45939 } else {
45940 return overlappingNodes[overlappingNodes.length - 1];
45941 }
45942 } else {
45943 return undefined;
45944 }
45945 }
45946 /**
45947 * retrieve all edges overlapping with given object, selector is around center
45948 * @param {Object} object An object with parameters left, top, right, bottom
45949 * @param {number[]} overlappingEdges An array with id's of the overlapping nodes
45950 * @private
45951 */
45952
45953 }, {
45954 key: "_getEdgesOverlappingWith",
45955 value: function _getEdgesOverlappingWith(object, overlappingEdges) {
45956 var edges = this.body.edges;
45957
45958 for (var i = 0; i < this.body.edgeIndices.length; i++) {
45959 var edgeId = this.body.edgeIndices[i];
45960
45961 if (edges[edgeId].isOverlappingWith(object)) {
45962 overlappingEdges.push(edgeId);
45963 }
45964 }
45965 }
45966 /**
45967 * retrieve all nodes overlapping with given object
45968 * @param {Object} object An object with parameters left, top, right, bottom
45969 * @return {number[]} An array with id's of the overlapping nodes
45970 * @private
45971 */
45972
45973 }, {
45974 key: "_getAllEdgesOverlappingWith",
45975 value: function _getAllEdgesOverlappingWith(object) {
45976 var overlappingEdges = [];
45977
45978 this._getEdgesOverlappingWith(object, overlappingEdges);
45979
45980 return overlappingEdges;
45981 }
45982 /**
45983 * Get the edges nearest to the passed point (like a click)
45984 *
45985 * @param {{x: number, y: number}} pointer
45986 * @param {boolean} [returnEdge=true]
45987 * @return {Edge | undefined} node
45988 */
45989
45990 }, {
45991 key: "getEdgeAt",
45992 value: function getEdgeAt(pointer) {
45993 var returnEdge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
45994 // Iterate over edges, pick closest within 10
45995 var canvasPos = this.canvas.DOMtoCanvas(pointer);
45996 var mindist = 10;
45997 var overlappingEdge = null;
45998 var edges = this.body.edges;
45999
46000 for (var i = 0; i < this.body.edgeIndices.length; i++) {
46001 var edgeId = this.body.edgeIndices[i];
46002 var edge = edges[edgeId];
46003
46004 if (edge.connected) {
46005 var xFrom = edge.from.x;
46006 var yFrom = edge.from.y;
46007 var xTo = edge.to.x;
46008 var yTo = edge.to.y;
46009 var dist = edge.edgeType.getDistanceToEdge(xFrom, yFrom, xTo, yTo, canvasPos.x, canvasPos.y);
46010
46011 if (dist < mindist) {
46012 overlappingEdge = edgeId;
46013 mindist = dist;
46014 }
46015 }
46016 }
46017
46018 if (overlappingEdge !== null) {
46019 if (returnEdge === true) {
46020 return this.body.edges[overlappingEdge];
46021 } else {
46022 return overlappingEdge;
46023 }
46024 } else {
46025 return undefined;
46026 }
46027 }
46028 /**
46029 * Add object to the selection array.
46030 *
46031 * @param {Object} obj
46032 * @private
46033 */
46034
46035 }, {
46036 key: "_addToSelection",
46037 value: function _addToSelection(obj) {
46038 if (obj instanceof Node) {
46039 this.selectionObj.nodes[obj.id] = obj;
46040 } else {
46041 this.selectionObj.edges[obj.id] = obj;
46042 }
46043 }
46044 /**
46045 * Add object to the selection array.
46046 *
46047 * @param {Object} obj
46048 * @private
46049 */
46050
46051 }, {
46052 key: "_addToHover",
46053 value: function _addToHover(obj) {
46054 if (obj instanceof Node) {
46055 this.hoverObj.nodes[obj.id] = obj;
46056 } else {
46057 this.hoverObj.edges[obj.id] = obj;
46058 }
46059 }
46060 /**
46061 * Remove a single option from selection.
46062 *
46063 * @param {Object} obj
46064 * @private
46065 */
46066
46067 }, {
46068 key: "_removeFromSelection",
46069 value: function _removeFromSelection(obj) {
46070 if (obj instanceof Node) {
46071 delete this.selectionObj.nodes[obj.id];
46072
46073 this._unselectConnectedEdges(obj);
46074 } else {
46075 delete this.selectionObj.edges[obj.id];
46076 }
46077 }
46078 /**
46079 * Unselect all. The selectionObj is useful for this.
46080 */
46081
46082 }, {
46083 key: "unselectAll",
46084 value: function unselectAll() {
46085 for (var nodeId in this.selectionObj.nodes) {
46086 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46087 this.selectionObj.nodes[nodeId].unselect();
46088 }
46089 }
46090
46091 for (var edgeId in this.selectionObj.edges) {
46092 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46093 this.selectionObj.edges[edgeId].unselect();
46094 }
46095 }
46096
46097 this.selectionObj = {
46098 nodes: {},
46099 edges: {}
46100 };
46101 }
46102 /**
46103 * return the number of selected nodes
46104 *
46105 * @returns {number}
46106 * @private
46107 */
46108
46109 }, {
46110 key: "_getSelectedNodeCount",
46111 value: function _getSelectedNodeCount() {
46112 var count = 0;
46113
46114 for (var nodeId in this.selectionObj.nodes) {
46115 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46116 count += 1;
46117 }
46118 }
46119
46120 return count;
46121 }
46122 /**
46123 * return the selected node
46124 *
46125 * @returns {number}
46126 * @private
46127 */
46128
46129 }, {
46130 key: "_getSelectedNode",
46131 value: function _getSelectedNode() {
46132 for (var nodeId in this.selectionObj.nodes) {
46133 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46134 return this.selectionObj.nodes[nodeId];
46135 }
46136 }
46137
46138 return undefined;
46139 }
46140 /**
46141 * return the selected edge
46142 *
46143 * @returns {number}
46144 * @private
46145 */
46146
46147 }, {
46148 key: "_getSelectedEdge",
46149 value: function _getSelectedEdge() {
46150 for (var edgeId in this.selectionObj.edges) {
46151 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46152 return this.selectionObj.edges[edgeId];
46153 }
46154 }
46155
46156 return undefined;
46157 }
46158 /**
46159 * return the number of selected edges
46160 *
46161 * @returns {number}
46162 * @private
46163 */
46164
46165 }, {
46166 key: "_getSelectedEdgeCount",
46167 value: function _getSelectedEdgeCount() {
46168 var count = 0;
46169
46170 for (var edgeId in this.selectionObj.edges) {
46171 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46172 count += 1;
46173 }
46174 }
46175
46176 return count;
46177 }
46178 /**
46179 * return the number of selected objects.
46180 *
46181 * @returns {number}
46182 * @private
46183 */
46184
46185 }, {
46186 key: "_getSelectedObjectCount",
46187 value: function _getSelectedObjectCount() {
46188 var count = 0;
46189
46190 for (var nodeId in this.selectionObj.nodes) {
46191 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46192 count += 1;
46193 }
46194 }
46195
46196 for (var edgeId in this.selectionObj.edges) {
46197 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46198 count += 1;
46199 }
46200 }
46201
46202 return count;
46203 }
46204 /**
46205 * Check if anything is selected
46206 *
46207 * @returns {boolean}
46208 * @private
46209 */
46210
46211 }, {
46212 key: "_selectionIsEmpty",
46213 value: function _selectionIsEmpty() {
46214 for (var nodeId in this.selectionObj.nodes) {
46215 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46216 return false;
46217 }
46218 }
46219
46220 for (var edgeId in this.selectionObj.edges) {
46221 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46222 return false;
46223 }
46224 }
46225
46226 return true;
46227 }
46228 /**
46229 * check if one of the selected nodes is a cluster.
46230 *
46231 * @returns {boolean}
46232 * @private
46233 */
46234
46235 }, {
46236 key: "_clusterInSelection",
46237 value: function _clusterInSelection() {
46238 for (var nodeId in this.selectionObj.nodes) {
46239 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46240 if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
46241 return true;
46242 }
46243 }
46244 }
46245
46246 return false;
46247 }
46248 /**
46249 * select the edges connected to the node that is being selected
46250 *
46251 * @param {Node} node
46252 * @private
46253 */
46254
46255 }, {
46256 key: "_selectConnectedEdges",
46257 value: function _selectConnectedEdges(node) {
46258 for (var i = 0; i < node.edges.length; i++) {
46259 var edge = node.edges[i];
46260 edge.select();
46261
46262 this._addToSelection(edge);
46263 }
46264 }
46265 /**
46266 * select the edges connected to the node that is being selected
46267 *
46268 * @param {Node} node
46269 * @private
46270 */
46271
46272 }, {
46273 key: "_hoverConnectedEdges",
46274 value: function _hoverConnectedEdges(node) {
46275 for (var i = 0; i < node.edges.length; i++) {
46276 var edge = node.edges[i];
46277 edge.hover = true;
46278
46279 this._addToHover(edge);
46280 }
46281 }
46282 /**
46283 * unselect the edges connected to the node that is being selected
46284 *
46285 * @param {Node} node
46286 * @private
46287 */
46288
46289 }, {
46290 key: "_unselectConnectedEdges",
46291 value: function _unselectConnectedEdges(node) {
46292 for (var i = 0; i < node.edges.length; i++) {
46293 var edge = node.edges[i];
46294 edge.unselect();
46295
46296 this._removeFromSelection(edge);
46297 }
46298 }
46299 /**
46300 * Remove the highlight from a node or edge, in response to mouse movement
46301 *
46302 * @param {Event} event
46303 * @param {{x: number, y: number}} pointer object with the x and y screen coordinates of the mouse
46304 * @param {Node|vis.Edge} object
46305 * @private
46306 */
46307
46308 }, {
46309 key: "emitBlurEvent",
46310 value: function emitBlurEvent(event, pointer, object) {
46311 var properties = this._initBaseEvent(event, pointer);
46312
46313 if (object.hover === true) {
46314 object.hover = false;
46315
46316 if (object instanceof Node) {
46317 properties.node = object.id;
46318 this.body.emitter.emit("blurNode", properties);
46319 } else {
46320 properties.edge = object.id;
46321 this.body.emitter.emit("blurEdge", properties);
46322 }
46323 }
46324 }
46325 /**
46326 * Create the highlight for a node or edge, in response to mouse movement
46327 *
46328 * @param {Event} event
46329 * @param {{x: number, y: number}} pointer object with the x and y screen coordinates of the mouse
46330 * @param {Node|vis.Edge} object
46331 * @returns {boolean} hoverChanged
46332 * @private
46333 */
46334
46335 }, {
46336 key: "emitHoverEvent",
46337 value: function emitHoverEvent(event, pointer, object) {
46338 var properties = this._initBaseEvent(event, pointer);
46339
46340 var hoverChanged = false;
46341
46342 if (object.hover === false) {
46343 object.hover = true;
46344
46345 this._addToHover(object);
46346
46347 hoverChanged = true;
46348
46349 if (object instanceof Node) {
46350 properties.node = object.id;
46351 this.body.emitter.emit("hoverNode", properties);
46352 } else {
46353 properties.edge = object.id;
46354 this.body.emitter.emit("hoverEdge", properties);
46355 }
46356 }
46357
46358 return hoverChanged;
46359 }
46360 /**
46361 * Perform actions in response to a mouse movement.
46362 *
46363 * @param {Event} event
46364 * @param {{x: number, y: number}} pointer | object with the x and y screen coordinates of the mouse
46365 */
46366
46367 }, {
46368 key: "hoverObject",
46369 value: function hoverObject(event, pointer) {
46370 var object = this.getNodeAt(pointer);
46371
46372 if (object === undefined) {
46373 object = this.getEdgeAt(pointer);
46374 }
46375
46376 var hoverChanged = false; // remove all node hover highlights
46377
46378 for (var nodeId in this.hoverObj.nodes) {
46379 if (this.hoverObj.nodes.hasOwnProperty(nodeId)) {
46380 if (object === undefined || object instanceof Node && object.id != nodeId || object instanceof Edge) {
46381 this.emitBlurEvent(event, pointer, this.hoverObj.nodes[nodeId]);
46382 delete this.hoverObj.nodes[nodeId];
46383 hoverChanged = true;
46384 }
46385 }
46386 } // removing all edge hover highlights
46387
46388
46389 for (var edgeId in this.hoverObj.edges) {
46390 if (this.hoverObj.edges.hasOwnProperty(edgeId)) {
46391 // if the hover has been changed here it means that the node has been hovered over or off
46392 // we then do not use the emitBlurEvent method here.
46393 if (hoverChanged === true) {
46394 this.hoverObj.edges[edgeId].hover = false;
46395 delete this.hoverObj.edges[edgeId];
46396 } // if the blur remains the same and the object is undefined (mouse off) or another
46397 // edge has been hovered, or another node has been hovered we blur the edge.
46398 else if (object === undefined || object instanceof Edge && object.id != edgeId || object instanceof Node && !object.hover) {
46399 this.emitBlurEvent(event, pointer, this.hoverObj.edges[edgeId]);
46400 delete this.hoverObj.edges[edgeId];
46401 hoverChanged = true;
46402 }
46403 }
46404 }
46405
46406 if (object !== undefined) {
46407 var hoveredEdgesCount = Object.keys(this.hoverObj.edges).length;
46408 var hoveredNodesCount = Object.keys(this.hoverObj.nodes).length;
46409 var newOnlyHoveredEdge = object instanceof Edge && hoveredEdgesCount === 0 && hoveredNodesCount === 0;
46410 var newOnlyHoveredNode = object instanceof Node && hoveredEdgesCount === 0 && hoveredNodesCount === 0;
46411
46412 if (hoverChanged || newOnlyHoveredEdge || newOnlyHoveredNode) {
46413 hoverChanged = this.emitHoverEvent(event, pointer, object);
46414 }
46415
46416 if (object instanceof Node && this.options.hoverConnectedEdges === true) {
46417 this._hoverConnectedEdges(object);
46418 }
46419 }
46420
46421 if (hoverChanged === true) {
46422 this.body.emitter.emit('_requestRedraw');
46423 }
46424 }
46425 /**
46426 *
46427 * retrieve the currently selected objects
46428 * @return {{nodes: Array.<string>, edges: Array.<string>}} selection
46429 */
46430
46431 }, {
46432 key: "getSelection",
46433 value: function getSelection() {
46434 var nodeIds = this.getSelectedNodes();
46435 var edgeIds = this.getSelectedEdges();
46436 return {
46437 nodes: nodeIds,
46438 edges: edgeIds
46439 };
46440 }
46441 /**
46442 *
46443 * retrieve the currently selected nodes
46444 * @return {string[]} selection An array with the ids of the
46445 * selected nodes.
46446 */
46447
46448 }, {
46449 key: "getSelectedNodes",
46450 value: function getSelectedNodes() {
46451 var idArray = [];
46452
46453 if (this.options.selectable === true) {
46454 for (var nodeId in this.selectionObj.nodes) {
46455 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46456 idArray.push(this.selectionObj.nodes[nodeId].id);
46457 }
46458 }
46459 }
46460
46461 return idArray;
46462 }
46463 /**
46464 *
46465 * retrieve the currently selected edges
46466 * @return {Array} selection An array with the ids of the
46467 * selected nodes.
46468 */
46469
46470 }, {
46471 key: "getSelectedEdges",
46472 value: function getSelectedEdges() {
46473 var idArray = [];
46474
46475 if (this.options.selectable === true) {
46476 for (var edgeId in this.selectionObj.edges) {
46477 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46478 idArray.push(this.selectionObj.edges[edgeId].id);
46479 }
46480 }
46481 }
46482
46483 return idArray;
46484 }
46485 /**
46486 * Updates the current selection
46487 * @param {{nodes: Array.<string>, edges: Array.<string>}} selection
46488 * @param {Object} options Options
46489 */
46490
46491 }, {
46492 key: "setSelection",
46493 value: function setSelection(selection) {
46494 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
46495 var i, id;
46496 if (!selection || !selection.nodes && !selection.edges) throw 'Selection must be an object with nodes and/or edges properties'; // first unselect any selected node, if option is true or undefined
46497
46498 if (options.unselectAll || options.unselectAll === undefined) {
46499 this.unselectAll();
46500 }
46501
46502 if (selection.nodes) {
46503 for (i = 0; i < selection.nodes.length; i++) {
46504 id = selection.nodes[i];
46505 var node = this.body.nodes[id];
46506
46507 if (!node) {
46508 throw new RangeError('Node with id "' + id + '" not found');
46509 } // don't select edges with it
46510
46511
46512 this.selectObject(node, options.highlightEdges);
46513 }
46514 }
46515
46516 if (selection.edges) {
46517 for (i = 0; i < selection.edges.length; i++) {
46518 id = selection.edges[i];
46519 var edge = this.body.edges[id];
46520
46521 if (!edge) {
46522 throw new RangeError('Edge with id "' + id + '" not found');
46523 }
46524
46525 this.selectObject(edge);
46526 }
46527 }
46528
46529 this.body.emitter.emit('_requestRedraw');
46530 }
46531 /**
46532 * select zero or more nodes with the option to highlight edges
46533 * @param {number[] | string[]} selection An array with the ids of the
46534 * selected nodes.
46535 * @param {boolean} [highlightEdges]
46536 */
46537
46538 }, {
46539 key: "selectNodes",
46540 value: function selectNodes(selection) {
46541 var highlightEdges = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
46542 if (!selection || selection.length === undefined) throw 'Selection must be an array with ids';
46543 this.setSelection({
46544 nodes: selection
46545 }, {
46546 highlightEdges: highlightEdges
46547 });
46548 }
46549 /**
46550 * select zero or more edges
46551 * @param {number[] | string[]} selection An array with the ids of the
46552 * selected nodes.
46553 */
46554
46555 }, {
46556 key: "selectEdges",
46557 value: function selectEdges(selection) {
46558 if (!selection || selection.length === undefined) throw 'Selection must be an array with ids';
46559 this.setSelection({
46560 edges: selection
46561 });
46562 }
46563 /**
46564 * Validate the selection: remove ids of nodes which no longer exist
46565 * @private
46566 */
46567
46568 }, {
46569 key: "updateSelection",
46570 value: function updateSelection() {
46571 for (var nodeId in this.selectionObj.nodes) {
46572 if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
46573 if (!this.body.nodes.hasOwnProperty(nodeId)) {
46574 delete this.selectionObj.nodes[nodeId];
46575 }
46576 }
46577 }
46578
46579 for (var edgeId in this.selectionObj.edges) {
46580 if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
46581 if (!this.body.edges.hasOwnProperty(edgeId)) {
46582 delete this.selectionObj.edges[edgeId];
46583 }
46584 }
46585 }
46586 }
46587 /**
46588 * Determine all the visual elements clicked which are on the given point.
46589 *
46590 * All elements are returned; this includes nodes, edges and their labels.
46591 * The order returned is from highest to lowest, i.e. element 0 of the return
46592 * value is the topmost item clicked on.
46593 *
46594 * The return value consists of an array of the following possible elements:
46595 *
46596 * - `{nodeId:number}` - node with given id clicked on
46597 * - `{nodeId:number, labelId:0}` - label of node with given id clicked on
46598 * - `{edgeId:number}` - edge with given id clicked on
46599 * - `{edge:number, labelId:0}` - label of edge with given id clicked on
46600 *
46601 * ## NOTES
46602 *
46603 * - Currently, there is only one label associated with a node or an edge,
46604 * but this is expected to change somewhere in the future.
46605 * - Since there is no z-indexing yet, it is not really possible to set the nodes and
46606 * edges in the correct order. For the time being, nodes come first.
46607 *
46608 * @param {point} pointer mouse position in screen coordinates
46609 * @returns {Array.<nodeClickItem|nodeLabelClickItem|edgeClickItem|edgeLabelClickItem>}
46610 * @private
46611 */
46612
46613 }, {
46614 key: "getClickedItems",
46615 value: function getClickedItems(pointer) {
46616 var point = this.canvas.DOMtoCanvas(pointer);
46617 var items = []; // Note reverse order; we want the topmost clicked items to be first in the array
46618 // Also note that selected nodes are disregarded here; these normally display on top
46619
46620 var nodeIndices = this.body.nodeIndices;
46621 var nodes = this.body.nodes;
46622
46623 for (var i = nodeIndices.length - 1; i >= 0; i--) {
46624 var node = nodes[nodeIndices[i]];
46625 var ret = node.getItemsOnPoint(point);
46626 items.push.apply(items, ret); // Append the return value to the running list.
46627 }
46628
46629 var edgeIndices = this.body.edgeIndices;
46630 var edges = this.body.edges;
46631
46632 for (var _i = edgeIndices.length - 1; _i >= 0; _i--) {
46633 var edge = edges[edgeIndices[_i]];
46634
46635 var _ret = edge.getItemsOnPoint(point);
46636
46637 items.push.apply(items, _ret); // Append the return value to the running list.
46638 }
46639
46640 return items;
46641 }
46642 }]);
46643
46644 return SelectionHandler;
46645 }();
46646
46647 var timsort = createCommonjsModule(function (module, exports) {
46648 /****
46649 * The MIT License
46650 *
46651 * Copyright (c) 2015 Marco Ziccardi
46652 *
46653 * Permission is hereby granted, free of charge, to any person obtaining a copy
46654 * of this software and associated documentation files (the "Software"), to deal
46655 * in the Software without restriction, including without limitation the rights
46656 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46657 * copies of the Software, and to permit persons to whom the Software is
46658 * furnished to do so, subject to the following conditions:
46659 *
46660 * The above copyright notice and this permission notice shall be included in
46661 * all copies or substantial portions of the Software.
46662 *
46663 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46664 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46665 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46666 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46667 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46668 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46669 * THE SOFTWARE.
46670 *
46671 ****/
46672 (function (global, factory) {
46673 {
46674 factory(exports);
46675 }
46676 })(commonjsGlobal, function (exports) {
46677
46678 exports.__esModule = true;
46679 exports.sort = sort;
46680
46681 function _classCallCheck(instance, Constructor) {
46682 if (!(instance instanceof Constructor)) {
46683 throw new TypeError('Cannot call a class as a function');
46684 }
46685 }
46686
46687 var DEFAULT_MIN_MERGE = 32;
46688 var DEFAULT_MIN_GALLOPING = 7;
46689 var DEFAULT_TMP_STORAGE_LENGTH = 256;
46690 var POWERS_OF_TEN = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9];
46691
46692 function log10(x) {
46693 if (x < 1e5) {
46694 if (x < 1e2) {
46695 return x < 1e1 ? 0 : 1;
46696 }
46697
46698 if (x < 1e4) {
46699 return x < 1e3 ? 2 : 3;
46700 }
46701
46702 return 4;
46703 }
46704
46705 if (x < 1e7) {
46706 return x < 1e6 ? 5 : 6;
46707 }
46708
46709 if (x < 1e9) {
46710 return x < 1e8 ? 7 : 8;
46711 }
46712
46713 return 9;
46714 }
46715
46716 function alphabeticalCompare(a, b) {
46717 if (a === b) {
46718 return 0;
46719 }
46720
46721 if (~~a === a && ~~b === b) {
46722 if (a === 0 || b === 0) {
46723 return a < b ? -1 : 1;
46724 }
46725
46726 if (a < 0 || b < 0) {
46727 if (b >= 0) {
46728 return -1;
46729 }
46730
46731 if (a >= 0) {
46732 return 1;
46733 }
46734
46735 a = -a;
46736 b = -b;
46737 }
46738
46739 var al = log10(a);
46740 var bl = log10(b);
46741 var t = 0;
46742
46743 if (al < bl) {
46744 a *= POWERS_OF_TEN[bl - al - 1];
46745 b /= 10;
46746 t = -1;
46747 } else if (al > bl) {
46748 b *= POWERS_OF_TEN[al - bl - 1];
46749 a /= 10;
46750 t = 1;
46751 }
46752
46753 if (a === b) {
46754 return t;
46755 }
46756
46757 return a < b ? -1 : 1;
46758 }
46759
46760 var aStr = String(a);
46761 var bStr = String(b);
46762
46763 if (aStr === bStr) {
46764 return 0;
46765 }
46766
46767 return aStr < bStr ? -1 : 1;
46768 }
46769
46770 function minRunLength(n) {
46771 var r = 0;
46772
46773 while (n >= DEFAULT_MIN_MERGE) {
46774 r |= n & 1;
46775 n >>= 1;
46776 }
46777
46778 return n + r;
46779 }
46780
46781 function makeAscendingRun(array, lo, hi, compare) {
46782 var runHi = lo + 1;
46783
46784 if (runHi === hi) {
46785 return 1;
46786 }
46787
46788 if (compare(array[runHi++], array[lo]) < 0) {
46789 while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
46790 runHi++;
46791 }
46792
46793 reverseRun(array, lo, runHi);
46794 } else {
46795 while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
46796 runHi++;
46797 }
46798 }
46799
46800 return runHi - lo;
46801 }
46802
46803 function reverseRun(array, lo, hi) {
46804 hi--;
46805
46806 while (lo < hi) {
46807 var t = array[lo];
46808 array[lo++] = array[hi];
46809 array[hi--] = t;
46810 }
46811 }
46812
46813 function binaryInsertionSort(array, lo, hi, start, compare) {
46814 if (start === lo) {
46815 start++;
46816 }
46817
46818 for (; start < hi; start++) {
46819 var pivot = array[start];
46820 var left = lo;
46821 var right = start;
46822
46823 while (left < right) {
46824 var mid = left + right >>> 1;
46825
46826 if (compare(pivot, array[mid]) < 0) {
46827 right = mid;
46828 } else {
46829 left = mid + 1;
46830 }
46831 }
46832
46833 var n = start - left;
46834
46835 switch (n) {
46836 case 3:
46837 array[left + 3] = array[left + 2];
46838
46839 case 2:
46840 array[left + 2] = array[left + 1];
46841
46842 case 1:
46843 array[left + 1] = array[left];
46844 break;
46845
46846 default:
46847 while (n > 0) {
46848 array[left + n] = array[left + n - 1];
46849 n--;
46850 }
46851
46852 }
46853
46854 array[left] = pivot;
46855 }
46856 }
46857
46858 function gallopLeft(value, array, start, length, hint, compare) {
46859 var lastOffset = 0;
46860 var maxOffset = 0;
46861 var offset = 1;
46862
46863 if (compare(value, array[start + hint]) > 0) {
46864 maxOffset = length - hint;
46865
46866 while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
46867 lastOffset = offset;
46868 offset = (offset << 1) + 1;
46869
46870 if (offset <= 0) {
46871 offset = maxOffset;
46872 }
46873 }
46874
46875 if (offset > maxOffset) {
46876 offset = maxOffset;
46877 }
46878
46879 lastOffset += hint;
46880 offset += hint;
46881 } else {
46882 maxOffset = hint + 1;
46883
46884 while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
46885 lastOffset = offset;
46886 offset = (offset << 1) + 1;
46887
46888 if (offset <= 0) {
46889 offset = maxOffset;
46890 }
46891 }
46892
46893 if (offset > maxOffset) {
46894 offset = maxOffset;
46895 }
46896
46897 var tmp = lastOffset;
46898 lastOffset = hint - offset;
46899 offset = hint - tmp;
46900 }
46901
46902 lastOffset++;
46903
46904 while (lastOffset < offset) {
46905 var m = lastOffset + (offset - lastOffset >>> 1);
46906
46907 if (compare(value, array[start + m]) > 0) {
46908 lastOffset = m + 1;
46909 } else {
46910 offset = m;
46911 }
46912 }
46913
46914 return offset;
46915 }
46916
46917 function gallopRight(value, array, start, length, hint, compare) {
46918 var lastOffset = 0;
46919 var maxOffset = 0;
46920 var offset = 1;
46921
46922 if (compare(value, array[start + hint]) < 0) {
46923 maxOffset = hint + 1;
46924
46925 while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
46926 lastOffset = offset;
46927 offset = (offset << 1) + 1;
46928
46929 if (offset <= 0) {
46930 offset = maxOffset;
46931 }
46932 }
46933
46934 if (offset > maxOffset) {
46935 offset = maxOffset;
46936 }
46937
46938 var tmp = lastOffset;
46939 lastOffset = hint - offset;
46940 offset = hint - tmp;
46941 } else {
46942 maxOffset = length - hint;
46943
46944 while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
46945 lastOffset = offset;
46946 offset = (offset << 1) + 1;
46947
46948 if (offset <= 0) {
46949 offset = maxOffset;
46950 }
46951 }
46952
46953 if (offset > maxOffset) {
46954 offset = maxOffset;
46955 }
46956
46957 lastOffset += hint;
46958 offset += hint;
46959 }
46960
46961 lastOffset++;
46962
46963 while (lastOffset < offset) {
46964 var m = lastOffset + (offset - lastOffset >>> 1);
46965
46966 if (compare(value, array[start + m]) < 0) {
46967 offset = m;
46968 } else {
46969 lastOffset = m + 1;
46970 }
46971 }
46972
46973 return offset;
46974 }
46975
46976 var TimSort = function () {
46977 function TimSort(array, compare) {
46978 _classCallCheck(this, TimSort);
46979
46980 this.array = null;
46981 this.compare = null;
46982 this.minGallop = DEFAULT_MIN_GALLOPING;
46983 this.length = 0;
46984 this.tmpStorageLength = DEFAULT_TMP_STORAGE_LENGTH;
46985 this.stackLength = 0;
46986 this.runStart = null;
46987 this.runLength = null;
46988 this.stackSize = 0;
46989 this.array = array;
46990 this.compare = compare;
46991 this.length = array.length;
46992
46993 if (this.length < 2 * DEFAULT_TMP_STORAGE_LENGTH) {
46994 this.tmpStorageLength = this.length >>> 1;
46995 }
46996
46997 this.tmp = new Array(this.tmpStorageLength);
46998 this.stackLength = this.length < 120 ? 5 : this.length < 1542 ? 10 : this.length < 119151 ? 19 : 40;
46999 this.runStart = new Array(this.stackLength);
47000 this.runLength = new Array(this.stackLength);
47001 }
47002
47003 TimSort.prototype.pushRun = function pushRun(runStart, runLength) {
47004 this.runStart[this.stackSize] = runStart;
47005 this.runLength[this.stackSize] = runLength;
47006 this.stackSize += 1;
47007 };
47008
47009 TimSort.prototype.mergeRuns = function mergeRuns() {
47010 while (this.stackSize > 1) {
47011 var n = this.stackSize - 2;
47012
47013 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]) {
47014 if (this.runLength[n - 1] < this.runLength[n + 1]) {
47015 n--;
47016 }
47017 } else if (this.runLength[n] > this.runLength[n + 1]) {
47018 break;
47019 }
47020
47021 this.mergeAt(n);
47022 }
47023 };
47024
47025 TimSort.prototype.forceMergeRuns = function forceMergeRuns() {
47026 while (this.stackSize > 1) {
47027 var n = this.stackSize - 2;
47028
47029 if (n > 0 && this.runLength[n - 1] < this.runLength[n + 1]) {
47030 n--;
47031 }
47032
47033 this.mergeAt(n);
47034 }
47035 };
47036
47037 TimSort.prototype.mergeAt = function mergeAt(i) {
47038 var compare = this.compare;
47039 var array = this.array;
47040 var start1 = this.runStart[i];
47041 var length1 = this.runLength[i];
47042 var start2 = this.runStart[i + 1];
47043 var length2 = this.runLength[i + 1];
47044 this.runLength[i] = length1 + length2;
47045
47046 if (i === this.stackSize - 3) {
47047 this.runStart[i + 1] = this.runStart[i + 2];
47048 this.runLength[i + 1] = this.runLength[i + 2];
47049 }
47050
47051 this.stackSize--;
47052 var k = gallopRight(array[start2], array, start1, length1, 0, compare);
47053 start1 += k;
47054 length1 -= k;
47055
47056 if (length1 === 0) {
47057 return;
47058 }
47059
47060 length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);
47061
47062 if (length2 === 0) {
47063 return;
47064 }
47065
47066 if (length1 <= length2) {
47067 this.mergeLow(start1, length1, start2, length2);
47068 } else {
47069 this.mergeHigh(start1, length1, start2, length2);
47070 }
47071 };
47072
47073 TimSort.prototype.mergeLow = function mergeLow(start1, length1, start2, length2) {
47074 var compare = this.compare;
47075 var array = this.array;
47076 var tmp = this.tmp;
47077 var i = 0;
47078
47079 for (i = 0; i < length1; i++) {
47080 tmp[i] = array[start1 + i];
47081 }
47082
47083 var cursor1 = 0;
47084 var cursor2 = start2;
47085 var dest = start1;
47086 array[dest++] = array[cursor2++];
47087
47088 if (--length2 === 0) {
47089 for (i = 0; i < length1; i++) {
47090 array[dest + i] = tmp[cursor1 + i];
47091 }
47092
47093 return;
47094 }
47095
47096 if (length1 === 1) {
47097 for (i = 0; i < length2; i++) {
47098 array[dest + i] = array[cursor2 + i];
47099 }
47100
47101 array[dest + length2] = tmp[cursor1];
47102 return;
47103 }
47104
47105 var minGallop = this.minGallop;
47106
47107 while (true) {
47108 var count1 = 0;
47109 var count2 = 0;
47110 var exit = false;
47111
47112 do {
47113 if (compare(array[cursor2], tmp[cursor1]) < 0) {
47114 array[dest++] = array[cursor2++];
47115 count2++;
47116 count1 = 0;
47117
47118 if (--length2 === 0) {
47119 exit = true;
47120 break;
47121 }
47122 } else {
47123 array[dest++] = tmp[cursor1++];
47124 count1++;
47125 count2 = 0;
47126
47127 if (--length1 === 1) {
47128 exit = true;
47129 break;
47130 }
47131 }
47132 } while ((count1 | count2) < minGallop);
47133
47134 if (exit) {
47135 break;
47136 }
47137
47138 do {
47139 count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);
47140
47141 if (count1 !== 0) {
47142 for (i = 0; i < count1; i++) {
47143 array[dest + i] = tmp[cursor1 + i];
47144 }
47145
47146 dest += count1;
47147 cursor1 += count1;
47148 length1 -= count1;
47149
47150 if (length1 <= 1) {
47151 exit = true;
47152 break;
47153 }
47154 }
47155
47156 array[dest++] = array[cursor2++];
47157
47158 if (--length2 === 0) {
47159 exit = true;
47160 break;
47161 }
47162
47163 count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);
47164
47165 if (count2 !== 0) {
47166 for (i = 0; i < count2; i++) {
47167 array[dest + i] = array[cursor2 + i];
47168 }
47169
47170 dest += count2;
47171 cursor2 += count2;
47172 length2 -= count2;
47173
47174 if (length2 === 0) {
47175 exit = true;
47176 break;
47177 }
47178 }
47179
47180 array[dest++] = tmp[cursor1++];
47181
47182 if (--length1 === 1) {
47183 exit = true;
47184 break;
47185 }
47186
47187 minGallop--;
47188 } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
47189
47190 if (exit) {
47191 break;
47192 }
47193
47194 if (minGallop < 0) {
47195 minGallop = 0;
47196 }
47197
47198 minGallop += 2;
47199 }
47200
47201 this.minGallop = minGallop;
47202
47203 if (minGallop < 1) {
47204 this.minGallop = 1;
47205 }
47206
47207 if (length1 === 1) {
47208 for (i = 0; i < length2; i++) {
47209 array[dest + i] = array[cursor2 + i];
47210 }
47211
47212 array[dest + length2] = tmp[cursor1];
47213 } else if (length1 === 0) {
47214 throw new Error('mergeLow preconditions were not respected');
47215 } else {
47216 for (i = 0; i < length1; i++) {
47217 array[dest + i] = tmp[cursor1 + i];
47218 }
47219 }
47220 };
47221
47222 TimSort.prototype.mergeHigh = function mergeHigh(start1, length1, start2, length2) {
47223 var compare = this.compare;
47224 var array = this.array;
47225 var tmp = this.tmp;
47226 var i = 0;
47227
47228 for (i = 0; i < length2; i++) {
47229 tmp[i] = array[start2 + i];
47230 }
47231
47232 var cursor1 = start1 + length1 - 1;
47233 var cursor2 = length2 - 1;
47234 var dest = start2 + length2 - 1;
47235 var customCursor = 0;
47236 var customDest = 0;
47237 array[dest--] = array[cursor1--];
47238
47239 if (--length1 === 0) {
47240 customCursor = dest - (length2 - 1);
47241
47242 for (i = 0; i < length2; i++) {
47243 array[customCursor + i] = tmp[i];
47244 }
47245
47246 return;
47247 }
47248
47249 if (length2 === 1) {
47250 dest -= length1;
47251 cursor1 -= length1;
47252 customDest = dest + 1;
47253 customCursor = cursor1 + 1;
47254
47255 for (i = length1 - 1; i >= 0; i--) {
47256 array[customDest + i] = array[customCursor + i];
47257 }
47258
47259 array[dest] = tmp[cursor2];
47260 return;
47261 }
47262
47263 var minGallop = this.minGallop;
47264
47265 while (true) {
47266 var count1 = 0;
47267 var count2 = 0;
47268 var exit = false;
47269
47270 do {
47271 if (compare(tmp[cursor2], array[cursor1]) < 0) {
47272 array[dest--] = array[cursor1--];
47273 count1++;
47274 count2 = 0;
47275
47276 if (--length1 === 0) {
47277 exit = true;
47278 break;
47279 }
47280 } else {
47281 array[dest--] = tmp[cursor2--];
47282 count2++;
47283 count1 = 0;
47284
47285 if (--length2 === 1) {
47286 exit = true;
47287 break;
47288 }
47289 }
47290 } while ((count1 | count2) < minGallop);
47291
47292 if (exit) {
47293 break;
47294 }
47295
47296 do {
47297 count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);
47298
47299 if (count1 !== 0) {
47300 dest -= count1;
47301 cursor1 -= count1;
47302 length1 -= count1;
47303 customDest = dest + 1;
47304 customCursor = cursor1 + 1;
47305
47306 for (i = count1 - 1; i >= 0; i--) {
47307 array[customDest + i] = array[customCursor + i];
47308 }
47309
47310 if (length1 === 0) {
47311 exit = true;
47312 break;
47313 }
47314 }
47315
47316 array[dest--] = tmp[cursor2--];
47317
47318 if (--length2 === 1) {
47319 exit = true;
47320 break;
47321 }
47322
47323 count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);
47324
47325 if (count2 !== 0) {
47326 dest -= count2;
47327 cursor2 -= count2;
47328 length2 -= count2;
47329 customDest = dest + 1;
47330 customCursor = cursor2 + 1;
47331
47332 for (i = 0; i < count2; i++) {
47333 array[customDest + i] = tmp[customCursor + i];
47334 }
47335
47336 if (length2 <= 1) {
47337 exit = true;
47338 break;
47339 }
47340 }
47341
47342 array[dest--] = array[cursor1--];
47343
47344 if (--length1 === 0) {
47345 exit = true;
47346 break;
47347 }
47348
47349 minGallop--;
47350 } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
47351
47352 if (exit) {
47353 break;
47354 }
47355
47356 if (minGallop < 0) {
47357 minGallop = 0;
47358 }
47359
47360 minGallop += 2;
47361 }
47362
47363 this.minGallop = minGallop;
47364
47365 if (minGallop < 1) {
47366 this.minGallop = 1;
47367 }
47368
47369 if (length2 === 1) {
47370 dest -= length1;
47371 cursor1 -= length1;
47372 customDest = dest + 1;
47373 customCursor = cursor1 + 1;
47374
47375 for (i = length1 - 1; i >= 0; i--) {
47376 array[customDest + i] = array[customCursor + i];
47377 }
47378
47379 array[dest] = tmp[cursor2];
47380 } else if (length2 === 0) {
47381 throw new Error('mergeHigh preconditions were not respected');
47382 } else {
47383 customCursor = dest - (length2 - 1);
47384
47385 for (i = 0; i < length2; i++) {
47386 array[customCursor + i] = tmp[i];
47387 }
47388 }
47389 };
47390
47391 return TimSort;
47392 }();
47393
47394 function sort(array, compare, lo, hi) {
47395 if (!Array.isArray(array)) {
47396 throw new TypeError('Can only sort arrays');
47397 }
47398
47399 if (!compare) {
47400 compare = alphabeticalCompare;
47401 } else if (typeof compare !== 'function') {
47402 hi = lo;
47403 lo = compare;
47404 compare = alphabeticalCompare;
47405 }
47406
47407 if (!lo) {
47408 lo = 0;
47409 }
47410
47411 if (!hi) {
47412 hi = array.length;
47413 }
47414
47415 var remaining = hi - lo;
47416
47417 if (remaining < 2) {
47418 return;
47419 }
47420
47421 var runLength = 0;
47422
47423 if (remaining < DEFAULT_MIN_MERGE) {
47424 runLength = makeAscendingRun(array, lo, hi, compare);
47425 binaryInsertionSort(array, lo, hi, lo + runLength, compare);
47426 return;
47427 }
47428
47429 var ts = new TimSort(array, compare);
47430 var minRun = minRunLength(remaining);
47431
47432 do {
47433 runLength = makeAscendingRun(array, lo, hi, compare);
47434
47435 if (runLength < minRun) {
47436 var force = remaining;
47437
47438 if (force > minRun) {
47439 force = minRun;
47440 }
47441
47442 binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
47443 runLength = force;
47444 }
47445
47446 ts.pushRun(lo, runLength);
47447 ts.mergeRuns();
47448 remaining -= runLength;
47449 lo += runLength;
47450 } while (remaining !== 0);
47451
47452 ts.forceMergeRuns();
47453 }
47454 });
47455 });
47456 unwrapExports(timsort);
47457
47458 var timsort$1 = timsort;
47459 var timsort_1 = timsort$1.sort;
47460
47461 /**
47462 * Interface definition for direction strategy classes.
47463 *
47464 * This class describes the interface for the Strategy
47465 * pattern classes used to differentiate horizontal and vertical
47466 * direction of hierarchical results.
47467 *
47468 * For a given direction, one coordinate will be 'fixed', meaning that it is
47469 * determined by level.
47470 * The other coordinate is 'unfixed', meaning that the nodes on a given level
47471 * can still move along that coordinate. So:
47472 *
47473 * - `vertical` layout: `x` unfixed, `y` fixed per level
47474 * - `horizontal` layout: `x` fixed per level, `y` unfixed
47475 *
47476 * The local methods are stubs and should be regarded as abstract.
47477 * Derived classes **must** implement all the methods themselves.
47478 *
47479 * @private
47480 */
47481
47482 var DirectionInterface =
47483 /*#__PURE__*/
47484 function () {
47485 function DirectionInterface() {
47486 _classCallCheck(this, DirectionInterface);
47487 }
47488
47489 _createClass(DirectionInterface, [{
47490 key: "abstract",
47491
47492 /** @ignore **/
47493 value: function abstract() {
47494 throw new Error("Can't instantiate abstract class!");
47495 }
47496 /**
47497 * This is a dummy call which is used to suppress the jsdoc errors of type:
47498 *
47499 * "'param' is assigned a value but never used"
47500 *
47501 * @ignore
47502 **/
47503
47504 }, {
47505 key: "fake_use",
47506 value: function fake_use() {} // Do nothing special
47507
47508 /**
47509 * Type to use to translate dynamic curves to, in the case of hierarchical layout.
47510 * Dynamic curves do not work for these.
47511 *
47512 * The value should be perpendicular to the actual direction of the layout.
47513 *
47514 * @return {string} Direction, either 'vertical' or 'horizontal'
47515 */
47516
47517 }, {
47518 key: "curveType",
47519 value: function curveType() {
47520 return this.abstract();
47521 }
47522 /**
47523 * Return the value of the coordinate that is not fixed for this direction.
47524 *
47525 * @param {Node} node The node to read
47526 * @return {number} Value of the unfixed coordinate
47527 */
47528
47529 }, {
47530 key: "getPosition",
47531 value: function getPosition(node) {
47532 this.fake_use(node);
47533 return this.abstract();
47534 }
47535 /**
47536 * Set the value of the coordinate that is not fixed for this direction.
47537 *
47538 * @param {Node} node The node to adjust
47539 * @param {number} position
47540 * @param {number} [level] if specified, the hierarchy level that this node should be fixed to
47541 */
47542
47543 }, {
47544 key: "setPosition",
47545 value: function setPosition(node, position) {
47546 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
47547 this.fake_use(node, position, level);
47548 this.abstract();
47549 }
47550 /**
47551 * Get the width of a tree.
47552 *
47553 * A `tree` here is a subset of nodes within the network which are not connected to other nodes,
47554 * only among themselves. In essence, it is a sub-network.
47555 *
47556 * @param {number} index The index number of a tree
47557 * @return {number} the width of a tree in the view coordinates
47558 */
47559
47560 }, {
47561 key: "getTreeSize",
47562 value: function getTreeSize(index) {
47563 this.fake_use(index);
47564 return this.abstract();
47565 }
47566 /**
47567 * Sort array of nodes on the unfixed coordinates.
47568 *
47569 * **Note:** chrome has non-stable sorting implementation, which
47570 * has a tendency to change the order of the array items,
47571 * even if the custom sort function returns 0.
47572 *
47573 * For this reason, an external sort implementation is used,
47574 * which has the added benefit of being faster than the standard
47575 * platforms implementation. This has been verified on `node.js`,
47576 * `firefox` and `chrome` (all linux).
47577 *
47578 * @param {Array.<Node>} nodeArray array of nodes to sort
47579 */
47580
47581 }, {
47582 key: "sort",
47583 value: function sort(nodeArray) {
47584 this.fake_use(nodeArray);
47585 this.abstract();
47586 }
47587 /**
47588 * Assign the fixed coordinate of the node to the given level
47589 *
47590 * @param {Node} node The node to adjust
47591 * @param {number} level The level to fix to
47592 */
47593
47594 }, {
47595 key: "fix",
47596 value: function fix(node, level) {
47597 this.fake_use(node, level);
47598 this.abstract();
47599 }
47600 /**
47601 * Add an offset to the unfixed coordinate of the given node.
47602 *
47603 * @param {NodeId} nodeId Id of the node to adjust
47604 * @param {number} diff Offset to add to the unfixed coordinate
47605 */
47606
47607 }, {
47608 key: "shift",
47609 value: function shift(nodeId, diff) {
47610 this.fake_use(nodeId, diff);
47611 this.abstract();
47612 }
47613 }]);
47614
47615 return DirectionInterface;
47616 }();
47617 /**
47618 * Vertical Strategy
47619 *
47620 * Coordinate `y` is fixed on levels, coordinate `x` is unfixed.
47621 *
47622 * @extends DirectionInterface
47623 * @private
47624 */
47625
47626
47627 var VerticalStrategy =
47628 /*#__PURE__*/
47629 function (_DirectionInterface) {
47630 _inherits(VerticalStrategy, _DirectionInterface);
47631
47632 /**
47633 * Constructor
47634 *
47635 * @param {Object} layout reference to the parent LayoutEngine instance.
47636 */
47637 function VerticalStrategy(layout) {
47638 var _this;
47639
47640 _classCallCheck(this, VerticalStrategy);
47641
47642 _this = _possibleConstructorReturn(this, _getPrototypeOf(VerticalStrategy).call(this));
47643 _this.layout = layout;
47644 return _this;
47645 }
47646 /** @inheritdoc */
47647
47648
47649 _createClass(VerticalStrategy, [{
47650 key: "curveType",
47651 value: function curveType() {
47652 return 'horizontal';
47653 }
47654 /** @inheritdoc */
47655
47656 }, {
47657 key: "getPosition",
47658 value: function getPosition(node) {
47659 return node.x;
47660 }
47661 /** @inheritdoc */
47662
47663 }, {
47664 key: "setPosition",
47665 value: function setPosition(node, position) {
47666 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
47667
47668 if (level !== undefined) {
47669 this.layout.hierarchical.addToOrdering(node, level);
47670 }
47671
47672 node.x = position;
47673 }
47674 /** @inheritdoc */
47675
47676 }, {
47677 key: "getTreeSize",
47678 value: function getTreeSize(index) {
47679 var res = this.layout.hierarchical.getTreeSize(this.layout.body.nodes, index);
47680 return {
47681 min: res.min_x,
47682 max: res.max_x
47683 };
47684 }
47685 /** @inheritdoc */
47686
47687 }, {
47688 key: "sort",
47689 value: function sort(nodeArray) {
47690 timsort_1(nodeArray, function (a, b) {
47691 return a.x - b.x;
47692 });
47693 }
47694 /** @inheritdoc */
47695
47696 }, {
47697 key: "fix",
47698 value: function fix(node, level) {
47699 node.y = this.layout.options.hierarchical.levelSeparation * level;
47700 node.options.fixed.y = true;
47701 }
47702 /** @inheritdoc */
47703
47704 }, {
47705 key: "shift",
47706 value: function shift(nodeId, diff) {
47707 this.layout.body.nodes[nodeId].x += diff;
47708 }
47709 }]);
47710
47711 return VerticalStrategy;
47712 }(DirectionInterface);
47713 /**
47714 * Horizontal Strategy
47715 *
47716 * Coordinate `x` is fixed on levels, coordinate `y` is unfixed.
47717 *
47718 * @extends DirectionInterface
47719 * @private
47720 */
47721
47722
47723 var HorizontalStrategy =
47724 /*#__PURE__*/
47725 function (_DirectionInterface2) {
47726 _inherits(HorizontalStrategy, _DirectionInterface2);
47727
47728 /**
47729 * Constructor
47730 *
47731 * @param {Object} layout reference to the parent LayoutEngine instance.
47732 */
47733 function HorizontalStrategy(layout) {
47734 var _this2;
47735
47736 _classCallCheck(this, HorizontalStrategy);
47737
47738 _this2 = _possibleConstructorReturn(this, _getPrototypeOf(HorizontalStrategy).call(this));
47739 _this2.layout = layout;
47740 return _this2;
47741 }
47742 /** @inheritdoc */
47743
47744
47745 _createClass(HorizontalStrategy, [{
47746 key: "curveType",
47747 value: function curveType() {
47748 return 'vertical';
47749 }
47750 /** @inheritdoc */
47751
47752 }, {
47753 key: "getPosition",
47754 value: function getPosition(node) {
47755 return node.y;
47756 }
47757 /** @inheritdoc */
47758
47759 }, {
47760 key: "setPosition",
47761 value: function setPosition(node, position) {
47762 var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
47763
47764 if (level !== undefined) {
47765 this.layout.hierarchical.addToOrdering(node, level);
47766 }
47767
47768 node.y = position;
47769 }
47770 /** @inheritdoc */
47771
47772 }, {
47773 key: "getTreeSize",
47774 value: function getTreeSize(index) {
47775 var res = this.layout.hierarchical.getTreeSize(this.layout.body.nodes, index);
47776 return {
47777 min: res.min_y,
47778 max: res.max_y
47779 };
47780 }
47781 /** @inheritdoc */
47782
47783 }, {
47784 key: "sort",
47785 value: function sort(nodeArray) {
47786 timsort_1(nodeArray, function (a, b) {
47787 return a.y - b.y;
47788 });
47789 }
47790 /** @inheritdoc */
47791
47792 }, {
47793 key: "fix",
47794 value: function fix(node, level) {
47795 node.x = this.layout.options.hierarchical.levelSeparation * level;
47796 node.options.fixed.x = true;
47797 }
47798 /** @inheritdoc */
47799
47800 }, {
47801 key: "shift",
47802 value: function shift(nodeId, diff) {
47803 this.layout.body.nodes[nodeId].y += diff;
47804 }
47805 }]);
47806
47807 return HorizontalStrategy;
47808 }(DirectionInterface);
47809
47810 var $every$1 = arrayIteration.every;
47811
47812
47813 // `Array.prototype.every` method
47814 // https://tc39.github.io/ecma262/#sec-array.prototype.every
47815 _export({ target: 'Array', proto: true, forced: sloppyArrayMethod('every') }, {
47816 every: function every(callbackfn /* , thisArg */) {
47817 return $every$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
47818 }
47819 });
47820
47821 /**
47822 * Try to assign levels to nodes according to their positions in the cyclic “hierarchy”.
47823 *
47824 * @param nodes - Nodes of the graph.
47825 * @param levels - If present levels will be added to it, if not a new object will be created.
47826 *
47827 * @returns Populated node levels.
47828 */
47829 function fillLevelsByDirectionCyclic(nodes, levels) {
47830 var edges = new Set();
47831 nodes.forEach(function (node) {
47832 node.edges.forEach(function (edge) {
47833 if (edge.connected) {
47834 edges.add(edge);
47835 }
47836 });
47837 });
47838 edges.forEach(function (edge) {
47839 var fromId = edge.from.id;
47840 var toId = edge.to.id;
47841
47842 if (levels[fromId] == null) {
47843 levels[fromId] = 0;
47844 }
47845
47846 if (levels[toId] == null || levels[fromId] >= levels[toId]) {
47847 levels[toId] = levels[fromId] + 1;
47848 }
47849 });
47850 return levels;
47851 }
47852 /**
47853 * 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.
47854 *
47855 * @param nodes - Nodes of the graph.
47856 * @param levels - If present levels will be added to it, if not a new object will be created.
47857 *
47858 * @returns Populated node levels.
47859 */
47860
47861
47862 function fillLevelsByDirectionLeaves(nodes) {
47863 var levels = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.create(null);
47864 return fillLevelsByDirection( // Pick only leaves (nodes without children).
47865 function (node) {
47866 return !node.edges.every(function (edge) {
47867 return edge.to === node;
47868 });
47869 }, // Use the lowest level.
47870 function (newLevel, oldLevel) {
47871 return oldLevel > newLevel;
47872 }, // Go against the direction of the edges.
47873 "from", nodes, levels);
47874 }
47875 /**
47876 * 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.
47877 *
47878 * @param nodes - Nodes of the graph.
47879 * @param levels - If present levels will be added to it, if not a new object will be created.
47880 *
47881 * @returns Populated node levels.
47882 */
47883
47884 function fillLevelsByDirectionRoots(nodes) {
47885 var levels = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.create(null);
47886 return fillLevelsByDirection( // Pick only roots (nodes without parents).
47887 function (node) {
47888 return !node.edges.every(function (edge) {
47889 return edge.from === node;
47890 });
47891 }, // Use the highest level.
47892 function (newLevel, oldLevel) {
47893 return oldLevel < newLevel;
47894 }, // Go in the direction of the edges.
47895 "to", nodes, levels);
47896 }
47897 /**
47898 * Assign levels to nodes according to their positions in the hierarchy.
47899 *
47900 * @param isEntryNode - Checks and return true if the graph should be traversed from this node.
47901 * @param shouldLevelBeReplaced - Checks and returns true if the level of given node should be updated to the new value.
47902 * @param direction - Wheter the graph should be traversed in the direction of the edges `"to"` or in the other way `"from"`.
47903 * @param nodes - Nodes of the graph.
47904 * @param levels - If present levels will be added to it, if not a new object will be created.
47905 *
47906 * @returns Populated node levels.
47907 */
47908
47909 function fillLevelsByDirection(isEntryNode, shouldLevelBeReplaced, direction, nodes, levels) {
47910 var limit = nodes.length;
47911 var edgeIdProp = direction + "Id";
47912 var newLevelDiff = direction === "to" ? 1 : -1;
47913 var _iteratorNormalCompletion = true;
47914 var _didIteratorError = false;
47915 var _iteratorError = undefined;
47916
47917 try {
47918 var _loop = function _loop() {
47919 var entryNode = _step.value;
47920
47921 if (isEntryNode(entryNode)) {
47922 return "continue";
47923 } // Line up all the entry nodes on level 0.
47924
47925
47926 levels[entryNode.id] = 0;
47927 var stack = [entryNode];
47928 var done = 0;
47929 var node = void 0;
47930
47931 var _loop2 = function _loop2() {
47932 var newLevel = levels[node.id] + newLevelDiff;
47933 node.edges.filter(function (edge) {
47934 return (// Ignore disconnected edges.
47935 edge.connected && // Ignore circular edges.
47936 edge.to !== edge.from && // Ignore edges leading to the node that's currently being processed.
47937 edge[direction] !== node
47938 );
47939 }).forEach(function (edge) {
47940 var targetNodeId = edge[edgeIdProp];
47941 var oldLevel = levels[targetNodeId];
47942
47943 if (oldLevel == null || shouldLevelBeReplaced(newLevel, oldLevel)) {
47944 levels[targetNodeId] = newLevel;
47945 stack.push(edge[direction]);
47946 }
47947 });
47948
47949 if (done > limit) {
47950 // This would run forever on a cyclic graph.
47951 return {
47952 v: {
47953 v: fillLevelsByDirectionCyclic(nodes, levels)
47954 }
47955 };
47956 } else {
47957 ++done;
47958 }
47959 };
47960
47961 while (node = stack.pop()) {
47962 var _ret2 = _loop2();
47963
47964 if (_typeof(_ret2) === "object") return _ret2.v;
47965 }
47966 };
47967
47968 for (var _iterator = nodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
47969 var _ret = _loop();
47970
47971 switch (_ret) {
47972 case "continue":
47973 continue;
47974
47975 default:
47976 if (_typeof(_ret) === "object") return _ret.v;
47977 }
47978 }
47979 } catch (err) {
47980 _didIteratorError = true;
47981 _iteratorError = err;
47982 } finally {
47983 try {
47984 if (!_iteratorNormalCompletion && _iterator.return != null) {
47985 _iterator.return();
47986 }
47987 } finally {
47988 if (_didIteratorError) {
47989 throw _iteratorError;
47990 }
47991 }
47992 }
47993
47994 return levels;
47995 }
47996
47997 /**
47998 * There's a mix-up with terms in the code. Following are the formal definitions:
47999 *
48000 * tree - a strict hierarchical network, i.e. every node has at most one parent
48001 * forest - a collection of trees. These distinct trees are thus not connected.
48002 *
48003 * So:
48004 * - in a network that is not a tree, there exist nodes with multiple parents.
48005 * - a network consisting of unconnected sub-networks, of which at least one
48006 * is not a tree, is not a forest.
48007 *
48008 * In the code, the definitions are:
48009 *
48010 * tree - any disconnected sub-network, strict hierarchical or not.
48011 * forest - a bunch of these sub-networks
48012 *
48013 * The difference between tree and not-tree is important in the code, notably within
48014 * to the block-shifting algorithm. The algorithm assumes formal trees and fails
48015 * for not-trees, often in a spectacular manner (search for 'exploding network' in the issues).
48016 *
48017 * In order to distinguish the definitions in the following code, the adjective 'formal' is
48018 * used. If 'formal' is absent, you must assume the non-formal definition.
48019 *
48020 * ----------------------------------------------------------------------------------
48021 * NOTES
48022 * =====
48023 *
48024 * A hierarchical layout is a different thing from a hierarchical network.
48025 * The layout is a way to arrange the nodes in the view; this can be done
48026 * on non-hierarchical networks as well. The converse is also possible.
48027 */
48028 /**
48029 * Container for derived data on current network, relating to hierarchy.
48030 *
48031 * @private
48032 */
48033
48034 var HierarchicalStatus =
48035 /*#__PURE__*/
48036 function () {
48037 /**
48038 * @ignore
48039 */
48040 function HierarchicalStatus() {
48041 _classCallCheck(this, HierarchicalStatus);
48042
48043 this.childrenReference = {}; // child id's per node id
48044
48045 this.parentReference = {}; // parent id's per node id
48046
48047 this.trees = {}; // tree id per node id; i.e. to which tree does given node id belong
48048
48049 this.distributionOrdering = {}; // The nodes per level, in the display order
48050
48051 this.levels = {}; // hierarchy level per node id
48052
48053 this.distributionIndex = {}; // The position of the node in the level sorting order, per node id.
48054
48055 this.isTree = false; // True if current network is a formal tree
48056
48057 this.treeIndex = -1; // Highest tree id in current network.
48058 }
48059 /**
48060 * Add the relation between given nodes to the current state.
48061 *
48062 * @param {Node.id} parentNodeId
48063 * @param {Node.id} childNodeId
48064 */
48065
48066
48067 _createClass(HierarchicalStatus, [{
48068 key: "addRelation",
48069 value: function addRelation(parentNodeId, childNodeId) {
48070 if (this.childrenReference[parentNodeId] === undefined) {
48071 this.childrenReference[parentNodeId] = [];
48072 }
48073
48074 this.childrenReference[parentNodeId].push(childNodeId);
48075
48076 if (this.parentReference[childNodeId] === undefined) {
48077 this.parentReference[childNodeId] = [];
48078 }
48079
48080 this.parentReference[childNodeId].push(parentNodeId);
48081 }
48082 /**
48083 * Check if the current state is for a formal tree or formal forest.
48084 *
48085 * This is the case if every node has at most one parent.
48086 *
48087 * Pre: parentReference init'ed properly for current network
48088 */
48089
48090 }, {
48091 key: "checkIfTree",
48092 value: function checkIfTree() {
48093 for (var i in this.parentReference) {
48094 if (this.parentReference[i].length > 1) {
48095 this.isTree = false;
48096 return;
48097 }
48098 }
48099
48100 this.isTree = true;
48101 }
48102 /**
48103 * Return the number of separate trees in the current network.
48104 * @returns {number}
48105 */
48106
48107 }, {
48108 key: "numTrees",
48109 value: function numTrees() {
48110 return this.treeIndex + 1; // This assumes the indexes are assigned consecitively
48111 }
48112 /**
48113 * Assign a tree id to a node
48114 * @param {Node} node
48115 * @param {string|number} treeId
48116 */
48117
48118 }, {
48119 key: "setTreeIndex",
48120 value: function setTreeIndex(node, treeId) {
48121 if (treeId === undefined) return; // Don't bother
48122
48123 if (this.trees[node.id] === undefined) {
48124 this.trees[node.id] = treeId;
48125 this.treeIndex = Math.max(treeId, this.treeIndex);
48126 }
48127 }
48128 /**
48129 * Ensure level for given id is defined.
48130 *
48131 * Sets level to zero for given node id if not already present
48132 *
48133 * @param {Node.id} nodeId
48134 */
48135
48136 }, {
48137 key: "ensureLevel",
48138 value: function ensureLevel(nodeId) {
48139 if (this.levels[nodeId] === undefined) {
48140 this.levels[nodeId] = 0;
48141 }
48142 }
48143 /**
48144 * get the maximum level of a branch.
48145 *
48146 * TODO: Never entered; find a test case to test this!
48147 * @param {Node.id} nodeId
48148 * @returns {number}
48149 */
48150
48151 }, {
48152 key: "getMaxLevel",
48153 value: function getMaxLevel(nodeId) {
48154 var _this = this;
48155
48156 var accumulator = {};
48157
48158 var _getMaxLevel = function _getMaxLevel(nodeId) {
48159 if (accumulator[nodeId] !== undefined) {
48160 return accumulator[nodeId];
48161 }
48162
48163 var level = _this.levels[nodeId];
48164
48165 if (_this.childrenReference[nodeId]) {
48166 var children = _this.childrenReference[nodeId];
48167
48168 if (children.length > 0) {
48169 for (var i = 0; i < children.length; i++) {
48170 level = Math.max(level, _getMaxLevel(children[i]));
48171 }
48172 }
48173 }
48174
48175 accumulator[nodeId] = level;
48176 return level;
48177 };
48178
48179 return _getMaxLevel(nodeId);
48180 }
48181 /**
48182 *
48183 * @param {Node} nodeA
48184 * @param {Node} nodeB
48185 */
48186
48187 }, {
48188 key: "levelDownstream",
48189 value: function levelDownstream(nodeA, nodeB) {
48190 if (this.levels[nodeB.id] === undefined) {
48191 // set initial level
48192 if (this.levels[nodeA.id] === undefined) {
48193 this.levels[nodeA.id] = 0;
48194 } // set level
48195
48196
48197 this.levels[nodeB.id] = this.levels[nodeA.id] + 1;
48198 }
48199 }
48200 /**
48201 * Small util method to set the minimum levels of the nodes to zero.
48202 *
48203 * @param {Array.<Node>} nodes
48204 */
48205
48206 }, {
48207 key: "setMinLevelToZero",
48208 value: function setMinLevelToZero(nodes) {
48209 var minLevel = 1e9; // get the minimum level
48210
48211 for (var nodeId in nodes) {
48212 if (nodes.hasOwnProperty(nodeId)) {
48213 if (this.levels[nodeId] !== undefined) {
48214 minLevel = Math.min(this.levels[nodeId], minLevel);
48215 }
48216 }
48217 } // subtract the minimum from the set so we have a range starting from 0
48218
48219
48220 for (var _nodeId in nodes) {
48221 if (nodes.hasOwnProperty(_nodeId)) {
48222 if (this.levels[_nodeId] !== undefined) {
48223 this.levels[_nodeId] -= minLevel;
48224 }
48225 }
48226 }
48227 }
48228 /**
48229 * Get the min and max xy-coordinates of a given tree
48230 *
48231 * @param {Array.<Node>} nodes
48232 * @param {number} index
48233 * @returns {{min_x: number, max_x: number, min_y: number, max_y: number}}
48234 */
48235
48236 }, {
48237 key: "getTreeSize",
48238 value: function getTreeSize(nodes, index) {
48239 var min_x = 1e9;
48240 var max_x = -1e9;
48241 var min_y = 1e9;
48242 var max_y = -1e9;
48243
48244 for (var nodeId in this.trees) {
48245 if (this.trees.hasOwnProperty(nodeId)) {
48246 if (this.trees[nodeId] === index) {
48247 var node = nodes[nodeId];
48248 min_x = Math.min(node.x, min_x);
48249 max_x = Math.max(node.x, max_x);
48250 min_y = Math.min(node.y, min_y);
48251 max_y = Math.max(node.y, max_y);
48252 }
48253 }
48254 }
48255
48256 return {
48257 min_x: min_x,
48258 max_x: max_x,
48259 min_y: min_y,
48260 max_y: max_y
48261 };
48262 }
48263 /**
48264 * Check if two nodes have the same parent(s)
48265 *
48266 * @param {Node} node1
48267 * @param {Node} node2
48268 * @return {boolean} true if the two nodes have a same ancestor node, false otherwise
48269 */
48270
48271 }, {
48272 key: "hasSameParent",
48273 value: function hasSameParent(node1, node2) {
48274 var parents1 = this.parentReference[node1.id];
48275 var parents2 = this.parentReference[node2.id];
48276
48277 if (parents1 === undefined || parents2 === undefined) {
48278 return false;
48279 }
48280
48281 for (var i = 0; i < parents1.length; i++) {
48282 for (var j = 0; j < parents2.length; j++) {
48283 if (parents1[i] == parents2[j]) {
48284 return true;
48285 }
48286 }
48287 }
48288
48289 return false;
48290 }
48291 /**
48292 * Check if two nodes are in the same tree.
48293 *
48294 * @param {Node} node1
48295 * @param {Node} node2
48296 * @return {Boolean} true if this is so, false otherwise
48297 */
48298
48299 }, {
48300 key: "inSameSubNetwork",
48301 value: function inSameSubNetwork(node1, node2) {
48302 return this.trees[node1.id] === this.trees[node2.id];
48303 }
48304 /**
48305 * Get a list of the distinct levels in the current network
48306 *
48307 * @returns {Array}
48308 */
48309
48310 }, {
48311 key: "getLevels",
48312 value: function getLevels() {
48313 return Object.keys(this.distributionOrdering);
48314 }
48315 /**
48316 * Add a node to the ordering per level
48317 *
48318 * @param {Node} node
48319 * @param {number} level
48320 */
48321
48322 }, {
48323 key: "addToOrdering",
48324 value: function addToOrdering(node, level) {
48325 if (this.distributionOrdering[level] === undefined) {
48326 this.distributionOrdering[level] = [];
48327 }
48328
48329 var isPresent = false;
48330 var curLevel = this.distributionOrdering[level];
48331
48332 for (var n in curLevel) {
48333 //if (curLevel[n].id === node.id) {
48334 if (curLevel[n] === node) {
48335 isPresent = true;
48336 break;
48337 }
48338 }
48339
48340 if (!isPresent) {
48341 this.distributionOrdering[level].push(node);
48342 this.distributionIndex[node.id] = this.distributionOrdering[level].length - 1;
48343 }
48344 }
48345 }]);
48346
48347 return HierarchicalStatus;
48348 }();
48349 /**
48350 * The Layout Engine
48351 */
48352
48353
48354 var LayoutEngine =
48355 /*#__PURE__*/
48356 function () {
48357 /**
48358 * @param {Object} body
48359 */
48360 function LayoutEngine(body) {
48361 _classCallCheck(this, LayoutEngine);
48362
48363 this.body = body;
48364 this.initialRandomSeed = Math.round(Math.random() * 1000000);
48365 this.randomSeed = this.initialRandomSeed;
48366 this.setPhysics = false;
48367 this.options = {};
48368 this.optionsBackup = {
48369 physics: {}
48370 };
48371 this.defaultOptions = {
48372 randomSeed: undefined,
48373 improvedLayout: true,
48374 clusterThreshold: 150,
48375 hierarchical: {
48376 enabled: false,
48377 levelSeparation: 150,
48378 nodeSpacing: 100,
48379 treeSpacing: 200,
48380 blockShifting: true,
48381 edgeMinimization: true,
48382 parentCentralization: true,
48383 direction: 'UD',
48384 // UD, DU, LR, RL
48385 sortMethod: 'hubsize' // hubsize, directed
48386
48387 }
48388 };
48389 extend(this.options, this.defaultOptions);
48390 this.bindEventListeners();
48391 }
48392 /**
48393 * Binds event listeners
48394 */
48395
48396
48397 _createClass(LayoutEngine, [{
48398 key: "bindEventListeners",
48399 value: function bindEventListeners() {
48400 var _this2 = this;
48401
48402 this.body.emitter.on('_dataChanged', function () {
48403 _this2.setupHierarchicalLayout();
48404 });
48405 this.body.emitter.on('_dataLoaded', function () {
48406 _this2.layoutNetwork();
48407 });
48408 this.body.emitter.on('_resetHierarchicalLayout', function () {
48409 _this2.setupHierarchicalLayout();
48410 });
48411 this.body.emitter.on('_adjustEdgesForHierarchicalLayout', function () {
48412 if (_this2.options.hierarchical.enabled !== true) {
48413 return;
48414 } // get the type of static smooth curve in case it is required
48415
48416
48417 var type = _this2.direction.curveType(); // force all edges into static smooth curves.
48418
48419
48420 _this2.body.emitter.emit('_forceDisableDynamicCurves', type, false);
48421 });
48422 }
48423 /**
48424 *
48425 * @param {Object} options
48426 * @param {Object} allOptions
48427 * @returns {Object}
48428 */
48429
48430 }, {
48431 key: "setOptions",
48432 value: function setOptions(options, allOptions) {
48433 if (options !== undefined) {
48434 var hierarchical = this.options.hierarchical;
48435 var prevHierarchicalState = hierarchical.enabled;
48436 selectiveDeepExtend(["randomSeed", "improvedLayout", "clusterThreshold"], this.options, options);
48437 mergeOptions(this.options, options, 'hierarchical');
48438
48439 if (options.randomSeed !== undefined) {
48440 this.initialRandomSeed = options.randomSeed;
48441 }
48442
48443 if (hierarchical.enabled === true) {
48444 if (prevHierarchicalState === true) {
48445 // refresh the overridden options for nodes and edges.
48446 this.body.emitter.emit('refresh', true);
48447 } // make sure the level separation is the right way up
48448
48449
48450 if (hierarchical.direction === 'RL' || hierarchical.direction === 'DU') {
48451 if (hierarchical.levelSeparation > 0) {
48452 hierarchical.levelSeparation *= -1;
48453 }
48454 } else {
48455 if (hierarchical.levelSeparation < 0) {
48456 hierarchical.levelSeparation *= -1;
48457 }
48458 }
48459
48460 this.setDirectionStrategy();
48461 this.body.emitter.emit('_resetHierarchicalLayout'); // because the hierarchical system needs it's own physics and smooth curve settings,
48462 // we adapt the other options if needed.
48463
48464 return this.adaptAllOptionsForHierarchicalLayout(allOptions);
48465 } else {
48466 if (prevHierarchicalState === true) {
48467 // refresh the overridden options for nodes and edges.
48468 this.body.emitter.emit('refresh');
48469 return deepExtend(allOptions, this.optionsBackup);
48470 }
48471 }
48472 }
48473
48474 return allOptions;
48475 }
48476 /**
48477 *
48478 * @param {Object} allOptions
48479 * @returns {Object}
48480 */
48481
48482 }, {
48483 key: "adaptAllOptionsForHierarchicalLayout",
48484 value: function adaptAllOptionsForHierarchicalLayout(allOptions) {
48485 if (this.options.hierarchical.enabled === true) {
48486 var backupPhysics = this.optionsBackup.physics; // set the physics
48487
48488 if (allOptions.physics === undefined || allOptions.physics === true) {
48489 allOptions.physics = {
48490 enabled: backupPhysics.enabled === undefined ? true : backupPhysics.enabled,
48491 solver: 'hierarchicalRepulsion'
48492 };
48493 backupPhysics.enabled = backupPhysics.enabled === undefined ? true : backupPhysics.enabled;
48494 backupPhysics.solver = backupPhysics.solver || 'barnesHut';
48495 } else if (_typeof(allOptions.physics) === 'object') {
48496 backupPhysics.enabled = allOptions.physics.enabled === undefined ? true : allOptions.physics.enabled;
48497 backupPhysics.solver = allOptions.physics.solver || 'barnesHut';
48498 allOptions.physics.solver = 'hierarchicalRepulsion';
48499 } else if (allOptions.physics !== false) {
48500 backupPhysics.solver = 'barnesHut';
48501 allOptions.physics = {
48502 solver: 'hierarchicalRepulsion'
48503 };
48504 } // get the type of static smooth curve in case it is required
48505
48506
48507 var type = this.direction.curveType(); // disable smooth curves if nothing is defined. If smooth curves have been turned on,
48508 // turn them into static smooth curves.
48509
48510 if (allOptions.edges === undefined) {
48511 this.optionsBackup.edges = {
48512 smooth: {
48513 enabled: true,
48514 type: 'dynamic'
48515 }
48516 };
48517 allOptions.edges = {
48518 smooth: false
48519 };
48520 } else if (allOptions.edges.smooth === undefined) {
48521 this.optionsBackup.edges = {
48522 smooth: {
48523 enabled: true,
48524 type: 'dynamic'
48525 }
48526 };
48527 allOptions.edges.smooth = false;
48528 } else {
48529 if (typeof allOptions.edges.smooth === 'boolean') {
48530 this.optionsBackup.edges = {
48531 smooth: allOptions.edges.smooth
48532 };
48533 allOptions.edges.smooth = {
48534 enabled: allOptions.edges.smooth,
48535 type: type
48536 };
48537 } else {
48538 var smooth = allOptions.edges.smooth; // allow custom types except for dynamic
48539
48540 if (smooth.type !== undefined && smooth.type !== 'dynamic') {
48541 type = smooth.type;
48542 } // TODO: this is options merging; see if the standard routines can be used here.
48543
48544
48545 this.optionsBackup.edges = {
48546 smooth: smooth.enabled === undefined ? true : smooth.enabled,
48547 type: smooth.type === undefined ? 'dynamic' : smooth.type,
48548 roundness: smooth.roundness === undefined ? 0.5 : smooth.roundness,
48549 forceDirection: smooth.forceDirection === undefined ? false : smooth.forceDirection
48550 }; // NOTE: Copying an object to self; this is basically setting defaults for undefined variables
48551
48552 allOptions.edges.smooth = {
48553 enabled: smooth.enabled === undefined ? true : smooth.enabled,
48554 type: type,
48555 roundness: smooth.roundness === undefined ? 0.5 : smooth.roundness,
48556 forceDirection: smooth.forceDirection === undefined ? false : smooth.forceDirection
48557 };
48558 }
48559 } // Force all edges into static smooth curves.
48560 // Only applies to edges that do not use the global options for smooth.
48561
48562
48563 this.body.emitter.emit('_forceDisableDynamicCurves', type);
48564 }
48565
48566 return allOptions;
48567 }
48568 /**
48569 *
48570 * @returns {number}
48571 */
48572
48573 }, {
48574 key: "seededRandom",
48575 value: function seededRandom() {
48576 var x = Math.sin(this.randomSeed++) * 10000;
48577 return x - Math.floor(x);
48578 }
48579 /**
48580 *
48581 * @param {Array.<Node>} nodesArray
48582 */
48583
48584 }, {
48585 key: "positionInitially",
48586 value: function positionInitially(nodesArray) {
48587 if (this.options.hierarchical.enabled !== true) {
48588 this.randomSeed = this.initialRandomSeed;
48589 var radius = nodesArray.length + 50;
48590
48591 for (var i = 0; i < nodesArray.length; i++) {
48592 var node = nodesArray[i];
48593 var angle = 2 * Math.PI * this.seededRandom();
48594
48595 if (node.x === undefined) {
48596 node.x = radius * Math.cos(angle);
48597 }
48598
48599 if (node.y === undefined) {
48600 node.y = radius * Math.sin(angle);
48601 }
48602 }
48603 }
48604 }
48605 /**
48606 * Use Kamada Kawai to position nodes. This is quite a heavy algorithm so if there are a lot of nodes we
48607 * cluster them first to reduce the amount.
48608 */
48609
48610 }, {
48611 key: "layoutNetwork",
48612 value: function layoutNetwork() {
48613 if (this.options.hierarchical.enabled !== true && this.options.improvedLayout === true) {
48614 var indices = this.body.nodeIndices; // first check if we should Kamada Kawai to layout. The threshold is if less than half of the visible
48615 // nodes have predefined positions we use this.
48616
48617 var positionDefined = 0;
48618
48619 for (var i = 0; i < indices.length; i++) {
48620 var node = this.body.nodes[indices[i]];
48621
48622 if (node.predefinedPosition === true) {
48623 positionDefined += 1;
48624 }
48625 } // if less than half of the nodes have a predefined position we continue
48626
48627
48628 if (positionDefined < 0.5 * indices.length) {
48629 var MAX_LEVELS = 10;
48630 var level = 0;
48631 var clusterThreshold = this.options.clusterThreshold; //
48632 // Define the options for the hidden cluster nodes
48633 // These options don't propagate outside the clustering phase.
48634 //
48635 // Some options are explicitly disabled, because they may be set in group or default node options.
48636 // The clusters are never displayed, so most explicit settings here serve as performance optimizations.
48637 //
48638 // The explicit setting of 'shape' is to avoid `shape: 'image'`; images are not passed to the hidden
48639 // cluster nodes, leading to an exception on creation.
48640 //
48641 // All settings here are performance related, except when noted otherwise.
48642 //
48643
48644 var clusterOptions = {
48645 clusterNodeProperties: {
48646 shape: 'ellipse',
48647 // Bugfix: avoid type 'image', no images supplied
48648 label: '',
48649 // avoid label handling
48650 group: '',
48651 // avoid group handling
48652 font: {
48653 multi: false
48654 } // avoid font propagation
48655
48656 },
48657 clusterEdgeProperties: {
48658 label: '',
48659 // avoid label handling
48660 font: {
48661 multi: false
48662 },
48663 // avoid font propagation
48664 smooth: {
48665 enabled: false // avoid drawing penalty for complex edges
48666
48667 }
48668 }
48669 }; // if there are a lot of nodes, we cluster before we run the algorithm.
48670 // NOTE: this part fails to find clusters for large scale-free networks, which should
48671 // be easily clusterable.
48672 // TODO: examine why this is so
48673
48674 if (indices.length > clusterThreshold) {
48675 var startLength = indices.length;
48676
48677 while (indices.length > clusterThreshold && level <= MAX_LEVELS) {
48678 //console.time("clustering")
48679 level += 1;
48680 var before = indices.length; // if there are many nodes we do a hubsize cluster
48681
48682 if (level % 3 === 0) {
48683 this.body.modules.clustering.clusterBridges(clusterOptions);
48684 } else {
48685 this.body.modules.clustering.clusterOutliers(clusterOptions);
48686 }
48687
48688 var after = indices.length;
48689
48690 if (before == after && level % 3 !== 0) {
48691 this._declusterAll();
48692
48693 this.body.emitter.emit("_layoutFailed");
48694 console.info("This network could not be positioned by this version of the improved layout algorithm." + " Please disable improvedLayout for better performance.");
48695 return;
48696 } //console.timeEnd("clustering")
48697 //console.log(before,level,after);
48698
48699 } // increase the size of the edges
48700
48701
48702 this.body.modules.kamadaKawai.setOptions({
48703 springLength: Math.max(150, 2 * startLength)
48704 });
48705 }
48706
48707 if (level > MAX_LEVELS) {
48708 console.info("The clustering didn't succeed within the amount of interations allowed," + " progressing with partial result.");
48709 } // position the system for these nodes and edges
48710
48711
48712 this.body.modules.kamadaKawai.solve(indices, this.body.edgeIndices, true); // shift to center point
48713
48714 this._shiftToCenter(); // perturb the nodes a little bit to force the physics to kick in
48715
48716
48717 var offset = 70;
48718
48719 for (var _i = 0; _i < indices.length; _i++) {
48720 // Only perturb the nodes that aren't fixed
48721 var _node = this.body.nodes[indices[_i]];
48722
48723 if (_node.predefinedPosition === false) {
48724 _node.x += (0.5 - this.seededRandom()) * offset;
48725 _node.y += (0.5 - this.seededRandom()) * offset;
48726 }
48727 } // uncluster all clusters
48728
48729
48730 this._declusterAll(); // reposition all bezier nodes.
48731
48732
48733 this.body.emitter.emit("_repositionBezierNodes");
48734 }
48735 }
48736 }
48737 /**
48738 * Move all the nodes towards to the center so gravitational pull wil not move the nodes away from view
48739 * @private
48740 */
48741
48742 }, {
48743 key: "_shiftToCenter",
48744 value: function _shiftToCenter() {
48745 var range = NetworkUtil.getRangeCore(this.body.nodes, this.body.nodeIndices);
48746 var center = NetworkUtil.findCenter(range);
48747
48748 for (var i = 0; i < this.body.nodeIndices.length; i++) {
48749 var node = this.body.nodes[this.body.nodeIndices[i]];
48750 node.x -= center.x;
48751 node.y -= center.y;
48752 }
48753 }
48754 /**
48755 * Expands all clusters
48756 * @private
48757 */
48758
48759 }, {
48760 key: "_declusterAll",
48761 value: function _declusterAll() {
48762 var clustersPresent = true;
48763
48764 while (clustersPresent === true) {
48765 clustersPresent = false;
48766
48767 for (var i = 0; i < this.body.nodeIndices.length; i++) {
48768 if (this.body.nodes[this.body.nodeIndices[i]].isCluster === true) {
48769 clustersPresent = true;
48770 this.body.modules.clustering.openCluster(this.body.nodeIndices[i], {}, false);
48771 }
48772 }
48773
48774 if (clustersPresent === true) {
48775 this.body.emitter.emit('_dataChanged');
48776 }
48777 }
48778 }
48779 /**
48780 *
48781 * @returns {number|*}
48782 */
48783
48784 }, {
48785 key: "getSeed",
48786 value: function getSeed() {
48787 return this.initialRandomSeed;
48788 }
48789 /**
48790 * This is the main function to layout the nodes in a hierarchical way.
48791 * It checks if the node details are supplied correctly
48792 *
48793 * @private
48794 */
48795
48796 }, {
48797 key: "setupHierarchicalLayout",
48798 value: function setupHierarchicalLayout() {
48799 if (this.options.hierarchical.enabled === true && this.body.nodeIndices.length > 0) {
48800 // get the size of the largest hubs and check if the user has defined a level for a node.
48801 var node, nodeId;
48802 var definedLevel = false;
48803 var undefinedLevel = false;
48804 this.lastNodeOnLevel = {};
48805 this.hierarchical = new HierarchicalStatus();
48806
48807 for (nodeId in this.body.nodes) {
48808 if (this.body.nodes.hasOwnProperty(nodeId)) {
48809 node = this.body.nodes[nodeId];
48810
48811 if (node.options.level !== undefined) {
48812 definedLevel = true;
48813 this.hierarchical.levels[nodeId] = node.options.level;
48814 } else {
48815 undefinedLevel = true;
48816 }
48817 }
48818 } // if the user defined some levels but not all, alert and run without hierarchical layout
48819
48820
48821 if (undefinedLevel === true && definedLevel === true) {
48822 throw new Error('To use the hierarchical layout, nodes require either no predefined levels' + ' or levels have to be defined for all nodes.');
48823 } else {
48824 // define levels if undefined by the users. Based on hubsize.
48825 if (undefinedLevel === true) {
48826 var sortMethod = this.options.hierarchical.sortMethod;
48827
48828 if (sortMethod === 'hubsize') {
48829 this._determineLevelsByHubsize();
48830 } else if (sortMethod === 'directed') {
48831 this._determineLevelsDirected();
48832 } else if (sortMethod === 'custom') {
48833 this._determineLevelsCustomCallback();
48834 }
48835 } // fallback for cases where there are nodes but no edges
48836
48837
48838 for (var _nodeId2 in this.body.nodes) {
48839 if (this.body.nodes.hasOwnProperty(_nodeId2)) {
48840 this.hierarchical.ensureLevel(_nodeId2);
48841 }
48842 } // check the distribution of the nodes per level.
48843
48844
48845 var distribution = this._getDistribution(); // get the parent children relations.
48846
48847
48848 this._generateMap(); // place the nodes on the canvas.
48849
48850
48851 this._placeNodesByHierarchy(distribution); // condense the whitespace.
48852
48853
48854 this._condenseHierarchy(); // shift to center so gravity does not have to do much
48855
48856
48857 this._shiftToCenter();
48858 }
48859 }
48860 }
48861 /**
48862 * @private
48863 */
48864
48865 }, {
48866 key: "_condenseHierarchy",
48867 value: function _condenseHierarchy() {
48868 var _this3 = this;
48869
48870 // Global var in this scope to define when the movement has stopped.
48871 var stillShifting = false;
48872 var branches = {}; // first we have some methods to help shifting trees around.
48873 // the main method to shift the trees
48874
48875 var shiftTrees = function shiftTrees() {
48876 var treeSizes = getTreeSizes();
48877 var shiftBy = 0;
48878
48879 for (var i = 0; i < treeSizes.length - 1; i++) {
48880 var diff = treeSizes[i].max - treeSizes[i + 1].min;
48881 shiftBy += diff + _this3.options.hierarchical.treeSpacing;
48882 shiftTree(i + 1, shiftBy);
48883 }
48884 }; // shift a single tree by an offset
48885
48886
48887 var shiftTree = function shiftTree(index, offset) {
48888 var trees = _this3.hierarchical.trees;
48889
48890 for (var nodeId in trees) {
48891 if (trees.hasOwnProperty(nodeId)) {
48892 if (trees[nodeId] === index) {
48893 _this3.direction.shift(nodeId, offset);
48894 }
48895 }
48896 }
48897 }; // get the width of all trees
48898
48899
48900 var getTreeSizes = function getTreeSizes() {
48901 var treeWidths = [];
48902
48903 for (var i = 0; i < _this3.hierarchical.numTrees(); i++) {
48904 treeWidths.push(_this3.direction.getTreeSize(i));
48905 }
48906
48907 return treeWidths;
48908 }; // get a map of all nodes in this branch
48909
48910
48911 var getBranchNodes = function getBranchNodes(source, map) {
48912 if (map[source.id]) {
48913 return;
48914 }
48915
48916 map[source.id] = true;
48917
48918 if (_this3.hierarchical.childrenReference[source.id]) {
48919 var children = _this3.hierarchical.childrenReference[source.id];
48920
48921 if (children.length > 0) {
48922 for (var i = 0; i < children.length; i++) {
48923 getBranchNodes(_this3.body.nodes[children[i]], map);
48924 }
48925 }
48926 }
48927 }; // get a min max width as well as the maximum movement space it has on either sides
48928 // we use min max terminology because width and height can interchange depending on the direction of the layout
48929
48930
48931 var getBranchBoundary = function getBranchBoundary(branchMap) {
48932 var maxLevel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1e9;
48933 var minSpace = 1e9;
48934 var maxSpace = 1e9;
48935 var min = 1e9;
48936 var max = -1e9;
48937
48938 for (var branchNode in branchMap) {
48939 if (branchMap.hasOwnProperty(branchNode)) {
48940 var node = _this3.body.nodes[branchNode];
48941 var level = _this3.hierarchical.levels[node.id];
48942
48943 var position = _this3.direction.getPosition(node); // get the space around the node.
48944
48945
48946 var _this3$_getSpaceAroun = _this3._getSpaceAroundNode(node, branchMap),
48947 _this3$_getSpaceAroun2 = _slicedToArray(_this3$_getSpaceAroun, 2),
48948 minSpaceNode = _this3$_getSpaceAroun2[0],
48949 maxSpaceNode = _this3$_getSpaceAroun2[1];
48950
48951 minSpace = Math.min(minSpaceNode, minSpace);
48952 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.
48953
48954 if (level <= maxLevel) {
48955 min = Math.min(position, min);
48956 max = Math.max(position, max);
48957 }
48958 }
48959 }
48960
48961 return [min, max, minSpace, maxSpace];
48962 }; // check what the maximum level is these nodes have in common.
48963
48964
48965 var getCollisionLevel = function getCollisionLevel(node1, node2) {
48966 var maxLevel1 = _this3.hierarchical.getMaxLevel(node1.id);
48967
48968 var maxLevel2 = _this3.hierarchical.getMaxLevel(node2.id);
48969
48970 return Math.min(maxLevel1, maxLevel2);
48971 };
48972 /**
48973 * Condense elements. These can be nodes or branches depending on the callback.
48974 *
48975 * @param {function} callback
48976 * @param {Array.<number>} levels
48977 * @param {*} centerParents
48978 */
48979
48980
48981 var shiftElementsCloser = function shiftElementsCloser(callback, levels, centerParents) {
48982 var hier = _this3.hierarchical;
48983
48984 for (var i = 0; i < levels.length; i++) {
48985 var level = levels[i];
48986 var levelNodes = hier.distributionOrdering[level];
48987
48988 if (levelNodes.length > 1) {
48989 for (var j = 0; j < levelNodes.length - 1; j++) {
48990 var node1 = levelNodes[j];
48991 var node2 = levelNodes[j + 1]; // NOTE: logic maintained as it was; if nodes have same ancestor,
48992 // then of course they are in the same sub-network.
48993
48994 if (hier.hasSameParent(node1, node2) && hier.inSameSubNetwork(node1, node2)) {
48995 callback(node1, node2, centerParents);
48996 }
48997 }
48998 }
48999 }
49000 }; // callback for shifting branches
49001
49002
49003 var branchShiftCallback = function branchShiftCallback(node1, node2) {
49004 var centerParent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
49005
49006 //window.CALLBACKS.push(() => {
49007 var pos1 = _this3.direction.getPosition(node1);
49008
49009 var pos2 = _this3.direction.getPosition(node2);
49010
49011 var diffAbs = Math.abs(pos2 - pos1);
49012 var nodeSpacing = _this3.options.hierarchical.nodeSpacing; //console.log("NOW CHECKING:", node1.id, node2.id, diffAbs);
49013
49014 if (diffAbs > nodeSpacing) {
49015 var branchNodes1 = {};
49016 var branchNodes2 = {};
49017 getBranchNodes(node1, branchNodes1);
49018 getBranchNodes(node2, branchNodes2); // check the largest distance between the branches
49019
49020 var maxLevel = getCollisionLevel(node1, node2);
49021 var branchNodeBoundary1 = getBranchBoundary(branchNodes1, maxLevel);
49022 var branchNodeBoundary2 = getBranchBoundary(branchNodes2, maxLevel);
49023 var max1 = branchNodeBoundary1[1];
49024 var min2 = branchNodeBoundary2[0];
49025 var minSpace2 = branchNodeBoundary2[2]; //console.log(node1.id, getBranchBoundary(branchNodes1, maxLevel), node2.id,
49026 // getBranchBoundary(branchNodes2, maxLevel), maxLevel);
49027
49028 var diffBranch = Math.abs(max1 - min2);
49029
49030 if (diffBranch > nodeSpacing) {
49031 var offset = max1 - min2 + nodeSpacing;
49032
49033 if (offset < -minSpace2 + nodeSpacing) {
49034 offset = -minSpace2 + nodeSpacing; //console.log("RESETTING OFFSET", max1 - min2 + this.options.hierarchical.nodeSpacing, -minSpace2, offset);
49035 }
49036
49037 if (offset < 0) {
49038 //console.log("SHIFTING", node2.id, offset);
49039 _this3._shiftBlock(node2.id, offset);
49040
49041 stillShifting = true;
49042 if (centerParent === true) _this3._centerParent(node2);
49043 }
49044 }
49045 } //this.body.emitter.emit("_redraw");})
49046
49047 };
49048
49049 var minimizeEdgeLength = function minimizeEdgeLength(iterations, node) {
49050 //window.CALLBACKS.push(() => {
49051 // console.log("ts",node.id);
49052 var nodeId = node.id;
49053 var allEdges = node.edges;
49054 var nodeLevel = _this3.hierarchical.levels[node.id]; // gather constants
49055
49056 var C2 = _this3.options.hierarchical.levelSeparation * _this3.options.hierarchical.levelSeparation;
49057 var referenceNodes = {};
49058 var aboveEdges = [];
49059
49060 for (var i = 0; i < allEdges.length; i++) {
49061 var edge = allEdges[i];
49062
49063 if (edge.toId != edge.fromId) {
49064 var otherNode = edge.toId == nodeId ? edge.from : edge.to;
49065 referenceNodes[allEdges[i].id] = otherNode;
49066
49067 if (_this3.hierarchical.levels[otherNode.id] < nodeLevel) {
49068 aboveEdges.push(edge);
49069 }
49070 }
49071 } // differentiated sum of lengths based on only moving one node over one axis
49072
49073
49074 var getFx = function getFx(point, edges) {
49075 var sum = 0;
49076
49077 for (var _i2 = 0; _i2 < edges.length; _i2++) {
49078 if (referenceNodes[edges[_i2].id] !== undefined) {
49079 var a = _this3.direction.getPosition(referenceNodes[edges[_i2].id]) - point;
49080 sum += a / Math.sqrt(a * a + C2);
49081 }
49082 }
49083
49084 return sum;
49085 }; // doubly differentiated sum of lengths based on only moving one node over one axis
49086
49087
49088 var getDFx = function getDFx(point, edges) {
49089 var sum = 0;
49090
49091 for (var _i3 = 0; _i3 < edges.length; _i3++) {
49092 if (referenceNodes[edges[_i3].id] !== undefined) {
49093 var a = _this3.direction.getPosition(referenceNodes[edges[_i3].id]) - point;
49094 sum -= C2 * Math.pow(a * a + C2, -1.5);
49095 }
49096 }
49097
49098 return sum;
49099 };
49100
49101 var getGuess = function getGuess(iterations, edges) {
49102 var guess = _this3.direction.getPosition(node); // Newton's method for optimization
49103
49104
49105 var guessMap = {};
49106
49107 for (var _i4 = 0; _i4 < iterations; _i4++) {
49108 var fx = getFx(guess, edges);
49109 var dfx = getDFx(guess, edges); // we limit the movement to avoid instability.
49110
49111 var limit = 40;
49112 var ratio = Math.max(-limit, Math.min(limit, Math.round(fx / dfx)));
49113 guess = guess - ratio; // reduce duplicates
49114
49115 if (guessMap[guess] !== undefined) {
49116 break;
49117 }
49118
49119 guessMap[guess] = _i4;
49120 }
49121
49122 return guess;
49123 };
49124
49125 var moveBranch = function moveBranch(guess) {
49126 // position node if there is space
49127 var nodePosition = _this3.direction.getPosition(node); // check movable area of the branch
49128
49129
49130 if (branches[node.id] === undefined) {
49131 var branchNodes = {};
49132 getBranchNodes(node, branchNodes);
49133 branches[node.id] = branchNodes;
49134 }
49135
49136 var branchBoundary = getBranchBoundary(branches[node.id]);
49137 var minSpaceBranch = branchBoundary[2];
49138 var maxSpaceBranch = branchBoundary[3];
49139 var diff = guess - nodePosition; // check if we are allowed to move the node:
49140
49141 var branchOffset = 0;
49142
49143 if (diff > 0) {
49144 branchOffset = Math.min(diff, maxSpaceBranch - _this3.options.hierarchical.nodeSpacing);
49145 } else if (diff < 0) {
49146 branchOffset = -Math.min(-diff, minSpaceBranch - _this3.options.hierarchical.nodeSpacing);
49147 }
49148
49149 if (branchOffset != 0) {
49150 //console.log("moving branch:",branchOffset, maxSpaceBranch, minSpaceBranch)
49151 _this3._shiftBlock(node.id, branchOffset); //this.body.emitter.emit("_redraw");
49152
49153
49154 stillShifting = true;
49155 }
49156 };
49157
49158 var moveNode = function moveNode(guess) {
49159 var nodePosition = _this3.direction.getPosition(node); // position node if there is space
49160
49161
49162 var _this3$_getSpaceAroun3 = _this3._getSpaceAroundNode(node),
49163 _this3$_getSpaceAroun4 = _slicedToArray(_this3$_getSpaceAroun3, 2),
49164 minSpace = _this3$_getSpaceAroun4[0],
49165 maxSpace = _this3$_getSpaceAroun4[1];
49166
49167 var diff = guess - nodePosition; // check if we are allowed to move the node:
49168
49169 var newPosition = nodePosition;
49170
49171 if (diff > 0) {
49172 newPosition = Math.min(nodePosition + (maxSpace - _this3.options.hierarchical.nodeSpacing), guess);
49173 } else if (diff < 0) {
49174 newPosition = Math.max(nodePosition - (minSpace - _this3.options.hierarchical.nodeSpacing), guess);
49175 }
49176
49177 if (newPosition !== nodePosition) {
49178 //console.log("moving Node:",diff, minSpace, maxSpace);
49179 _this3.direction.setPosition(node, newPosition); //this.body.emitter.emit("_redraw");
49180
49181
49182 stillShifting = true;
49183 }
49184 };
49185
49186 var guess = getGuess(iterations, aboveEdges);
49187 moveBranch(guess);
49188 guess = getGuess(iterations, allEdges);
49189 moveNode(guess); //})
49190 }; // method to remove whitespace between branches. Because we do bottom up, we can center the parents.
49191
49192
49193 var minimizeEdgeLengthBottomUp = function minimizeEdgeLengthBottomUp(iterations) {
49194 var levels = _this3.hierarchical.getLevels();
49195
49196 levels = levels.reverse();
49197
49198 for (var i = 0; i < iterations; i++) {
49199 stillShifting = false;
49200
49201 for (var j = 0; j < levels.length; j++) {
49202 var level = levels[j];
49203 var levelNodes = _this3.hierarchical.distributionOrdering[level];
49204
49205 for (var k = 0; k < levelNodes.length; k++) {
49206 minimizeEdgeLength(1000, levelNodes[k]);
49207 }
49208 }
49209
49210 if (stillShifting !== true) {
49211 //console.log("FINISHED minimizeEdgeLengthBottomUp IN " + i);
49212 break;
49213 }
49214 }
49215 }; // method to remove whitespace between branches. Because we do bottom up, we can center the parents.
49216
49217
49218 var shiftBranchesCloserBottomUp = function shiftBranchesCloserBottomUp(iterations) {
49219 var levels = _this3.hierarchical.getLevels();
49220
49221 levels = levels.reverse();
49222
49223 for (var i = 0; i < iterations; i++) {
49224 stillShifting = false;
49225 shiftElementsCloser(branchShiftCallback, levels, true);
49226
49227 if (stillShifting !== true) {
49228 //console.log("FINISHED shiftBranchesCloserBottomUp IN " + (i+1));
49229 break;
49230 }
49231 }
49232 }; // center all parents
49233
49234
49235 var centerAllParents = function centerAllParents() {
49236 for (var nodeId in _this3.body.nodes) {
49237 if (_this3.body.nodes.hasOwnProperty(nodeId)) _this3._centerParent(_this3.body.nodes[nodeId]);
49238 }
49239 }; // center all parents
49240
49241
49242 var centerAllParentsBottomUp = function centerAllParentsBottomUp() {
49243 var levels = _this3.hierarchical.getLevels();
49244
49245 levels = levels.reverse();
49246
49247 for (var i = 0; i < levels.length; i++) {
49248 var level = levels[i];
49249 var levelNodes = _this3.hierarchical.distributionOrdering[level];
49250
49251 for (var j = 0; j < levelNodes.length; j++) {
49252 _this3._centerParent(levelNodes[j]);
49253 }
49254 }
49255 }; // the actual work is done here.
49256
49257
49258 if (this.options.hierarchical.blockShifting === true) {
49259 shiftBranchesCloserBottomUp(5);
49260 centerAllParents();
49261 } // minimize edge length
49262
49263
49264 if (this.options.hierarchical.edgeMinimization === true) {
49265 minimizeEdgeLengthBottomUp(20);
49266 }
49267
49268 if (this.options.hierarchical.parentCentralization === true) {
49269 centerAllParentsBottomUp();
49270 }
49271
49272 shiftTrees();
49273 }
49274 /**
49275 * This gives the space around the node. IF a map is supplied, it will only check against nodes NOT in the map.
49276 * This is used to only get the distances to nodes outside of a branch.
49277 * @param {Node} node
49278 * @param {{Node.id: vis.Node}} map
49279 * @returns {number[]}
49280 * @private
49281 */
49282
49283 }, {
49284 key: "_getSpaceAroundNode",
49285 value: function _getSpaceAroundNode(node, map) {
49286 var useMap = true;
49287
49288 if (map === undefined) {
49289 useMap = false;
49290 }
49291
49292 var level = this.hierarchical.levels[node.id];
49293
49294 if (level !== undefined) {
49295 var index = this.hierarchical.distributionIndex[node.id];
49296 var position = this.direction.getPosition(node);
49297 var ordering = this.hierarchical.distributionOrdering[level];
49298 var minSpace = 1e9;
49299 var maxSpace = 1e9;
49300
49301 if (index !== 0) {
49302 var prevNode = ordering[index - 1];
49303
49304 if (useMap === true && map[prevNode.id] === undefined || useMap === false) {
49305 var prevPos = this.direction.getPosition(prevNode);
49306 minSpace = position - prevPos;
49307 }
49308 }
49309
49310 if (index != ordering.length - 1) {
49311 var nextNode = ordering[index + 1];
49312
49313 if (useMap === true && map[nextNode.id] === undefined || useMap === false) {
49314 var nextPos = this.direction.getPosition(nextNode);
49315 maxSpace = Math.min(maxSpace, nextPos - position);
49316 }
49317 }
49318
49319 return [minSpace, maxSpace];
49320 } else {
49321 return [0, 0];
49322 }
49323 }
49324 /**
49325 * We use this method to center a parent node and check if it does not cross other nodes when it does.
49326 * @param {Node} node
49327 * @private
49328 */
49329
49330 }, {
49331 key: "_centerParent",
49332 value: function _centerParent(node) {
49333 if (this.hierarchical.parentReference[node.id]) {
49334 var parents = this.hierarchical.parentReference[node.id];
49335
49336 for (var i = 0; i < parents.length; i++) {
49337 var parentId = parents[i];
49338 var parentNode = this.body.nodes[parentId];
49339 var children = this.hierarchical.childrenReference[parentId];
49340
49341 if (children !== undefined) {
49342 // get the range of the children
49343 var newPosition = this._getCenterPosition(children);
49344
49345 var position = this.direction.getPosition(parentNode);
49346
49347 var _this$_getSpaceAround = this._getSpaceAroundNode(parentNode),
49348 _this$_getSpaceAround2 = _slicedToArray(_this$_getSpaceAround, 2),
49349 minSpace = _this$_getSpaceAround2[0],
49350 maxSpace = _this$_getSpaceAround2[1];
49351
49352 var diff = position - newPosition;
49353
49354 if (diff < 0 && Math.abs(diff) < maxSpace - this.options.hierarchical.nodeSpacing || diff > 0 && Math.abs(diff) < minSpace - this.options.hierarchical.nodeSpacing) {
49355 this.direction.setPosition(parentNode, newPosition);
49356 }
49357 }
49358 }
49359 }
49360 }
49361 /**
49362 * This function places the nodes on the canvas based on the hierarchial distribution.
49363 *
49364 * @param {Object} distribution | obtained by the function this._getDistribution()
49365 * @private
49366 */
49367
49368 }, {
49369 key: "_placeNodesByHierarchy",
49370 value: function _placeNodesByHierarchy(distribution) {
49371 this.positionedNodes = {}; // start placing all the level 0 nodes first. Then recursively position their branches.
49372
49373 for (var level in distribution) {
49374 if (distribution.hasOwnProperty(level)) {
49375 // sort nodes in level by position:
49376 var nodeArray = Object.keys(distribution[level]);
49377 nodeArray = this._indexArrayToNodes(nodeArray);
49378 this.direction.sort(nodeArray);
49379 var handledNodeCount = 0;
49380
49381 for (var i = 0; i < nodeArray.length; i++) {
49382 var node = nodeArray[i];
49383
49384 if (this.positionedNodes[node.id] === undefined) {
49385 var spacing = this.options.hierarchical.nodeSpacing;
49386 var pos = spacing * handledNodeCount; // We get the X or Y values we need and store them in pos and previousPos.
49387 // The get and set make sure we get X or Y
49388
49389 if (handledNodeCount > 0) {
49390 pos = this.direction.getPosition(nodeArray[i - 1]) + spacing;
49391 }
49392
49393 this.direction.setPosition(node, pos, level);
49394
49395 this._validatePositionAndContinue(node, level, pos);
49396
49397 handledNodeCount++;
49398 }
49399 }
49400 }
49401 }
49402 }
49403 /**
49404 * This is a recursively called function to enumerate the branches from the largest hubs and place the nodes
49405 * on a X position that ensures there will be no overlap.
49406 *
49407 * @param {Node.id} parentId
49408 * @param {number} parentLevel
49409 * @private
49410 */
49411
49412 }, {
49413 key: "_placeBranchNodes",
49414 value: function _placeBranchNodes(parentId, parentLevel) {
49415 var childRef = this.hierarchical.childrenReference[parentId]; // if this is not a parent, cancel the placing. This can happen with multiple parents to one child.
49416
49417 if (childRef === undefined) {
49418 return;
49419 } // get a list of childNodes
49420
49421
49422 var childNodes = [];
49423
49424 for (var i = 0; i < childRef.length; i++) {
49425 childNodes.push(this.body.nodes[childRef[i]]);
49426 } // use the positions to order the nodes.
49427
49428
49429 this.direction.sort(childNodes); // position the childNodes
49430
49431 for (var _i5 = 0; _i5 < childNodes.length; _i5++) {
49432 var childNode = childNodes[_i5];
49433 var childNodeLevel = this.hierarchical.levels[childNode.id]; // check if the child node is below the parent node and if it has already been positioned.
49434
49435 if (childNodeLevel > parentLevel && this.positionedNodes[childNode.id] === undefined) {
49436 // get the amount of space required for this node. If parent the width is based on the amount of children.
49437 var spacing = this.options.hierarchical.nodeSpacing;
49438 var pos = void 0; // we get the X or Y values we need and store them in pos and previousPos.
49439 // The get and set make sure we get X or Y
49440
49441 if (_i5 === 0) {
49442 pos = this.direction.getPosition(this.body.nodes[parentId]);
49443 } else {
49444 pos = this.direction.getPosition(childNodes[_i5 - 1]) + spacing;
49445 }
49446
49447 this.direction.setPosition(childNode, pos, childNodeLevel);
49448
49449 this._validatePositionAndContinue(childNode, childNodeLevel, pos);
49450 } else {
49451 return;
49452 }
49453 } // center the parent nodes.
49454
49455
49456 var center = this._getCenterPosition(childNodes);
49457
49458 this.direction.setPosition(this.body.nodes[parentId], center, parentLevel);
49459 }
49460 /**
49461 * This method checks for overlap and if required shifts the branch. It also keeps records of positioned nodes.
49462 * Finally it will call _placeBranchNodes to place the branch nodes.
49463 * @param {Node} node
49464 * @param {number} level
49465 * @param {number} pos
49466 * @private
49467 */
49468
49469 }, {
49470 key: "_validatePositionAndContinue",
49471 value: function _validatePositionAndContinue(node, level, pos) {
49472 // This method only works for formal trees and formal forests
49473 // Early exit if this is not the case
49474 if (!this.hierarchical.isTree) return; // if overlap has been detected, we shift the branch
49475
49476 if (this.lastNodeOnLevel[level] !== undefined) {
49477 var previousPos = this.direction.getPosition(this.body.nodes[this.lastNodeOnLevel[level]]);
49478
49479 if (pos - previousPos < this.options.hierarchical.nodeSpacing) {
49480 var diff = previousPos + this.options.hierarchical.nodeSpacing - pos;
49481
49482 var sharedParent = this._findCommonParent(this.lastNodeOnLevel[level], node.id);
49483
49484 this._shiftBlock(sharedParent.withChild, diff);
49485 }
49486 }
49487
49488 this.lastNodeOnLevel[level] = node.id; // store change in position.
49489
49490 this.positionedNodes[node.id] = true;
49491
49492 this._placeBranchNodes(node.id, level);
49493 }
49494 /**
49495 * Receives an array with node indices and returns an array with the actual node references.
49496 * Used for sorting based on node properties.
49497 * @param {Array.<Node.id>} idArray
49498 * @returns {Array.<Node>}
49499 */
49500
49501 }, {
49502 key: "_indexArrayToNodes",
49503 value: function _indexArrayToNodes(idArray) {
49504 var array = [];
49505
49506 for (var i = 0; i < idArray.length; i++) {
49507 array.push(this.body.nodes[idArray[i]]);
49508 }
49509
49510 return array;
49511 }
49512 /**
49513 * This function get the distribution of levels based on hubsize
49514 *
49515 * @returns {Object}
49516 * @private
49517 */
49518
49519 }, {
49520 key: "_getDistribution",
49521 value: function _getDistribution() {
49522 var distribution = {};
49523 var nodeId, node; // we fix Y because the hierarchy is vertical,
49524 // we fix X so we do not give a node an x position for a second time.
49525 // the fix of X is removed after the x value has been set.
49526
49527 for (nodeId in this.body.nodes) {
49528 if (this.body.nodes.hasOwnProperty(nodeId)) {
49529 node = this.body.nodes[nodeId];
49530 var level = this.hierarchical.levels[nodeId] === undefined ? 0 : this.hierarchical.levels[nodeId];
49531 this.direction.fix(node, level);
49532
49533 if (distribution[level] === undefined) {
49534 distribution[level] = {};
49535 }
49536
49537 distribution[level][nodeId] = node;
49538 }
49539 }
49540
49541 return distribution;
49542 }
49543 /**
49544 * Return the active (i.e. visible) edges for this node
49545 *
49546 * @param {Node} node
49547 * @returns {Array.<vis.Edge>} Array of edge instances
49548 * @private
49549 */
49550
49551 }, {
49552 key: "_getActiveEdges",
49553 value: function _getActiveEdges(node) {
49554 var _this4 = this;
49555
49556 var result = [];
49557 forEach(node.edges, function (edge) {
49558 if (_this4.body.edgeIndices.indexOf(edge.id) !== -1) {
49559 result.push(edge);
49560 }
49561 });
49562 return result;
49563 }
49564 /**
49565 * Get the hubsizes for all active nodes.
49566 *
49567 * @returns {number}
49568 * @private
49569 */
49570
49571 }, {
49572 key: "_getHubSizes",
49573 value: function _getHubSizes() {
49574 var _this5 = this;
49575
49576 var hubSizes = {};
49577 var nodeIds = this.body.nodeIndices;
49578 forEach(nodeIds, function (nodeId) {
49579 var node = _this5.body.nodes[nodeId];
49580
49581 var hubSize = _this5._getActiveEdges(node).length;
49582
49583 hubSizes[hubSize] = true;
49584 }); // Make an array of the size sorted descending
49585
49586 var result = [];
49587 forEach(hubSizes, function (size) {
49588 result.push(Number(size));
49589 });
49590 timsort$1.sort(result, function (a, b) {
49591 return b - a;
49592 });
49593 return result;
49594 }
49595 /**
49596 * this function allocates nodes in levels based on the recursive branching from the largest hubs.
49597 *
49598 * @private
49599 */
49600
49601 }, {
49602 key: "_determineLevelsByHubsize",
49603 value: function _determineLevelsByHubsize() {
49604 var _this6 = this;
49605
49606 var levelDownstream = function levelDownstream(nodeA, nodeB) {
49607 _this6.hierarchical.levelDownstream(nodeA, nodeB);
49608 };
49609
49610 var hubSizes = this._getHubSizes();
49611
49612 var _loop = function _loop(i) {
49613 var hubSize = hubSizes[i];
49614 if (hubSize === 0) return "break";
49615 forEach(_this6.body.nodeIndices, function (nodeId) {
49616 var node = _this6.body.nodes[nodeId];
49617
49618 if (hubSize === _this6._getActiveEdges(node).length) {
49619 _this6._crawlNetwork(levelDownstream, nodeId);
49620 }
49621 });
49622 };
49623
49624 for (var i = 0; i < hubSizes.length; ++i) {
49625 var _ret = _loop(i);
49626
49627 if (_ret === "break") break;
49628 }
49629 }
49630 /**
49631 * TODO: release feature
49632 * TODO: Determine if this feature is needed at all
49633 *
49634 * @private
49635 */
49636
49637 }, {
49638 key: "_determineLevelsCustomCallback",
49639 value: function _determineLevelsCustomCallback() {
49640 var _this7 = this;
49641
49642 var minLevel = 100000; // TODO: this should come from options.
49643
49644 var customCallback = function customCallback(nodeA, nodeB, edge) {// eslint-disable-line no-unused-vars
49645 }; // TODO: perhaps move to HierarchicalStatus.
49646 // But I currently don't see the point, this method is not used.
49647
49648
49649 var levelByDirection = function levelByDirection(nodeA, nodeB, edge) {
49650 var levelA = _this7.hierarchical.levels[nodeA.id]; // set initial level
49651
49652 if (levelA === undefined) {
49653 levelA = _this7.hierarchical.levels[nodeA.id] = minLevel;
49654 }
49655
49656 var diff = customCallback(NetworkUtil.cloneOptions(nodeA, 'node'), NetworkUtil.cloneOptions(nodeB, 'node'), NetworkUtil.cloneOptions(edge, 'edge'));
49657 _this7.hierarchical.levels[nodeB.id] = levelA + diff;
49658 };
49659
49660 this._crawlNetwork(levelByDirection);
49661
49662 this.hierarchical.setMinLevelToZero(this.body.nodes);
49663 }
49664 /**
49665 * Allocate nodes in levels based on the direction of the edges.
49666 *
49667 * @private
49668 */
49669
49670 }, {
49671 key: "_determineLevelsDirected",
49672 value: function _determineLevelsDirected() {
49673 var _this8 = this;
49674
49675 var nodes = this.body.nodeIndices.map(function (id) {
49676 return _this8.body.nodes[id];
49677 });
49678 var levels = this.hierarchical.levels;
49679
49680 if (this.options.hierarchical.shakeTowards === "roots") {
49681 this.hierarchical.levels = fillLevelsByDirectionRoots(nodes, this.hierarchical.levels);
49682 } else {
49683 this.hierarchical.levels = fillLevelsByDirectionLeaves(nodes, this.hierarchical.levels);
49684 }
49685
49686 this.hierarchical.setMinLevelToZero(this.body.nodes);
49687 }
49688 /**
49689 * Update the bookkeeping of parent and child.
49690 * @private
49691 */
49692
49693 }, {
49694 key: "_generateMap",
49695 value: function _generateMap() {
49696 var _this9 = this;
49697
49698 var fillInRelations = function fillInRelations(parentNode, childNode) {
49699 if (_this9.hierarchical.levels[childNode.id] > _this9.hierarchical.levels[parentNode.id]) {
49700 _this9.hierarchical.addRelation(parentNode.id, childNode.id);
49701 }
49702 };
49703
49704 this._crawlNetwork(fillInRelations);
49705
49706 this.hierarchical.checkIfTree();
49707 }
49708 /**
49709 * Crawl over the entire network and use a callback on each node couple that is connected to each other.
49710 * @param {function} [callback=function(){}] | will receive nodeA, nodeB and the connecting edge. A and B are distinct.
49711 * @param {Node.id} startingNodeId
49712 * @private
49713 */
49714
49715 }, {
49716 key: "_crawlNetwork",
49717 value: function _crawlNetwork() {
49718 var _this10 = this;
49719
49720 var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
49721 var startingNodeId = arguments.length > 1 ? arguments[1] : undefined;
49722 var progress = {};
49723
49724 var crawler = function crawler(node, tree) {
49725 if (progress[node.id] === undefined) {
49726 _this10.hierarchical.setTreeIndex(node, tree);
49727
49728 progress[node.id] = true;
49729 var childNode;
49730
49731 var edges = _this10._getActiveEdges(node);
49732
49733 for (var i = 0; i < edges.length; i++) {
49734 var edge = edges[i];
49735
49736 if (edge.connected === true) {
49737 if (edge.toId == node.id) {
49738 // Not '===' because id's can be string and numeric
49739 childNode = edge.from;
49740 } else {
49741 childNode = edge.to;
49742 }
49743
49744 if (node.id != childNode.id) {
49745 // Not '!==' because id's can be string and numeric
49746 callback(node, childNode, edge);
49747 crawler(childNode, tree);
49748 }
49749 }
49750 }
49751 }
49752 };
49753
49754 if (startingNodeId === undefined) {
49755 // Crawl over all nodes
49756 var treeIndex = 0; // Serves to pass a unique id for the current distinct tree
49757
49758 for (var i = 0; i < this.body.nodeIndices.length; i++) {
49759 var nodeId = this.body.nodeIndices[i];
49760
49761 if (progress[nodeId] === undefined) {
49762 var node = this.body.nodes[nodeId];
49763 crawler(node, treeIndex);
49764 treeIndex += 1;
49765 }
49766 }
49767 } else {
49768 // Crawl from the given starting node
49769 var _node2 = this.body.nodes[startingNodeId];
49770
49771 if (_node2 === undefined) {
49772 console.error("Node not found:", startingNodeId);
49773 return;
49774 }
49775
49776 crawler(_node2);
49777 }
49778 }
49779 /**
49780 * Shift a branch a certain distance
49781 * @param {Node.id} parentId
49782 * @param {number} diff
49783 * @private
49784 */
49785
49786 }, {
49787 key: "_shiftBlock",
49788 value: function _shiftBlock(parentId, diff) {
49789 var _this11 = this;
49790
49791 var progress = {};
49792
49793 var shifter = function shifter(parentId) {
49794 if (progress[parentId]) {
49795 return;
49796 }
49797
49798 progress[parentId] = true;
49799
49800 _this11.direction.shift(parentId, diff);
49801
49802 var childRef = _this11.hierarchical.childrenReference[parentId];
49803
49804 if (childRef !== undefined) {
49805 for (var i = 0; i < childRef.length; i++) {
49806 shifter(childRef[i]);
49807 }
49808 }
49809 };
49810
49811 shifter(parentId);
49812 }
49813 /**
49814 * Find a common parent between branches.
49815 * @param {Node.id} childA
49816 * @param {Node.id} childB
49817 * @returns {{foundParent, withChild}}
49818 * @private
49819 */
49820
49821 }, {
49822 key: "_findCommonParent",
49823 value: function _findCommonParent(childA, childB) {
49824 var _this12 = this;
49825
49826 var parents = {};
49827
49828 var iterateParents = function iterateParents(parents, child) {
49829 var parentRef = _this12.hierarchical.parentReference[child];
49830
49831 if (parentRef !== undefined) {
49832 for (var i = 0; i < parentRef.length; i++) {
49833 var parent = parentRef[i];
49834 parents[parent] = true;
49835 iterateParents(parents, parent);
49836 }
49837 }
49838 };
49839
49840 var findParent = function findParent(parents, child) {
49841 var parentRef = _this12.hierarchical.parentReference[child];
49842
49843 if (parentRef !== undefined) {
49844 for (var i = 0; i < parentRef.length; i++) {
49845 var parent = parentRef[i];
49846
49847 if (parents[parent] !== undefined) {
49848 return {
49849 foundParent: parent,
49850 withChild: child
49851 };
49852 }
49853
49854 var branch = findParent(parents, parent);
49855
49856 if (branch.foundParent !== null) {
49857 return branch;
49858 }
49859 }
49860 }
49861
49862 return {
49863 foundParent: null,
49864 withChild: child
49865 };
49866 };
49867
49868 iterateParents(parents, childA);
49869 return findParent(parents, childB);
49870 }
49871 /**
49872 * Set the strategy pattern for handling the coordinates given the current direction.
49873 *
49874 * The individual instances contain all the operations and data specific to a layout direction.
49875 *
49876 * @param {Node} node
49877 * @param {{x: number, y: number}} position
49878 * @param {number} level
49879 * @param {boolean} [doNotUpdate=false]
49880 * @private
49881 */
49882
49883 }, {
49884 key: "setDirectionStrategy",
49885 value: function setDirectionStrategy() {
49886 var isVertical = this.options.hierarchical.direction === 'UD' || this.options.hierarchical.direction === 'DU';
49887
49888 if (isVertical) {
49889 this.direction = new VerticalStrategy(this);
49890 } else {
49891 this.direction = new HorizontalStrategy(this);
49892 }
49893 }
49894 /**
49895 * Determine the center position of a branch from the passed list of child nodes
49896 *
49897 * This takes into account the positions of all the child nodes.
49898 * @param {Array.<Node|vis.Node.id>} childNodes Array of either child nodes or node id's
49899 * @return {number}
49900 * @private
49901 */
49902
49903 }, {
49904 key: "_getCenterPosition",
49905 value: function _getCenterPosition(childNodes) {
49906 var minPos = 1e9;
49907 var maxPos = -1e9;
49908
49909 for (var i = 0; i < childNodes.length; i++) {
49910 var childNode = void 0;
49911
49912 if (childNodes[i].id !== undefined) {
49913 childNode = childNodes[i];
49914 } else {
49915 var childNodeId = childNodes[i];
49916 childNode = this.body.nodes[childNodeId];
49917 }
49918
49919 var position = this.direction.getPosition(childNode);
49920 minPos = Math.min(minPos, position);
49921 maxPos = Math.max(maxPos, position);
49922 }
49923
49924 return 0.5 * (minPos + maxPos);
49925 }
49926 }]);
49927
49928 return LayoutEngine;
49929 }();
49930
49931 var css$3 = "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(top, #ffffff 0%, #fcfcfc 48%, #fafafa 50%, #fcfcfc 100%); /* FF3.6+ */\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(48%,#fcfcfc), color-stop(50%,#fafafa), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* Opera 11.10+ */\n background: -ms-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* IE10+ */\n background: linear-gradient(to bottom, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* 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 {\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 div.vis-close {\n position:absolute;\n right: 0;\n top: 0;\n width: 30px;\n height: 30px;\n\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 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-close:hover {\n opacity: 0.6;\n}\n\ndiv.vis-network div.vis-manipulation div.vis-button,\ndiv.vis-network div.vis-edit-mode div.vis-button {\n float:left;\n font-family: verdana;\n font-size: 12px;\n -moz-border-radius: 15px;\n border-radius: 15px;\n display:inline-block;\n background-position: 0px 0px;\n background-repeat:no-repeat;\n height:24px;\n margin-left: 10px;\n /*vertical-align:middle;*/\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 div.vis-button:hover {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.20);\n}\n\ndiv.vis-network div.vis-manipulation div.vis-button:active {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.50);\n}\n\ndiv.vis-network div.vis-manipulation div.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-button.vis-none:hover {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0);\n cursor: default;\n}\ndiv.vis-network div.vis-manipulation div.vis-button.vis-none:active {\n box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0);\n}\ndiv.vis-network div.vis-manipulation div.vis-button.vis-none {\n padding: 0;\n}\ndiv.vis-network div.vis-manipulation div.notification {\n margin: 2px;\n font-weight: bold;\n}\n\ndiv.vis-network div.vis-manipulation div.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 div.vis-button.vis-edit,\ndiv.vis-network div.vis-edit-mode div.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 div.vis-button.vis-edit.vis-edit-mode {\n background-color: #fcfcfc;\n border: 1px solid #cccccc;\n}\n\ndiv.vis-network div.vis-manipulation div.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 div.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\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk1hbmlwdWxhdGlvblN5c3RlbS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSx1QkFBdUI7O0VBRXZCLGVBQWU7RUFDZixrQkFBa0I7RUFDbEIsa0JBQWtCO0VBQ2xCLHFCQUFxQjtFQUNyQixtQkFBbUIsRUFBRSxpQkFBaUI7RUFDdEMsMEZBQTBGLEVBQUUsV0FBVztFQUN2RywrSkFBK0osRUFBRSxvQkFBb0I7RUFDckwsMEZBQTBGLEVBQUUseUJBQXlCO0VBQ3JILHFGQUFxRixFQUFFLGlCQUFpQjtFQUN4RyxzRkFBc0YsRUFBRSxVQUFVO0VBQ2xHLHdGQUF3RixFQUFFLFFBQVE7RUFDbEcsbUhBQW1ILEVBQUUsVUFBVTs7RUFFL0gsZUFBZTtFQUNmLGtCQUFrQjtFQUNsQixPQUFPO0VBQ1AsTUFBTTtFQUNOLFdBQVc7RUFDWCxZQUFZO0FBQ2Q7O0FBRUE7RUFDRSxpQkFBaUI7RUFDakIsT0FBTztFQUNQLFFBQVE7RUFDUixZQUFZO0FBQ2Q7O0FBRUEsa0ZBQWtGOztBQUVsRjtFQUNFLGlCQUFpQjtFQUNqQixRQUFRO0VBQ1IsTUFBTTtFQUNOLFdBQVc7RUFDWCxZQUFZOztFQUVaLDZCQUE2QjtFQUM3Qiw0QkFBNEI7RUFDNUIsbTR2QkFBcUM7RUFDckMsZUFBZTtFQUNmLDJCQUEyQjtFQUMzQix5QkFBeUI7RUFDekIsd0JBQXdCO0VBQ3hCLHNCQUFzQjtFQUN0QixxQkFBcUI7RUFDckIsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsWUFBWTtBQUNkOztBQUVBOztFQUVFLFVBQVU7RUFDVixvQkFBb0I7RUFDcEIsZUFBZTtFQUNmLHdCQUF3QjtFQUN4QixtQkFBbUI7RUFDbkIsb0JBQW9CO0VBQ3BCLDRCQUE0QjtFQUM1QiwyQkFBMkI7RUFDM0IsV0FBVztFQUNYLGlCQUFpQjtFQUNqQix5QkFBeUI7RUFDekIsZUFBZTtFQUNmLHdCQUF3QjtFQUN4QiwyQkFBMkI7RUFDM0IseUJBQXlCO0VBQ3pCLHdCQUF3QjtFQUN4QixzQkFBc0I7RUFDdEIscUJBQXFCO0VBQ3JCLGlCQUFpQjtBQUNuQjs7QUFFQTtFQUNFLDJDQUEyQztBQUM3Qzs7QUFFQTtFQUNFLDJDQUEyQztBQUM3Qzs7QUFFQTtFQUNFLHVvMkJBQXdDO0FBQzFDOztBQUVBO0VBQ0UsMENBQTBDO0VBQzFDLGVBQWU7QUFDakI7QUFDQTtFQUNFLDBDQUEwQztBQUM1QztBQUNBO0VBQ0UsVUFBVTtBQUNaO0FBQ0E7RUFDRSxXQUFXO0VBQ1gsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsKzQyQkFBMkM7QUFDN0M7O0FBRUE7O0VBRUUsdTYyQkFBd0M7QUFDMUM7O0FBRUE7RUFDRSx5QkFBeUI7RUFDekIseUJBQXlCO0FBQzNCOztBQUVBO0VBQ0UsdWwyQkFBMkM7QUFDN0M7O0FBRUE7RUFDRSx1MzJCQUEwQztBQUM1QztBQUNBLDBCQUEwQjtBQUMxQjs7RUFFRSxrQkFBa0I7RUFDbEIsaUJBQWlCO0FBQ25CO0FBQ0E7RUFDRSxVQUFVO0VBQ1Ysb0JBQW9CO0VBQ3BCLFNBQVM7RUFDVCxXQUFXO0VBQ1gseUJBQXlCO0VBQ3pCLHNCQUFzQixFQUFFLHdCQUF3QjtBQUNsRDs7QUFFQTs7Ozs7Ozs7Q0FRQyIsImZpbGUiOiJNYW5pcHVsYXRpb25TeXN0ZW0uY3NzIiwic291cmNlc0NvbnRlbnQiOlsiZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbWFuaXB1bGF0aW9uIHtcbiAgYm94LXNpemluZzogY29udGVudC1ib3g7XG5cbiAgYm9yZGVyLXdpZHRoOiAwO1xuICBib3JkZXItYm90dG9tOiAxcHg7XG4gIGJvcmRlci1zdHlsZTpzb2xpZDtcbiAgYm9yZGVyLWNvbG9yOiAjZDZkOWQ4O1xuICBiYWNrZ3JvdW5kOiAjZmZmZmZmOyAvKiBPbGQgYnJvd3NlcnMgKi9cbiAgYmFja2dyb3VuZDogLW1vei1saW5lYXItZ3JhZGllbnQodG9wLCAgI2ZmZmZmZiAwJSwgI2ZjZmNmYyA0OCUsICNmYWZhZmEgNTAlLCAjZmNmY2ZjIDEwMCUpOyAvKiBGRjMuNisgKi9cbiAgYmFja2dyb3VuZDogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIGxlZnQgdG9wLCBsZWZ0IGJvdHRvbSwgY29sb3Itc3RvcCgwJSwjZmZmZmZmKSwgY29sb3Itc3RvcCg0OCUsI2ZjZmNmYyksIGNvbG9yLXN0b3AoNTAlLCNmYWZhZmEpLCBjb2xvci1zdG9wKDEwMCUsI2ZjZmNmYykpOyAvKiBDaHJvbWUsU2FmYXJpNCsgKi9cbiAgYmFja2dyb3VuZDogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLCAgI2ZmZmZmZiAwJSwjZmNmY2ZjIDQ4JSwjZmFmYWZhIDUwJSwjZmNmY2ZjIDEwMCUpOyAvKiBDaHJvbWUxMCssU2FmYXJpNS4xKyAqL1xuICBiYWNrZ3JvdW5kOiAtby1saW5lYXItZ3JhZGllbnQodG9wLCAgI2ZmZmZmZiAwJSwjZmNmY2ZjIDQ4JSwjZmFmYWZhIDUwJSwjZmNmY2ZjIDEwMCUpOyAvKiBPcGVyYSAxMS4xMCsgKi9cbiAgYmFja2dyb3VuZDogLW1zLWxpbmVhci1ncmFkaWVudCh0b3AsICAjZmZmZmZmIDAlLCNmY2ZjZmMgNDglLCNmYWZhZmEgNTAlLCNmY2ZjZmMgMTAwJSk7IC8qIElFMTArICovXG4gIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICAjZmZmZmZmIDAlLCNmY2ZjZmMgNDglLCNmYWZhZmEgNTAlLCNmY2ZjZmMgMTAwJSk7IC8qIFczQyAqL1xuICBmaWx0ZXI6IHByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudCggc3RhcnRDb2xvcnN0cj0nI2ZmZmZmZicsIGVuZENvbG9yc3RyPScjZmNmY2ZjJyxHcmFkaWVudFR5cGU9MCApOyAvKiBJRTYtOSAqL1xuXG4gIHBhZGRpbmctdG9wOjRweDtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAwO1xuICB0b3A6IDA7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDI4cHg7XG59XG5cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLWVkaXQtbW9kZSB7XG4gIHBvc2l0aW9uOmFic29sdXRlO1xuICBsZWZ0OiAwO1xuICB0b3A6IDVweDtcbiAgaGVpZ2h0OiAzMHB4O1xufVxuXG4vKiBGSVhNRTogc2hvdWxkbid0IHRoZSB2aXMtY2xvc2UgYnV0dG9uIGJlIGEgY2hpbGQgb2YgdGhlIHZpcy1tYW5pcHVsYXRpb24gZGl2PyAqL1xuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1jbG9zZSB7XG4gIHBvc2l0aW9uOmFic29sdXRlO1xuICByaWdodDogMDtcbiAgdG9wOiAwO1xuICB3aWR0aDogMzBweDtcbiAgaGVpZ2h0OiAzMHB4O1xuXG4gIGJhY2tncm91bmQtcG9zaXRpb246IDIwcHggM3B4O1xuICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLWltYWdlOiBpbmxpbmUoXCJjcm9zcy5wbmdcIik7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgLXdlYmtpdC10b3VjaC1jYWxsb3V0OiBub25lO1xuICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xuICAta2h0bWwtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tcy11c2VyLXNlbGVjdDogbm9uZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLWNsb3NlOmhvdmVyIHtcbiAgb3BhY2l0eTogMC42O1xufVxuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b24sXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1lZGl0LW1vZGUgZGl2LnZpcy1idXR0b24ge1xuICBmbG9hdDpsZWZ0O1xuICBmb250LWZhbWlseTogdmVyZGFuYTtcbiAgZm9udC1zaXplOiAxMnB4O1xuICAtbW96LWJvcmRlci1yYWRpdXM6IDE1cHg7XG4gIGJvcmRlci1yYWRpdXM6IDE1cHg7XG4gIGRpc3BsYXk6aW5saW5lLWJsb2NrO1xuICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwcHggMHB4O1xuICBiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7XG4gIGhlaWdodDoyNHB4O1xuICBtYXJnaW4tbGVmdDogMTBweDtcbiAgLyp2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7Ki9cbiAgY3Vyc29yOiBwb2ludGVyO1xuICBwYWRkaW5nOiAwcHggOHB4IDBweCA4cHg7XG4gIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgLWtodG1sLXVzZXItc2VsZWN0OiBub25lO1xuICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xuICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIHVzZXItc2VsZWN0OiBub25lO1xufVxuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b246aG92ZXIge1xuICBib3gtc2hhZG93OiAxcHggMXB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMjApO1xufVxuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b246YWN0aXZlIHtcbiAgYm94LXNoYWRvdzogMXB4IDFweCA4cHggcmdiYSgwLCAwLCAwLCAwLjUwKTtcbn1cblxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbWFuaXB1bGF0aW9uIGRpdi52aXMtYnV0dG9uLnZpcy1iYWNrIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwiYmFja0ljb24ucG5nXCIpO1xufVxuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b24udmlzLW5vbmU6aG92ZXIge1xuICBib3gtc2hhZG93OiAxcHggMXB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMCk7XG4gIGN1cnNvcjogZGVmYXVsdDtcbn1cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLW1hbmlwdWxhdGlvbiBkaXYudmlzLWJ1dHRvbi52aXMtbm9uZTphY3RpdmUge1xuICBib3gtc2hhZG93OiAxcHggMXB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMCk7XG59XG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b24udmlzLW5vbmUge1xuICBwYWRkaW5nOiAwO1xufVxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbWFuaXB1bGF0aW9uIGRpdi5ub3RpZmljYXRpb24ge1xuICBtYXJnaW46IDJweDtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLW1hbmlwdWxhdGlvbiBkaXYudmlzLWJ1dHRvbi52aXMtYWRkIHtcbiAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwiYWRkTm9kZUljb24ucG5nXCIpO1xufVxuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b24udmlzLWVkaXQsXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1lZGl0LW1vZGUgZGl2LnZpcy1idXR0b24udmlzLWVkaXQge1xuICBiYWNrZ3JvdW5kLWltYWdlOiBpbmxpbmUoXCJlZGl0SWNvbi5wbmdcIik7XG59XG5cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLWVkaXQtbW9kZSBkaXYudmlzLWJ1dHRvbi52aXMtZWRpdC52aXMtZWRpdC1tb2RlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZjZmNmYztcbiAgYm9yZGVyOiAxcHggc29saWQgI2NjY2NjYztcbn1cblxuZGl2LnZpcy1uZXR3b3JrIGRpdi52aXMtbWFuaXB1bGF0aW9uIGRpdi52aXMtYnV0dG9uLnZpcy1jb25uZWN0IHtcbiAgYmFja2dyb3VuZC1pbWFnZTogaW5saW5lKFwiY29ubmVjdEljb24ucG5nXCIpO1xufVxuXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1idXR0b24udmlzLWRlbGV0ZSB7XG4gIGJhY2tncm91bmQtaW1hZ2U6IGlubGluZShcImRlbGV0ZUljb24ucG5nXCIpO1xufVxuLyogdG9wIHJpZ2h0IGJvdHRvbSBsZWZ0ICovXG5kaXYudmlzLW5ldHdvcmsgZGl2LnZpcy1tYW5pcHVsYXRpb24gZGl2LnZpcy1sYWJlbCxcbmRpdi52aXMtbmV0d29yayBkaXYudmlzLWVkaXQtbW9kZSBkaXYudmlzLWxhYmVsIHtcbiAgbWFyZ2luOiAwIDAgMCAyM3B4O1xuICBsaW5lLWhlaWdodDogMjVweDtcbn1cbmRpdi52aXMtbmV0d29yayBkaXYudmlzLW1hbmlwdWxhdGlvbiBkaXYudmlzLXNlcGFyYXRvci1saW5lIHtcbiAgZmxvYXQ6bGVmdDtcbiAgZGlzcGxheTppbmxpbmUtYmxvY2s7XG4gIHdpZHRoOjFweDtcbiAgaGVpZ2h0OjIxcHg7XG4gIGJhY2tncm91bmQtY29sb3I6ICNiZGJkYmQ7XG4gIG1hcmdpbjogMHB4IDdweCAwIDE1cHg7IC8qdG9wIHJpZ2h0IGJvdHRvbSBsZWZ0Ki9cbn1cblxuLyogVE9ETzogaXMgdGhpcyByZWR1bmRhbnQ/XG5kaXYubmV0d29yay1uYXZpZ2F0aW9uX3dyYXBwZXIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDA7XG4gIHRvcDogMDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbn1cbiovXG4iXX0= */";
49932 styleInject(css$3);
49933
49934 /**
49935 * Clears the toolbar div element of children
49936 *
49937 * @private
49938 */
49939
49940 var ManipulationSystem =
49941 /*#__PURE__*/
49942 function () {
49943 /**
49944 * @param {Object} body
49945 * @param {Canvas} canvas
49946 * @param {SelectionHandler} selectionHandler
49947 */
49948 function ManipulationSystem(body, canvas, selectionHandler, interactionHandler) {
49949 var _this = this;
49950
49951 _classCallCheck(this, ManipulationSystem);
49952
49953 this.body = body;
49954 this.canvas = canvas;
49955 this.selectionHandler = selectionHandler;
49956 this.interactionHandler = interactionHandler;
49957 this.editMode = false;
49958 this.manipulationDiv = undefined;
49959 this.editModeDiv = undefined;
49960 this.closeDiv = undefined;
49961 this.manipulationHammers = [];
49962 this.temporaryUIFunctions = {};
49963 this.temporaryEventFunctions = [];
49964 this.touchTime = 0;
49965 this.temporaryIds = {
49966 nodes: [],
49967 edges: []
49968 };
49969 this.guiEnabled = false;
49970 this.inMode = false;
49971 this.selectedControlNode = undefined;
49972 this.options = {};
49973 this.defaultOptions = {
49974 enabled: false,
49975 initiallyActive: false,
49976 addNode: true,
49977 addEdge: true,
49978 editNode: undefined,
49979 editEdge: true,
49980 deleteNode: true,
49981 deleteEdge: true,
49982 controlNodeStyle: {
49983 shape: 'dot',
49984 size: 6,
49985 color: {
49986 background: '#ff0000',
49987 border: '#3c3c3c',
49988 highlight: {
49989 background: '#07f968',
49990 border: '#3c3c3c'
49991 }
49992 },
49993 borderWidth: 2,
49994 borderWidthSelected: 2
49995 }
49996 };
49997 extend(this.options, this.defaultOptions);
49998 this.body.emitter.on('destroy', function () {
49999 _this._clean();
50000 });
50001 this.body.emitter.on('_dataChanged', this._restore.bind(this));
50002 this.body.emitter.on('_resetData', this._restore.bind(this));
50003 }
50004 /**
50005 * If something changes in the data during editing, switch back to the initial datamanipulation state and close all edit modes.
50006 * @private
50007 */
50008
50009
50010 _createClass(ManipulationSystem, [{
50011 key: "_restore",
50012 value: function _restore() {
50013 if (this.inMode !== false) {
50014 if (this.options.initiallyActive === true) {
50015 this.enableEditMode();
50016 } else {
50017 this.disableEditMode();
50018 }
50019 }
50020 }
50021 /**
50022 * Set the Options
50023 *
50024 * @param {Object} options
50025 * @param {Object} allOptions
50026 * @param {Object} globalOptions
50027 */
50028
50029 }, {
50030 key: "setOptions",
50031 value: function setOptions(options, allOptions, globalOptions) {
50032 if (allOptions !== undefined) {
50033 if (allOptions.locale !== undefined) {
50034 this.options.locale = allOptions.locale;
50035 } else {
50036 this.options.locale = globalOptions.locale;
50037 }
50038
50039 if (allOptions.locales !== undefined) {
50040 this.options.locales = allOptions.locales;
50041 } else {
50042 this.options.locales = globalOptions.locales;
50043 }
50044 }
50045
50046 if (options !== undefined) {
50047 if (typeof options === 'boolean') {
50048 this.options.enabled = options;
50049 } else {
50050 this.options.enabled = true;
50051 deepExtend(this.options, options);
50052 }
50053
50054 if (this.options.initiallyActive === true) {
50055 this.editMode = true;
50056 }
50057
50058 this._setup();
50059 }
50060 }
50061 /**
50062 * Enable or disable edit-mode. Draws the DOM required and cleans up after itself.
50063 *
50064 * @private
50065 */
50066
50067 }, {
50068 key: "toggleEditMode",
50069 value: function toggleEditMode() {
50070 if (this.editMode === true) {
50071 this.disableEditMode();
50072 } else {
50073 this.enableEditMode();
50074 }
50075 }
50076 /**
50077 * Enables Edit Mode
50078 */
50079
50080 }, {
50081 key: "enableEditMode",
50082 value: function enableEditMode() {
50083 this.editMode = true;
50084
50085 this._clean();
50086
50087 if (this.guiEnabled === true) {
50088 this.manipulationDiv.style.display = 'block';
50089 this.closeDiv.style.display = 'block';
50090 this.editModeDiv.style.display = 'none';
50091 this.showManipulatorToolbar();
50092 }
50093 }
50094 /**
50095 * Disables Edit Mode
50096 */
50097
50098 }, {
50099 key: "disableEditMode",
50100 value: function disableEditMode() {
50101 this.editMode = false;
50102
50103 this._clean();
50104
50105 if (this.guiEnabled === true) {
50106 this.manipulationDiv.style.display = 'none';
50107 this.closeDiv.style.display = 'none';
50108 this.editModeDiv.style.display = 'block';
50109
50110 this._createEditButton();
50111 }
50112 }
50113 /**
50114 * Creates the main toolbar. Removes functions bound to the select event. Binds all the buttons of the toolbar.
50115 *
50116 * @private
50117 */
50118
50119 }, {
50120 key: "showManipulatorToolbar",
50121 value: function showManipulatorToolbar() {
50122 // restore the state of any bound functions or events, remove control nodes, restore physics
50123 this._clean(); // reset global variables
50124
50125
50126 this.manipulationDOM = {}; // if the gui is enabled, draw all elements.
50127
50128 if (this.guiEnabled === true) {
50129 // a _restore will hide these menus
50130 this.editMode = true;
50131 this.manipulationDiv.style.display = 'block';
50132 this.closeDiv.style.display = 'block';
50133
50134 var selectedNodeCount = this.selectionHandler._getSelectedNodeCount();
50135
50136 var selectedEdgeCount = this.selectionHandler._getSelectedEdgeCount();
50137
50138 var selectedTotalCount = selectedNodeCount + selectedEdgeCount;
50139 var locale = this.options.locales[this.options.locale];
50140 var needSeperator = false;
50141
50142 if (this.options.addNode !== false) {
50143 this._createAddNodeButton(locale);
50144
50145 needSeperator = true;
50146 }
50147
50148 if (this.options.addEdge !== false) {
50149 if (needSeperator === true) {
50150 this._createSeperator(1);
50151 } else {
50152 needSeperator = true;
50153 }
50154
50155 this._createAddEdgeButton(locale);
50156 }
50157
50158 if (selectedNodeCount === 1 && typeof this.options.editNode === 'function') {
50159 if (needSeperator === true) {
50160 this._createSeperator(2);
50161 } else {
50162 needSeperator = true;
50163 }
50164
50165 this._createEditNodeButton(locale);
50166 } else if (selectedEdgeCount === 1 && selectedNodeCount === 0 && this.options.editEdge !== false) {
50167 if (needSeperator === true) {
50168 this._createSeperator(3);
50169 } else {
50170 needSeperator = true;
50171 }
50172
50173 this._createEditEdgeButton(locale);
50174 } // remove buttons
50175
50176
50177 if (selectedTotalCount !== 0) {
50178 if (selectedNodeCount > 0 && this.options.deleteNode !== false) {
50179 if (needSeperator === true) {
50180 this._createSeperator(4);
50181 }
50182
50183 this._createDeleteButton(locale);
50184 } else if (selectedNodeCount === 0 && this.options.deleteEdge !== false) {
50185 if (needSeperator === true) {
50186 this._createSeperator(4);
50187 }
50188
50189 this._createDeleteButton(locale);
50190 }
50191 } // bind the close button
50192
50193
50194 this._bindHammerToDiv(this.closeDiv, this.toggleEditMode.bind(this)); // refresh this bar based on what has been selected
50195
50196
50197 this._temporaryBindEvent('select', this.showManipulatorToolbar.bind(this));
50198 } // redraw to show any possible changes
50199
50200
50201 this.body.emitter.emit('_redraw');
50202 }
50203 /**
50204 * Create the toolbar for adding Nodes
50205 */
50206
50207 }, {
50208 key: "addNodeMode",
50209 value: function addNodeMode() {
50210 // when using the gui, enable edit mode if it wasnt already.
50211 if (this.editMode !== true) {
50212 this.enableEditMode();
50213 } // restore the state of any bound functions or events, remove control nodes, restore physics
50214
50215
50216 this._clean();
50217
50218 this.inMode = 'addNode';
50219
50220 if (this.guiEnabled === true) {
50221 var locale = this.options.locales[this.options.locale];
50222 this.manipulationDOM = {};
50223
50224 this._createBackButton(locale);
50225
50226 this._createSeperator();
50227
50228 this._createDescription(locale['addDescription'] || this.options.locales['en']['addDescription']); // bind the close button
50229
50230
50231 this._bindHammerToDiv(this.closeDiv, this.toggleEditMode.bind(this));
50232 }
50233
50234 this._temporaryBindEvent('click', this._performAddNode.bind(this));
50235 }
50236 /**
50237 * call the bound function to handle the editing of the node. The node has to be selected.
50238 */
50239
50240 }, {
50241 key: "editNode",
50242 value: function editNode() {
50243 var _this2 = this;
50244
50245 // when using the gui, enable edit mode if it wasnt already.
50246 if (this.editMode !== true) {
50247 this.enableEditMode();
50248 } // restore the state of any bound functions or events, remove control nodes, restore physics
50249
50250
50251 this._clean();
50252
50253 var node = this.selectionHandler._getSelectedNode();
50254
50255 if (node !== undefined) {
50256 this.inMode = 'editNode';
50257
50258 if (typeof this.options.editNode === 'function') {
50259 if (node.isCluster !== true) {
50260 var data = deepExtend({}, node.options, false);
50261 data.x = node.x;
50262 data.y = node.y;
50263
50264 if (this.options.editNode.length === 2) {
50265 this.options.editNode(data, function (finalizedData) {
50266 if (finalizedData !== null && finalizedData !== undefined && _this2.inMode === 'editNode') {
50267 // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
50268 _this2.body.data.nodes.getDataSet().update(finalizedData);
50269 }
50270
50271 _this2.showManipulatorToolbar();
50272 });
50273 } else {
50274 throw new Error('The function for edit does not support two arguments (data, callback)');
50275 }
50276 } else {
50277 alert(this.options.locales[this.options.locale]['editClusterError'] || this.options.locales['en']['editClusterError']);
50278 }
50279 } else {
50280 throw new Error('No function has been configured to handle the editing of nodes.');
50281 }
50282 } else {
50283 this.showManipulatorToolbar();
50284 }
50285 }
50286 /**
50287 * create the toolbar to connect nodes
50288 */
50289
50290 }, {
50291 key: "addEdgeMode",
50292 value: function addEdgeMode() {
50293 // when using the gui, enable edit mode if it wasnt already.
50294 if (this.editMode !== true) {
50295 this.enableEditMode();
50296 } // restore the state of any bound functions or events, remove control nodes, restore physics
50297
50298
50299 this._clean();
50300
50301 this.inMode = 'addEdge';
50302
50303 if (this.guiEnabled === true) {
50304 var locale = this.options.locales[this.options.locale];
50305 this.manipulationDOM = {};
50306
50307 this._createBackButton(locale);
50308
50309 this._createSeperator();
50310
50311 this._createDescription(locale['edgeDescription'] || this.options.locales['en']['edgeDescription']); // bind the close button
50312
50313
50314 this._bindHammerToDiv(this.closeDiv, this.toggleEditMode.bind(this));
50315 } // temporarily overload functions
50316
50317
50318 this._temporaryBindUI('onTouch', this._handleConnect.bind(this));
50319
50320 this._temporaryBindUI('onDragEnd', this._finishConnect.bind(this));
50321
50322 this._temporaryBindUI('onDrag', this._dragControlNode.bind(this));
50323
50324 this._temporaryBindUI('onRelease', this._finishConnect.bind(this));
50325
50326 this._temporaryBindUI('onDragStart', this._dragStartEdge.bind(this));
50327
50328 this._temporaryBindUI('onHold', function () {});
50329 }
50330 /**
50331 * create the toolbar to edit edges
50332 */
50333
50334 }, {
50335 key: "editEdgeMode",
50336 value: function editEdgeMode() {
50337 // when using the gui, enable edit mode if it wasn't already.
50338 if (this.editMode !== true) {
50339 this.enableEditMode();
50340 } // restore the state of any bound functions or events, remove control nodes, restore physics
50341
50342
50343 this._clean();
50344
50345 this.inMode = 'editEdge';
50346
50347 if (_typeof(this.options.editEdge) === 'object' && typeof this.options.editEdge.editWithoutDrag === "function") {
50348 this.edgeBeingEditedId = this.selectionHandler.getSelectedEdges()[0];
50349
50350 if (this.edgeBeingEditedId !== undefined) {
50351 var edge = this.body.edges[this.edgeBeingEditedId];
50352
50353 this._performEditEdge(edge.from.id, edge.to.id);
50354
50355 return;
50356 }
50357 }
50358
50359 if (this.guiEnabled === true) {
50360 var locale = this.options.locales[this.options.locale];
50361 this.manipulationDOM = {};
50362
50363 this._createBackButton(locale);
50364
50365 this._createSeperator();
50366
50367 this._createDescription(locale['editEdgeDescription'] || this.options.locales['en']['editEdgeDescription']); // bind the close button
50368
50369
50370 this._bindHammerToDiv(this.closeDiv, this.toggleEditMode.bind(this));
50371 }
50372
50373 this.edgeBeingEditedId = this.selectionHandler.getSelectedEdges()[0];
50374
50375 if (this.edgeBeingEditedId !== undefined) {
50376 var _edge = this.body.edges[this.edgeBeingEditedId]; // create control nodes
50377
50378 var controlNodeFrom = this._getNewTargetNode(_edge.from.x, _edge.from.y);
50379
50380 var controlNodeTo = this._getNewTargetNode(_edge.to.x, _edge.to.y);
50381
50382 this.temporaryIds.nodes.push(controlNodeFrom.id);
50383 this.temporaryIds.nodes.push(controlNodeTo.id);
50384 this.body.nodes[controlNodeFrom.id] = controlNodeFrom;
50385 this.body.nodeIndices.push(controlNodeFrom.id);
50386 this.body.nodes[controlNodeTo.id] = controlNodeTo;
50387 this.body.nodeIndices.push(controlNodeTo.id); // temporarily overload UI functions, cleaned up automatically because of _temporaryBindUI
50388
50389 this._temporaryBindUI('onTouch', this._controlNodeTouch.bind(this)); // used to get the position
50390
50391
50392 this._temporaryBindUI('onTap', function () {}); // disabled
50393
50394
50395 this._temporaryBindUI('onHold', function () {}); // disabled
50396
50397
50398 this._temporaryBindUI('onDragStart', this._controlNodeDragStart.bind(this)); // used to select control node
50399
50400
50401 this._temporaryBindUI('onDrag', this._controlNodeDrag.bind(this)); // used to drag control node
50402
50403
50404 this._temporaryBindUI('onDragEnd', this._controlNodeDragEnd.bind(this)); // used to connect or revert control nodes
50405
50406
50407 this._temporaryBindUI('onMouseMove', function () {}); // disabled
50408 // create function to position control nodes correctly on movement
50409 // automatically cleaned up because we use the temporary bind
50410
50411
50412 this._temporaryBindEvent('beforeDrawing', function (ctx) {
50413 var positions = _edge.edgeType.findBorderPositions(ctx);
50414
50415 if (controlNodeFrom.selected === false) {
50416 controlNodeFrom.x = positions.from.x;
50417 controlNodeFrom.y = positions.from.y;
50418 }
50419
50420 if (controlNodeTo.selected === false) {
50421 controlNodeTo.x = positions.to.x;
50422 controlNodeTo.y = positions.to.y;
50423 }
50424 });
50425
50426 this.body.emitter.emit('_redraw');
50427 } else {
50428 this.showManipulatorToolbar();
50429 }
50430 }
50431 /**
50432 * delete everything in the selection
50433 */
50434
50435 }, {
50436 key: "deleteSelected",
50437 value: function deleteSelected() {
50438 var _this3 = this;
50439
50440 // when using the gui, enable edit mode if it wasnt already.
50441 if (this.editMode !== true) {
50442 this.enableEditMode();
50443 } // restore the state of any bound functions or events, remove control nodes, restore physics
50444
50445
50446 this._clean();
50447
50448 this.inMode = 'delete';
50449 var selectedNodes = this.selectionHandler.getSelectedNodes();
50450 var selectedEdges = this.selectionHandler.getSelectedEdges();
50451 var deleteFunction = undefined;
50452
50453 if (selectedNodes.length > 0) {
50454 for (var i = 0; i < selectedNodes.length; i++) {
50455 if (this.body.nodes[selectedNodes[i]].isCluster === true) {
50456 alert(this.options.locales[this.options.locale]['deleteClusterError'] || this.options.locales['en']['deleteClusterError']);
50457 return;
50458 }
50459 }
50460
50461 if (typeof this.options.deleteNode === 'function') {
50462 deleteFunction = this.options.deleteNode;
50463 }
50464 } else if (selectedEdges.length > 0) {
50465 if (typeof this.options.deleteEdge === 'function') {
50466 deleteFunction = this.options.deleteEdge;
50467 }
50468 }
50469
50470 if (typeof deleteFunction === 'function') {
50471 var data = {
50472 nodes: selectedNodes,
50473 edges: selectedEdges
50474 };
50475
50476 if (deleteFunction.length === 2) {
50477 deleteFunction(data, function (finalizedData) {
50478 if (finalizedData !== null && finalizedData !== undefined && _this3.inMode === 'delete') {
50479 // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
50480 _this3.body.data.edges.getDataSet().remove(finalizedData.edges);
50481
50482 _this3.body.data.nodes.getDataSet().remove(finalizedData.nodes);
50483
50484 _this3.body.emitter.emit('startSimulation');
50485
50486 _this3.showManipulatorToolbar();
50487 } else {
50488 _this3.body.emitter.emit('startSimulation');
50489
50490 _this3.showManipulatorToolbar();
50491 }
50492 });
50493 } else {
50494 throw new Error('The function for delete does not support two arguments (data, callback)');
50495 }
50496 } else {
50497 this.body.data.edges.getDataSet().remove(selectedEdges);
50498 this.body.data.nodes.getDataSet().remove(selectedNodes);
50499 this.body.emitter.emit('startSimulation');
50500 this.showManipulatorToolbar();
50501 }
50502 } //********************************************** PRIVATE ***************************************//
50503
50504 /**
50505 * draw or remove the DOM
50506 * @private
50507 */
50508
50509 }, {
50510 key: "_setup",
50511 value: function _setup() {
50512 if (this.options.enabled === true) {
50513 // Enable the GUI
50514 this.guiEnabled = true;
50515
50516 this._createWrappers();
50517
50518 if (this.editMode === false) {
50519 this._createEditButton();
50520 } else {
50521 this.showManipulatorToolbar();
50522 }
50523 } else {
50524 this._removeManipulationDOM(); // disable the gui
50525
50526
50527 this.guiEnabled = false;
50528 }
50529 }
50530 /**
50531 * create the div overlays that contain the DOM
50532 * @private
50533 */
50534
50535 }, {
50536 key: "_createWrappers",
50537 value: function _createWrappers() {
50538 // load the manipulator HTML elements. All styling done in css.
50539 if (this.manipulationDiv === undefined) {
50540 this.manipulationDiv = document.createElement('div');
50541 this.manipulationDiv.className = 'vis-manipulation';
50542
50543 if (this.editMode === true) {
50544 this.manipulationDiv.style.display = 'block';
50545 } else {
50546 this.manipulationDiv.style.display = 'none';
50547 }
50548
50549 this.canvas.frame.appendChild(this.manipulationDiv);
50550 } // container for the edit button.
50551
50552
50553 if (this.editModeDiv === undefined) {
50554 this.editModeDiv = document.createElement('div');
50555 this.editModeDiv.className = 'vis-edit-mode';
50556
50557 if (this.editMode === true) {
50558 this.editModeDiv.style.display = 'none';
50559 } else {
50560 this.editModeDiv.style.display = 'block';
50561 }
50562
50563 this.canvas.frame.appendChild(this.editModeDiv);
50564 } // container for the close div button
50565
50566
50567 if (this.closeDiv === undefined) {
50568 this.closeDiv = document.createElement('div');
50569 this.closeDiv.className = 'vis-close';
50570 this.closeDiv.style.display = this.manipulationDiv.style.display;
50571 this.canvas.frame.appendChild(this.closeDiv);
50572 }
50573 }
50574 /**
50575 * generate a new target node. Used for creating new edges and editing edges
50576 *
50577 * @param {number} x
50578 * @param {number} y
50579 * @returns {Node}
50580 * @private
50581 */
50582
50583 }, {
50584 key: "_getNewTargetNode",
50585 value: function _getNewTargetNode(x, y) {
50586 var controlNodeStyle = deepExtend({}, this.options.controlNodeStyle);
50587 controlNodeStyle.id = 'targetNode' + uuid4();
50588 controlNodeStyle.hidden = false;
50589 controlNodeStyle.physics = false;
50590 controlNodeStyle.x = x;
50591 controlNodeStyle.y = y; // we have to define the bounding box in order for the nodes to be drawn immediately
50592
50593 var node = this.body.functions.createNode(controlNodeStyle);
50594 node.shape.boundingBox = {
50595 left: x,
50596 right: x,
50597 top: y,
50598 bottom: y
50599 };
50600 return node;
50601 }
50602 /**
50603 * Create the edit button
50604 */
50605
50606 }, {
50607 key: "_createEditButton",
50608 value: function _createEditButton() {
50609 // restore everything to it's original state (if applicable)
50610 this._clean(); // reset the manipulationDOM
50611
50612
50613 this.manipulationDOM = {}; // empty the editModeDiv
50614
50615 recursiveDOMDelete(this.editModeDiv); // create the contents for the editMode button
50616
50617 var locale = this.options.locales[this.options.locale];
50618
50619 var button = this._createButton('editMode', 'vis-button vis-edit vis-edit-mode', locale['edit'] || this.options.locales['en']['edit']);
50620
50621 this.editModeDiv.appendChild(button); // bind a hammer listener to the button, calling the function toggleEditMode.
50622
50623 this._bindHammerToDiv(button, this.toggleEditMode.bind(this));
50624 }
50625 /**
50626 * this function cleans up after everything this module does. Temporary elements, functions and events are removed, physics restored, hammers removed.
50627 * @private
50628 */
50629
50630 }, {
50631 key: "_clean",
50632 value: function _clean() {
50633 // not in mode
50634 this.inMode = false; // _clean the divs
50635
50636 if (this.guiEnabled === true) {
50637 recursiveDOMDelete(this.editModeDiv);
50638 recursiveDOMDelete(this.manipulationDiv); // removes all the bindings and overloads
50639
50640 this._cleanManipulatorHammers();
50641 } // remove temporary nodes and edges
50642
50643
50644 this._cleanupTemporaryNodesAndEdges(); // restore overloaded UI functions
50645
50646
50647 this._unbindTemporaryUIs(); // remove the temporaryEventFunctions
50648
50649
50650 this._unbindTemporaryEvents(); // restore the physics if required
50651
50652
50653 this.body.emitter.emit('restorePhysics');
50654 }
50655 /**
50656 * Each dom element has it's own hammer. They are stored in this.manipulationHammers. This cleans them up.
50657 * @private
50658 */
50659
50660 }, {
50661 key: "_cleanManipulatorHammers",
50662 value: function _cleanManipulatorHammers() {
50663 // _clean hammer bindings
50664 if (this.manipulationHammers.length != 0) {
50665 for (var i = 0; i < this.manipulationHammers.length; i++) {
50666 this.manipulationHammers[i].destroy();
50667 }
50668
50669 this.manipulationHammers = [];
50670 }
50671 }
50672 /**
50673 * Remove all DOM elements created by this module.
50674 * @private
50675 */
50676
50677 }, {
50678 key: "_removeManipulationDOM",
50679 value: function _removeManipulationDOM() {
50680 // removes all the bindings and overloads
50681 this._clean(); // empty the manipulation divs
50682
50683
50684 recursiveDOMDelete(this.manipulationDiv);
50685 recursiveDOMDelete(this.editModeDiv);
50686 recursiveDOMDelete(this.closeDiv); // remove the manipulation divs
50687
50688 if (this.manipulationDiv) {
50689 this.canvas.frame.removeChild(this.manipulationDiv);
50690 }
50691
50692 if (this.editModeDiv) {
50693 this.canvas.frame.removeChild(this.editModeDiv);
50694 }
50695
50696 if (this.closeDiv) {
50697 this.canvas.frame.removeChild(this.closeDiv);
50698 } // set the references to undefined
50699
50700
50701 this.manipulationDiv = undefined;
50702 this.editModeDiv = undefined;
50703 this.closeDiv = undefined;
50704 }
50705 /**
50706 * create a seperator line. the index is to differentiate in the manipulation dom
50707 * @param {number} [index=1]
50708 * @private
50709 */
50710
50711 }, {
50712 key: "_createSeperator",
50713 value: function _createSeperator() {
50714 var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
50715 this.manipulationDOM['seperatorLineDiv' + index] = document.createElement('div');
50716 this.manipulationDOM['seperatorLineDiv' + index].className = 'vis-separator-line';
50717 this.manipulationDiv.appendChild(this.manipulationDOM['seperatorLineDiv' + index]);
50718 } // ---------------------- DOM functions for buttons --------------------------//
50719
50720 /**
50721 *
50722 * @param {Locale} locale
50723 * @private
50724 */
50725
50726 }, {
50727 key: "_createAddNodeButton",
50728 value: function _createAddNodeButton(locale) {
50729 var button = this._createButton('addNode', 'vis-button vis-add', locale['addNode'] || this.options.locales['en']['addNode']);
50730
50731 this.manipulationDiv.appendChild(button);
50732
50733 this._bindHammerToDiv(button, this.addNodeMode.bind(this));
50734 }
50735 /**
50736 *
50737 * @param {Locale} locale
50738 * @private
50739 */
50740
50741 }, {
50742 key: "_createAddEdgeButton",
50743 value: function _createAddEdgeButton(locale) {
50744 var button = this._createButton('addEdge', 'vis-button vis-connect', locale['addEdge'] || this.options.locales['en']['addEdge']);
50745
50746 this.manipulationDiv.appendChild(button);
50747
50748 this._bindHammerToDiv(button, this.addEdgeMode.bind(this));
50749 }
50750 /**
50751 *
50752 * @param {Locale} locale
50753 * @private
50754 */
50755
50756 }, {
50757 key: "_createEditNodeButton",
50758 value: function _createEditNodeButton(locale) {
50759 var button = this._createButton('editNode', 'vis-button vis-edit', locale['editNode'] || this.options.locales['en']['editNode']);
50760
50761 this.manipulationDiv.appendChild(button);
50762
50763 this._bindHammerToDiv(button, this.editNode.bind(this));
50764 }
50765 /**
50766 *
50767 * @param {Locale} locale
50768 * @private
50769 */
50770
50771 }, {
50772 key: "_createEditEdgeButton",
50773 value: function _createEditEdgeButton(locale) {
50774 var button = this._createButton('editEdge', 'vis-button vis-edit', locale['editEdge'] || this.options.locales['en']['editEdge']);
50775
50776 this.manipulationDiv.appendChild(button);
50777
50778 this._bindHammerToDiv(button, this.editEdgeMode.bind(this));
50779 }
50780 /**
50781 *
50782 * @param {Locale} locale
50783 * @private
50784 */
50785
50786 }, {
50787 key: "_createDeleteButton",
50788 value: function _createDeleteButton(locale) {
50789 var deleteBtnClass;
50790
50791 if (this.options.rtl) {
50792 deleteBtnClass = 'vis-button vis-delete-rtl';
50793 } else {
50794 deleteBtnClass = 'vis-button vis-delete';
50795 }
50796
50797 var button = this._createButton('delete', deleteBtnClass, locale['del'] || this.options.locales['en']['del']);
50798
50799 this.manipulationDiv.appendChild(button);
50800
50801 this._bindHammerToDiv(button, this.deleteSelected.bind(this));
50802 }
50803 /**
50804 *
50805 * @param {Locale} locale
50806 * @private
50807 */
50808
50809 }, {
50810 key: "_createBackButton",
50811 value: function _createBackButton(locale) {
50812 var button = this._createButton('back', 'vis-button vis-back', locale['back'] || this.options.locales['en']['back']);
50813
50814 this.manipulationDiv.appendChild(button);
50815
50816 this._bindHammerToDiv(button, this.showManipulatorToolbar.bind(this));
50817 }
50818 /**
50819 *
50820 * @param {number|string} id
50821 * @param {string} className
50822 * @param {label} label
50823 * @param {string} labelClassName
50824 * @returns {HTMLElement}
50825 * @private
50826 */
50827
50828 }, {
50829 key: "_createButton",
50830 value: function _createButton(id, className, label) {
50831 var labelClassName = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'vis-label';
50832 this.manipulationDOM[id + 'Div'] = document.createElement('div');
50833 this.manipulationDOM[id + 'Div'].className = className;
50834 this.manipulationDOM[id + 'Label'] = document.createElement('div');
50835 this.manipulationDOM[id + 'Label'].className = labelClassName;
50836 this.manipulationDOM[id + 'Label'].innerHTML = label;
50837 this.manipulationDOM[id + 'Div'].appendChild(this.manipulationDOM[id + 'Label']);
50838 return this.manipulationDOM[id + 'Div'];
50839 }
50840 /**
50841 *
50842 * @param {Label} label
50843 * @private
50844 */
50845
50846 }, {
50847 key: "_createDescription",
50848 value: function _createDescription(label) {
50849 this.manipulationDiv.appendChild(this._createButton('description', 'vis-button vis-none', label));
50850 } // -------------------------- End of DOM functions for buttons ------------------------------//
50851
50852 /**
50853 * this binds an event until cleanup by the clean functions.
50854 * @param {Event} event The event
50855 * @param {function} newFunction
50856 * @private
50857 */
50858
50859 }, {
50860 key: "_temporaryBindEvent",
50861 value: function _temporaryBindEvent(event, newFunction) {
50862 this.temporaryEventFunctions.push({
50863 event: event,
50864 boundFunction: newFunction
50865 });
50866 this.body.emitter.on(event, newFunction);
50867 }
50868 /**
50869 * this overrides an UI function until cleanup by the clean function
50870 * @param {string} UIfunctionName
50871 * @param {function} newFunction
50872 * @private
50873 */
50874
50875 }, {
50876 key: "_temporaryBindUI",
50877 value: function _temporaryBindUI(UIfunctionName, newFunction) {
50878 if (this.body.eventListeners[UIfunctionName] !== undefined) {
50879 this.temporaryUIFunctions[UIfunctionName] = this.body.eventListeners[UIfunctionName];
50880 this.body.eventListeners[UIfunctionName] = newFunction;
50881 } else {
50882 throw new Error('This UI function does not exist. Typo? You tried: ' + UIfunctionName + ' possible are: ' + JSON.stringify(Object.keys(this.body.eventListeners)));
50883 }
50884 }
50885 /**
50886 * Restore the overridden UI functions to their original state.
50887 *
50888 * @private
50889 */
50890
50891 }, {
50892 key: "_unbindTemporaryUIs",
50893 value: function _unbindTemporaryUIs() {
50894 for (var functionName in this.temporaryUIFunctions) {
50895 if (this.temporaryUIFunctions.hasOwnProperty(functionName)) {
50896 this.body.eventListeners[functionName] = this.temporaryUIFunctions[functionName];
50897 delete this.temporaryUIFunctions[functionName];
50898 }
50899 }
50900
50901 this.temporaryUIFunctions = {};
50902 }
50903 /**
50904 * Unbind the events created by _temporaryBindEvent
50905 * @private
50906 */
50907
50908 }, {
50909 key: "_unbindTemporaryEvents",
50910 value: function _unbindTemporaryEvents() {
50911 for (var i = 0; i < this.temporaryEventFunctions.length; i++) {
50912 var eventName = this.temporaryEventFunctions[i].event;
50913 var boundFunction = this.temporaryEventFunctions[i].boundFunction;
50914 this.body.emitter.off(eventName, boundFunction);
50915 }
50916
50917 this.temporaryEventFunctions = [];
50918 }
50919 /**
50920 * Bind an hammer instance to a DOM element.
50921 *
50922 * @param {Element} domElement
50923 * @param {function} boundFunction
50924 */
50925
50926 }, {
50927 key: "_bindHammerToDiv",
50928 value: function _bindHammerToDiv(domElement, boundFunction) {
50929 var hammer$1 = new hammer(domElement, {});
50930 hammerUtil.onTouch(hammer$1, boundFunction);
50931 this.manipulationHammers.push(hammer$1);
50932 }
50933 /**
50934 * Neatly clean up temporary edges and nodes
50935 * @private
50936 */
50937
50938 }, {
50939 key: "_cleanupTemporaryNodesAndEdges",
50940 value: function _cleanupTemporaryNodesAndEdges() {
50941 // _clean temporary edges
50942 for (var i = 0; i < this.temporaryIds.edges.length; i++) {
50943 this.body.edges[this.temporaryIds.edges[i]].disconnect();
50944 delete this.body.edges[this.temporaryIds.edges[i]];
50945 var indexTempEdge = this.body.edgeIndices.indexOf(this.temporaryIds.edges[i]);
50946
50947 if (indexTempEdge !== -1) {
50948 this.body.edgeIndices.splice(indexTempEdge, 1);
50949 }
50950 } // _clean temporary nodes
50951
50952
50953 for (var _i = 0; _i < this.temporaryIds.nodes.length; _i++) {
50954 delete this.body.nodes[this.temporaryIds.nodes[_i]];
50955 var indexTempNode = this.body.nodeIndices.indexOf(this.temporaryIds.nodes[_i]);
50956
50957 if (indexTempNode !== -1) {
50958 this.body.nodeIndices.splice(indexTempNode, 1);
50959 }
50960 }
50961
50962 this.temporaryIds = {
50963 nodes: [],
50964 edges: []
50965 };
50966 } // ------------------------------------------ EDIT EDGE FUNCTIONS -----------------------------------------//
50967
50968 /**
50969 * the touch is used to get the position of the initial click
50970 * @param {Event} event The event
50971 * @private
50972 */
50973
50974 }, {
50975 key: "_controlNodeTouch",
50976 value: function _controlNodeTouch(event) {
50977 this.selectionHandler.unselectAll();
50978 this.lastTouch = this.body.functions.getPointer(event.center);
50979 this.lastTouch.translation = extend({}, this.body.view.translation); // copy the object
50980 }
50981 /**
50982 * the drag start is used to mark one of the control nodes as selected.
50983 * @param {Event} event The event
50984 * @private
50985 */
50986
50987 }, {
50988 key: "_controlNodeDragStart",
50989 value: function _controlNodeDragStart(event) {
50990 // eslint-disable-line no-unused-vars
50991 var pointer = this.lastTouch;
50992
50993 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer);
50994
50995 var from = this.body.nodes[this.temporaryIds.nodes[0]];
50996 var to = this.body.nodes[this.temporaryIds.nodes[1]];
50997 var edge = this.body.edges[this.edgeBeingEditedId];
50998 this.selectedControlNode = undefined;
50999 var fromSelect = from.isOverlappingWith(pointerObj);
51000 var toSelect = to.isOverlappingWith(pointerObj);
51001
51002 if (fromSelect === true) {
51003 this.selectedControlNode = from;
51004 edge.edgeType.from = from;
51005 } else if (toSelect === true) {
51006 this.selectedControlNode = to;
51007 edge.edgeType.to = to;
51008 } // we use the selection to find the node that is being dragged. We explicitly select it here.
51009
51010
51011 if (this.selectedControlNode !== undefined) {
51012 this.selectionHandler.selectObject(this.selectedControlNode);
51013 }
51014
51015 this.body.emitter.emit('_redraw');
51016 }
51017 /**
51018 * dragging the control nodes or the canvas
51019 * @param {Event} event The event
51020 * @private
51021 */
51022
51023 }, {
51024 key: "_controlNodeDrag",
51025 value: function _controlNodeDrag(event) {
51026 this.body.emitter.emit('disablePhysics');
51027 var pointer = this.body.functions.getPointer(event.center);
51028 var pos = this.canvas.DOMtoCanvas(pointer);
51029
51030 if (this.selectedControlNode !== undefined) {
51031 this.selectedControlNode.x = pos.x;
51032 this.selectedControlNode.y = pos.y;
51033 } else {
51034 this.interactionHandler.onDrag(event);
51035 }
51036
51037 this.body.emitter.emit('_redraw');
51038 }
51039 /**
51040 * connecting or restoring the control nodes.
51041 * @param {Event} event The event
51042 * @private
51043 */
51044
51045 }, {
51046 key: "_controlNodeDragEnd",
51047 value: function _controlNodeDragEnd(event) {
51048 var pointer = this.body.functions.getPointer(event.center);
51049
51050 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer);
51051
51052 var edge = this.body.edges[this.edgeBeingEditedId]; // if the node that was dragged is not a control node, return
51053
51054 if (this.selectedControlNode === undefined) {
51055 return;
51056 } // we use the selection to find the node that is being dragged. We explicitly DEselect the control node here.
51057
51058
51059 this.selectionHandler.unselectAll();
51060
51061 var overlappingNodeIds = this.selectionHandler._getAllNodesOverlappingWith(pointerObj);
51062
51063 var node = undefined;
51064
51065 for (var i = overlappingNodeIds.length - 1; i >= 0; i--) {
51066 if (overlappingNodeIds[i] !== this.selectedControlNode.id) {
51067 node = this.body.nodes[overlappingNodeIds[i]];
51068 break;
51069 }
51070 } // perform the connection
51071
51072
51073 if (node !== undefined && this.selectedControlNode !== undefined) {
51074 if (node.isCluster === true) {
51075 alert(this.options.locales[this.options.locale]['createEdgeError'] || this.options.locales['en']['createEdgeError']);
51076 } else {
51077 var from = this.body.nodes[this.temporaryIds.nodes[0]];
51078
51079 if (this.selectedControlNode.id === from.id) {
51080 this._performEditEdge(node.id, edge.to.id);
51081 } else {
51082 this._performEditEdge(edge.from.id, node.id);
51083 }
51084 }
51085 } else {
51086 edge.updateEdgeType();
51087 this.body.emitter.emit('restorePhysics');
51088 }
51089
51090 this.body.emitter.emit('_redraw');
51091 } // ------------------------------------ END OF EDIT EDGE FUNCTIONS -----------------------------------------//
51092 // ------------------------------------------- ADD EDGE FUNCTIONS -----------------------------------------//
51093
51094 /**
51095 * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
51096 * to walk the user through the process.
51097 *
51098 * @param {Event} event
51099 * @private
51100 */
51101
51102 }, {
51103 key: "_handleConnect",
51104 value: function _handleConnect(event) {
51105 // check to avoid double fireing of this function.
51106 if (new Date().valueOf() - this.touchTime > 100) {
51107 this.lastTouch = this.body.functions.getPointer(event.center);
51108 this.lastTouch.translation = extend({}, this.body.view.translation); // copy the object
51109
51110 var pointer = this.lastTouch;
51111 var node = this.selectionHandler.getNodeAt(pointer);
51112
51113 if (node !== undefined) {
51114 if (node.isCluster === true) {
51115 alert(this.options.locales[this.options.locale]['createEdgeError'] || this.options.locales['en']['createEdgeError']);
51116 } else {
51117 // create a node the temporary line can look at
51118 var targetNode = this._getNewTargetNode(node.x, node.y);
51119
51120 this.body.nodes[targetNode.id] = targetNode;
51121 this.body.nodeIndices.push(targetNode.id); // create a temporary edge
51122
51123 var connectionEdge = this.body.functions.createEdge({
51124 id: 'connectionEdge' + uuid4(),
51125 from: node.id,
51126 to: targetNode.id,
51127 physics: false,
51128 smooth: {
51129 enabled: true,
51130 type: 'continuous',
51131 roundness: 0.5
51132 }
51133 });
51134 this.body.edges[connectionEdge.id] = connectionEdge;
51135 this.body.edgeIndices.push(connectionEdge.id);
51136 this.temporaryIds.nodes.push(targetNode.id);
51137 this.temporaryIds.edges.push(connectionEdge.id);
51138 }
51139 }
51140
51141 this.touchTime = new Date().valueOf();
51142 }
51143 }
51144 /**
51145 *
51146 * @param {Event} event
51147 * @private
51148 */
51149
51150 }, {
51151 key: "_dragControlNode",
51152 value: function _dragControlNode(event) {
51153 var pointer = this.body.functions.getPointer(event.center);
51154
51155 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer); // remember the edge id
51156
51157
51158 var connectFromId = undefined;
51159
51160 if (this.temporaryIds.edges[0] !== undefined) {
51161 connectFromId = this.body.edges[this.temporaryIds.edges[0]].fromId;
51162 } // get the overlapping node but NOT the temporary node;
51163
51164
51165 var overlappingNodeIds = this.selectionHandler._getAllNodesOverlappingWith(pointerObj);
51166
51167 var node = undefined;
51168
51169 for (var i = overlappingNodeIds.length - 1; i >= 0; i--) {
51170 // if the node id is NOT a temporary node, accept the node.
51171 if (this.temporaryIds.nodes.indexOf(overlappingNodeIds[i]) === -1) {
51172 node = this.body.nodes[overlappingNodeIds[i]];
51173 break;
51174 }
51175 }
51176
51177 event.controlEdge = {
51178 from: connectFromId,
51179 to: node ? node.id : undefined
51180 };
51181
51182 this.selectionHandler._generateClickEvent('controlNodeDragging', event, pointer);
51183
51184 if (this.temporaryIds.nodes[0] !== undefined) {
51185 var targetNode = this.body.nodes[this.temporaryIds.nodes[0]]; // there is only one temp node in the add edge mode.
51186
51187 targetNode.x = this.canvas._XconvertDOMtoCanvas(pointer.x);
51188 targetNode.y = this.canvas._YconvertDOMtoCanvas(pointer.y);
51189 this.body.emitter.emit('_redraw');
51190 } else {
51191 this.interactionHandler.onDrag(event);
51192 }
51193 }
51194 /**
51195 * Connect the new edge to the target if one exists, otherwise remove temp line
51196 * @param {Event} event The event
51197 * @private
51198 */
51199
51200 }, {
51201 key: "_finishConnect",
51202 value: function _finishConnect(event) {
51203 var pointer = this.body.functions.getPointer(event.center);
51204
51205 var pointerObj = this.selectionHandler._pointerToPositionObject(pointer); // remember the edge id
51206
51207
51208 var connectFromId = undefined;
51209
51210 if (this.temporaryIds.edges[0] !== undefined) {
51211 connectFromId = this.body.edges[this.temporaryIds.edges[0]].fromId;
51212 } // get the overlapping node but NOT the temporary node;
51213
51214
51215 var overlappingNodeIds = this.selectionHandler._getAllNodesOverlappingWith(pointerObj);
51216
51217 var node = undefined;
51218
51219 for (var i = overlappingNodeIds.length - 1; i >= 0; i--) {
51220 // if the node id is NOT a temporary node, accept the node.
51221 if (this.temporaryIds.nodes.indexOf(overlappingNodeIds[i]) === -1) {
51222 node = this.body.nodes[overlappingNodeIds[i]];
51223 break;
51224 }
51225 } // clean temporary nodes and edges.
51226
51227
51228 this._cleanupTemporaryNodesAndEdges(); // perform the connection
51229
51230
51231 if (node !== undefined) {
51232 if (node.isCluster === true) {
51233 alert(this.options.locales[this.options.locale]['createEdgeError'] || this.options.locales['en']['createEdgeError']);
51234 } else {
51235 if (this.body.nodes[connectFromId] !== undefined && this.body.nodes[node.id] !== undefined) {
51236 this._performAddEdge(connectFromId, node.id);
51237 }
51238 }
51239 }
51240
51241 event.controlEdge = {
51242 from: connectFromId,
51243 to: node ? node.id : undefined
51244 };
51245
51246 this.selectionHandler._generateClickEvent('controlNodeDragEnd', event, pointer); // No need to do _generateclickevent('dragEnd') here, the regular dragEnd event fires.
51247
51248
51249 this.body.emitter.emit('_redraw');
51250 }
51251 /**
51252 *
51253 * @param {Event} event
51254 * @private
51255 */
51256
51257 }, {
51258 key: "_dragStartEdge",
51259 value: function _dragStartEdge(event) {
51260 var pointer = this.lastTouch;
51261
51262 this.selectionHandler._generateClickEvent('dragStart', event, pointer, undefined, true);
51263 } // --------------------------------------- END OF ADD EDGE FUNCTIONS -------------------------------------//
51264 // ------------------------------ Performing all the actual data manipulation ------------------------//
51265
51266 /**
51267 * Adds a node on the specified location
51268 *
51269 * @param {Object} clickData
51270 * @private
51271 */
51272
51273 }, {
51274 key: "_performAddNode",
51275 value: function _performAddNode(clickData) {
51276 var _this4 = this;
51277
51278 var defaultData = {
51279 id: uuid4(),
51280 x: clickData.pointer.canvas.x,
51281 y: clickData.pointer.canvas.y,
51282 label: 'new'
51283 };
51284
51285 if (typeof this.options.addNode === 'function') {
51286 if (this.options.addNode.length === 2) {
51287 this.options.addNode(defaultData, function (finalizedData) {
51288 if (finalizedData !== null && finalizedData !== undefined && _this4.inMode === 'addNode') {
51289 // if for whatever reason the mode has changes (due to dataset change) disregard the callback
51290 _this4.body.data.nodes.getDataSet().add(finalizedData);
51291 }
51292
51293 _this4.showManipulatorToolbar();
51294 });
51295 } else {
51296 this.showManipulatorToolbar();
51297 throw new Error('The function for add does not support two arguments (data,callback)');
51298 }
51299 } else {
51300 this.body.data.nodes.getDataSet().add(defaultData);
51301 this.showManipulatorToolbar();
51302 }
51303 }
51304 /**
51305 * connect two nodes with a new edge.
51306 *
51307 * @param {Node.id} sourceNodeId
51308 * @param {Node.id} targetNodeId
51309 * @private
51310 */
51311
51312 }, {
51313 key: "_performAddEdge",
51314 value: function _performAddEdge(sourceNodeId, targetNodeId) {
51315 var _this5 = this;
51316
51317 var defaultData = {
51318 from: sourceNodeId,
51319 to: targetNodeId
51320 };
51321
51322 if (typeof this.options.addEdge === 'function') {
51323 if (this.options.addEdge.length === 2) {
51324 this.options.addEdge(defaultData, function (finalizedData) {
51325 if (finalizedData !== null && finalizedData !== undefined && _this5.inMode === 'addEdge') {
51326 // if for whatever reason the mode has changes (due to dataset change) disregard the callback
51327 _this5.body.data.edges.getDataSet().add(finalizedData);
51328
51329 _this5.selectionHandler.unselectAll();
51330
51331 _this5.showManipulatorToolbar();
51332 }
51333 });
51334 } else {
51335 throw new Error('The function for connect does not support two arguments (data,callback)');
51336 }
51337 } else {
51338 this.body.data.edges.getDataSet().add(defaultData);
51339 this.selectionHandler.unselectAll();
51340 this.showManipulatorToolbar();
51341 }
51342 }
51343 /**
51344 * connect two nodes with a new edge.
51345 *
51346 * @param {Node.id} sourceNodeId
51347 * @param {Node.id} targetNodeId
51348 * @private
51349 */
51350
51351 }, {
51352 key: "_performEditEdge",
51353 value: function _performEditEdge(sourceNodeId, targetNodeId) {
51354 var _this6 = this;
51355
51356 var defaultData = {
51357 id: this.edgeBeingEditedId,
51358 from: sourceNodeId,
51359 to: targetNodeId,
51360 label: this.body.data.edges._data[this.edgeBeingEditedId].label
51361 };
51362 var eeFunct = this.options.editEdge;
51363
51364 if (_typeof(eeFunct) === 'object') {
51365 eeFunct = eeFunct.editWithoutDrag;
51366 }
51367
51368 if (typeof eeFunct === 'function') {
51369 if (eeFunct.length === 2) {
51370 eeFunct(defaultData, function (finalizedData) {
51371 if (finalizedData === null || finalizedData === undefined || _this6.inMode !== 'editEdge') {
51372 // if for whatever reason the mode has changes (due to dataset change) disregard the callback) {
51373 _this6.body.edges[defaultData.id].updateEdgeType();
51374
51375 _this6.body.emitter.emit('_redraw');
51376
51377 _this6.showManipulatorToolbar();
51378 } else {
51379 _this6.body.data.edges.getDataSet().update(finalizedData);
51380
51381 _this6.selectionHandler.unselectAll();
51382
51383 _this6.showManipulatorToolbar();
51384 }
51385 });
51386 } else {
51387 throw new Error('The function for edit does not support two arguments (data, callback)');
51388 }
51389 } else {
51390 this.body.data.edges.getDataSet().update(defaultData);
51391 this.selectionHandler.unselectAll();
51392 this.showManipulatorToolbar();
51393 }
51394 }
51395 }]);
51396
51397 return ManipulationSystem;
51398 }();
51399
51400 var css$4 = "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\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\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(linear, left top, left bottom, color-stop(0%,#dedede), color-stop(99%,#c8c8c8)); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(top, #dedede 0%,#c8c8c8 99%); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* 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(linear, left top, left bottom, color-stop(0%,#3876c2), color-stop(100%,#385380)); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(top, #3876c2 0%,#385380 100%); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(top, #3876c2 0%,#385380 100%); /* 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(linear, left top, left bottom, color-stop(0%,#9d9d9d), color-stop(99%,#c8c8c8)); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(top, #9d9d9d 0%,#c8c8c8 99%); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(top, #9d9d9d 0%,#c8c8c8 99%); /* 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(linear, left top, left bottom, color-stop(0%,#dedede), color-stop(99%,#c8c8c8)); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(top, #dedede 0%,#c8c8c8 99%); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* 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, .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/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbmZpZ3VyYXRvci5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7SUFDSSxpQkFBaUI7SUFDakIsYUFBYTtJQUNiLFVBQVU7SUFDVixjQUFjO0FBQ2xCOztBQUVBO0lBQ0ksYUFBYTtJQUNiLFdBQVc7QUFDZjs7QUFFQTtFQUNFLFdBQVc7RUFDWCxXQUFXO0VBQ1gsY0FBYztBQUNoQjs7QUFFQTtJQUNJLGFBQWE7SUFDYixXQUFXO0lBQ1gseUJBQXlCO0lBQ3pCLHdCQUF3QjtJQUN4QixpQkFBaUI7SUFDakIsZUFBZTtJQUNmLFNBQVM7SUFDVCxnQkFBZ0I7QUFDcEI7O0FBRUE7SUFDSSxhQUFhO0lBQ2IsV0FBVztJQUNYLFdBQVc7SUFDWCxzQkFBc0I7SUFDdEIsZ0JBQWdCO0lBQ2hCLHlCQUF5QjtJQUN6Qix3QkFBd0I7SUFDeEIsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixTQUFTO0lBQ1QsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixrQkFBa0I7QUFDdEI7O0FBRUE7SUFDSSx5QkFBeUI7SUFDekIsd0JBQXdCO0lBQ3hCLGFBQWE7QUFDakI7O0FBRUE7SUFDSSxhQUFhO0lBQ2IsVUFBVTtJQUNWLFdBQVc7SUFDWCxXQUFXO0lBQ1gsc0JBQXNCO0lBQ3RCLGdCQUFnQjtBQUNwQjs7O0FBR0E7SUFDSSxTQUFTO0lBQ1QseUJBQXlCO0lBQ3pCLGdCQUFnQjtJQUNoQixpQkFBaUI7QUFDckI7QUFDQTtJQUNJLFNBQVM7SUFDVCx5QkFBeUI7SUFDekIsZ0JBQWdCO0lBQ2hCLGlCQUFpQjtBQUNyQjtBQUNBO0lBQ0ksU0FBUztJQUNULHlCQUF5QjtJQUN6QixnQkFBZ0I7SUFDaEIsaUJBQWlCO0FBQ3JCOztBQUVBO0lBQ0ksY0FBYztJQUNkLGlCQUFpQjtBQUNyQjs7QUFFQTtJQUNJLFdBQVc7SUFDWCxXQUFXO0lBQ1gsaUJBQWlCO0FBQ3JCOztBQUVBO0lBQ0ksV0FBVztBQUNmO0FBQ0E7SUFDSSxXQUFXO0FBQ2Y7O0FBRUE7SUFDSSxPQUFPO0lBQ1AsVUFBVTtJQUNWLFdBQVc7SUFDWCx3QkFBd0I7SUFDeEIsaUJBQWlCO0lBQ2pCLFdBQVc7SUFDWCxVQUFVO0lBQ1YsY0FBYztBQUNsQjs7QUFFQTtJQUNJLFNBQVM7QUFDYjs7O0FBR0E7SUFDSSxpQkFBaUI7SUFDakIsUUFBUTtJQUNSLFVBQVU7SUFDVixlQUFlO0lBQ2YsV0FBVztJQUNYLFFBQVE7SUFDUixtQkFBbUI7QUFDdkI7O0FBRUE7SUFDSSxnQ0FBZ0M7SUFDaEMsd0JBQXdCOztJQUV4Qiw4Q0FBOEM7SUFDOUMsdUJBQXVCO0lBQ3ZCLDhCQUE4Qjs7SUFFOUIseUNBQXlDO0lBQ3pDLFlBQVk7SUFDWixXQUFXO0FBQ2Y7QUFDQTtJQUNJLFlBQVk7SUFDWixXQUFXO0lBQ1gsbUJBQW1CLEVBQUUsaUJBQWlCO0lBQ3RDLCtEQUErRCxFQUFFLFdBQVc7SUFDNUUsNEdBQTRHLEVBQUUsb0JBQW9CO0lBQ2xJLGlFQUFpRSxFQUFFLHlCQUF5QjtJQUM1Riw0REFBNEQsRUFBRSxpQkFBaUI7SUFDL0UsNkRBQTZELEVBQUUsVUFBVTtJQUN6RSwrREFBK0QsRUFBRSxRQUFRO0lBQ3pFLG1IQUFtSCxFQUFFLFVBQVU7O0lBRS9ILHlCQUF5QjtJQUN6QixtQ0FBbUM7SUFDbkMsa0JBQWtCO0FBQ3RCO0FBQ0E7SUFDSSx3QkFBd0I7SUFDeEIseUJBQXlCO0lBQ3pCLFlBQVk7SUFDWixXQUFXO0lBQ1gsa0JBQWtCO0lBQ2xCLG1CQUFtQixFQUFFLGlCQUFpQjtJQUN0QyxnRUFBZ0UsRUFBRSxXQUFXO0lBQzdFLDZHQUE2RyxFQUFFLG9CQUFvQjtJQUNuSSxrRUFBa0UsRUFBRSx5QkFBeUI7SUFDN0YsNkRBQTZELEVBQUUsaUJBQWlCO0lBQ2hGLDhEQUE4RCxFQUFFLFVBQVU7SUFDMUUsZ0VBQWdFLEVBQUUsUUFBUTtJQUMxRSxtSEFBbUgsRUFBRSxVQUFVO0lBQy9ILG1DQUFtQztJQUNuQyxnQkFBZ0I7QUFDcEI7QUFDQTtJQUNJLGFBQWE7QUFDakI7QUFDQTtJQUNJLG1CQUFtQixFQUFFLGlCQUFpQjtJQUN0Qyw4REFBOEQsRUFBRSxXQUFXO0lBQzNFLDRHQUE0RyxFQUFFLG9CQUFvQjtJQUNsSSxpRUFBaUUsRUFBRSx5QkFBeUI7SUFDNUYsNERBQTRELEVBQUUsaUJBQWlCO0lBQy9FLDZEQUE2RCxFQUFFLFVBQVU7SUFDekUsK0RBQStELEVBQUUsUUFBUTtJQUN6RSxtSEFBbUgsRUFBRSxVQUFVO0FBQ25JOztBQUVBO0lBQ0ksWUFBWTtJQUNaLFlBQVk7SUFDWixtQkFBbUIsRUFBRSxpQkFBaUI7SUFDdEMsK0RBQStELEVBQUUsV0FBVztJQUM1RSw0R0FBNEcsRUFBRSxvQkFBb0I7SUFDbEksaUVBQWlFLEVBQUUseUJBQXlCO0lBQzVGLDREQUE0RCxFQUFFLGlCQUFpQjtJQUMvRSw2REFBNkQsRUFBRSxVQUFVO0lBQ3pFLCtEQUErRCxFQUFFLFFBQVE7SUFDekUsbUhBQW1ILEVBQUUsVUFBVTs7SUFFL0gseUJBQXlCO0lBQ3pCLG1DQUFtQztJQUNuQyxrQkFBa0I7QUFDdEI7QUFDQTtJQUNJLFlBQVk7SUFDWixZQUFZO0lBQ1osV0FBVzs7SUFFWCxrQkFBa0I7SUFDbEIsb0JBQW9CO0FBQ3hCOztBQUVBLHFDQUFxQztBQUNyQztJQUNJLHdCQUF3QjtJQUN4QixvQkFBb0I7QUFDeEI7O0FBRUE7SUFDSSxZQUFZO0lBQ1osV0FBVzs7SUFFWCxzRkFBc0Y7SUFDdEYsdUJBQXVCOztJQUV2Qix5RUFBeUU7SUFDekUseUJBQXlCO0lBQ3pCLG1CQUFtQjs7SUFFbkIsNEJBQTRCO0lBQzVCLGtCQUFrQjtBQUN0QjtBQUNBO0lBQ0ksZ0JBQWdCO0lBQ2hCLG1CQUFtQjtBQUN2QjtBQUNBO0lBQ0ksZ0JBQWdCO0lBQ2hCLG1CQUFtQjtBQUN2QjtBQUNBO0lBQ0ksWUFBWTtJQUNaLFlBQVk7SUFDWixXQUFXO0lBQ1gsa0JBQWtCO0lBQ2xCLG9CQUFvQjtBQUN4QjtBQUNBO0lBQ0ksZ0JBQWdCO0FBQ3BCO0FBQ0E7SUFDSSxnQkFBZ0I7QUFDcEI7O0FBRUE7SUFDSSxrQkFBa0I7SUFDbEIsa0NBQWtDO0lBQ2xDLHlCQUF5QjtJQUN6QixnQkFBZ0I7SUFDaEIsV0FBVztJQUNYLFdBQVc7SUFDWCxpQkFBaUI7SUFDakIsY0FBYztJQUNkLGNBQWM7SUFDZCxpQkFBaUI7SUFDakIsNENBQTRDO0lBQzVDLHlDQUF5QztJQUN6QyxvQ0FBb0M7QUFDeEM7QUFDQTtJQUNJLFVBQVU7SUFDVixRQUFRO0lBQ1IseUJBQXlCO0lBQ3pCLFlBQVk7SUFDWixTQUFTO0lBQ1QsUUFBUTtJQUNSLGtCQUFrQjtJQUNsQixvQkFBb0I7QUFDeEI7O0FBRUE7SUFDSSxvQ0FBb0M7SUFDcEMseUNBQXlDO0lBQ3pDLGlCQUFpQjtJQUNqQixnQkFBZ0I7QUFDcEI7QUFDQTtJQUNJLG9DQUFvQztJQUNwQywwQkFBMEI7SUFDMUIsa0JBQWtCO0lBQ2xCLGlCQUFpQjtBQUNyQiIsImZpbGUiOiJDb25maWd1cmF0b3IuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiZGl2LnZpcy1jb25maWd1cmF0aW9uIHtcbiAgICBwb3NpdGlvbjpyZWxhdGl2ZTtcbiAgICBkaXNwbGF5OmJsb2NrO1xuICAgIGZsb2F0OmxlZnQ7XG4gICAgZm9udC1zaXplOjEycHg7XG59XG5cbmRpdi52aXMtY29uZmlndXJhdGlvbi13cmFwcGVyIHtcbiAgICBkaXNwbGF5OmJsb2NrO1xuICAgIHdpZHRoOjcwMHB4O1xufVxuXG5kaXYudmlzLWNvbmZpZ3VyYXRpb24td3JhcHBlcjo6YWZ0ZXIge1xuICBjbGVhcjogYm90aDtcbiAgY29udGVudDogXCJcIjtcbiAgZGlzcGxheTogYmxvY2s7XG59XG5cbmRpdi52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLW9wdGlvbi1jb250YWluZXJ7XG4gICAgZGlzcGxheTpibG9jaztcbiAgICB3aWR0aDo0OTVweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuICAgIGJvcmRlcjoycHggc29saWQgI2Y3ZjhmYTtcbiAgICBib3JkZXItcmFkaXVzOjRweDtcbiAgICBtYXJnaW4tdG9wOjIwcHg7XG4gICAgbGVmdDoxMHB4O1xuICAgIHBhZGRpbmctbGVmdDo1cHg7XG59XG5cbmRpdi52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLWJ1dHRvbntcbiAgICBkaXNwbGF5OmJsb2NrO1xuICAgIHdpZHRoOjQ5NXB4O1xuICAgIGhlaWdodDoyNXB4O1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgbGluZS1oZWlnaHQ6MjVweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmOGZhO1xuICAgIGJvcmRlcjoycHggc29saWQgI2NlY2VkMDtcbiAgICBib3JkZXItcmFkaXVzOjRweDtcbiAgICBtYXJnaW4tdG9wOjIwcHg7XG4gICAgbGVmdDoxMHB4O1xuICAgIHBhZGRpbmctbGVmdDo1cHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIG1hcmdpbi1ib3R0b206MzBweDtcbn1cblxuZGl2LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctYnV0dG9uLmhvdmVye1xuICAgIGJhY2tncm91bmQtY29sb3I6ICM0NTg4ZTY7XG4gICAgYm9yZGVyOjJweCBzb2xpZCAjMjE0MzczO1xuICAgIGNvbG9yOiNmZmZmZmY7XG59XG5cbmRpdi52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLWl0ZW17XG4gICAgZGlzcGxheTpibG9jaztcbiAgICBmbG9hdDpsZWZ0O1xuICAgIHdpZHRoOjQ5NXB4O1xuICAgIGhlaWdodDoyNXB4O1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgbGluZS1oZWlnaHQ6MjVweDtcbn1cblxuXG5kaXYudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1pdGVtLnZpcy1jb25maWctczJ7XG4gICAgbGVmdDoxMHB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmN2Y4ZmE7XG4gICAgcGFkZGluZy1sZWZ0OjVweDtcbiAgICBib3JkZXItcmFkaXVzOjNweDtcbn1cbmRpdi52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLWl0ZW0udmlzLWNvbmZpZy1zM3tcbiAgICBsZWZ0OjIwcHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2U0ZTlmMDtcbiAgICBwYWRkaW5nLWxlZnQ6NXB4O1xuICAgIGJvcmRlci1yYWRpdXM6M3B4O1xufVxuZGl2LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctaXRlbS52aXMtY29uZmlnLXM0e1xuICAgIGxlZnQ6MzBweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjY2ZkOGU2O1xuICAgIHBhZGRpbmctbGVmdDo1cHg7XG4gICAgYm9yZGVyLXJhZGl1czozcHg7XG59XG5cbmRpdi52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLWhlYWRlcntcbiAgICBmb250LXNpemU6MThweDtcbiAgICBmb250LXdlaWdodDogYm9sZDtcbn1cblxuZGl2LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctbGFiZWx7XG4gICAgd2lkdGg6MTIwcHg7XG4gICAgaGVpZ2h0OjI1cHg7XG4gICAgbGluZS1oZWlnaHQ6IDI1cHg7XG59XG5cbmRpdi52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLWxhYmVsLnZpcy1jb25maWctczN7XG4gICAgd2lkdGg6MTEwcHg7XG59XG5kaXYudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1sYWJlbC52aXMtY29uZmlnLXM0e1xuICAgIHdpZHRoOjEwMHB4O1xufVxuXG5kaXYudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1jb2xvckJsb2Nre1xuICAgIHRvcDoxcHg7XG4gICAgd2lkdGg6MzBweDtcbiAgICBoZWlnaHQ6MTlweDtcbiAgICBib3JkZXI6MXB4IHNvbGlkICM0NDQ0NDQ7XG4gICAgYm9yZGVyLXJhZGl1czoycHg7XG4gICAgcGFkZGluZzowcHg7XG4gICAgbWFyZ2luOjBweDtcbiAgICBjdXJzb3I6cG9pbnRlcjtcbn1cblxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1jaGVja2JveCB7XG4gICAgbGVmdDotNXB4O1xufVxuXG5cbmlucHV0LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctcmFuZ2VpbnB1dHtcbiAgICBwb3NpdGlvbjpyZWxhdGl2ZTtcbiAgICB0b3A6LTVweDtcbiAgICB3aWR0aDo2MHB4O1xuICAgIC8qaGVpZ2h0OjEzcHg7Ki9cbiAgICBwYWRkaW5nOjFweDtcbiAgICBtYXJnaW46MDtcbiAgICBwb2ludGVyLWV2ZW50czpub25lO1xufVxuXG5pbnB1dC52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLXJhbmdle1xuICAgIC8qcmVtb3ZlcyBkZWZhdWx0IHdlYmtpdCBzdHlsZXMqL1xuICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcblxuICAgIC8qZml4IGZvciBGRiB1bmFibGUgdG8gYXBwbHkgZm9jdXMgc3R5bGUgYnVnICovXG4gICAgYm9yZGVyOiAwcHggc29saWQgd2hpdGU7XG4gICAgYmFja2dyb3VuZC1jb2xvcjpyZ2JhKDAsMCwwLDApO1xuXG4gICAgLypyZXF1aXJlZCBmb3IgcHJvcGVyIHRyYWNrIHNpemluZyBpbiBGRiovXG4gICAgd2lkdGg6IDMwMHB4O1xuICAgIGhlaWdodDoyMHB4O1xufVxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1yYW5nZTo6LXdlYmtpdC1zbGlkZXItcnVubmFibGUtdHJhY2sge1xuICAgIHdpZHRoOiAzMDBweDtcbiAgICBoZWlnaHQ6IDVweDtcbiAgICBiYWNrZ3JvdW5kOiAjZGVkZWRlOyAvKiBPbGQgYnJvd3NlcnMgKi9cbiAgICBiYWNrZ3JvdW5kOiAtbW96LWxpbmVhci1ncmFkaWVudCh0b3AsICAjZGVkZWRlIDAlLCAjYzhjOGM4IDk5JSk7IC8qIEZGMy42KyAqL1xuICAgIGJhY2tncm91bmQ6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgbGVmdCBib3R0b20sIGNvbG9yLXN0b3AoMCUsI2RlZGVkZSksIGNvbG9yLXN0b3AoOTklLCNjOGM4YzgpKTsgLyogQ2hyb21lLFNhZmFyaTQrICovXG4gICAgYmFja2dyb3VuZDogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLCAgI2RlZGVkZSAwJSwjYzhjOGM4IDk5JSk7IC8qIENocm9tZTEwKyxTYWZhcmk1LjErICovXG4gICAgYmFja2dyb3VuZDogLW8tbGluZWFyLWdyYWRpZW50KHRvcCwgI2RlZGVkZSAwJSwgI2M4YzhjOCA5OSUpOyAvKiBPcGVyYSAxMS4xMCsgKi9cbiAgICBiYWNrZ3JvdW5kOiAtbXMtbGluZWFyLWdyYWRpZW50KHRvcCwgICNkZWRlZGUgMCUsI2M4YzhjOCA5OSUpOyAvKiBJRTEwKyAqL1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICAjZGVkZWRlIDAlLCNjOGM4YzggOTklKTsgLyogVzNDICovXG4gICAgZmlsdGVyOiBwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoIHN0YXJ0Q29sb3JzdHI9JyNkZWRlZGUnLCBlbmRDb2xvcnN0cj0nI2M4YzhjOCcsR3JhZGllbnRUeXBlPTAgKTsgLyogSUU2LTkgKi9cblxuICAgIGJvcmRlcjogMXB4IHNvbGlkICM5OTk5OTk7XG4gICAgYm94LXNoYWRvdzogI2FhYWFhYSAwcHggMHB4IDNweCAwcHg7XG4gICAgYm9yZGVyLXJhZGl1czogM3B4O1xufVxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1yYW5nZTo6LXdlYmtpdC1zbGlkZXItdGh1bWIge1xuICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjMTQzMzRiO1xuICAgIGhlaWdodDogMTdweDtcbiAgICB3aWR0aDogMTdweDtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgYmFja2dyb3VuZDogIzM4NzZjMjsgLyogT2xkIGJyb3dzZXJzICovXG4gICAgYmFja2dyb3VuZDogLW1vei1saW5lYXItZ3JhZGllbnQodG9wLCAgIzM4NzZjMiAwJSwgIzM4NTM4MCAxMDAlKTsgLyogRkYzLjYrICovXG4gICAgYmFja2dyb3VuZDogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIGxlZnQgdG9wLCBsZWZ0IGJvdHRvbSwgY29sb3Itc3RvcCgwJSwjMzg3NmMyKSwgY29sb3Itc3RvcCgxMDAlLCMzODUzODApKTsgLyogQ2hyb21lLFNhZmFyaTQrICovXG4gICAgYmFja2dyb3VuZDogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLCAgIzM4NzZjMiAwJSwjMzg1MzgwIDEwMCUpOyAvKiBDaHJvbWUxMCssU2FmYXJpNS4xKyAqL1xuICAgIGJhY2tncm91bmQ6IC1vLWxpbmVhci1ncmFkaWVudCh0b3AsICAjMzg3NmMyIDAlLCMzODUzODAgMTAwJSk7IC8qIE9wZXJhIDExLjEwKyAqL1xuICAgIGJhY2tncm91bmQ6IC1tcy1saW5lYXItZ3JhZGllbnQodG9wLCAgIzM4NzZjMiAwJSwjMzg1MzgwIDEwMCUpOyAvKiBJRTEwKyAqL1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICAjMzg3NmMyIDAlLCMzODUzODAgMTAwJSk7IC8qIFczQyAqL1xuICAgIGZpbHRlcjogcHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KCBzdGFydENvbG9yc3RyPScjMzg3NmMyJywgZW5kQ29sb3JzdHI9JyMzODUzODAnLEdyYWRpZW50VHlwZT0wICk7IC8qIElFNi05ICovXG4gICAgYm94LXNoYWRvdzogIzExMTkyNyAwcHggMHB4IDFweCAwcHg7XG4gICAgbWFyZ2luLXRvcDogLTdweDtcbn1cbmlucHV0LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctcmFuZ2U6Zm9jdXMge1xuICAgIG91dGxpbmU6IG5vbmU7XG59XG5pbnB1dC52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLXJhbmdlOmZvY3VzOjotd2Via2l0LXNsaWRlci1ydW5uYWJsZS10cmFjayB7XG4gICAgYmFja2dyb3VuZDogIzlkOWQ5ZDsgLyogT2xkIGJyb3dzZXJzICovXG4gICAgYmFja2dyb3VuZDogLW1vei1saW5lYXItZ3JhZGllbnQodG9wLCAjOWQ5ZDlkIDAlLCAjYzhjOGM4IDk5JSk7IC8qIEZGMy42KyAqL1xuICAgIGJhY2tncm91bmQ6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgbGVmdCBib3R0b20sIGNvbG9yLXN0b3AoMCUsIzlkOWQ5ZCksIGNvbG9yLXN0b3AoOTklLCNjOGM4YzgpKTsgLyogQ2hyb21lLFNhZmFyaTQrICovXG4gICAgYmFja2dyb3VuZDogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLCAgIzlkOWQ5ZCAwJSwjYzhjOGM4IDk5JSk7IC8qIENocm9tZTEwKyxTYWZhcmk1LjErICovXG4gICAgYmFja2dyb3VuZDogLW8tbGluZWFyLWdyYWRpZW50KHRvcCwgICM5ZDlkOWQgMCUsI2M4YzhjOCA5OSUpOyAvKiBPcGVyYSAxMS4xMCsgKi9cbiAgICBiYWNrZ3JvdW5kOiAtbXMtbGluZWFyLWdyYWRpZW50KHRvcCwgICM5ZDlkOWQgMCUsI2M4YzhjOCA5OSUpOyAvKiBJRTEwKyAqL1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICAjOWQ5ZDlkIDAlLCNjOGM4YzggOTklKTsgLyogVzNDICovXG4gICAgZmlsdGVyOiBwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoIHN0YXJ0Q29sb3JzdHI9JyM5ZDlkOWQnLCBlbmRDb2xvcnN0cj0nI2M4YzhjOCcsR3JhZGllbnRUeXBlPTAgKTsgLyogSUU2LTkgKi9cbn1cblxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1yYW5nZTo6LW1vei1yYW5nZS10cmFjayB7XG4gICAgd2lkdGg6IDMwMHB4O1xuICAgIGhlaWdodDogMTBweDtcbiAgICBiYWNrZ3JvdW5kOiAjZGVkZWRlOyAvKiBPbGQgYnJvd3NlcnMgKi9cbiAgICBiYWNrZ3JvdW5kOiAtbW96LWxpbmVhci1ncmFkaWVudCh0b3AsICAjZGVkZWRlIDAlLCAjYzhjOGM4IDk5JSk7IC8qIEZGMy42KyAqL1xuICAgIGJhY2tncm91bmQ6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgbGVmdCBib3R0b20sIGNvbG9yLXN0b3AoMCUsI2RlZGVkZSksIGNvbG9yLXN0b3AoOTklLCNjOGM4YzgpKTsgLyogQ2hyb21lLFNhZmFyaTQrICovXG4gICAgYmFja2dyb3VuZDogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLCAgI2RlZGVkZSAwJSwjYzhjOGM4IDk5JSk7IC8qIENocm9tZTEwKyxTYWZhcmk1LjErICovXG4gICAgYmFja2dyb3VuZDogLW8tbGluZWFyLWdyYWRpZW50KHRvcCwgI2RlZGVkZSAwJSwgI2M4YzhjOCA5OSUpOyAvKiBPcGVyYSAxMS4xMCsgKi9cbiAgICBiYWNrZ3JvdW5kOiAtbXMtbGluZWFyLWdyYWRpZW50KHRvcCwgICNkZWRlZGUgMCUsI2M4YzhjOCA5OSUpOyAvKiBJRTEwKyAqL1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICAjZGVkZWRlIDAlLCNjOGM4YzggOTklKTsgLyogVzNDICovXG4gICAgZmlsdGVyOiBwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoIHN0YXJ0Q29sb3JzdHI9JyNkZWRlZGUnLCBlbmRDb2xvcnN0cj0nI2M4YzhjOCcsR3JhZGllbnRUeXBlPTAgKTsgLyogSUU2LTkgKi9cblxuICAgIGJvcmRlcjogMXB4IHNvbGlkICM5OTk5OTk7XG4gICAgYm94LXNoYWRvdzogI2FhYWFhYSAwcHggMHB4IDNweCAwcHg7XG4gICAgYm9yZGVyLXJhZGl1czogM3B4O1xufVxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1yYW5nZTo6LW1vei1yYW5nZS10aHVtYiB7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGhlaWdodDogMTZweDtcbiAgICB3aWR0aDogMTZweDtcblxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBiYWNrZ3JvdW5kOiAgIzM4NTM4MDtcbn1cblxuLypoaWRlIHRoZSBvdXRsaW5lIGJlaGluZCB0aGUgYm9yZGVyKi9cbmlucHV0LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctcmFuZ2U6LW1vei1mb2N1c3Jpbmd7XG4gICAgb3V0bGluZTogMXB4IHNvbGlkIHdoaXRlO1xuICAgIG91dGxpbmUtb2Zmc2V0OiAtMXB4O1xufVxuXG5pbnB1dC52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLXJhbmdlOjotbXMtdHJhY2sge1xuICAgIHdpZHRoOiAzMDBweDtcbiAgICBoZWlnaHQ6IDVweDtcblxuICAgIC8qcmVtb3ZlIGJnIGNvbG91ciBmcm9tIHRoZSB0cmFjaywgd2UnbGwgdXNlIG1zLWZpbGwtbG93ZXIgYW5kIG1zLWZpbGwtdXBwZXIgaW5zdGVhZCAqL1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuXG4gICAgLypsZWF2ZSByb29tIGZvciB0aGUgbGFyZ2VyIHRodW1iIHRvIG92ZXJmbG93IHdpdGggYSB0cmFuc3BhcmVudCBib3JkZXIgKi9cbiAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci13aWR0aDogNnB4IDA7XG5cbiAgICAvKnJlbW92ZSBkZWZhdWx0IHRpY2sgbWFya3MqL1xuICAgIGNvbG9yOiB0cmFuc3BhcmVudDtcbn1cbmlucHV0LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctcmFuZ2U6Oi1tcy1maWxsLWxvd2VyIHtcbiAgICBiYWNrZ3JvdW5kOiAjNzc3O1xuICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XG59XG5pbnB1dC52aXMtY29uZmlndXJhdGlvbi52aXMtY29uZmlnLXJhbmdlOjotbXMtZmlsbC11cHBlciB7XG4gICAgYmFja2dyb3VuZDogI2RkZDtcbiAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xufVxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1yYW5nZTo6LW1zLXRodW1iIHtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgaGVpZ2h0OiAxNnB4O1xuICAgIHdpZHRoOiAxNnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBiYWNrZ3JvdW5kOiAgIzM4NTM4MDtcbn1cbmlucHV0LnZpcy1jb25maWd1cmF0aW9uLnZpcy1jb25maWctcmFuZ2U6Zm9jdXM6Oi1tcy1maWxsLWxvd2VyIHtcbiAgICBiYWNrZ3JvdW5kOiAjODg4O1xufVxuaW5wdXQudmlzLWNvbmZpZ3VyYXRpb24udmlzLWNvbmZpZy1yYW5nZTpmb2N1czo6LW1zLWZpbGwtdXBwZXIge1xuICAgIGJhY2tncm91bmQ6ICNjY2M7XG59XG5cbi52aXMtY29uZmlndXJhdGlvbi1wb3B1cCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoNTcsIDc2LCA4OSwgMC44NSk7XG4gICAgYm9yZGVyOiAycHggc29saWQgI2YyZmFmZjtcbiAgICBsaW5lLWhlaWdodDozMHB4O1xuICAgIGhlaWdodDozMHB4O1xuICAgIHdpZHRoOjE1MHB4O1xuICAgIHRleHQtYWxpZ246Y2VudGVyO1xuICAgIGNvbG9yOiAjZmZmZmZmO1xuICAgIGZvbnQtc2l6ZToxNHB4O1xuICAgIGJvcmRlci1yYWRpdXM6NHB4O1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbjogb3BhY2l0eSAwLjNzIGVhc2UtaW4tb3V0O1xuICAgIC1tb3otdHJhbnNpdGlvbjogb3BhY2l0eSAwLjNzIGVhc2UtaW4tb3V0O1xuICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMC4zcyBlYXNlLWluLW91dDtcbn1cbi52aXMtY29uZmlndXJhdGlvbi1wb3B1cDphZnRlciwgLnZpcy1jb25maWd1cmF0aW9uLXBvcHVwOmJlZm9yZSB7XG4gICAgbGVmdDogMTAwJTtcbiAgICB0b3A6IDUwJTtcbiAgICBib3JkZXI6IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIGNvbnRlbnQ6IFwiIFwiO1xuICAgIGhlaWdodDogMDtcbiAgICB3aWR0aDogMDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi52aXMtY29uZmlndXJhdGlvbi1wb3B1cDphZnRlciB7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2JhKDEzNiwgMTgzLCAyMTMsIDApO1xuICAgIGJvcmRlci1sZWZ0LWNvbG9yOiByZ2JhKDU3LCA3NiwgODksIDAuODUpO1xuICAgIGJvcmRlci13aWR0aDogOHB4O1xuICAgIG1hcmdpbi10b3A6IC04cHg7XG59XG4udmlzLWNvbmZpZ3VyYXRpb24tcG9wdXA6YmVmb3JlIHtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMTk0LCAyMjUsIDI0NSwgMCk7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6ICNmMmZhZmY7XG4gICAgYm9yZGVyLXdpZHRoOiAxMnB4O1xuICAgIG1hcmdpbi10b3A6IC0xMnB4O1xufSJdfQ== */";
51401 styleInject(css$4);
51402
51403 var css$5 = "\ndiv.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\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(top, #4c4c4c 0%, #595959 12%, #666666 25%, #474747 39%, #2c2c2c 50%, #000000 51%, #111111 60%, #2b2b2b 76%, #1c1c1c 91%, #131313 100%); /* FF3.6+ */\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(12%,#595959), color-stop(25%,#666666), color-stop(39%,#474747), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(60%,#111111), color-stop(76%,#2b2b2b), color-stop(91%,#1c1c1c), color-stop(100%,#131313)); /* Chrome,Safari4+ */\n background: -webkit-linear-gradient(top, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* Chrome10+,Safari5.1+ */\n background: -o-linear-gradient(top, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* Opera 11.10+ */\n background: -ms-linear-gradient(top, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* IE10+ */\n background: linear-gradient(to bottom, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%); /* W3C */\n filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */\n}\n\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}\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\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/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbG9yUGlja2VyLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7RUFDRSxpQkFBaUI7RUFDakIsUUFBUTtFQUNSLFVBQVU7RUFDVixpQkFBaUI7RUFDakIsZ0JBQWdCO0VBQ2hCLFdBQVc7RUFDWCxZQUFZO0VBQ1osVUFBVTtFQUNWLGFBQWE7RUFDYixrQkFBa0I7RUFDbEIsd0JBQXdCO0VBQ3hCLGFBQWE7RUFDYiw0Q0FBNEM7QUFDOUM7O0FBRUE7RUFDRSxrQkFBa0I7RUFDbEIsU0FBUztFQUNULFFBQVE7QUFDVjs7QUFFQTs7RUFFRSxXQUFXO0VBQ1gsUUFBUTtFQUNSLHlCQUF5QjtFQUN6QixZQUFZO0VBQ1osU0FBUztFQUNULFFBQVE7RUFDUixrQkFBa0I7RUFDbEIsb0JBQW9CO0FBQ3RCOztBQUVBO0VBQ0Usb0NBQW9DO0VBQ3BDLDJCQUEyQjtFQUMzQixrQkFBa0I7RUFDbEIsaUJBQWlCO0FBQ25COztBQUVBO0VBQ0UsaUJBQWlCO0VBQ2pCLFlBQVk7RUFDWixhQUFhO0VBQ2IsZUFBZTtBQUNqQjs7OztBQUlBO0VBQ0Usa0JBQWtCO0VBQ2xCLFNBQVM7QUFDWDs7QUFFQTtFQUNFLGlCQUFpQjtFQUNqQixTQUFTO0FBQ1g7O0FBRUE7RUFDRSxpQkFBaUI7RUFDakIsU0FBUztFQUNULFVBQVU7RUFDVixVQUFVO0VBQ1YsV0FBVztFQUNYLGtCQUFrQjtFQUNsQix3QkFBd0I7RUFDeEIsbUJBQW1CLEVBQUUsaUJBQWlCO0VBQ3RDLHdLQUF3SyxFQUFFLFdBQVc7RUFDckwscVRBQXFULEVBQUUsb0JBQW9CO0VBQzNVLGtLQUFrSyxFQUFFLHlCQUF5QjtFQUM3TCw2SkFBNkosRUFBRSxpQkFBaUI7RUFDaEwsOEpBQThKLEVBQUUsVUFBVTtFQUMxSyxnS0FBZ0ssRUFBRSxRQUFRO0VBQzFLLG1IQUFtSCxFQUFFLFVBQVU7QUFDakk7Ozs7QUFJQTtFQUNFLGlCQUFpQjtFQUNqQixXQUFXO0VBQ1gsV0FBVztFQUNYLGdDQUFnQztFQUNoQyxpQkFBaUI7RUFDakIsU0FBUztFQUNULFVBQVU7RUFDVixnQkFBZ0I7RUFDaEIsaUJBQWlCO0VBQ2pCLGNBQWM7RUFDZCxxQkFBcUI7RUFDckIscUJBQXFCO0VBQ3JCLGdCQUFnQjs7QUFFbEI7O0FBRUE7RUFDRSxpQkFBaUI7RUFDakIsV0FBVztFQUNYLFdBQVc7RUFDWCxnQ0FBZ0M7RUFDaEMsaUJBQWlCO0VBQ2pCLFNBQVM7RUFDVCxTQUFTO0VBQ1QsZUFBZTtFQUNmLGdCQUFnQjtFQUNoQixjQUFjO0VBQ2QscUJBQXFCO0VBQ3JCLHFCQUFxQjtFQUNyQixnQkFBZ0I7QUFDbEI7O0FBRUE7RUFDRSxpQkFBaUI7RUFDakIsV0FBVztFQUNYLFNBQVM7QUFDWDs7QUFFQTtFQUNFLFNBQVM7QUFDWDs7QUFFQTtFQUNFLFNBQVM7QUFDWDs7QUFFQTtFQUNFLGlCQUFpQjtFQUNqQixVQUFVO0VBQ1YsV0FBVztFQUNYLGtCQUFrQjtFQUNsQixzQkFBc0I7RUFDdEIsaUJBQWlCO0VBQ2pCLGlCQUFpQjtFQUNqQixTQUFTO0VBQ1Qsd0JBQXdCO0VBQ3hCLHlCQUF5QjtFQUN6QixjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsNEJBQTRCO0VBQzVCLDZCQUE2QjtFQUM3QixRQUFRO0FBQ1Y7QUFDQTtFQUNFLDRCQUE0QjtFQUM1Qiw2QkFBNkI7RUFDN0IsU0FBUztBQUNYO0FBQ0E7RUFDRSw0QkFBNEI7RUFDNUIsNkJBQTZCO0VBQzdCLFVBQVU7QUFDWjtBQUNBO0VBQ0UsNEJBQTRCO0VBQzVCLDZCQUE2QjtFQUM3QixVQUFVO0FBQ1o7OztBQUdBO0VBQ0UsWUFBWTtFQUNaLFdBQVc7QUFDYjs7QUFFQTs7Ozs7Ozs7RUFRRSIsImZpbGUiOiJDb2xvclBpY2tlci5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJcbmRpdi52aXMtY29sb3ItcGlja2VyIHtcbiAgcG9zaXRpb246YWJzb2x1dGU7XG4gIHRvcDogMHB4O1xuICBsZWZ0OiAzMHB4O1xuICBtYXJnaW4tdG9wOi0xNDBweDtcbiAgbWFyZ2luLWxlZnQ6MzBweDtcbiAgd2lkdGg6MzEwcHg7XG4gIGhlaWdodDo0NDRweDtcbiAgei1pbmRleDogMTtcbiAgcGFkZGluZzogMTBweDtcbiAgYm9yZGVyLXJhZGl1czoxNXB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmY7XG4gIGRpc3BsYXk6IG5vbmU7XG4gIGJveC1zaGFkb3c6IHJnYmEoMCwwLDAsMC41KSAwcHggMHB4IDEwcHggMHB4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLWFycm93IHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6MTQ3cHg7XG4gIGxlZnQ6NXB4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLWFycm93OjphZnRlcixcbmRpdi52aXMtY29sb3ItcGlja2VyIGRpdi52aXMtYXJyb3c6OmJlZm9yZSB7XG4gIHJpZ2h0OiAxMDAlO1xuICB0b3A6IDUwJTtcbiAgYm9yZGVyOiBzb2xpZCB0cmFuc3BhcmVudDtcbiAgY29udGVudDogXCIgXCI7XG4gIGhlaWdodDogMDtcbiAgd2lkdGg6IDA7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbmRpdi52aXMtY29sb3ItcGlja2VyIGRpdi52aXMtYXJyb3c6YWZ0ZXIge1xuICBib3JkZXItY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMCk7XG4gIGJvcmRlci1yaWdodC1jb2xvcjogI2ZmZmZmZjtcbiAgYm9yZGVyLXdpZHRoOiAzMHB4O1xuICBtYXJnaW4tdG9wOiAtMzBweDtcbn1cblxuZGl2LnZpcy1jb2xvci1waWNrZXIgZGl2LnZpcy1jb2xvciB7XG4gIHBvc2l0aW9uOmFic29sdXRlO1xuICB3aWR0aDogMjg5cHg7XG4gIGhlaWdodDogMjg5cHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuXG5cbmRpdi52aXMtY29sb3ItcGlja2VyIGRpdi52aXMtYnJpZ2h0bmVzcyB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOjMxM3B4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLW9wYWNpdHkge1xuICBwb3NpdGlvbjphYnNvbHV0ZTtcbiAgdG9wOjM1MHB4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLXNlbGVjdG9yIHtcbiAgcG9zaXRpb246YWJzb2x1dGU7XG4gIHRvcDoxMzdweDtcbiAgbGVmdDoxMzdweDtcbiAgd2lkdGg6MTVweDtcbiAgaGVpZ2h0OjE1cHg7XG4gIGJvcmRlci1yYWRpdXM6MTVweDtcbiAgYm9yZGVyOjFweCBzb2xpZCAjZmZmZmZmO1xuICBiYWNrZ3JvdW5kOiAjNGM0YzRjOyAvKiBPbGQgYnJvd3NlcnMgKi9cbiAgYmFja2dyb3VuZDogLW1vei1saW5lYXItZ3JhZGllbnQodG9wLCAgIzRjNGM0YyAwJSwgIzU5NTk1OSAxMiUsICM2NjY2NjYgMjUlLCAjNDc0NzQ3IDM5JSwgIzJjMmMyYyA1MCUsICMwMDAwMDAgNTElLCAjMTExMTExIDYwJSwgIzJiMmIyYiA3NiUsICMxYzFjMWMgOTElLCAjMTMxMzEzIDEwMCUpOyAvKiBGRjMuNisgKi9cbiAgYmFja2dyb3VuZDogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIGxlZnQgdG9wLCBsZWZ0IGJvdHRvbSwgY29sb3Itc3RvcCgwJSwjNGM0YzRjKSwgY29sb3Itc3RvcCgxMiUsIzU5NTk1OSksIGNvbG9yLXN0b3AoMjUlLCM2NjY2NjYpLCBjb2xvci1zdG9wKDM5JSwjNDc0NzQ3KSwgY29sb3Itc3RvcCg1MCUsIzJjMmMyYyksIGNvbG9yLXN0b3AoNTElLCMwMDAwMDApLCBjb2xvci1zdG9wKDYwJSwjMTExMTExKSwgY29sb3Itc3RvcCg3NiUsIzJiMmIyYiksIGNvbG9yLXN0b3AoOTElLCMxYzFjMWMpLCBjb2xvci1zdG9wKDEwMCUsIzEzMTMxMykpOyAvKiBDaHJvbWUsU2FmYXJpNCsgKi9cbiAgYmFja2dyb3VuZDogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQodG9wLCAgIzRjNGM0YyAwJSwjNTk1OTU5IDEyJSwjNjY2NjY2IDI1JSwjNDc0NzQ3IDM5JSwjMmMyYzJjIDUwJSwjMDAwMDAwIDUxJSwjMTExMTExIDYwJSwjMmIyYjJiIDc2JSwjMWMxYzFjIDkxJSwjMTMxMzEzIDEwMCUpOyAvKiBDaHJvbWUxMCssU2FmYXJpNS4xKyAqL1xuICBiYWNrZ3JvdW5kOiAtby1saW5lYXItZ3JhZGllbnQodG9wLCAgIzRjNGM0YyAwJSwjNTk1OTU5IDEyJSwjNjY2NjY2IDI1JSwjNDc0NzQ3IDM5JSwjMmMyYzJjIDUwJSwjMDAwMDAwIDUxJSwjMTExMTExIDYwJSwjMmIyYjJiIDc2JSwjMWMxYzFjIDkxJSwjMTMxMzEzIDEwMCUpOyAvKiBPcGVyYSAxMS4xMCsgKi9cbiAgYmFja2dyb3VuZDogLW1zLWxpbmVhci1ncmFkaWVudCh0b3AsICAjNGM0YzRjIDAlLCM1OTU5NTkgMTIlLCM2NjY2NjYgMjUlLCM0NzQ3NDcgMzklLCMyYzJjMmMgNTAlLCMwMDAwMDAgNTElLCMxMTExMTEgNjAlLCMyYjJiMmIgNzYlLCMxYzFjMWMgOTElLCMxMzEzMTMgMTAwJSk7IC8qIElFMTArICovXG4gIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byBib3R0b20sICAjNGM0YzRjIDAlLCM1OTU5NTkgMTIlLCM2NjY2NjYgMjUlLCM0NzQ3NDcgMzklLCMyYzJjMmMgNTAlLCMwMDAwMDAgNTElLCMxMTExMTEgNjAlLCMyYjJiMmIgNzYlLCMxYzFjMWMgOTElLCMxMzEzMTMgMTAwJSk7IC8qIFczQyAqL1xuICBmaWx0ZXI6IHByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudCggc3RhcnRDb2xvcnN0cj0nIzRjNGM0YycsIGVuZENvbG9yc3RyPScjMTMxMzEzJyxHcmFkaWVudFR5cGU9MCApOyAvKiBJRTYtOSAqL1xufVxuXG5cblxuZGl2LnZpcy1jb2xvci1waWNrZXIgZGl2LnZpcy1uZXctY29sb3Ige1xuICBwb3NpdGlvbjphYnNvbHV0ZTtcbiAgd2lkdGg6MTQwcHg7XG4gIGhlaWdodDoyMHB4O1xuICBib3JkZXI6MXB4IHNvbGlkIHJnYmEoMCwwLDAsMC4xKTtcbiAgYm9yZGVyLXJhZGl1czo1cHg7XG4gIHRvcDozODBweDtcbiAgbGVmdDoxNTlweDtcbiAgdGV4dC1hbGlnbjpyaWdodDtcbiAgcGFkZGluZy1yaWdodDoycHg7XG4gIGZvbnQtc2l6ZToxMHB4O1xuICBjb2xvcjpyZ2JhKDAsMCwwLDAuNCk7XG4gIHZlcnRpY2FsLWFsaWduOm1pZGRsZTtcbiAgbGluZS1oZWlnaHQ6MjBweDtcblxufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLWluaXRpYWwtY29sb3Ige1xuICBwb3NpdGlvbjphYnNvbHV0ZTtcbiAgd2lkdGg6MTQwcHg7XG4gIGhlaWdodDoyMHB4O1xuICBib3JkZXI6MXB4IHNvbGlkIHJnYmEoMCwwLDAsMC4xKTtcbiAgYm9yZGVyLXJhZGl1czo1cHg7XG4gIHRvcDozODBweDtcbiAgbGVmdDoxMHB4O1xuICB0ZXh0LWFsaWduOmxlZnQ7XG4gIHBhZGRpbmctbGVmdDoycHg7XG4gIGZvbnQtc2l6ZToxMHB4O1xuICBjb2xvcjpyZ2JhKDAsMCwwLDAuNCk7XG4gIHZlcnRpY2FsLWFsaWduOm1pZGRsZTtcbiAgbGluZS1oZWlnaHQ6MjBweDtcbn1cblxuZGl2LnZpcy1jb2xvci1waWNrZXIgZGl2LnZpcy1sYWJlbCB7XG4gIHBvc2l0aW9uOmFic29sdXRlO1xuICB3aWR0aDozMDBweDtcbiAgbGVmdDoxMHB4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLWxhYmVsLnZpcy1icmlnaHRuZXNzIHtcbiAgdG9wOjMwMHB4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLWxhYmVsLnZpcy1vcGFjaXR5IHtcbiAgdG9wOjMzOHB4O1xufVxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBkaXYudmlzLWJ1dHRvbiB7XG4gIHBvc2l0aW9uOmFic29sdXRlO1xuICB3aWR0aDo2OHB4O1xuICBoZWlnaHQ6MjVweDtcbiAgYm9yZGVyLXJhZGl1czoxMHB4O1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICB0ZXh0LWFsaWduOmNlbnRlcjtcbiAgbGluZS1oZWlnaHQ6IDI1cHg7XG4gIHRvcDo0MTBweDtcbiAgYm9yZGVyOjJweCBzb2xpZCAjZDlkOWQ5O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3O1xuICBjdXJzb3I6cG9pbnRlcjtcbn1cblxuZGl2LnZpcy1jb2xvci1waWNrZXIgZGl2LnZpcy1idXR0b24udmlzLWNhbmNlbCB7XG4gIC8qYm9yZGVyOjJweCBzb2xpZCAjZmY0ZTMzOyovXG4gIC8qYmFja2dyb3VuZC1jb2xvcjogI2ZmNzc2MTsqL1xuICBsZWZ0OjVweDtcbn1cbmRpdi52aXMtY29sb3ItcGlja2VyIGRpdi52aXMtYnV0dG9uLnZpcy1sb2FkIHtcbiAgLypib3JkZXI6MnB4IHNvbGlkICNhMTUzZTY7Ki9cbiAgLypiYWNrZ3JvdW5kLWNvbG9yOiAjY2I4ZGZmOyovXG4gIGxlZnQ6ODJweDtcbn1cbmRpdi52aXMtY29sb3ItcGlja2VyIGRpdi52aXMtYnV0dG9uLnZpcy1hcHBseSB7XG4gIC8qYm9yZGVyOjJweCBzb2xpZCAjNDU4OGU2OyovXG4gIC8qYmFja2dyb3VuZC1jb2xvcjogIzgyYjZmZjsqL1xuICBsZWZ0OjE1OXB4O1xufVxuZGl2LnZpcy1jb2xvci1waWNrZXIgZGl2LnZpcy1idXR0b24udmlzLXNhdmUge1xuICAvKmJvcmRlcjoycHggc29saWQgIzQ1ZTY1NTsqL1xuICAvKmJhY2tncm91bmQtY29sb3I6ICM2ZGZmN2M7Ki9cbiAgbGVmdDoyMzZweDtcbn1cblxuXG5kaXYudmlzLWNvbG9yLXBpY2tlciBpbnB1dC52aXMtcmFuZ2Uge1xuICB3aWR0aDogMjkwcHg7XG4gIGhlaWdodDoyMHB4O1xufVxuXG4vKiBUT0RPOiBpcyB0aGlzIHJlZHVuZGFudD9cbmRpdi52aXMtY29sb3ItcGlja2VyIGlucHV0LnZpcy1yYW5nZS1icmlnaHRuZXNzIHtcbiAgd2lkdGg6IDI4OXB4ICFpbXBvcnRhbnQ7XG59XG5cblxuZGl2LnZpcy1jb2xvci1waWNrZXIgaW5wdXQudmlzLXNhdHVyYXRpb24tcmFuZ2Uge1xuICB3aWR0aDogMjg5cHggIWltcG9ydGFudDtcbn0qLyJdfQ== */";
51404 styleInject(css$5);
51405
51406 var htmlColors = {
51407 black: '#000000',
51408 navy: '#000080',
51409 darkblue: '#00008B',
51410 mediumblue: '#0000CD',
51411 blue: '#0000FF',
51412 darkgreen: '#006400',
51413 green: '#008000',
51414 teal: '#008080',
51415 darkcyan: '#008B8B',
51416 deepskyblue: '#00BFFF',
51417 darkturquoise: '#00CED1',
51418 mediumspringgreen: '#00FA9A',
51419 lime: '#00FF00',
51420 springgreen: '#00FF7F',
51421 aqua: '#00FFFF',
51422 cyan: '#00FFFF',
51423 midnightblue: '#191970',
51424 dodgerblue: '#1E90FF',
51425 lightseagreen: '#20B2AA',
51426 forestgreen: '#228B22',
51427 seagreen: '#2E8B57',
51428 darkslategray: '#2F4F4F',
51429 limegreen: '#32CD32',
51430 mediumseagreen: '#3CB371',
51431 turquoise: '#40E0D0',
51432 royalblue: '#4169E1',
51433 steelblue: '#4682B4',
51434 darkslateblue: '#483D8B',
51435 mediumturquoise: '#48D1CC',
51436 indigo: '#4B0082',
51437 darkolivegreen: '#556B2F',
51438 cadetblue: '#5F9EA0',
51439 cornflowerblue: '#6495ED',
51440 mediumaquamarine: '#66CDAA',
51441 dimgray: '#696969',
51442 slateblue: '#6A5ACD',
51443 olivedrab: '#6B8E23',
51444 slategray: '#708090',
51445 lightslategray: '#778899',
51446 mediumslateblue: '#7B68EE',
51447 lawngreen: '#7CFC00',
51448 chartreuse: '#7FFF00',
51449 aquamarine: '#7FFFD4',
51450 maroon: '#800000',
51451 purple: '#800080',
51452 olive: '#808000',
51453 gray: '#808080',
51454 skyblue: '#87CEEB',
51455 lightskyblue: '#87CEFA',
51456 blueviolet: '#8A2BE2',
51457 darkred: '#8B0000',
51458 darkmagenta: '#8B008B',
51459 saddlebrown: '#8B4513',
51460 darkseagreen: '#8FBC8F',
51461 lightgreen: '#90EE90',
51462 mediumpurple: '#9370D8',
51463 darkviolet: '#9400D3',
51464 palegreen: '#98FB98',
51465 darkorchid: '#9932CC',
51466 yellowgreen: '#9ACD32',
51467 sienna: '#A0522D',
51468 brown: '#A52A2A',
51469 darkgray: '#A9A9A9',
51470 lightblue: '#ADD8E6',
51471 greenyellow: '#ADFF2F',
51472 paleturquoise: '#AFEEEE',
51473 lightsteelblue: '#B0C4DE',
51474 powderblue: '#B0E0E6',
51475 firebrick: '#B22222',
51476 darkgoldenrod: '#B8860B',
51477 mediumorchid: '#BA55D3',
51478 rosybrown: '#BC8F8F',
51479 darkkhaki: '#BDB76B',
51480 silver: '#C0C0C0',
51481 mediumvioletred: '#C71585',
51482 indianred: '#CD5C5C',
51483 peru: '#CD853F',
51484 chocolate: '#D2691E',
51485 tan: '#D2B48C',
51486 lightgrey: '#D3D3D3',
51487 palevioletred: '#D87093',
51488 thistle: '#D8BFD8',
51489 orchid: '#DA70D6',
51490 goldenrod: '#DAA520',
51491 crimson: '#DC143C',
51492 gainsboro: '#DCDCDC',
51493 plum: '#DDA0DD',
51494 burlywood: '#DEB887',
51495 lightcyan: '#E0FFFF',
51496 lavender: '#E6E6FA',
51497 darksalmon: '#E9967A',
51498 violet: '#EE82EE',
51499 palegoldenrod: '#EEE8AA',
51500 lightcoral: '#F08080',
51501 khaki: '#F0E68C',
51502 aliceblue: '#F0F8FF',
51503 honeydew: '#F0FFF0',
51504 azure: '#F0FFFF',
51505 sandybrown: '#F4A460',
51506 wheat: '#F5DEB3',
51507 beige: '#F5F5DC',
51508 whitesmoke: '#F5F5F5',
51509 mintcream: '#F5FFFA',
51510 ghostwhite: '#F8F8FF',
51511 salmon: '#FA8072',
51512 antiquewhite: '#FAEBD7',
51513 linen: '#FAF0E6',
51514 lightgoldenrodyellow: '#FAFAD2',
51515 oldlace: '#FDF5E6',
51516 red: '#FF0000',
51517 fuchsia: '#FF00FF',
51518 magenta: '#FF00FF',
51519 deeppink: '#FF1493',
51520 orangered: '#FF4500',
51521 tomato: '#FF6347',
51522 hotpink: '#FF69B4',
51523 coral: '#FF7F50',
51524 darkorange: '#FF8C00',
51525 lightsalmon: '#FFA07A',
51526 orange: '#FFA500',
51527 lightpink: '#FFB6C1',
51528 pink: '#FFC0CB',
51529 gold: '#FFD700',
51530 peachpuff: '#FFDAB9',
51531 navajowhite: '#FFDEAD',
51532 moccasin: '#FFE4B5',
51533 bisque: '#FFE4C4',
51534 mistyrose: '#FFE4E1',
51535 blanchedalmond: '#FFEBCD',
51536 papayawhip: '#FFEFD5',
51537 lavenderblush: '#FFF0F5',
51538 seashell: '#FFF5EE',
51539 cornsilk: '#FFF8DC',
51540 lemonchiffon: '#FFFACD',
51541 floralwhite: '#FFFAF0',
51542 snow: '#FFFAFA',
51543 yellow: '#FFFF00',
51544 lightyellow: '#FFFFE0',
51545 ivory: '#FFFFF0',
51546 white: '#FFFFFF'
51547 };
51548 /**
51549 * @param {number} [pixelRatio=1]
51550 */
51551
51552 var ColorPicker =
51553 /*#__PURE__*/
51554 function () {
51555 /**
51556 * @param {number} [pixelRatio=1]
51557 */
51558 function ColorPicker() {
51559 var pixelRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
51560
51561 _classCallCheck(this, ColorPicker);
51562
51563 this.pixelRatio = pixelRatio;
51564 this.generated = false;
51565 this.centerCoordinates = {
51566 x: 289 / 2,
51567 y: 289 / 2
51568 };
51569 this.r = 289 * 0.49;
51570 this.color = {
51571 r: 255,
51572 g: 255,
51573 b: 255,
51574 a: 1.0
51575 };
51576 this.hueCircle = undefined;
51577 this.initialColor = {
51578 r: 255,
51579 g: 255,
51580 b: 255,
51581 a: 1.0
51582 };
51583 this.previousColor = undefined;
51584 this.applied = false; // bound by
51585
51586 this.updateCallback = function () {};
51587
51588 this.closeCallback = function () {}; // create all DOM elements
51589
51590
51591 this._create();
51592 }
51593 /**
51594 * this inserts the colorPicker into a div from the DOM
51595 * @param {Element} container
51596 */
51597
51598
51599 _createClass(ColorPicker, [{
51600 key: "insertTo",
51601 value: function insertTo(container) {
51602 if (this.hammer !== undefined) {
51603 this.hammer.destroy();
51604 this.hammer = undefined;
51605 }
51606
51607 this.container = container;
51608 this.container.appendChild(this.frame);
51609
51610 this._bindHammer();
51611
51612 this._setSize();
51613 }
51614 /**
51615 * the callback is executed on apply and save. Bind it to the application
51616 * @param {function} callback
51617 */
51618
51619 }, {
51620 key: "setUpdateCallback",
51621 value: function setUpdateCallback(callback) {
51622 if (typeof callback === 'function') {
51623 this.updateCallback = callback;
51624 } else {
51625 throw new Error("Function attempted to set as colorPicker update callback is not a function.");
51626 }
51627 }
51628 /**
51629 * the callback is executed on apply and save. Bind it to the application
51630 * @param {function} callback
51631 */
51632
51633 }, {
51634 key: "setCloseCallback",
51635 value: function setCloseCallback(callback) {
51636 if (typeof callback === 'function') {
51637 this.closeCallback = callback;
51638 } else {
51639 throw new Error("Function attempted to set as colorPicker closing callback is not a function.");
51640 }
51641 }
51642 /**
51643 *
51644 * @param {string} color
51645 * @returns {String}
51646 * @private
51647 */
51648
51649 }, {
51650 key: "_isColorString",
51651 value: function _isColorString(color) {
51652 if (typeof color === 'string') {
51653 return htmlColors[color];
51654 }
51655 }
51656 /**
51657 * Set the color of the colorPicker
51658 * Supported formats:
51659 * 'red' --> HTML color string
51660 * '#ffffff' --> hex string
51661 * 'rgb(255,255,255)' --> rgb string
51662 * 'rgba(255,255,255,1.0)' --> rgba string
51663 * {r:255,g:255,b:255} --> rgb object
51664 * {r:255,g:255,b:255,a:1.0} --> rgba object
51665 * @param {string|Object} color
51666 * @param {boolean} [setInitial=true]
51667 */
51668
51669 }, {
51670 key: "setColor",
51671 value: function setColor(color) {
51672 var setInitial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
51673
51674 if (color === 'none') {
51675 return;
51676 }
51677
51678 var rgba; // if a html color shorthand is used, convert to hex
51679
51680 var htmlColor = this._isColorString(color);
51681
51682 if (htmlColor !== undefined) {
51683 color = htmlColor;
51684 } // check format
51685
51686
51687 if (isString(color) === true) {
51688 if (isValidRGB(color) === true) {
51689 var rgbaArray = color.substr(4).substr(0, color.length - 5).split(',');
51690 rgba = {
51691 r: rgbaArray[0],
51692 g: rgbaArray[1],
51693 b: rgbaArray[2],
51694 a: 1.0
51695 };
51696 } else if (isValidRGBA(color) === true) {
51697 var _rgbaArray = color.substr(5).substr(0, color.length - 6).split(',');
51698
51699 rgba = {
51700 r: _rgbaArray[0],
51701 g: _rgbaArray[1],
51702 b: _rgbaArray[2],
51703 a: _rgbaArray[3]
51704 };
51705 } else if (isValidHex(color) === true) {
51706 var rgbObj = hexToRGB(color);
51707 rgba = {
51708 r: rgbObj.r,
51709 g: rgbObj.g,
51710 b: rgbObj.b,
51711 a: 1.0
51712 };
51713 }
51714 } else {
51715 if (color instanceof Object) {
51716 if (color.r !== undefined && color.g !== undefined && color.b !== undefined) {
51717 var alpha = color.a !== undefined ? color.a : '1.0';
51718 rgba = {
51719 r: color.r,
51720 g: color.g,
51721 b: color.b,
51722 a: alpha
51723 };
51724 }
51725 }
51726 } // set color
51727
51728
51729 if (rgba === undefined) {
51730 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: " + JSON.stringify(color));
51731 } else {
51732 this._setColor(rgba, setInitial);
51733 }
51734 }
51735 /**
51736 * this shows the color picker.
51737 * The hue circle is constructed once and stored.
51738 */
51739
51740 }, {
51741 key: "show",
51742 value: function show() {
51743 if (this.closeCallback !== undefined) {
51744 this.closeCallback();
51745 this.closeCallback = undefined;
51746 }
51747
51748 this.applied = false;
51749 this.frame.style.display = 'block';
51750
51751 this._generateHueCircle();
51752 } // ------------------------------------------ PRIVATE ----------------------------- //
51753
51754 /**
51755 * Hide the picker. Is called by the cancel button.
51756 * Optional boolean to store the previous color for easy access later on.
51757 * @param {boolean} [storePrevious=true]
51758 * @private
51759 */
51760
51761 }, {
51762 key: "_hide",
51763 value: function _hide() {
51764 var _this = this;
51765
51766 var storePrevious = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
51767
51768 // store the previous color for next time;
51769 if (storePrevious === true) {
51770 this.previousColor = extend({}, this.color);
51771 }
51772
51773 if (this.applied === true) {
51774 this.updateCallback(this.initialColor);
51775 }
51776
51777 this.frame.style.display = 'none'; // call the closing callback, restoring the onclick method.
51778 // this is in a setTimeout because it will trigger the show again before the click is done.
51779
51780 setTimeout(function () {
51781 if (_this.closeCallback !== undefined) {
51782 _this.closeCallback();
51783
51784 _this.closeCallback = undefined;
51785 }
51786 }, 0);
51787 }
51788 /**
51789 * bound to the save button. Saves and hides.
51790 * @private
51791 */
51792
51793 }, {
51794 key: "_save",
51795 value: function _save() {
51796 this.updateCallback(this.color);
51797 this.applied = false;
51798
51799 this._hide();
51800 }
51801 /**
51802 * Bound to apply button. Saves but does not close. Is undone by the cancel button.
51803 * @private
51804 */
51805
51806 }, {
51807 key: "_apply",
51808 value: function _apply() {
51809 this.applied = true;
51810 this.updateCallback(this.color);
51811
51812 this._updatePicker(this.color);
51813 }
51814 /**
51815 * load the color from the previous session.
51816 * @private
51817 */
51818
51819 }, {
51820 key: "_loadLast",
51821 value: function _loadLast() {
51822 if (this.previousColor !== undefined) {
51823 this.setColor(this.previousColor, false);
51824 } else {
51825 alert("There is no last color to load...");
51826 }
51827 }
51828 /**
51829 * set the color, place the picker
51830 * @param {Object} rgba
51831 * @param {boolean} [setInitial=true]
51832 * @private
51833 */
51834
51835 }, {
51836 key: "_setColor",
51837 value: function _setColor(rgba) {
51838 var setInitial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
51839
51840 // store the initial color
51841 if (setInitial === true) {
51842 this.initialColor = extend({}, rgba);
51843 }
51844
51845 this.color = rgba;
51846 var hsv = RGBToHSV(rgba.r, rgba.g, rgba.b);
51847 var angleConvert = 2 * Math.PI;
51848 var radius = this.r * hsv.s;
51849 var x = this.centerCoordinates.x + radius * Math.sin(angleConvert * hsv.h);
51850 var y = this.centerCoordinates.y + radius * Math.cos(angleConvert * hsv.h);
51851 this.colorPickerSelector.style.left = x - 0.5 * this.colorPickerSelector.clientWidth + 'px';
51852 this.colorPickerSelector.style.top = y - 0.5 * this.colorPickerSelector.clientHeight + 'px';
51853
51854 this._updatePicker(rgba);
51855 }
51856 /**
51857 * bound to opacity control
51858 * @param {number} value
51859 * @private
51860 */
51861
51862 }, {
51863 key: "_setOpacity",
51864 value: function _setOpacity(value) {
51865 this.color.a = value / 100;
51866
51867 this._updatePicker(this.color);
51868 }
51869 /**
51870 * bound to brightness control
51871 * @param {number} value
51872 * @private
51873 */
51874
51875 }, {
51876 key: "_setBrightness",
51877 value: function _setBrightness(value) {
51878 var hsv = RGBToHSV(this.color.r, this.color.g, this.color.b);
51879 hsv.v = value / 100;
51880 var rgba = HSVToRGB(hsv.h, hsv.s, hsv.v);
51881 rgba['a'] = this.color.a;
51882 this.color = rgba;
51883
51884 this._updatePicker();
51885 }
51886 /**
51887 * update the color picker. A black circle overlays the hue circle to mimic the brightness decreasing.
51888 * @param {Object} rgba
51889 * @private
51890 */
51891
51892 }, {
51893 key: "_updatePicker",
51894 value: function _updatePicker() {
51895 var rgba = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.color;
51896 var hsv = RGBToHSV(rgba.r, rgba.g, rgba.b);
51897 var ctx = this.colorPickerCanvas.getContext('2d');
51898
51899 if (this.pixelRation === undefined) {
51900 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
51901 }
51902
51903 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); // clear the canvas
51904
51905 var w = this.colorPickerCanvas.clientWidth;
51906 var h = this.colorPickerCanvas.clientHeight;
51907 ctx.clearRect(0, 0, w, h);
51908 ctx.putImageData(this.hueCircle, 0, 0);
51909 ctx.fillStyle = 'rgba(0,0,0,' + (1 - hsv.v) + ')';
51910 ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
51911 ctx.fill();
51912 this.brightnessRange.value = 100 * hsv.v;
51913 this.opacityRange.value = 100 * rgba.a;
51914 this.initialColorDiv.style.backgroundColor = 'rgba(' + this.initialColor.r + ',' + this.initialColor.g + ',' + this.initialColor.b + ',' + this.initialColor.a + ')';
51915 this.newColorDiv.style.backgroundColor = 'rgba(' + this.color.r + ',' + this.color.g + ',' + this.color.b + ',' + this.color.a + ')';
51916 }
51917 /**
51918 * used by create to set the size of the canvas.
51919 * @private
51920 */
51921
51922 }, {
51923 key: "_setSize",
51924 value: function _setSize() {
51925 this.colorPickerCanvas.style.width = '100%';
51926 this.colorPickerCanvas.style.height = '100%';
51927 this.colorPickerCanvas.width = 289 * this.pixelRatio;
51928 this.colorPickerCanvas.height = 289 * this.pixelRatio;
51929 }
51930 /**
51931 * create all dom elements
51932 * TODO: cleanup, lots of similar dom elements
51933 * @private
51934 */
51935
51936 }, {
51937 key: "_create",
51938 value: function _create() {
51939 this.frame = document.createElement('div');
51940 this.frame.className = 'vis-color-picker';
51941 this.colorPickerDiv = document.createElement('div');
51942 this.colorPickerSelector = document.createElement('div');
51943 this.colorPickerSelector.className = 'vis-selector';
51944 this.colorPickerDiv.appendChild(this.colorPickerSelector);
51945 this.colorPickerCanvas = document.createElement('canvas');
51946 this.colorPickerDiv.appendChild(this.colorPickerCanvas);
51947
51948 if (!this.colorPickerCanvas.getContext) {
51949 var noCanvas = document.createElement('DIV');
51950 noCanvas.style.color = 'red';
51951 noCanvas.style.fontWeight = 'bold';
51952 noCanvas.style.padding = '10px';
51953 noCanvas.innerHTML = 'Error: your browser does not support HTML canvas';
51954 this.colorPickerCanvas.appendChild(noCanvas);
51955 } else {
51956 var ctx = this.colorPickerCanvas.getContext("2d");
51957 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
51958 this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
51959 }
51960
51961 this.colorPickerDiv.className = 'vis-color';
51962 this.opacityDiv = document.createElement('div');
51963 this.opacityDiv.className = 'vis-opacity';
51964 this.brightnessDiv = document.createElement('div');
51965 this.brightnessDiv.className = 'vis-brightness';
51966 this.arrowDiv = document.createElement('div');
51967 this.arrowDiv.className = 'vis-arrow';
51968 this.opacityRange = document.createElement('input');
51969
51970 try {
51971 this.opacityRange.type = 'range'; // Not supported on IE9
51972
51973 this.opacityRange.min = '0';
51974 this.opacityRange.max = '100';
51975 } // TODO: Add some error handling and remove this lint exception
51976 catch (err) {} // eslint-disable-line no-empty
51977
51978
51979 this.opacityRange.value = '100';
51980 this.opacityRange.className = 'vis-range';
51981 this.brightnessRange = document.createElement('input');
51982
51983 try {
51984 this.brightnessRange.type = 'range'; // Not supported on IE9
51985
51986 this.brightnessRange.min = '0';
51987 this.brightnessRange.max = '100';
51988 } // TODO: Add some error handling and remove this lint exception
51989 catch (err) {} // eslint-disable-line no-empty
51990
51991
51992 this.brightnessRange.value = '100';
51993 this.brightnessRange.className = 'vis-range';
51994 this.opacityDiv.appendChild(this.opacityRange);
51995 this.brightnessDiv.appendChild(this.brightnessRange);
51996 var me = this;
51997
51998 this.opacityRange.onchange = function () {
51999 me._setOpacity(this.value);
52000 };
52001
52002 this.opacityRange.oninput = function () {
52003 me._setOpacity(this.value);
52004 };
52005
52006 this.brightnessRange.onchange = function () {
52007 me._setBrightness(this.value);
52008 };
52009
52010 this.brightnessRange.oninput = function () {
52011 me._setBrightness(this.value);
52012 };
52013
52014 this.brightnessLabel = document.createElement("div");
52015 this.brightnessLabel.className = "vis-label vis-brightness";
52016 this.brightnessLabel.innerHTML = 'brightness:';
52017 this.opacityLabel = document.createElement("div");
52018 this.opacityLabel.className = "vis-label vis-opacity";
52019 this.opacityLabel.innerHTML = 'opacity:';
52020 this.newColorDiv = document.createElement("div");
52021 this.newColorDiv.className = "vis-new-color";
52022 this.newColorDiv.innerHTML = 'new';
52023 this.initialColorDiv = document.createElement("div");
52024 this.initialColorDiv.className = "vis-initial-color";
52025 this.initialColorDiv.innerHTML = 'initial';
52026 this.cancelButton = document.createElement("div");
52027 this.cancelButton.className = "vis-button vis-cancel";
52028 this.cancelButton.innerHTML = 'cancel';
52029 this.cancelButton.onclick = this._hide.bind(this, false);
52030 this.applyButton = document.createElement("div");
52031 this.applyButton.className = "vis-button vis-apply";
52032 this.applyButton.innerHTML = 'apply';
52033 this.applyButton.onclick = this._apply.bind(this);
52034 this.saveButton = document.createElement("div");
52035 this.saveButton.className = "vis-button vis-save";
52036 this.saveButton.innerHTML = 'save';
52037 this.saveButton.onclick = this._save.bind(this);
52038 this.loadButton = document.createElement("div");
52039 this.loadButton.className = "vis-button vis-load";
52040 this.loadButton.innerHTML = 'load last';
52041 this.loadButton.onclick = this._loadLast.bind(this);
52042 this.frame.appendChild(this.colorPickerDiv);
52043 this.frame.appendChild(this.arrowDiv);
52044 this.frame.appendChild(this.brightnessLabel);
52045 this.frame.appendChild(this.brightnessDiv);
52046 this.frame.appendChild(this.opacityLabel);
52047 this.frame.appendChild(this.opacityDiv);
52048 this.frame.appendChild(this.newColorDiv);
52049 this.frame.appendChild(this.initialColorDiv);
52050 this.frame.appendChild(this.cancelButton);
52051 this.frame.appendChild(this.applyButton);
52052 this.frame.appendChild(this.saveButton);
52053 this.frame.appendChild(this.loadButton);
52054 }
52055 /**
52056 * bind hammer to the color picker
52057 * @private
52058 */
52059
52060 }, {
52061 key: "_bindHammer",
52062 value: function _bindHammer() {
52063 var _this2 = this;
52064
52065 this.drag = {};
52066 this.pinch = {};
52067 this.hammer = new hammer(this.colorPickerCanvas);
52068 this.hammer.get('pinch').set({
52069 enable: true
52070 });
52071 hammerUtil.onTouch(this.hammer, function (event) {
52072 _this2._moveSelector(event);
52073 });
52074 this.hammer.on('tap', function (event) {
52075 _this2._moveSelector(event);
52076 });
52077 this.hammer.on('panstart', function (event) {
52078 _this2._moveSelector(event);
52079 });
52080 this.hammer.on('panmove', function (event) {
52081 _this2._moveSelector(event);
52082 });
52083 this.hammer.on('panend', function (event) {
52084 _this2._moveSelector(event);
52085 });
52086 }
52087 /**
52088 * generate the hue circle. This is relatively heavy (200ms) and is done only once on the first time it is shown.
52089 * @private
52090 */
52091
52092 }, {
52093 key: "_generateHueCircle",
52094 value: function _generateHueCircle() {
52095 if (this.generated === false) {
52096 var ctx = this.colorPickerCanvas.getContext('2d');
52097
52098 if (this.pixelRation === undefined) {
52099 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
52100 }
52101
52102 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); // clear the canvas
52103
52104 var w = this.colorPickerCanvas.clientWidth;
52105 var h = this.colorPickerCanvas.clientHeight;
52106 ctx.clearRect(0, 0, w, h); // draw hue circle
52107
52108 var x, y, hue, sat;
52109 this.centerCoordinates = {
52110 x: w * 0.5,
52111 y: h * 0.5
52112 };
52113 this.r = 0.49 * w;
52114 var angleConvert = 2 * Math.PI / 360;
52115 var hfac = 1 / 360;
52116 var sfac = 1 / this.r;
52117 var rgb;
52118
52119 for (hue = 0; hue < 360; hue++) {
52120 for (sat = 0; sat < this.r; sat++) {
52121 x = this.centerCoordinates.x + sat * Math.sin(angleConvert * hue);
52122 y = this.centerCoordinates.y + sat * Math.cos(angleConvert * hue);
52123 rgb = HSVToRGB(hue * hfac, sat * sfac, 1);
52124 ctx.fillStyle = 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
52125 ctx.fillRect(x - 0.5, y - 0.5, 2, 2);
52126 }
52127 }
52128
52129 ctx.strokeStyle = 'rgba(0,0,0,1)';
52130 ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
52131 ctx.stroke();
52132 this.hueCircle = ctx.getImageData(0, 0, w, h);
52133 }
52134
52135 this.generated = true;
52136 }
52137 /**
52138 * move the selector. This is called by hammer functions.
52139 *
52140 * @param {Event} event The event
52141 * @private
52142 */
52143
52144 }, {
52145 key: "_moveSelector",
52146 value: function _moveSelector(event) {
52147 var rect = this.colorPickerDiv.getBoundingClientRect();
52148 var left = event.center.x - rect.left;
52149 var top = event.center.y - rect.top;
52150 var centerY = 0.5 * this.colorPickerDiv.clientHeight;
52151 var centerX = 0.5 * this.colorPickerDiv.clientWidth;
52152 var x = left - centerX;
52153 var y = top - centerY;
52154 var angle = Math.atan2(x, y);
52155 var radius = 0.98 * Math.min(Math.sqrt(x * x + y * y), centerX);
52156 var newTop = Math.cos(angle) * radius + centerY;
52157 var newLeft = Math.sin(angle) * radius + centerX;
52158 this.colorPickerSelector.style.top = newTop - 0.5 * this.colorPickerSelector.clientHeight + 'px';
52159 this.colorPickerSelector.style.left = newLeft - 0.5 * this.colorPickerSelector.clientWidth + 'px'; // set color
52160
52161 var h = angle / (2 * Math.PI);
52162 h = h < 0 ? h + 1 : h;
52163 var s = radius / this.r;
52164 var hsv = RGBToHSV(this.color.r, this.color.g, this.color.b);
52165 hsv.h = h;
52166 hsv.s = s;
52167 var rgba = HSVToRGB(hsv.h, hsv.s, hsv.v);
52168 rgba['a'] = this.color.a;
52169 this.color = rgba; // update previews
52170
52171 this.initialColorDiv.style.backgroundColor = 'rgba(' + this.initialColor.r + ',' + this.initialColor.g + ',' + this.initialColor.b + ',' + this.initialColor.a + ')';
52172 this.newColorDiv.style.backgroundColor = 'rgba(' + this.color.r + ',' + this.color.g + ',' + this.color.b + ',' + this.color.a + ')';
52173 }
52174 }]);
52175
52176 return ColorPicker;
52177 }();
52178
52179 /**
52180 * 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.
52181 * Boolean options are recognised as Boolean
52182 * Number options should be written as array: [default value, min value, max value, stepsize]
52183 * Colors should be written as array: ['color', '#ffffff']
52184 * Strings with should be written as array: [option1, option2, option3, ..]
52185 *
52186 * The options are matched with their counterparts in each of the modules and the values used in the configuration are
52187 */
52188
52189 var Configurator =
52190 /*#__PURE__*/
52191 function () {
52192 /**
52193 * @param {Object} parentModule | the location where parentModule.setOptions() can be called
52194 * @param {Object} defaultContainer | the default container of the module
52195 * @param {Object} configureOptions | the fully configured and predefined options set found in allOptions.js
52196 * @param {number} pixelRatio | canvas pixel ratio
52197 */
52198 function Configurator(parentModule, defaultContainer, configureOptions) {
52199 var pixelRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
52200
52201 _classCallCheck(this, Configurator);
52202
52203 this.parent = parentModule;
52204 this.changedOptions = [];
52205 this.container = defaultContainer;
52206 this.allowCreation = false;
52207 this.options = {};
52208 this.initialized = false;
52209 this.popupCounter = 0;
52210 this.defaultOptions = {
52211 enabled: false,
52212 filter: true,
52213 container: undefined,
52214 showButton: true
52215 };
52216 extend(this.options, this.defaultOptions);
52217 this.configureOptions = configureOptions;
52218 this.moduleOptions = {};
52219 this.domElements = [];
52220 this.popupDiv = {};
52221 this.popupLimit = 5;
52222 this.popupHistory = {};
52223 this.colorPicker = new ColorPicker(pixelRatio);
52224 this.wrapper = undefined;
52225 }
52226 /**
52227 * refresh all options.
52228 * Because all modules parse their options by themselves, we just use their options. We copy them here.
52229 *
52230 * @param {Object} options
52231 */
52232
52233
52234 _createClass(Configurator, [{
52235 key: "setOptions",
52236 value: function setOptions(options) {
52237 if (options !== undefined) {
52238 // reset the popup history because the indices may have been changed.
52239 this.popupHistory = {};
52240
52241 this._removePopup();
52242
52243 var enabled = true;
52244
52245 if (typeof options === 'string') {
52246 this.options.filter = options;
52247 } else if (options instanceof Array) {
52248 this.options.filter = options.join();
52249 } else if (_typeof(options) === 'object') {
52250 if (options == null) {
52251 throw new TypeError('options cannot be null');
52252 }
52253
52254 if (options.container !== undefined) {
52255 this.options.container = options.container;
52256 }
52257
52258 if (options.filter !== undefined) {
52259 this.options.filter = options.filter;
52260 }
52261
52262 if (options.showButton !== undefined) {
52263 this.options.showButton = options.showButton;
52264 }
52265
52266 if (options.enabled !== undefined) {
52267 enabled = options.enabled;
52268 }
52269 } else if (typeof options === 'boolean') {
52270 this.options.filter = true;
52271 enabled = options;
52272 } else if (typeof options === 'function') {
52273 this.options.filter = options;
52274 enabled = true;
52275 }
52276
52277 if (this.options.filter === false) {
52278 enabled = false;
52279 }
52280
52281 this.options.enabled = enabled;
52282 }
52283
52284 this._clean();
52285 }
52286 /**
52287 *
52288 * @param {Object} moduleOptions
52289 */
52290
52291 }, {
52292 key: "setModuleOptions",
52293 value: function setModuleOptions(moduleOptions) {
52294 this.moduleOptions = moduleOptions;
52295
52296 if (this.options.enabled === true) {
52297 this._clean();
52298
52299 if (this.options.container !== undefined) {
52300 this.container = this.options.container;
52301 }
52302
52303 this._create();
52304 }
52305 }
52306 /**
52307 * Create all DOM elements
52308 * @private
52309 */
52310
52311 }, {
52312 key: "_create",
52313 value: function _create() {
52314 this._clean();
52315
52316 this.changedOptions = [];
52317 var filter = this.options.filter;
52318 var counter = 0;
52319 var show = false;
52320
52321 for (var option in this.configureOptions) {
52322 if (this.configureOptions.hasOwnProperty(option)) {
52323 this.allowCreation = false;
52324 show = false;
52325
52326 if (typeof filter === 'function') {
52327 show = filter(option, []);
52328 show = show || this._handleObject(this.configureOptions[option], [option], true);
52329 } else if (filter === true || filter.indexOf(option) !== -1) {
52330 show = true;
52331 }
52332
52333 if (show !== false) {
52334 this.allowCreation = true; // linebreak between categories
52335
52336 if (counter > 0) {
52337 this._makeItem([]);
52338 } // a header for the category
52339
52340
52341 this._makeHeader(option); // get the sub options
52342
52343
52344 this._handleObject(this.configureOptions[option], [option]);
52345 }
52346
52347 counter++;
52348 }
52349 }
52350
52351 this._makeButton();
52352
52353 this._push(); //~ this.colorPicker.insertTo(this.container);
52354
52355 }
52356 /**
52357 * draw all DOM elements on the screen
52358 * @private
52359 */
52360
52361 }, {
52362 key: "_push",
52363 value: function _push() {
52364 this.wrapper = document.createElement('div');
52365 this.wrapper.className = 'vis-configuration-wrapper';
52366 this.container.appendChild(this.wrapper);
52367
52368 for (var i = 0; i < this.domElements.length; i++) {
52369 this.wrapper.appendChild(this.domElements[i]);
52370 }
52371
52372 this._showPopupIfNeeded();
52373 }
52374 /**
52375 * delete all DOM elements
52376 * @private
52377 */
52378
52379 }, {
52380 key: "_clean",
52381 value: function _clean() {
52382 for (var i = 0; i < this.domElements.length; i++) {
52383 this.wrapper.removeChild(this.domElements[i]);
52384 }
52385
52386 if (this.wrapper !== undefined) {
52387 this.container.removeChild(this.wrapper);
52388 this.wrapper = undefined;
52389 }
52390
52391 this.domElements = [];
52392
52393 this._removePopup();
52394 }
52395 /**
52396 * get the value from the actualOptions if it exists
52397 * @param {array} path | where to look for the actual option
52398 * @returns {*}
52399 * @private
52400 */
52401
52402 }, {
52403 key: "_getValue",
52404 value: function _getValue(path) {
52405 var base = this.moduleOptions;
52406
52407 for (var i = 0; i < path.length; i++) {
52408 if (base[path[i]] !== undefined) {
52409 base = base[path[i]];
52410 } else {
52411 base = undefined;
52412 break;
52413 }
52414 }
52415
52416 return base;
52417 }
52418 /**
52419 * all option elements are wrapped in an item
52420 * @param {Array} path | where to look for the actual option
52421 * @param {Array.<Element>} domElements
52422 * @returns {number}
52423 * @private
52424 */
52425
52426 }, {
52427 key: "_makeItem",
52428 value: function _makeItem(path) {
52429 if (this.allowCreation === true) {
52430 var item = document.createElement('div');
52431 item.className = 'vis-configuration vis-config-item vis-config-s' + path.length;
52432
52433 for (var _len = arguments.length, domElements = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
52434 domElements[_key - 1] = arguments[_key];
52435 }
52436
52437 domElements.forEach(function (element) {
52438 item.appendChild(element);
52439 });
52440 this.domElements.push(item);
52441 return this.domElements.length;
52442 }
52443
52444 return 0;
52445 }
52446 /**
52447 * header for major subjects
52448 * @param {string} name
52449 * @private
52450 */
52451
52452 }, {
52453 key: "_makeHeader",
52454 value: function _makeHeader(name) {
52455 var div = document.createElement('div');
52456 div.className = 'vis-configuration vis-config-header';
52457 div.innerHTML = name;
52458
52459 this._makeItem([], div);
52460 }
52461 /**
52462 * make a label, if it is an object label, it gets different styling.
52463 * @param {string} name
52464 * @param {array} path | where to look for the actual option
52465 * @param {string} objectLabel
52466 * @returns {HTMLElement}
52467 * @private
52468 */
52469
52470 }, {
52471 key: "_makeLabel",
52472 value: function _makeLabel(name, path) {
52473 var objectLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
52474 var div = document.createElement('div');
52475 div.className = 'vis-configuration vis-config-label vis-config-s' + path.length;
52476
52477 if (objectLabel === true) {
52478 div.innerHTML = '<i><b>' + name + ':</b></i>';
52479 } else {
52480 div.innerHTML = name + ':';
52481 }
52482
52483 return div;
52484 }
52485 /**
52486 * make a dropdown list for multiple possible string optoins
52487 * @param {Array.<number>} arr
52488 * @param {number} value
52489 * @param {array} path | where to look for the actual option
52490 * @private
52491 */
52492
52493 }, {
52494 key: "_makeDropdown",
52495 value: function _makeDropdown(arr, value, path) {
52496 var select = document.createElement('select');
52497 select.className = 'vis-configuration vis-config-select';
52498 var selectedValue = 0;
52499
52500 if (value !== undefined) {
52501 if (arr.indexOf(value) !== -1) {
52502 selectedValue = arr.indexOf(value);
52503 }
52504 }
52505
52506 for (var i = 0; i < arr.length; i++) {
52507 var option = document.createElement('option');
52508 option.value = arr[i];
52509
52510 if (i === selectedValue) {
52511 option.selected = 'selected';
52512 }
52513
52514 option.innerHTML = arr[i];
52515 select.appendChild(option);
52516 }
52517
52518 var me = this;
52519
52520 select.onchange = function () {
52521 me._update(this.value, path);
52522 };
52523
52524 var label = this._makeLabel(path[path.length - 1], path);
52525
52526 this._makeItem(path, label, select);
52527 }
52528 /**
52529 * make a range object for numeric options
52530 * @param {Array.<number>} arr
52531 * @param {number} value
52532 * @param {array} path | where to look for the actual option
52533 * @private
52534 */
52535
52536 }, {
52537 key: "_makeRange",
52538 value: function _makeRange(arr, value, path) {
52539 var defaultValue = arr[0];
52540 var min = arr[1];
52541 var max = arr[2];
52542 var step = arr[3];
52543 var range = document.createElement('input');
52544 range.className = 'vis-configuration vis-config-range';
52545
52546 try {
52547 range.type = 'range'; // not supported on IE9
52548
52549 range.min = min;
52550 range.max = max;
52551 } // TODO: Add some error handling and remove this lint exception
52552 catch (err) {} // eslint-disable-line no-empty
52553
52554
52555 range.step = step; // set up the popup settings in case they are needed.
52556
52557 var popupString = '';
52558 var popupValue = 0;
52559
52560 if (value !== undefined) {
52561 var factor = 1.20;
52562
52563 if (value < 0 && value * factor < min) {
52564 range.min = Math.ceil(value * factor);
52565 popupValue = range.min;
52566 popupString = 'range increased';
52567 } else if (value / factor < min) {
52568 range.min = Math.ceil(value / factor);
52569 popupValue = range.min;
52570 popupString = 'range increased';
52571 }
52572
52573 if (value * factor > max && max !== 1) {
52574 range.max = Math.ceil(value * factor);
52575 popupValue = range.max;
52576 popupString = 'range increased';
52577 }
52578
52579 range.value = value;
52580 } else {
52581 range.value = defaultValue;
52582 }
52583
52584 var input = document.createElement('input');
52585 input.className = 'vis-configuration vis-config-rangeinput';
52586 input.value = range.value;
52587 var me = this;
52588
52589 range.onchange = function () {
52590 input.value = this.value;
52591
52592 me._update(Number(this.value), path);
52593 };
52594
52595 range.oninput = function () {
52596 input.value = this.value;
52597 };
52598
52599 var label = this._makeLabel(path[path.length - 1], path);
52600
52601 var itemIndex = this._makeItem(path, label, range, input); // if a popup is needed AND it has not been shown for this value, show it.
52602
52603
52604 if (popupString !== '' && this.popupHistory[itemIndex] !== popupValue) {
52605 this.popupHistory[itemIndex] = popupValue;
52606
52607 this._setupPopup(popupString, itemIndex);
52608 }
52609 }
52610 /**
52611 * make a button object
52612 * @private
52613 */
52614
52615 }, {
52616 key: "_makeButton",
52617 value: function _makeButton() {
52618 var _this = this;
52619
52620 if (this.options.showButton === true) {
52621 var generateButton = document.createElement('div');
52622 generateButton.className = 'vis-configuration vis-config-button';
52623 generateButton.innerHTML = 'generate options';
52624
52625 generateButton.onclick = function () {
52626 _this._printOptions();
52627 };
52628
52629 generateButton.onmouseover = function () {
52630 generateButton.className = 'vis-configuration vis-config-button hover';
52631 };
52632
52633 generateButton.onmouseout = function () {
52634 generateButton.className = 'vis-configuration vis-config-button';
52635 };
52636
52637 this.optionsContainer = document.createElement('div');
52638 this.optionsContainer.className = 'vis-configuration vis-config-option-container';
52639 this.domElements.push(this.optionsContainer);
52640 this.domElements.push(generateButton);
52641 }
52642 }
52643 /**
52644 * prepare the popup
52645 * @param {string} string
52646 * @param {number} index
52647 * @private
52648 */
52649
52650 }, {
52651 key: "_setupPopup",
52652 value: function _setupPopup(string, index) {
52653 var _this2 = this;
52654
52655 if (this.initialized === true && this.allowCreation === true && this.popupCounter < this.popupLimit) {
52656 var div = document.createElement("div");
52657 div.id = "vis-configuration-popup";
52658 div.className = "vis-configuration-popup";
52659 div.innerHTML = string;
52660
52661 div.onclick = function () {
52662 _this2._removePopup();
52663 };
52664
52665 this.popupCounter += 1;
52666 this.popupDiv = {
52667 html: div,
52668 index: index
52669 };
52670 }
52671 }
52672 /**
52673 * remove the popup from the dom
52674 * @private
52675 */
52676
52677 }, {
52678 key: "_removePopup",
52679 value: function _removePopup() {
52680 if (this.popupDiv.html !== undefined) {
52681 this.popupDiv.html.parentNode.removeChild(this.popupDiv.html);
52682 clearTimeout(this.popupDiv.hideTimeout);
52683 clearTimeout(this.popupDiv.deleteTimeout);
52684 this.popupDiv = {};
52685 }
52686 }
52687 /**
52688 * Show the popup if it is needed.
52689 * @private
52690 */
52691
52692 }, {
52693 key: "_showPopupIfNeeded",
52694 value: function _showPopupIfNeeded() {
52695 var _this3 = this;
52696
52697 if (this.popupDiv.html !== undefined) {
52698 var correspondingElement = this.domElements[this.popupDiv.index];
52699 var rect = correspondingElement.getBoundingClientRect();
52700 this.popupDiv.html.style.left = rect.left + "px";
52701 this.popupDiv.html.style.top = rect.top - 30 + "px"; // 30 is the height;
52702
52703 document.body.appendChild(this.popupDiv.html);
52704 this.popupDiv.hideTimeout = setTimeout(function () {
52705 _this3.popupDiv.html.style.opacity = 0;
52706 }, 1500);
52707 this.popupDiv.deleteTimeout = setTimeout(function () {
52708 _this3._removePopup();
52709 }, 1800);
52710 }
52711 }
52712 /**
52713 * make a checkbox for boolean options.
52714 * @param {number} defaultValue
52715 * @param {number} value
52716 * @param {array} path | where to look for the actual option
52717 * @private
52718 */
52719
52720 }, {
52721 key: "_makeCheckbox",
52722 value: function _makeCheckbox(defaultValue, value, path) {
52723 var checkbox = document.createElement('input');
52724 checkbox.type = 'checkbox';
52725 checkbox.className = 'vis-configuration vis-config-checkbox';
52726 checkbox.checked = defaultValue;
52727
52728 if (value !== undefined) {
52729 checkbox.checked = value;
52730
52731 if (value !== defaultValue) {
52732 if (_typeof(defaultValue) === 'object') {
52733 if (value !== defaultValue.enabled) {
52734 this.changedOptions.push({
52735 path: path,
52736 value: value
52737 });
52738 }
52739 } else {
52740 this.changedOptions.push({
52741 path: path,
52742 value: value
52743 });
52744 }
52745 }
52746 }
52747
52748 var me = this;
52749
52750 checkbox.onchange = function () {
52751 me._update(this.checked, path);
52752 };
52753
52754 var label = this._makeLabel(path[path.length - 1], path);
52755
52756 this._makeItem(path, label, checkbox);
52757 }
52758 /**
52759 * make a text input field for string options.
52760 * @param {number} defaultValue
52761 * @param {number} value
52762 * @param {array} path | where to look for the actual option
52763 * @private
52764 */
52765
52766 }, {
52767 key: "_makeTextInput",
52768 value: function _makeTextInput(defaultValue, value, path) {
52769 var checkbox = document.createElement('input');
52770 checkbox.type = 'text';
52771 checkbox.className = 'vis-configuration vis-config-text';
52772 checkbox.value = value;
52773
52774 if (value !== defaultValue) {
52775 this.changedOptions.push({
52776 path: path,
52777 value: value
52778 });
52779 }
52780
52781 var me = this;
52782
52783 checkbox.onchange = function () {
52784 me._update(this.value, path);
52785 };
52786
52787 var label = this._makeLabel(path[path.length - 1], path);
52788
52789 this._makeItem(path, label, checkbox);
52790 }
52791 /**
52792 * make a color field with a color picker for color fields
52793 * @param {Array.<number>} arr
52794 * @param {number} value
52795 * @param {array} path | where to look for the actual option
52796 * @private
52797 */
52798
52799 }, {
52800 key: "_makeColorField",
52801 value: function _makeColorField(arr, value, path) {
52802 var _this4 = this;
52803
52804 var defaultColor = arr[1];
52805 var div = document.createElement('div');
52806 value = value === undefined ? defaultColor : value;
52807
52808 if (value !== 'none') {
52809 div.className = 'vis-configuration vis-config-colorBlock';
52810 div.style.backgroundColor = value;
52811 } else {
52812 div.className = 'vis-configuration vis-config-colorBlock none';
52813 }
52814
52815 value = value === undefined ? defaultColor : value;
52816
52817 div.onclick = function () {
52818 _this4._showColorPicker(value, div, path);
52819 };
52820
52821 var label = this._makeLabel(path[path.length - 1], path);
52822
52823 this._makeItem(path, label, div);
52824 }
52825 /**
52826 * used by the color buttons to call the color picker.
52827 * @param {number} value
52828 * @param {HTMLElement} div
52829 * @param {array} path | where to look for the actual option
52830 * @private
52831 */
52832
52833 }, {
52834 key: "_showColorPicker",
52835 value: function _showColorPicker(value, div, path) {
52836 var _this5 = this;
52837
52838 // clear the callback from this div
52839 div.onclick = function () {};
52840
52841 this.colorPicker.insertTo(div);
52842 this.colorPicker.show();
52843 this.colorPicker.setColor(value);
52844 this.colorPicker.setUpdateCallback(function (color) {
52845 var colorString = 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',' + color.a + ')';
52846 div.style.backgroundColor = colorString;
52847
52848 _this5._update(colorString, path);
52849 }); // on close of the colorpicker, restore the callback.
52850
52851 this.colorPicker.setCloseCallback(function () {
52852 div.onclick = function () {
52853 _this5._showColorPicker(value, div, path);
52854 };
52855 });
52856 }
52857 /**
52858 * parse an object and draw the correct items
52859 * @param {Object} obj
52860 * @param {array} [path=[]] | where to look for the actual option
52861 * @param {boolean} [checkOnly=false]
52862 * @returns {boolean}
52863 * @private
52864 */
52865
52866 }, {
52867 key: "_handleObject",
52868 value: function _handleObject(obj) {
52869 var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
52870 var checkOnly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
52871 var show = false;
52872 var filter = this.options.filter;
52873 var visibleInSet = false;
52874
52875 for (var subObj in obj) {
52876 if (obj.hasOwnProperty(subObj)) {
52877 show = true;
52878 var item = obj[subObj];
52879 var newPath = copyAndExtendArray(path, subObj);
52880
52881 if (typeof filter === 'function') {
52882 show = filter(subObj, path); // if needed we must go deeper into the object.
52883
52884 if (show === false) {
52885 if (!(item instanceof Array) && typeof item !== 'string' && typeof item !== 'boolean' && item instanceof Object) {
52886 this.allowCreation = false;
52887 show = this._handleObject(item, newPath, true);
52888 this.allowCreation = checkOnly === false;
52889 }
52890 }
52891 }
52892
52893 if (show !== false) {
52894 visibleInSet = true;
52895
52896 var value = this._getValue(newPath);
52897
52898 if (item instanceof Array) {
52899 this._handleArray(item, value, newPath);
52900 } else if (typeof item === 'string') {
52901 this._makeTextInput(item, value, newPath);
52902 } else if (typeof item === 'boolean') {
52903 this._makeCheckbox(item, value, newPath);
52904 } else if (item instanceof Object) {
52905 // collapse the physics options that are not enabled
52906 var draw = true;
52907
52908 if (path.indexOf('physics') !== -1) {
52909 if (this.moduleOptions.physics.solver !== subObj) {
52910 draw = false;
52911 }
52912 }
52913
52914 if (draw === true) {
52915 // initially collapse options with an disabled enabled option.
52916 if (item.enabled !== undefined) {
52917 var enabledPath = copyAndExtendArray(newPath, 'enabled');
52918
52919 var enabledValue = this._getValue(enabledPath);
52920
52921 if (enabledValue === true) {
52922 var label = this._makeLabel(subObj, newPath, true);
52923
52924 this._makeItem(newPath, label);
52925
52926 visibleInSet = this._handleObject(item, newPath) || visibleInSet;
52927 } else {
52928 this._makeCheckbox(item, enabledValue, newPath);
52929 }
52930 } else {
52931 var _label = this._makeLabel(subObj, newPath, true);
52932
52933 this._makeItem(newPath, _label);
52934
52935 visibleInSet = this._handleObject(item, newPath) || visibleInSet;
52936 }
52937 }
52938 } else {
52939 console.error('dont know how to handle', item, subObj, newPath);
52940 }
52941 }
52942 }
52943 }
52944
52945 return visibleInSet;
52946 }
52947 /**
52948 * handle the array type of option
52949 * @param {Array.<number>} arr
52950 * @param {number} value
52951 * @param {array} path | where to look for the actual option
52952 * @private
52953 */
52954
52955 }, {
52956 key: "_handleArray",
52957 value: function _handleArray(arr, value, path) {
52958 if (typeof arr[0] === 'string' && arr[0] === 'color') {
52959 this._makeColorField(arr, value, path);
52960
52961 if (arr[1] !== value) {
52962 this.changedOptions.push({
52963 path: path,
52964 value: value
52965 });
52966 }
52967 } else if (typeof arr[0] === 'string') {
52968 this._makeDropdown(arr, value, path);
52969
52970 if (arr[0] !== value) {
52971 this.changedOptions.push({
52972 path: path,
52973 value: value
52974 });
52975 }
52976 } else if (typeof arr[0] === 'number') {
52977 this._makeRange(arr, value, path);
52978
52979 if (arr[0] !== value) {
52980 this.changedOptions.push({
52981 path: path,
52982 value: Number(value)
52983 });
52984 }
52985 }
52986 }
52987 /**
52988 * called to update the network with the new settings.
52989 * @param {number} value
52990 * @param {array} path | where to look for the actual option
52991 * @private
52992 */
52993
52994 }, {
52995 key: "_update",
52996 value: function _update(value, path) {
52997 var options = this._constructOptions(value, path);
52998
52999 if (this.parent.body && this.parent.body.emitter && this.parent.body.emitter.emit) {
53000 this.parent.body.emitter.emit("configChange", options);
53001 }
53002
53003 this.initialized = true;
53004 this.parent.setOptions(options);
53005 }
53006 /**
53007 *
53008 * @param {string|Boolean} value
53009 * @param {Array.<string>} path
53010 * @param {{}} optionsObj
53011 * @returns {{}}
53012 * @private
53013 */
53014
53015 }, {
53016 key: "_constructOptions",
53017 value: function _constructOptions(value, path) {
53018 var optionsObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
53019 var pointer = optionsObj; // when dropdown boxes can be string or boolean, we typecast it into correct types
53020
53021 value = value === 'true' ? true : value;
53022 value = value === 'false' ? false : value;
53023
53024 for (var i = 0; i < path.length; i++) {
53025 if (path[i] !== 'global') {
53026 if (pointer[path[i]] === undefined) {
53027 pointer[path[i]] = {};
53028 }
53029
53030 if (i !== path.length - 1) {
53031 pointer = pointer[path[i]];
53032 } else {
53033 pointer[path[i]] = value;
53034 }
53035 }
53036 }
53037
53038 return optionsObj;
53039 }
53040 /**
53041 * @private
53042 */
53043
53044 }, {
53045 key: "_printOptions",
53046 value: function _printOptions() {
53047 var options = this.getOptions();
53048 this.optionsContainer.innerHTML = '<pre>var options = ' + JSON.stringify(options, null, 2) + '</pre>';
53049 }
53050 /**
53051 *
53052 * @returns {{}} options
53053 */
53054
53055 }, {
53056 key: "getOptions",
53057 value: function getOptions() {
53058 var options = {};
53059
53060 for (var i = 0; i < this.changedOptions.length; i++) {
53061 this._constructOptions(this.changedOptions[i].value, this.changedOptions[i].path, options);
53062 }
53063
53064 return options;
53065 }
53066 }]);
53067
53068 return Configurator;
53069 }();
53070
53071 /**
53072 * This object contains all possible options. It will check if the types are correct, if required if the option is one
53073 * of the allowed values.
53074 *
53075 * __any__ means that the name of the property does not matter.
53076 * __type__ is a required field for all objects and contains the allowed types of all objects
53077 */
53078 var string = 'string';
53079 var bool = 'boolean';
53080 var number = 'number';
53081 var array = 'array';
53082 var object = 'object'; // should only be in a __type__ property
53083
53084 var dom = 'dom';
53085 var any = 'any'; // List of endpoints
53086
53087 var endPoints = ["arrow", "bar", "box", "circle", "crow", "curve", "diamond", "image", "inv_curve", "inv_triangle", "triangle", "vee"];
53088 var allOptions$1 = {
53089 configure: {
53090 enabled: {
53091 boolean: bool
53092 },
53093 filter: {
53094 boolean: bool,
53095 string: string,
53096 array: array,
53097 'function': 'function'
53098 },
53099 container: {
53100 dom: dom
53101 },
53102 showButton: {
53103 boolean: bool
53104 },
53105 __type__: {
53106 object: object,
53107 boolean: bool,
53108 string: string,
53109 array: array,
53110 'function': 'function'
53111 }
53112 },
53113 edges: {
53114 arrows: {
53115 to: {
53116 enabled: {
53117 boolean: bool
53118 },
53119 scaleFactor: {
53120 number: number
53121 },
53122 type: {
53123 string: endPoints
53124 },
53125 imageHeight: {
53126 number: number
53127 },
53128 imageWidth: {
53129 number: number
53130 },
53131 src: {
53132 string: string
53133 },
53134 __type__: {
53135 object: object,
53136 boolean: bool
53137 }
53138 },
53139 middle: {
53140 enabled: {
53141 boolean: bool
53142 },
53143 scaleFactor: {
53144 number: number
53145 },
53146 type: {
53147 string: endPoints
53148 },
53149 imageWidth: {
53150 number: number
53151 },
53152 imageHeight: {
53153 number: number
53154 },
53155 src: {
53156 string: string
53157 },
53158 __type__: {
53159 object: object,
53160 boolean: bool
53161 }
53162 },
53163 from: {
53164 enabled: {
53165 boolean: bool
53166 },
53167 scaleFactor: {
53168 number: number
53169 },
53170 type: {
53171 string: endPoints
53172 },
53173 imageWidth: {
53174 number: number
53175 },
53176 imageHeight: {
53177 number: number
53178 },
53179 src: {
53180 string: string
53181 },
53182 __type__: {
53183 object: object,
53184 boolean: bool
53185 }
53186 },
53187 __type__: {
53188 string: ["from", "to", "middle"],
53189 object: object
53190 }
53191 },
53192 arrowStrikethrough: {
53193 boolean: bool
53194 },
53195 background: {
53196 enabled: {
53197 boolean: bool
53198 },
53199 color: {
53200 string: string
53201 },
53202 size: {
53203 number: number
53204 },
53205 dashes: {
53206 boolean: bool,
53207 array: array
53208 },
53209 __type__: {
53210 object: object,
53211 boolean: bool
53212 }
53213 },
53214 chosen: {
53215 label: {
53216 boolean: bool,
53217 'function': 'function'
53218 },
53219 edge: {
53220 boolean: bool,
53221 'function': 'function'
53222 },
53223 __type__: {
53224 object: object,
53225 boolean: bool
53226 }
53227 },
53228 color: {
53229 color: {
53230 string: string
53231 },
53232 highlight: {
53233 string: string
53234 },
53235 hover: {
53236 string: string
53237 },
53238 inherit: {
53239 string: ['from', 'to', 'both'],
53240 boolean: bool
53241 },
53242 opacity: {
53243 number: number
53244 },
53245 __type__: {
53246 object: object,
53247 string: string
53248 }
53249 },
53250 dashes: {
53251 boolean: bool,
53252 array: array
53253 },
53254 font: {
53255 color: {
53256 string: string
53257 },
53258 size: {
53259 number: number
53260 },
53261 // px
53262 face: {
53263 string: string
53264 },
53265 background: {
53266 string: string
53267 },
53268 strokeWidth: {
53269 number: number
53270 },
53271 // px
53272 strokeColor: {
53273 string: string
53274 },
53275 align: {
53276 string: ['horizontal', 'top', 'middle', 'bottom']
53277 },
53278 vadjust: {
53279 number: number
53280 },
53281 multi: {
53282 boolean: bool,
53283 string: string
53284 },
53285 bold: {
53286 color: {
53287 string: string
53288 },
53289 size: {
53290 number: number
53291 },
53292 // px
53293 face: {
53294 string: string
53295 },
53296 mod: {
53297 string: string
53298 },
53299 vadjust: {
53300 number: number
53301 },
53302 __type__: {
53303 object: object,
53304 string: string
53305 }
53306 },
53307 boldital: {
53308 color: {
53309 string: string
53310 },
53311 size: {
53312 number: number
53313 },
53314 // px
53315 face: {
53316 string: string
53317 },
53318 mod: {
53319 string: string
53320 },
53321 vadjust: {
53322 number: number
53323 },
53324 __type__: {
53325 object: object,
53326 string: string
53327 }
53328 },
53329 ital: {
53330 color: {
53331 string: string
53332 },
53333 size: {
53334 number: number
53335 },
53336 // px
53337 face: {
53338 string: string
53339 },
53340 mod: {
53341 string: string
53342 },
53343 vadjust: {
53344 number: number
53345 },
53346 __type__: {
53347 object: object,
53348 string: string
53349 }
53350 },
53351 mono: {
53352 color: {
53353 string: string
53354 },
53355 size: {
53356 number: number
53357 },
53358 // px
53359 face: {
53360 string: string
53361 },
53362 mod: {
53363 string: string
53364 },
53365 vadjust: {
53366 number: number
53367 },
53368 __type__: {
53369 object: object,
53370 string: string
53371 }
53372 },
53373 __type__: {
53374 object: object,
53375 string: string
53376 }
53377 },
53378 hidden: {
53379 boolean: bool
53380 },
53381 hoverWidth: {
53382 'function': 'function',
53383 number: number
53384 },
53385 label: {
53386 string: string,
53387 'undefined': 'undefined'
53388 },
53389 labelHighlightBold: {
53390 boolean: bool
53391 },
53392 length: {
53393 number: number,
53394 'undefined': 'undefined'
53395 },
53396 physics: {
53397 boolean: bool
53398 },
53399 scaling: {
53400 min: {
53401 number: number
53402 },
53403 max: {
53404 number: number
53405 },
53406 label: {
53407 enabled: {
53408 boolean: bool
53409 },
53410 min: {
53411 number: number
53412 },
53413 max: {
53414 number: number
53415 },
53416 maxVisible: {
53417 number: number
53418 },
53419 drawThreshold: {
53420 number: number
53421 },
53422 __type__: {
53423 object: object,
53424 boolean: bool
53425 }
53426 },
53427 customScalingFunction: {
53428 'function': 'function'
53429 },
53430 __type__: {
53431 object: object
53432 }
53433 },
53434 selectionWidth: {
53435 'function': 'function',
53436 number: number
53437 },
53438 selfReferenceSize: {
53439 number: number
53440 },
53441 shadow: {
53442 enabled: {
53443 boolean: bool
53444 },
53445 color: {
53446 string: string
53447 },
53448 size: {
53449 number: number
53450 },
53451 x: {
53452 number: number
53453 },
53454 y: {
53455 number: number
53456 },
53457 __type__: {
53458 object: object,
53459 boolean: bool
53460 }
53461 },
53462 smooth: {
53463 enabled: {
53464 boolean: bool
53465 },
53466 type: {
53467 string: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier']
53468 },
53469 roundness: {
53470 number: number
53471 },
53472 forceDirection: {
53473 string: ['horizontal', 'vertical', 'none'],
53474 boolean: bool
53475 },
53476 __type__: {
53477 object: object,
53478 boolean: bool
53479 }
53480 },
53481 title: {
53482 string: string,
53483 'undefined': 'undefined'
53484 },
53485 width: {
53486 number: number
53487 },
53488 widthConstraint: {
53489 maximum: {
53490 number: number
53491 },
53492 __type__: {
53493 object: object,
53494 boolean: bool,
53495 number: number
53496 }
53497 },
53498 value: {
53499 number: number,
53500 'undefined': 'undefined'
53501 },
53502 __type__: {
53503 object: object
53504 }
53505 },
53506 groups: {
53507 useDefaultGroups: {
53508 boolean: bool
53509 },
53510 __any__: 'get from nodes, will be overwritten below',
53511 __type__: {
53512 object: object
53513 }
53514 },
53515 interaction: {
53516 dragNodes: {
53517 boolean: bool
53518 },
53519 dragView: {
53520 boolean: bool
53521 },
53522 hideEdgesOnDrag: {
53523 boolean: bool
53524 },
53525 hideEdgesOnZoom: {
53526 boolean: bool
53527 },
53528 hideNodesOnDrag: {
53529 boolean: bool
53530 },
53531 hover: {
53532 boolean: bool
53533 },
53534 keyboard: {
53535 enabled: {
53536 boolean: bool
53537 },
53538 speed: {
53539 x: {
53540 number: number
53541 },
53542 y: {
53543 number: number
53544 },
53545 zoom: {
53546 number: number
53547 },
53548 __type__: {
53549 object: object
53550 }
53551 },
53552 bindToWindow: {
53553 boolean: bool
53554 },
53555 __type__: {
53556 object: object,
53557 boolean: bool
53558 }
53559 },
53560 multiselect: {
53561 boolean: bool
53562 },
53563 navigationButtons: {
53564 boolean: bool
53565 },
53566 selectable: {
53567 boolean: bool
53568 },
53569 selectConnectedEdges: {
53570 boolean: bool
53571 },
53572 hoverConnectedEdges: {
53573 boolean: bool
53574 },
53575 tooltipDelay: {
53576 number: number
53577 },
53578 zoomView: {
53579 boolean: bool
53580 },
53581 zoomSpeed: {
53582 number: number
53583 },
53584 __type__: {
53585 object: object
53586 }
53587 },
53588 layout: {
53589 randomSeed: {
53590 'undefined': 'undefined',
53591 number: number
53592 },
53593 improvedLayout: {
53594 boolean: bool
53595 },
53596 clusterThreshold: {
53597 number: number
53598 },
53599 hierarchical: {
53600 enabled: {
53601 boolean: bool
53602 },
53603 levelSeparation: {
53604 number: number
53605 },
53606 nodeSpacing: {
53607 number: number
53608 },
53609 treeSpacing: {
53610 number: number
53611 },
53612 blockShifting: {
53613 boolean: bool
53614 },
53615 edgeMinimization: {
53616 boolean: bool
53617 },
53618 parentCentralization: {
53619 boolean: bool
53620 },
53621 direction: {
53622 string: ['UD', 'DU', 'LR', 'RL']
53623 },
53624 // UD, DU, LR, RL
53625 sortMethod: {
53626 string: ['hubsize', 'directed']
53627 },
53628 // hubsize, directed
53629 shakeTowards: {
53630 string: ['leaves', 'roots']
53631 },
53632 // leaves, roots
53633 __type__: {
53634 object: object,
53635 boolean: bool
53636 }
53637 },
53638 __type__: {
53639 object: object
53640 }
53641 },
53642 manipulation: {
53643 enabled: {
53644 boolean: bool
53645 },
53646 initiallyActive: {
53647 boolean: bool
53648 },
53649 addNode: {
53650 boolean: bool,
53651 'function': 'function'
53652 },
53653 addEdge: {
53654 boolean: bool,
53655 'function': 'function'
53656 },
53657 editNode: {
53658 'function': 'function'
53659 },
53660 editEdge: {
53661 editWithoutDrag: {
53662 'function': 'function'
53663 },
53664 __type__: {
53665 object: object,
53666 boolean: bool,
53667 'function': 'function'
53668 }
53669 },
53670 deleteNode: {
53671 boolean: bool,
53672 'function': 'function'
53673 },
53674 deleteEdge: {
53675 boolean: bool,
53676 'function': 'function'
53677 },
53678 controlNodeStyle: 'get from nodes, will be overwritten below',
53679 __type__: {
53680 object: object,
53681 boolean: bool
53682 }
53683 },
53684 nodes: {
53685 borderWidth: {
53686 number: number
53687 },
53688 borderWidthSelected: {
53689 number: number,
53690 'undefined': 'undefined'
53691 },
53692 brokenImage: {
53693 string: string,
53694 'undefined': 'undefined'
53695 },
53696 chosen: {
53697 label: {
53698 boolean: bool,
53699 'function': 'function'
53700 },
53701 node: {
53702 boolean: bool,
53703 'function': 'function'
53704 },
53705 __type__: {
53706 object: object,
53707 boolean: bool
53708 }
53709 },
53710 color: {
53711 border: {
53712 string: string
53713 },
53714 background: {
53715 string: string
53716 },
53717 highlight: {
53718 border: {
53719 string: string
53720 },
53721 background: {
53722 string: string
53723 },
53724 __type__: {
53725 object: object,
53726 string: string
53727 }
53728 },
53729 hover: {
53730 border: {
53731 string: string
53732 },
53733 background: {
53734 string: string
53735 },
53736 __type__: {
53737 object: object,
53738 string: string
53739 }
53740 },
53741 __type__: {
53742 object: object,
53743 string: string
53744 }
53745 },
53746 fixed: {
53747 x: {
53748 boolean: bool
53749 },
53750 y: {
53751 boolean: bool
53752 },
53753 __type__: {
53754 object: object,
53755 boolean: bool
53756 }
53757 },
53758 font: {
53759 align: {
53760 string: string
53761 },
53762 color: {
53763 string: string
53764 },
53765 size: {
53766 number: number
53767 },
53768 // px
53769 face: {
53770 string: string
53771 },
53772 background: {
53773 string: string
53774 },
53775 strokeWidth: {
53776 number: number
53777 },
53778 // px
53779 strokeColor: {
53780 string: string
53781 },
53782 vadjust: {
53783 number: number
53784 },
53785 multi: {
53786 boolean: bool,
53787 string: string
53788 },
53789 bold: {
53790 color: {
53791 string: string
53792 },
53793 size: {
53794 number: number
53795 },
53796 // px
53797 face: {
53798 string: string
53799 },
53800 mod: {
53801 string: string
53802 },
53803 vadjust: {
53804 number: number
53805 },
53806 __type__: {
53807 object: object,
53808 string: string
53809 }
53810 },
53811 boldital: {
53812 color: {
53813 string: string
53814 },
53815 size: {
53816 number: number
53817 },
53818 // px
53819 face: {
53820 string: string
53821 },
53822 mod: {
53823 string: string
53824 },
53825 vadjust: {
53826 number: number
53827 },
53828 __type__: {
53829 object: object,
53830 string: string
53831 }
53832 },
53833 ital: {
53834 color: {
53835 string: string
53836 },
53837 size: {
53838 number: number
53839 },
53840 // px
53841 face: {
53842 string: string
53843 },
53844 mod: {
53845 string: string
53846 },
53847 vadjust: {
53848 number: number
53849 },
53850 __type__: {
53851 object: object,
53852 string: string
53853 }
53854 },
53855 mono: {
53856 color: {
53857 string: string
53858 },
53859 size: {
53860 number: number
53861 },
53862 // px
53863 face: {
53864 string: string
53865 },
53866 mod: {
53867 string: string
53868 },
53869 vadjust: {
53870 number: number
53871 },
53872 __type__: {
53873 object: object,
53874 string: string
53875 }
53876 },
53877 __type__: {
53878 object: object,
53879 string: string
53880 }
53881 },
53882 group: {
53883 string: string,
53884 number: number,
53885 'undefined': 'undefined'
53886 },
53887 heightConstraint: {
53888 minimum: {
53889 number: number
53890 },
53891 valign: {
53892 string: string
53893 },
53894 __type__: {
53895 object: object,
53896 boolean: bool,
53897 number: number
53898 }
53899 },
53900 hidden: {
53901 boolean: bool
53902 },
53903 icon: {
53904 face: {
53905 string: string
53906 },
53907 code: {
53908 string: string
53909 },
53910 //'\uf007',
53911 size: {
53912 number: number
53913 },
53914 //50,
53915 color: {
53916 string: string
53917 },
53918 weight: {
53919 string: string,
53920 number: number
53921 },
53922 __type__: {
53923 object: object
53924 }
53925 },
53926 id: {
53927 string: string,
53928 number: number
53929 },
53930 image: {
53931 selected: {
53932 string: string,
53933 'undefined': 'undefined'
53934 },
53935 // --> URL
53936 unselected: {
53937 string: string,
53938 'undefined': 'undefined'
53939 },
53940 // --> URL
53941 __type__: {
53942 object: object,
53943 string: string
53944 }
53945 },
53946 imagePadding: {
53947 top: {
53948 number: number
53949 },
53950 right: {
53951 number: number
53952 },
53953 bottom: {
53954 number: number
53955 },
53956 left: {
53957 number: number
53958 },
53959 __type__: {
53960 object: object,
53961 number: number
53962 }
53963 },
53964 label: {
53965 string: string,
53966 'undefined': 'undefined'
53967 },
53968 labelHighlightBold: {
53969 boolean: bool
53970 },
53971 level: {
53972 number: number,
53973 'undefined': 'undefined'
53974 },
53975 margin: {
53976 top: {
53977 number: number
53978 },
53979 right: {
53980 number: number
53981 },
53982 bottom: {
53983 number: number
53984 },
53985 left: {
53986 number: number
53987 },
53988 __type__: {
53989 object: object,
53990 number: number
53991 }
53992 },
53993 mass: {
53994 number: number
53995 },
53996 physics: {
53997 boolean: bool
53998 },
53999 scaling: {
54000 min: {
54001 number: number
54002 },
54003 max: {
54004 number: number
54005 },
54006 label: {
54007 enabled: {
54008 boolean: bool
54009 },
54010 min: {
54011 number: number
54012 },
54013 max: {
54014 number: number
54015 },
54016 maxVisible: {
54017 number: number
54018 },
54019 drawThreshold: {
54020 number: number
54021 },
54022 __type__: {
54023 object: object,
54024 boolean: bool
54025 }
54026 },
54027 customScalingFunction: {
54028 'function': 'function'
54029 },
54030 __type__: {
54031 object: object
54032 }
54033 },
54034 shadow: {
54035 enabled: {
54036 boolean: bool
54037 },
54038 color: {
54039 string: string
54040 },
54041 size: {
54042 number: number
54043 },
54044 x: {
54045 number: number
54046 },
54047 y: {
54048 number: number
54049 },
54050 __type__: {
54051 object: object,
54052 boolean: bool
54053 }
54054 },
54055 shape: {
54056 string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon', 'hexagon']
54057 },
54058 shapeProperties: {
54059 borderDashes: {
54060 boolean: bool,
54061 array: array
54062 },
54063 borderRadius: {
54064 number: number
54065 },
54066 interpolation: {
54067 boolean: bool
54068 },
54069 useImageSize: {
54070 boolean: bool
54071 },
54072 useBorderWithImage: {
54073 boolean: bool
54074 },
54075 __type__: {
54076 object: object
54077 }
54078 },
54079 size: {
54080 number: number
54081 },
54082 title: {
54083 string: string,
54084 dom: dom,
54085 'undefined': 'undefined'
54086 },
54087 value: {
54088 number: number,
54089 'undefined': 'undefined'
54090 },
54091 widthConstraint: {
54092 minimum: {
54093 number: number
54094 },
54095 maximum: {
54096 number: number
54097 },
54098 __type__: {
54099 object: object,
54100 boolean: bool,
54101 number: number
54102 }
54103 },
54104 x: {
54105 number: number
54106 },
54107 y: {
54108 number: number
54109 },
54110 __type__: {
54111 object: object
54112 }
54113 },
54114 physics: {
54115 enabled: {
54116 boolean: bool
54117 },
54118 barnesHut: {
54119 gravitationalConstant: {
54120 number: number
54121 },
54122 centralGravity: {
54123 number: number
54124 },
54125 springLength: {
54126 number: number
54127 },
54128 springConstant: {
54129 number: number
54130 },
54131 damping: {
54132 number: number
54133 },
54134 avoidOverlap: {
54135 number: number
54136 },
54137 __type__: {
54138 object: object
54139 }
54140 },
54141 forceAtlas2Based: {
54142 gravitationalConstant: {
54143 number: number
54144 },
54145 centralGravity: {
54146 number: number
54147 },
54148 springLength: {
54149 number: number
54150 },
54151 springConstant: {
54152 number: number
54153 },
54154 damping: {
54155 number: number
54156 },
54157 avoidOverlap: {
54158 number: number
54159 },
54160 __type__: {
54161 object: object
54162 }
54163 },
54164 repulsion: {
54165 centralGravity: {
54166 number: number
54167 },
54168 springLength: {
54169 number: number
54170 },
54171 springConstant: {
54172 number: number
54173 },
54174 nodeDistance: {
54175 number: number
54176 },
54177 damping: {
54178 number: number
54179 },
54180 __type__: {
54181 object: object
54182 }
54183 },
54184 hierarchicalRepulsion: {
54185 centralGravity: {
54186 number: number
54187 },
54188 springLength: {
54189 number: number
54190 },
54191 springConstant: {
54192 number: number
54193 },
54194 nodeDistance: {
54195 number: number
54196 },
54197 damping: {
54198 number: number
54199 },
54200 avoidOverlap: {
54201 number: number
54202 },
54203 __type__: {
54204 object: object
54205 }
54206 },
54207 maxVelocity: {
54208 number: number
54209 },
54210 minVelocity: {
54211 number: number
54212 },
54213 // px/s
54214 solver: {
54215 string: ['barnesHut', 'repulsion', 'hierarchicalRepulsion', 'forceAtlas2Based']
54216 },
54217 stabilization: {
54218 enabled: {
54219 boolean: bool
54220 },
54221 iterations: {
54222 number: number
54223 },
54224 // maximum number of iteration to stabilize
54225 updateInterval: {
54226 number: number
54227 },
54228 onlyDynamicEdges: {
54229 boolean: bool
54230 },
54231 fit: {
54232 boolean: bool
54233 },
54234 __type__: {
54235 object: object,
54236 boolean: bool
54237 }
54238 },
54239 timestep: {
54240 number: number
54241 },
54242 adaptiveTimestep: {
54243 boolean: bool
54244 },
54245 __type__: {
54246 object: object,
54247 boolean: bool
54248 }
54249 },
54250 //globals :
54251 autoResize: {
54252 boolean: bool
54253 },
54254 clickToUse: {
54255 boolean: bool
54256 },
54257 locale: {
54258 string: string
54259 },
54260 locales: {
54261 __any__: {
54262 any: any
54263 },
54264 __type__: {
54265 object: object
54266 }
54267 },
54268 height: {
54269 string: string
54270 },
54271 width: {
54272 string: string
54273 },
54274 __type__: {
54275 object: object
54276 }
54277 };
54278 allOptions$1.groups.__any__ = allOptions$1.nodes;
54279 allOptions$1.manipulation.controlNodeStyle = allOptions$1.nodes;
54280 var configureOptions = {
54281 nodes: {
54282 borderWidth: [1, 0, 10, 1],
54283 borderWidthSelected: [2, 0, 10, 1],
54284 color: {
54285 border: ['color', '#2B7CE9'],
54286 background: ['color', '#97C2FC'],
54287 highlight: {
54288 border: ['color', '#2B7CE9'],
54289 background: ['color', '#D2E5FF']
54290 },
54291 hover: {
54292 border: ['color', '#2B7CE9'],
54293 background: ['color', '#D2E5FF']
54294 }
54295 },
54296 fixed: {
54297 x: false,
54298 y: false
54299 },
54300 font: {
54301 color: ['color', '#343434'],
54302 size: [14, 0, 100, 1],
54303 // px
54304 face: ['arial', 'verdana', 'tahoma'],
54305 background: ['color', 'none'],
54306 strokeWidth: [0, 0, 50, 1],
54307 // px
54308 strokeColor: ['color', '#ffffff']
54309 },
54310 //group: 'string',
54311 hidden: false,
54312 labelHighlightBold: true,
54313 //icon: {
54314 // face: 'string', //'FontAwesome',
54315 // code: 'string', //'\uf007',
54316 // size: [50, 0, 200, 1], //50,
54317 // color: ['color','#2B7CE9'] //'#aa00ff'
54318 //},
54319 //image: 'string', // --> URL
54320 physics: true,
54321 scaling: {
54322 min: [10, 0, 200, 1],
54323 max: [30, 0, 200, 1],
54324 label: {
54325 enabled: false,
54326 min: [14, 0, 200, 1],
54327 max: [30, 0, 200, 1],
54328 maxVisible: [30, 0, 200, 1],
54329 drawThreshold: [5, 0, 20, 1]
54330 }
54331 },
54332 shadow: {
54333 enabled: false,
54334 color: 'rgba(0,0,0,0.5)',
54335 size: [10, 0, 20, 1],
54336 x: [5, -30, 30, 1],
54337 y: [5, -30, 30, 1]
54338 },
54339 shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown', 'hexagon'],
54340 shapeProperties: {
54341 borderDashes: false,
54342 borderRadius: [6, 0, 20, 1],
54343 interpolation: true,
54344 useImageSize: false
54345 },
54346 size: [25, 0, 200, 1]
54347 },
54348 edges: {
54349 arrows: {
54350 to: {
54351 enabled: false,
54352 scaleFactor: [1, 0, 3, 0.05],
54353 type: 'arrow'
54354 },
54355 middle: {
54356 enabled: false,
54357 scaleFactor: [1, 0, 3, 0.05],
54358 type: 'arrow'
54359 },
54360 from: {
54361 enabled: false,
54362 scaleFactor: [1, 0, 3, 0.05],
54363 type: 'arrow'
54364 }
54365 },
54366 arrowStrikethrough: true,
54367 color: {
54368 color: ['color', '#848484'],
54369 highlight: ['color', '#848484'],
54370 hover: ['color', '#848484'],
54371 inherit: ['from', 'to', 'both', true, false],
54372 opacity: [1, 0, 1, 0.05]
54373 },
54374 dashes: false,
54375 font: {
54376 color: ['color', '#343434'],
54377 size: [14, 0, 100, 1],
54378 // px
54379 face: ['arial', 'verdana', 'tahoma'],
54380 background: ['color', 'none'],
54381 strokeWidth: [2, 0, 50, 1],
54382 // px
54383 strokeColor: ['color', '#ffffff'],
54384 align: ['horizontal', 'top', 'middle', 'bottom']
54385 },
54386 hidden: false,
54387 hoverWidth: [1.5, 0, 5, 0.1],
54388 labelHighlightBold: true,
54389 physics: true,
54390 scaling: {
54391 min: [1, 0, 100, 1],
54392 max: [15, 0, 100, 1],
54393 label: {
54394 enabled: true,
54395 min: [14, 0, 200, 1],
54396 max: [30, 0, 200, 1],
54397 maxVisible: [30, 0, 200, 1],
54398 drawThreshold: [5, 0, 20, 1]
54399 }
54400 },
54401 selectionWidth: [1.5, 0, 5, 0.1],
54402 selfReferenceSize: [20, 0, 200, 1],
54403 shadow: {
54404 enabled: false,
54405 color: 'rgba(0,0,0,0.5)',
54406 size: [10, 0, 20, 1],
54407 x: [5, -30, 30, 1],
54408 y: [5, -30, 30, 1]
54409 },
54410 smooth: {
54411 enabled: true,
54412 type: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'],
54413 forceDirection: ['horizontal', 'vertical', 'none'],
54414 roundness: [0.5, 0, 1, 0.05]
54415 },
54416 width: [1, 0, 30, 1]
54417 },
54418 layout: {
54419 //randomSeed: [0, 0, 500, 1],
54420 //improvedLayout: true,
54421 hierarchical: {
54422 enabled: false,
54423 levelSeparation: [150, 20, 500, 5],
54424 nodeSpacing: [100, 20, 500, 5],
54425 treeSpacing: [200, 20, 500, 5],
54426 blockShifting: true,
54427 edgeMinimization: true,
54428 parentCentralization: true,
54429 direction: ['UD', 'DU', 'LR', 'RL'],
54430 // UD, DU, LR, RL
54431 sortMethod: ['hubsize', 'directed'],
54432 // hubsize, directed
54433 shakeTowards: ['leaves', 'roots'] // leaves, roots
54434
54435 }
54436 },
54437 interaction: {
54438 dragNodes: true,
54439 dragView: true,
54440 hideEdgesOnDrag: false,
54441 hideEdgesOnZoom: false,
54442 hideNodesOnDrag: false,
54443 hover: false,
54444 keyboard: {
54445 enabled: false,
54446 speed: {
54447 x: [10, 0, 40, 1],
54448 y: [10, 0, 40, 1],
54449 zoom: [0.02, 0, 0.1, 0.005]
54450 },
54451 bindToWindow: true
54452 },
54453 multiselect: false,
54454 navigationButtons: false,
54455 selectable: true,
54456 selectConnectedEdges: true,
54457 hoverConnectedEdges: true,
54458 tooltipDelay: [300, 0, 1000, 25],
54459 zoomView: true,
54460 zoomSpeed: [1, 1, 1, 1]
54461 },
54462 manipulation: {
54463 enabled: false,
54464 initiallyActive: false
54465 },
54466 physics: {
54467 enabled: true,
54468 barnesHut: {
54469 //theta: [0.5, 0.1, 1, 0.05],
54470 gravitationalConstant: [-2000, -30000, 0, 50],
54471 centralGravity: [0.3, 0, 10, 0.05],
54472 springLength: [95, 0, 500, 5],
54473 springConstant: [0.04, 0, 1.2, 0.005],
54474 damping: [0.09, 0, 1, 0.01],
54475 avoidOverlap: [0, 0, 1, 0.01]
54476 },
54477 forceAtlas2Based: {
54478 //theta: [0.5, 0.1, 1, 0.05],
54479 gravitationalConstant: [-50, -500, 0, 1],
54480 centralGravity: [0.01, 0, 1, 0.005],
54481 springLength: [95, 0, 500, 5],
54482 springConstant: [0.08, 0, 1.2, 0.005],
54483 damping: [0.4, 0, 1, 0.01],
54484 avoidOverlap: [0, 0, 1, 0.01]
54485 },
54486 repulsion: {
54487 centralGravity: [0.2, 0, 10, 0.05],
54488 springLength: [200, 0, 500, 5],
54489 springConstant: [0.05, 0, 1.2, 0.005],
54490 nodeDistance: [100, 0, 500, 5],
54491 damping: [0.09, 0, 1, 0.01]
54492 },
54493 hierarchicalRepulsion: {
54494 centralGravity: [0.2, 0, 10, 0.05],
54495 springLength: [100, 0, 500, 5],
54496 springConstant: [0.01, 0, 1.2, 0.005],
54497 nodeDistance: [120, 0, 500, 5],
54498 damping: [0.09, 0, 1, 0.01],
54499 avoidOverlap: [0, 0, 1, 0.01]
54500 },
54501 maxVelocity: [50, 0, 150, 1],
54502 minVelocity: [0.1, 0.01, 0.5, 0.01],
54503 solver: ['barnesHut', 'forceAtlas2Based', 'repulsion', 'hierarchicalRepulsion'],
54504 timestep: [0.5, 0.01, 1, 0.01] //adaptiveTimestep: true
54505
54506 }
54507 };
54508
54509 var options = /*#__PURE__*/Object.freeze({
54510 __proto__: null,
54511 allOptions: allOptions$1,
54512 configureOptions: configureOptions
54513 });
54514
54515 /**
54516 * The Floyd–Warshall algorithm is an algorithm for finding shortest paths in
54517 * a weighted graph with positive or negative edge weights (but with no negative
54518 * cycles). - https://en.wikipedia.org/wiki/Floyd–Warshall_algorithm
54519 */
54520 var FloydWarshall =
54521 /*#__PURE__*/
54522 function () {
54523 /**
54524 * @ignore
54525 */
54526 function FloydWarshall() {
54527 _classCallCheck(this, FloydWarshall);
54528 }
54529 /**
54530 *
54531 * @param {Object} body
54532 * @param {Array.<Node>} nodesArray
54533 * @param {Array.<Edge>} edgesArray
54534 * @returns {{}}
54535 */
54536
54537
54538 _createClass(FloydWarshall, [{
54539 key: "getDistances",
54540 value: function getDistances(body, nodesArray, edgesArray) {
54541 var D_matrix = {};
54542 var edges = body.edges; // prepare matrix with large numbers
54543
54544 for (var i = 0; i < nodesArray.length; i++) {
54545 var node = nodesArray[i];
54546 var cell = {};
54547 D_matrix[node] = cell;
54548
54549 for (var j = 0; j < nodesArray.length; j++) {
54550 cell[nodesArray[j]] = i == j ? 0 : 1e9;
54551 }
54552 } // put the weights for the edges in. This assumes unidirectionality.
54553
54554
54555 for (var _i = 0; _i < edgesArray.length; _i++) {
54556 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
54557
54558 if (edge.connected === true && D_matrix[edge.fromId] !== undefined && D_matrix[edge.toId] !== undefined) {
54559 D_matrix[edge.fromId][edge.toId] = 1;
54560 D_matrix[edge.toId][edge.fromId] = 1;
54561 }
54562 }
54563
54564 var nodeCount = nodesArray.length; // Adapted FloydWarshall based on unidirectionality to greatly reduce complexity.
54565
54566 for (var k = 0; k < nodeCount; k++) {
54567 var knode = nodesArray[k];
54568 var kcolm = D_matrix[knode];
54569
54570 for (var _i2 = 0; _i2 < nodeCount - 1; _i2++) {
54571 var inode = nodesArray[_i2];
54572 var icolm = D_matrix[inode];
54573
54574 for (var _j = _i2 + 1; _j < nodeCount; _j++) {
54575 var jnode = nodesArray[_j];
54576 var jcolm = D_matrix[jnode];
54577 var val = Math.min(icolm[jnode], icolm[knode] + kcolm[jnode]);
54578 icolm[jnode] = val;
54579 jcolm[inode] = val;
54580 }
54581 }
54582 }
54583
54584 return D_matrix;
54585 }
54586 }]);
54587
54588 return FloydWarshall;
54589 }();
54590
54591 /**
54592 * KamadaKawai positions the nodes initially based on
54593 *
54594 * "AN ALGORITHM FOR DRAWING GENERAL UNDIRECTED GRAPHS"
54595 * -- Tomihisa KAMADA and Satoru KAWAI in 1989
54596 *
54597 * Possible optimizations in the distance calculation can be implemented.
54598 */
54599
54600 var KamadaKawai =
54601 /*#__PURE__*/
54602 function () {
54603 /**
54604 * @param {Object} body
54605 * @param {number} edgeLength
54606 * @param {number} edgeStrength
54607 */
54608 function KamadaKawai(body, edgeLength, edgeStrength) {
54609 _classCallCheck(this, KamadaKawai);
54610
54611 this.body = body;
54612 this.springLength = edgeLength;
54613 this.springConstant = edgeStrength;
54614 this.distanceSolver = new FloydWarshall();
54615 }
54616 /**
54617 * Not sure if needed but can be used to update the spring length and spring constant
54618 * @param {Object} options
54619 */
54620
54621
54622 _createClass(KamadaKawai, [{
54623 key: "setOptions",
54624 value: function setOptions(options) {
54625 if (options) {
54626 if (options.springLength) {
54627 this.springLength = options.springLength;
54628 }
54629
54630 if (options.springConstant) {
54631 this.springConstant = options.springConstant;
54632 }
54633 }
54634 }
54635 /**
54636 * Position the system
54637 * @param {Array.<Node>} nodesArray
54638 * @param {Array.<vis.Edge>} edgesArray
54639 * @param {boolean} [ignoreClusters=false]
54640 */
54641
54642 }, {
54643 key: "solve",
54644 value: function solve(nodesArray, edgesArray) {
54645 var ignoreClusters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
54646 // get distance matrix
54647 var D_matrix = this.distanceSolver.getDistances(this.body, nodesArray, edgesArray); // distance matrix
54648 // get the L Matrix
54649
54650 this._createL_matrix(D_matrix); // get the K Matrix
54651
54652
54653 this._createK_matrix(D_matrix); // initial E Matrix
54654
54655
54656 this._createE_matrix(); // calculate positions
54657
54658
54659 var threshold = 0.01;
54660 var innerThreshold = 1;
54661 var iterations = 0;
54662 var maxIterations = Math.max(1000, Math.min(10 * this.body.nodeIndices.length, 6000));
54663 var maxInnerIterations = 5;
54664 var maxEnergy = 1e9;
54665 var highE_nodeId = 0,
54666 dE_dx = 0,
54667 dE_dy = 0,
54668 delta_m = 0,
54669 subIterations = 0;
54670
54671 while (maxEnergy > threshold && iterations < maxIterations) {
54672 iterations += 1;
54673
54674 var _this$_getHighestEner = this._getHighestEnergyNode(ignoreClusters);
54675
54676 var _this$_getHighestEner2 = _slicedToArray(_this$_getHighestEner, 4);
54677
54678 highE_nodeId = _this$_getHighestEner2[0];
54679 maxEnergy = _this$_getHighestEner2[1];
54680 dE_dx = _this$_getHighestEner2[2];
54681 dE_dy = _this$_getHighestEner2[3];
54682 delta_m = maxEnergy;
54683 subIterations = 0;
54684
54685 while (delta_m > innerThreshold && subIterations < maxInnerIterations) {
54686 subIterations += 1;
54687
54688 this._moveNode(highE_nodeId, dE_dx, dE_dy);
54689
54690 var _this$_getEnergy = this._getEnergy(highE_nodeId);
54691
54692 var _this$_getEnergy2 = _slicedToArray(_this$_getEnergy, 3);
54693
54694 delta_m = _this$_getEnergy2[0];
54695 dE_dx = _this$_getEnergy2[1];
54696 dE_dy = _this$_getEnergy2[2];
54697 }
54698 }
54699 }
54700 /**
54701 * get the node with the highest energy
54702 * @param {boolean} ignoreClusters
54703 * @returns {number[]}
54704 * @private
54705 */
54706
54707 }, {
54708 key: "_getHighestEnergyNode",
54709 value: function _getHighestEnergyNode(ignoreClusters) {
54710 var nodesArray = this.body.nodeIndices;
54711 var nodes = this.body.nodes;
54712 var maxEnergy = 0;
54713 var maxEnergyNodeId = nodesArray[0];
54714 var dE_dx_max = 0,
54715 dE_dy_max = 0;
54716
54717 for (var nodeIdx = 0; nodeIdx < nodesArray.length; nodeIdx++) {
54718 var m = nodesArray[nodeIdx]; // by not evaluating nodes with predefined positions we should only move nodes that have no positions.
54719
54720 if (nodes[m].predefinedPosition === false || nodes[m].isCluster === true && ignoreClusters === true || nodes[m].options.fixed.x === true || nodes[m].options.fixed.y === true) {
54721 var _this$_getEnergy3 = this._getEnergy(m),
54722 _this$_getEnergy4 = _slicedToArray(_this$_getEnergy3, 3),
54723 delta_m = _this$_getEnergy4[0],
54724 dE_dx = _this$_getEnergy4[1],
54725 dE_dy = _this$_getEnergy4[2];
54726
54727 if (maxEnergy < delta_m) {
54728 maxEnergy = delta_m;
54729 maxEnergyNodeId = m;
54730 dE_dx_max = dE_dx;
54731 dE_dy_max = dE_dy;
54732 }
54733 }
54734 }
54735
54736 return [maxEnergyNodeId, maxEnergy, dE_dx_max, dE_dy_max];
54737 }
54738 /**
54739 * calculate the energy of a single node
54740 * @param {Node.id} m
54741 * @returns {number[]}
54742 * @private
54743 */
54744
54745 }, {
54746 key: "_getEnergy",
54747 value: function _getEnergy(m) {
54748 var _this$E_sums$m = _slicedToArray(this.E_sums[m], 2),
54749 dE_dx = _this$E_sums$m[0],
54750 dE_dy = _this$E_sums$m[1];
54751
54752 var delta_m = Math.sqrt(Math.pow(dE_dx, 2) + Math.pow(dE_dy, 2));
54753 return [delta_m, dE_dx, dE_dy];
54754 }
54755 /**
54756 * move the node based on it's energy
54757 * the dx and dy are calculated from the linear system proposed by Kamada and Kawai
54758 * @param {number} m
54759 * @param {number} dE_dx
54760 * @param {number} dE_dy
54761 * @private
54762 */
54763
54764 }, {
54765 key: "_moveNode",
54766 value: function _moveNode(m, dE_dx, dE_dy) {
54767 var nodesArray = this.body.nodeIndices;
54768 var nodes = this.body.nodes;
54769 var d2E_dx2 = 0;
54770 var d2E_dxdy = 0;
54771 var d2E_dy2 = 0;
54772 var x_m = nodes[m].x;
54773 var y_m = nodes[m].y;
54774 var km = this.K_matrix[m];
54775 var lm = this.L_matrix[m];
54776
54777 for (var iIdx = 0; iIdx < nodesArray.length; iIdx++) {
54778 var i = nodesArray[iIdx];
54779
54780 if (i !== m) {
54781 var x_i = nodes[i].x;
54782 var y_i = nodes[i].y;
54783 var kmat = km[i];
54784 var lmat = lm[i];
54785 var denominator = 1.0 / Math.pow(Math.pow(x_m - x_i, 2) + Math.pow(y_m - y_i, 2), 1.5);
54786 d2E_dx2 += kmat * (1 - lmat * Math.pow(y_m - y_i, 2) * denominator);
54787 d2E_dxdy += kmat * (lmat * (x_m - x_i) * (y_m - y_i) * denominator);
54788 d2E_dy2 += kmat * (1 - lmat * Math.pow(x_m - x_i, 2) * denominator);
54789 }
54790 } // make the variable names easier to make the solving of the linear system easier to read
54791
54792
54793 var A = d2E_dx2,
54794 B = d2E_dxdy,
54795 C = dE_dx,
54796 D = d2E_dy2,
54797 E = dE_dy; // solve the linear system for dx and dy
54798
54799 var dy = (C / A + E / B) / (B / A - D / B);
54800 var dx = -(B * dy + C) / A; // move the node
54801
54802 nodes[m].x += dx;
54803 nodes[m].y += dy; // Recalculate E_matrix (should be incremental)
54804
54805 this._updateE_matrix(m);
54806 }
54807 /**
54808 * Create the L matrix: edge length times shortest path
54809 * @param {Object} D_matrix
54810 * @private
54811 */
54812
54813 }, {
54814 key: "_createL_matrix",
54815 value: function _createL_matrix(D_matrix) {
54816 var nodesArray = this.body.nodeIndices;
54817 var edgeLength = this.springLength;
54818 this.L_matrix = [];
54819
54820 for (var i = 0; i < nodesArray.length; i++) {
54821 this.L_matrix[nodesArray[i]] = {};
54822
54823 for (var j = 0; j < nodesArray.length; j++) {
54824 this.L_matrix[nodesArray[i]][nodesArray[j]] = edgeLength * D_matrix[nodesArray[i]][nodesArray[j]];
54825 }
54826 }
54827 }
54828 /**
54829 * Create the K matrix: spring constants times shortest path
54830 * @param {Object} D_matrix
54831 * @private
54832 */
54833
54834 }, {
54835 key: "_createK_matrix",
54836 value: function _createK_matrix(D_matrix) {
54837 var nodesArray = this.body.nodeIndices;
54838 var edgeStrength = this.springConstant;
54839 this.K_matrix = [];
54840
54841 for (var i = 0; i < nodesArray.length; i++) {
54842 this.K_matrix[nodesArray[i]] = {};
54843
54844 for (var j = 0; j < nodesArray.length; j++) {
54845 this.K_matrix[nodesArray[i]][nodesArray[j]] = edgeStrength * Math.pow(D_matrix[nodesArray[i]][nodesArray[j]], -2);
54846 }
54847 }
54848 }
54849 /**
54850 * Create matrix with all energies between nodes
54851 * @private
54852 */
54853
54854 }, {
54855 key: "_createE_matrix",
54856 value: function _createE_matrix() {
54857 var nodesArray = this.body.nodeIndices;
54858 var nodes = this.body.nodes;
54859 this.E_matrix = {};
54860 this.E_sums = {};
54861
54862 for (var mIdx = 0; mIdx < nodesArray.length; mIdx++) {
54863 this.E_matrix[nodesArray[mIdx]] = [];
54864 }
54865
54866 for (var _mIdx = 0; _mIdx < nodesArray.length; _mIdx++) {
54867 var m = nodesArray[_mIdx];
54868 var x_m = nodes[m].x;
54869 var y_m = nodes[m].y;
54870 var dE_dx = 0;
54871 var dE_dy = 0;
54872
54873 for (var iIdx = _mIdx; iIdx < nodesArray.length; iIdx++) {
54874 var i = nodesArray[iIdx];
54875
54876 if (i !== m) {
54877 var x_i = nodes[i].x;
54878 var y_i = nodes[i].y;
54879 var denominator = 1.0 / Math.sqrt(Math.pow(x_m - x_i, 2) + Math.pow(y_m - y_i, 2));
54880 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)];
54881 this.E_matrix[i][_mIdx] = this.E_matrix[m][iIdx];
54882 dE_dx += this.E_matrix[m][iIdx][0];
54883 dE_dy += this.E_matrix[m][iIdx][1];
54884 }
54885 } //Store sum
54886
54887
54888 this.E_sums[m] = [dE_dx, dE_dy];
54889 }
54890 }
54891 /**
54892 * Update method, just doing single column (rows are auto-updated) (update all sums)
54893 *
54894 * @param {number} m
54895 * @private
54896 */
54897
54898 }, {
54899 key: "_updateE_matrix",
54900 value: function _updateE_matrix(m) {
54901 var nodesArray = this.body.nodeIndices;
54902 var nodes = this.body.nodes;
54903 var colm = this.E_matrix[m];
54904 var kcolm = this.K_matrix[m];
54905 var lcolm = this.L_matrix[m];
54906 var x_m = nodes[m].x;
54907 var y_m = nodes[m].y;
54908 var dE_dx = 0;
54909 var dE_dy = 0;
54910
54911 for (var iIdx = 0; iIdx < nodesArray.length; iIdx++) {
54912 var i = nodesArray[iIdx];
54913
54914 if (i !== m) {
54915 //Keep old energy value for sum modification below
54916 var cell = colm[iIdx];
54917 var oldDx = cell[0];
54918 var oldDy = cell[1]; //Calc new energy:
54919
54920 var x_i = nodes[i].x;
54921 var y_i = nodes[i].y;
54922 var denominator = 1.0 / Math.sqrt(Math.pow(x_m - x_i, 2) + Math.pow(y_m - y_i, 2));
54923 var dx = kcolm[i] * (x_m - x_i - lcolm[i] * (x_m - x_i) * denominator);
54924 var dy = kcolm[i] * (y_m - y_i - lcolm[i] * (y_m - y_i) * denominator);
54925 colm[iIdx] = [dx, dy];
54926 dE_dx += dx;
54927 dE_dy += dy; //add new energy to sum of each column
54928
54929 var sum = this.E_sums[i];
54930 sum[0] += dx - oldDx;
54931 sum[1] += dy - oldDy;
54932 }
54933 } //Store sum at -1 index
54934
54935
54936 this.E_sums[m] = [dE_dx, dE_dy];
54937 }
54938 }]);
54939
54940 return KamadaKawai;
54941 }();
54942
54943 // Load custom shapes into CanvasRenderingContext2D
54944 /**
54945 * Create a network visualization, displaying nodes and edges.
54946 *
54947 * @param {Element} container The DOM element in which the Network will
54948 * be created. Normally a div element.
54949 * @param {Object} data An object containing parameters
54950 * {Array} nodes
54951 * {Array} edges
54952 * @param {Object} options Options
54953 * @constructor Network
54954 */
54955
54956 function Network(container, data, options) {
54957 var _this = this;
54958
54959 if (!(this instanceof Network)) {
54960 throw new SyntaxError('Constructor must be called with the new operator');
54961 } // set constant values
54962
54963
54964 this.options = {};
54965 this.defaultOptions = {
54966 locale: 'en',
54967 locales: locales,
54968 clickToUse: false
54969 };
54970 extend(this.options, this.defaultOptions);
54971 /**
54972 * Containers for nodes and edges.
54973 *
54974 * 'edges' and 'nodes' contain the full definitions of all the network elements.
54975 * 'nodeIndices' and 'edgeIndices' contain the id's of the active elements.
54976 *
54977 * The distinction is important, because a defined node need not be active, i.e.
54978 * visible on the canvas. This happens in particular when clusters are defined, in
54979 * that case there will be nodes and edges not displayed.
54980 * The bottom line is that all code with actions related to visibility, *must* use
54981 * 'nodeIndices' and 'edgeIndices', not 'nodes' and 'edges' directly.
54982 */
54983
54984 this.body = {
54985 container: container,
54986 // See comment above for following fields
54987 nodes: {},
54988 nodeIndices: [],
54989 edges: {},
54990 edgeIndices: [],
54991 emitter: {
54992 on: this.on.bind(this),
54993 off: this.off.bind(this),
54994 emit: this.emit.bind(this),
54995 once: this.once.bind(this)
54996 },
54997 eventListeners: {
54998 onTap: function onTap() {},
54999 onTouch: function onTouch() {},
55000 onDoubleTap: function onDoubleTap() {},
55001 onHold: function onHold() {},
55002 onDragStart: function onDragStart() {},
55003 onDrag: function onDrag() {},
55004 onDragEnd: function onDragEnd() {},
55005 onMouseWheel: function onMouseWheel() {},
55006 onPinch: function onPinch() {},
55007 onMouseMove: function onMouseMove() {},
55008 onRelease: function onRelease() {},
55009 onContext: function onContext() {}
55010 },
55011 data: {
55012 nodes: null,
55013 // A DataSet or DataView
55014 edges: null // A DataSet or DataView
55015
55016 },
55017 functions: {
55018 createNode: function createNode() {},
55019 createEdge: function createEdge() {},
55020 getPointer: function getPointer() {}
55021 },
55022 modules: {},
55023 view: {
55024 scale: 1,
55025 translation: {
55026 x: 0,
55027 y: 0
55028 }
55029 }
55030 }; // bind the event listeners
55031
55032 this.bindEventListeners(); // setting up all modules
55033
55034 this.images = new Images(function () {
55035 return _this.body.emitter.emit("_requestRedraw");
55036 }); // object with images
55037
55038 this.groups = new Groups(); // object with groups
55039
55040 this.canvas = new Canvas(this.body); // DOM handler
55041
55042 this.selectionHandler = new SelectionHandler(this.body, this.canvas); // Selection handler
55043
55044 this.interactionHandler = new InteractionHandler(this.body, this.canvas, this.selectionHandler); // Interaction handler handles all the hammer bindings (that are bound by canvas), key
55045
55046 this.view = new View(this.body, this.canvas); // camera handler, does animations and zooms
55047
55048 this.renderer = new CanvasRenderer(this.body, this.canvas); // renderer, starts renderloop, has events that modules can hook into
55049
55050 this.physics = new PhysicsEngine(this.body); // physics engine, does all the simulations
55051
55052 this.layoutEngine = new LayoutEngine(this.body); // layout engine for inital layout and hierarchical layout
55053
55054 this.clustering = new ClusterEngine(this.body); // clustering api
55055
55056 this.manipulation = new ManipulationSystem(this.body, this.canvas, this.selectionHandler, this.interactionHandler); // data manipulation system
55057
55058 this.nodesHandler = new NodesHandler(this.body, this.images, this.groups, this.layoutEngine); // Handle adding, deleting and updating of nodes as well as global options
55059
55060 this.edgesHandler = new EdgesHandler(this.body, this.images, this.groups); // Handle adding, deleting and updating of edges as well as global options
55061
55062 this.body.modules["kamadaKawai"] = new KamadaKawai(this.body, 150, 0.05); // Layouting algorithm.
55063
55064 this.body.modules["clustering"] = this.clustering; // create the DOM elements
55065
55066 this.canvas._create(); // apply options
55067
55068
55069 this.setOptions(options); // load data (the disable start variable will be the same as the enabled clustering)
55070
55071 this.setData(data);
55072 } // Extend Network with an Emitter mixin
55073
55074 componentEmitter(Network.prototype);
55075 /**
55076 * Set options
55077 * @param {Object} options
55078 */
55079
55080 Network.prototype.setOptions = function (options) {
55081 var _this2 = this;
55082
55083 if (options === null) {
55084 options = undefined; // This ensures that options handling doesn't crash in the handling
55085 }
55086
55087 if (options !== undefined) {
55088 var errorFound = Validator.validate(options, allOptions$1);
55089
55090 if (errorFound === true) {
55091 console.log('%cErrors have been found in the supplied options object.', printStyle);
55092 } // copy the global fields over
55093
55094
55095 var fields = ['locale', 'locales', 'clickToUse'];
55096 selectiveDeepExtend(fields, this.options, options); // the hierarchical system can adapt the edges and the physics to it's own options because not all combinations work with the hierarichical system.
55097
55098 options = this.layoutEngine.setOptions(options.layout, options);
55099 this.canvas.setOptions(options); // options for canvas are in globals
55100 // pass the options to the modules
55101
55102 this.groups.setOptions(options.groups);
55103 this.nodesHandler.setOptions(options.nodes);
55104 this.edgesHandler.setOptions(options.edges);
55105 this.physics.setOptions(options.physics);
55106 this.manipulation.setOptions(options.manipulation, options, this.options); // manipulation uses the locales in the globals
55107
55108 this.interactionHandler.setOptions(options.interaction);
55109 this.renderer.setOptions(options.interaction); // options for rendering are in interaction
55110
55111 this.selectionHandler.setOptions(options.interaction); // options for selection are in interaction
55112 // reload the settings of the nodes to apply changes in groups that are not referenced by pointer.
55113
55114 if (options.groups !== undefined) {
55115 this.body.emitter.emit("refreshNodes");
55116 } // these two do not have options at the moment, here for completeness
55117 //this.view.setOptions(options.view);
55118 //this.clustering.setOptions(options.clustering);
55119
55120
55121 if ('configure' in options) {
55122 if (!this.configurator) {
55123 this.configurator = new Configurator(this, this.body.container, configureOptions, this.canvas.pixelRatio);
55124 }
55125
55126 this.configurator.setOptions(options.configure);
55127 } // if the configuration system is enabled, copy all options and put them into the config system
55128
55129
55130 if (this.configurator && this.configurator.options.enabled === true) {
55131 var networkOptions = {
55132 nodes: {},
55133 edges: {},
55134 layout: {},
55135 interaction: {},
55136 manipulation: {},
55137 physics: {},
55138 global: {}
55139 };
55140 deepExtend(networkOptions.nodes, this.nodesHandler.options);
55141 deepExtend(networkOptions.edges, this.edgesHandler.options);
55142 deepExtend(networkOptions.layout, this.layoutEngine.options); // load the selectionHandler and render default options in to the interaction group
55143
55144 deepExtend(networkOptions.interaction, this.selectionHandler.options);
55145 deepExtend(networkOptions.interaction, this.renderer.options);
55146 deepExtend(networkOptions.interaction, this.interactionHandler.options);
55147 deepExtend(networkOptions.manipulation, this.manipulation.options);
55148 deepExtend(networkOptions.physics, this.physics.options); // load globals into the global object
55149
55150 deepExtend(networkOptions.global, this.canvas.options);
55151 deepExtend(networkOptions.global, this.options);
55152 this.configurator.setModuleOptions(networkOptions);
55153 } // handle network global options
55154
55155
55156 if (options.clickToUse !== undefined) {
55157 if (options.clickToUse === true) {
55158 if (this.activator === undefined) {
55159 this.activator = new Activator_1(this.canvas.frame);
55160 this.activator.on('change', function () {
55161 _this2.body.emitter.emit("activate");
55162 });
55163 }
55164 } else {
55165 if (this.activator !== undefined) {
55166 this.activator.destroy();
55167 delete this.activator;
55168 }
55169
55170 this.body.emitter.emit("activate");
55171 }
55172 } else {
55173 this.body.emitter.emit("activate");
55174 }
55175
55176 this.canvas.setSize(); // start the physics simulation. Can be safely called multiple times.
55177
55178 this.body.emitter.emit("startSimulation");
55179 }
55180 };
55181 /**
55182 * Update the visible nodes and edges list with the most recent node state.
55183 *
55184 * Visible nodes are stored in this.body.nodeIndices.
55185 * Visible edges are stored in this.body.edgeIndices.
55186 * A node or edges is visible if it is not hidden or clustered.
55187 *
55188 * @private
55189 */
55190
55191
55192 Network.prototype._updateVisibleIndices = function () {
55193 var nodes = this.body.nodes;
55194 var edges = this.body.edges;
55195 this.body.nodeIndices = [];
55196 this.body.edgeIndices = [];
55197
55198 for (var nodeId in nodes) {
55199 if (nodes.hasOwnProperty(nodeId)) {
55200 if (!this.clustering._isClusteredNode(nodeId) && nodes[nodeId].options.hidden === false) {
55201 this.body.nodeIndices.push(nodes[nodeId].id);
55202 }
55203 }
55204 }
55205
55206 for (var edgeId in edges) {
55207 if (edges.hasOwnProperty(edgeId)) {
55208 var edge = edges[edgeId]; // It can happen that this is executed *after* a node edge has been removed,
55209 // but *before* the edge itself has been removed. Taking this into account.
55210
55211 var fromNode = nodes[edge.fromId];
55212 var toNode = nodes[edge.toId];
55213 var edgeNodesPresent = fromNode !== undefined && toNode !== undefined;
55214 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
55215 && toNode.options.hidden === false; // idem
55216
55217 if (isVisible) {
55218 this.body.edgeIndices.push(edge.id);
55219 }
55220 }
55221 }
55222 };
55223 /**
55224 * Bind all events
55225 */
55226
55227
55228 Network.prototype.bindEventListeners = function () {
55229 var _this3 = this;
55230
55231 // This event will trigger a rebuilding of the cache everything.
55232 // Used when nodes or edges have been added or removed.
55233 this.body.emitter.on("_dataChanged", function () {
55234 _this3.edgesHandler._updateState();
55235
55236 _this3.body.emitter.emit("_dataUpdated");
55237 }); // this is called when options of EXISTING nodes or edges have changed.
55238
55239 this.body.emitter.on("_dataUpdated", function () {
55240 // Order important in following block
55241 _this3.clustering._updateState();
55242
55243 _this3._updateVisibleIndices();
55244
55245 _this3._updateValueRange(_this3.body.nodes);
55246
55247 _this3._updateValueRange(_this3.body.edges); // start simulation (can be called safely, even if already running)
55248
55249
55250 _this3.body.emitter.emit("startSimulation");
55251
55252 _this3.body.emitter.emit("_requestRedraw");
55253 });
55254 };
55255 /**
55256 * Set nodes and edges, and optionally options as well.
55257 *
55258 * @param {Object} data Object containing parameters:
55259 * {Array | DataSet | DataView} [nodes] Array with nodes
55260 * {Array | DataSet | DataView} [edges] Array with edges
55261 * {String} [dot] String containing data in DOT format
55262 * {String} [gephi] String containing data in gephi JSON format
55263 * {Options} [options] Object with options
55264 */
55265
55266
55267 Network.prototype.setData = function (data) {
55268 // reset the physics engine.
55269 this.body.emitter.emit("resetPhysics");
55270 this.body.emitter.emit("_resetData"); // unselect all to ensure no selections from old data are carried over.
55271
55272 this.selectionHandler.unselectAll();
55273
55274 if (data && data.dot && (data.nodes || data.edges)) {
55275 throw new SyntaxError('Data must contain either parameter "dot" or ' + ' parameter pair "nodes" and "edges", but not both.');
55276 } // set options
55277
55278
55279 this.setOptions(data && data.options); // set all data
55280
55281 if (data && data.dot) {
55282 console.log('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
55283
55284 var dotData = dotparser.DOTToGraph(data.dot);
55285 this.setData(dotData);
55286 return;
55287 } else if (data && data.gephi) {
55288 // parse DOT file
55289 console.log('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);');
55290 var gephiData = parseGephi(data.gephi);
55291 this.setData(gephiData);
55292 return;
55293 } else {
55294 this.nodesHandler.setData(data && data.nodes, true);
55295 this.edgesHandler.setData(data && data.edges, true);
55296 } // emit change in data
55297
55298
55299 this.body.emitter.emit("_dataChanged"); // emit data loaded
55300
55301 this.body.emitter.emit("_dataLoaded"); // find a stable position or start animating to a stable position
55302
55303 this.body.emitter.emit("initPhysics");
55304 };
55305 /**
55306 * Cleans up all bindings of the network, removing it fully from the memory IF the variable is set to null after calling this function.
55307 * var network = new vis.Network(..);
55308 * network.destroy();
55309 * network = null;
55310 */
55311
55312
55313 Network.prototype.destroy = function () {
55314 this.body.emitter.emit("destroy"); // clear events
55315
55316 this.body.emitter.off();
55317 this.off(); // delete modules
55318
55319 delete this.groups;
55320 delete this.canvas;
55321 delete this.selectionHandler;
55322 delete this.interactionHandler;
55323 delete this.view;
55324 delete this.renderer;
55325 delete this.physics;
55326 delete this.layoutEngine;
55327 delete this.clustering;
55328 delete this.manipulation;
55329 delete this.nodesHandler;
55330 delete this.edgesHandler;
55331 delete this.configurator;
55332 delete this.images;
55333
55334 for (var nodeId in this.body.nodes) {
55335 if (!this.body.nodes.hasOwnProperty(nodeId)) continue;
55336 delete this.body.nodes[nodeId];
55337 }
55338
55339 for (var edgeId in this.body.edges) {
55340 if (!this.body.edges.hasOwnProperty(edgeId)) continue;
55341 delete this.body.edges[edgeId];
55342 } // remove the container and everything inside it recursively
55343
55344
55345 recursiveDOMDelete(this.body.container);
55346 };
55347 /**
55348 * Update the values of all object in the given array according to the current
55349 * value range of the objects in the array.
55350 * @param {Object} obj An object containing a set of Edges or Nodes
55351 * The objects must have a method getValue() and
55352 * setValueRange(min, max).
55353 * @private
55354 */
55355
55356
55357 Network.prototype._updateValueRange = function (obj) {
55358 var id; // determine the range of the objects
55359
55360 var valueMin = undefined;
55361 var valueMax = undefined;
55362 var valueTotal = 0;
55363
55364 for (id in obj) {
55365 if (obj.hasOwnProperty(id)) {
55366 var value = obj[id].getValue();
55367
55368 if (value !== undefined) {
55369 valueMin = valueMin === undefined ? value : Math.min(value, valueMin);
55370 valueMax = valueMax === undefined ? value : Math.max(value, valueMax);
55371 valueTotal += value;
55372 }
55373 }
55374 } // adjust the range of all objects
55375
55376
55377 if (valueMin !== undefined && valueMax !== undefined) {
55378 for (id in obj) {
55379 if (obj.hasOwnProperty(id)) {
55380 obj[id].setValueRange(valueMin, valueMax, valueTotal);
55381 }
55382 }
55383 }
55384 };
55385 /**
55386 * Returns true when the Network is active.
55387 * @returns {boolean}
55388 */
55389
55390
55391 Network.prototype.isActive = function () {
55392 return !this.activator || this.activator.active;
55393 };
55394
55395 Network.prototype.setSize = function () {
55396 return this.canvas.setSize.apply(this.canvas, arguments);
55397 };
55398
55399 Network.prototype.canvasToDOM = function () {
55400 return this.canvas.canvasToDOM.apply(this.canvas, arguments);
55401 };
55402
55403 Network.prototype.DOMtoCanvas = function () {
55404 return this.canvas.DOMtoCanvas.apply(this.canvas, arguments);
55405 };
55406 /**
55407 * Nodes can be in clusters. Clusters can also be in clusters. This function returns and array of
55408 * nodeIds showing where the node is.
55409 *
55410 * If any nodeId in the chain, especially the first passed in as a parameter, is not present in
55411 * the current nodes list, an empty array is returned.
55412 *
55413 * Example:
55414 * cluster 'A' contains cluster 'B',
55415 * cluster 'B' contains cluster 'C',
55416 * cluster 'C' contains node 'fred'.
55417 * `jsnetwork.clustering.findNode('fred')` will return `['A','B','C','fred']`.
55418 *
55419 * @param {string|number} nodeId
55420 * @returns {Array}
55421 */
55422
55423
55424 Network.prototype.findNode = function () {
55425 return this.clustering.findNode.apply(this.clustering, arguments);
55426 };
55427
55428 Network.prototype.isCluster = function () {
55429 return this.clustering.isCluster.apply(this.clustering, arguments);
55430 };
55431
55432 Network.prototype.openCluster = function () {
55433 return this.clustering.openCluster.apply(this.clustering, arguments);
55434 };
55435
55436 Network.prototype.cluster = function () {
55437 return this.clustering.cluster.apply(this.clustering, arguments);
55438 };
55439
55440 Network.prototype.getNodesInCluster = function () {
55441 return this.clustering.getNodesInCluster.apply(this.clustering, arguments);
55442 };
55443
55444 Network.prototype.clusterByConnection = function () {
55445 return this.clustering.clusterByConnection.apply(this.clustering, arguments);
55446 };
55447
55448 Network.prototype.clusterByHubsize = function () {
55449 return this.clustering.clusterByHubsize.apply(this.clustering, arguments);
55450 };
55451 /**
55452 * This method will cluster all nodes with 1 edge with their respective connected node.
55453 * The options object is explained in full <a data-scroll="" data-options="{ &quot;easing&quot;: &quot;easeInCubic&quot; }" href="#optionsObject">below</a>.
55454 *
55455 * @param {object} [options]
55456 * @returns {undefined}
55457 */
55458
55459
55460 Network.prototype.clusterOutliers = function () {
55461 return this.clustering.clusterOutliers.apply(this.clustering, arguments);
55462 };
55463
55464 Network.prototype.getSeed = function () {
55465 return this.layoutEngine.getSeed.apply(this.layoutEngine, arguments);
55466 };
55467
55468 Network.prototype.enableEditMode = function () {
55469 return this.manipulation.enableEditMode.apply(this.manipulation, arguments);
55470 };
55471
55472 Network.prototype.disableEditMode = function () {
55473 return this.manipulation.disableEditMode.apply(this.manipulation, arguments);
55474 };
55475
55476 Network.prototype.addNodeMode = function () {
55477 return this.manipulation.addNodeMode.apply(this.manipulation, arguments);
55478 };
55479
55480 Network.prototype.editNode = function () {
55481 return this.manipulation.editNode.apply(this.manipulation, arguments);
55482 };
55483
55484 Network.prototype.editNodeMode = function () {
55485 console.log("Deprecated: Please use editNode instead of editNodeMode.");
55486 return this.manipulation.editNode.apply(this.manipulation, arguments);
55487 };
55488
55489 Network.prototype.addEdgeMode = function () {
55490 return this.manipulation.addEdgeMode.apply(this.manipulation, arguments);
55491 };
55492
55493 Network.prototype.editEdgeMode = function () {
55494 return this.manipulation.editEdgeMode.apply(this.manipulation, arguments);
55495 };
55496
55497 Network.prototype.deleteSelected = function () {
55498 return this.manipulation.deleteSelected.apply(this.manipulation, arguments);
55499 };
55500
55501 Network.prototype.getPositions = function () {
55502 return this.nodesHandler.getPositions.apply(this.nodesHandler, arguments);
55503 };
55504
55505 Network.prototype.storePositions = function () {
55506 return this.nodesHandler.storePositions.apply(this.nodesHandler, arguments);
55507 };
55508
55509 Network.prototype.moveNode = function () {
55510 return this.nodesHandler.moveNode.apply(this.nodesHandler, arguments);
55511 };
55512
55513 Network.prototype.getBoundingBox = function () {
55514 return this.nodesHandler.getBoundingBox.apply(this.nodesHandler, arguments);
55515 };
55516
55517 Network.prototype.getConnectedNodes = function (objectId) {
55518 if (this.body.nodes[objectId] !== undefined) {
55519 return this.nodesHandler.getConnectedNodes.apply(this.nodesHandler, arguments);
55520 } else {
55521 return this.edgesHandler.getConnectedNodes.apply(this.edgesHandler, arguments);
55522 }
55523 };
55524
55525 Network.prototype.getConnectedEdges = function () {
55526 return this.nodesHandler.getConnectedEdges.apply(this.nodesHandler, arguments);
55527 };
55528
55529 Network.prototype.startSimulation = function () {
55530 return this.physics.startSimulation.apply(this.physics, arguments);
55531 };
55532
55533 Network.prototype.stopSimulation = function () {
55534 return this.physics.stopSimulation.apply(this.physics, arguments);
55535 };
55536
55537 Network.prototype.stabilize = function () {
55538 return this.physics.stabilize.apply(this.physics, arguments);
55539 };
55540
55541 Network.prototype.getSelection = function () {
55542 return this.selectionHandler.getSelection.apply(this.selectionHandler, arguments);
55543 };
55544
55545 Network.prototype.setSelection = function () {
55546 return this.selectionHandler.setSelection.apply(this.selectionHandler, arguments);
55547 };
55548
55549 Network.prototype.getSelectedNodes = function () {
55550 return this.selectionHandler.getSelectedNodes.apply(this.selectionHandler, arguments);
55551 };
55552
55553 Network.prototype.getSelectedEdges = function () {
55554 return this.selectionHandler.getSelectedEdges.apply(this.selectionHandler, arguments);
55555 };
55556
55557 Network.prototype.getNodeAt = function () {
55558 var node = this.selectionHandler.getNodeAt.apply(this.selectionHandler, arguments);
55559
55560 if (node !== undefined && node.id !== undefined) {
55561 return node.id;
55562 }
55563
55564 return node;
55565 };
55566
55567 Network.prototype.getEdgeAt = function () {
55568 var edge = this.selectionHandler.getEdgeAt.apply(this.selectionHandler, arguments);
55569
55570 if (edge !== undefined && edge.id !== undefined) {
55571 return edge.id;
55572 }
55573
55574 return edge;
55575 };
55576
55577 Network.prototype.selectNodes = function () {
55578 return this.selectionHandler.selectNodes.apply(this.selectionHandler, arguments);
55579 };
55580
55581 Network.prototype.selectEdges = function () {
55582 return this.selectionHandler.selectEdges.apply(this.selectionHandler, arguments);
55583 };
55584
55585 Network.prototype.unselectAll = function () {
55586 this.selectionHandler.unselectAll.apply(this.selectionHandler, arguments);
55587 this.redraw();
55588 };
55589
55590 Network.prototype.redraw = function () {
55591 return this.renderer.redraw.apply(this.renderer, arguments);
55592 };
55593
55594 Network.prototype.getScale = function () {
55595 return this.view.getScale.apply(this.view, arguments);
55596 };
55597
55598 Network.prototype.getViewPosition = function () {
55599 return this.view.getViewPosition.apply(this.view, arguments);
55600 };
55601
55602 Network.prototype.fit = function () {
55603 return this.view.fit.apply(this.view, arguments);
55604 };
55605
55606 Network.prototype.moveTo = function () {
55607 return this.view.moveTo.apply(this.view, arguments);
55608 };
55609
55610 Network.prototype.focus = function () {
55611 return this.view.focus.apply(this.view, arguments);
55612 };
55613
55614 Network.prototype.releaseNode = function () {
55615 return this.view.releaseNode.apply(this.view, arguments);
55616 };
55617
55618 Network.prototype.getOptionsFromConfigurator = function () {
55619 var options = {};
55620
55621 if (this.configurator) {
55622 options = this.configurator.getOptions.apply(this.configurator);
55623 }
55624
55625 return options;
55626 };
55627
55628 var parseDOTNetwork = DOTToGraph_1;
55629 // overflow in UMD builds. They all export vis namespace therefore reexporting
55630 // leads to loading vis to load vis to load vis…
55631
55632 exports.DataSet = DataSet;
55633 exports.DataView = DataView$2;
55634 exports.Network = Network;
55635 exports.NetworkImages = Images;
55636 exports.Queue = Queue;
55637 exports.data = esm$1;
55638 exports.networkDOTParser = dotparser$1;
55639 exports.networkGephiParser = gephiParser;
55640 exports.networkOptions = options;
55641 exports.parseDOTNetwork = parseDOTNetwork;
55642 exports.parseGephiNetwork = parseGephi;
55643 exports.util = esm;
55644
55645 Object.defineProperty(exports, '__esModule', { value: true });
55646
55647})));
55648//# sourceMappingURL=vis-network.js.map