UNPKG

1.49 MBJavaScriptView Raw
1/**
2 * vis-timeline - timeline-graph2d
3 * https://github.com/visjs/vis-timeline
4 *
5 * Create a fully customizable, interactive timeline with items and ranges.
6 *
7 * @version 6.2.0
8 * @date 2019-11-09T08:23:36Z
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 */
26var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
27
28function commonjsRequire () {
29 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
30}
31
32function createCommonjsModule(fn, module) {
33 return module = { exports: {} }, fn(module, module.exports), module.exports;
34}
35
36var O = 'object';
37var check = function (it) {
38 return it && it.Math == Math && it;
39};
40
41// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
42var global_1 =
43 // eslint-disable-next-line no-undef
44 check(typeof globalThis == O && globalThis) ||
45 check(typeof window == O && window) ||
46 check(typeof self == O && self) ||
47 check(typeof commonjsGlobal == O && commonjsGlobal) ||
48 // eslint-disable-next-line no-new-func
49 Function('return this')();
50
51var fails = function (exec) {
52 try {
53 return !!exec();
54 } catch (error) {
55 return true;
56 }
57};
58
59// Thank's IE8 for his funny defineProperty
60var descriptors = !fails(function () {
61 return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
62});
63
64var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
65var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
66
67// Nashorn ~ JDK8 bug
68var NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
69
70// `Object.prototype.propertyIsEnumerable` method implementation
71// https://tc39.github.io/ecma262/#sec-object.prototype.propertyisenumerable
72var f = NASHORN_BUG ? function propertyIsEnumerable(V) {
73 var descriptor = getOwnPropertyDescriptor(this, V);
74 return !!descriptor && descriptor.enumerable;
75} : nativePropertyIsEnumerable;
76
77var objectPropertyIsEnumerable = {
78 f: f
79};
80
81var createPropertyDescriptor = function (bitmap, value) {
82 return {
83 enumerable: !(bitmap & 1),
84 configurable: !(bitmap & 2),
85 writable: !(bitmap & 4),
86 value: value
87 };
88};
89
90var toString = {}.toString;
91
92var classofRaw = function (it) {
93 return toString.call(it).slice(8, -1);
94};
95
96var split = ''.split;
97
98// fallback for non-array-like ES3 and non-enumerable old V8 strings
99var indexedObject = fails(function () {
100 // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
101 // eslint-disable-next-line no-prototype-builtins
102 return !Object('z').propertyIsEnumerable(0);
103}) ? function (it) {
104 return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
105} : Object;
106
107// `RequireObjectCoercible` abstract operation
108// https://tc39.github.io/ecma262/#sec-requireobjectcoercible
109var requireObjectCoercible = function (it) {
110 if (it == undefined) throw TypeError("Can't call method on " + it);
111 return it;
112};
113
114// toObject with fallback for non-array-like ES3 strings
115
116
117
118var toIndexedObject = function (it) {
119 return indexedObject(requireObjectCoercible(it));
120};
121
122var isObject = function (it) {
123 return typeof it === 'object' ? it !== null : typeof it === 'function';
124};
125
126// `ToPrimitive` abstract operation
127// https://tc39.github.io/ecma262/#sec-toprimitive
128// instead of the ES6 spec version, we didn't implement @@toPrimitive case
129// and the second argument - flag - preferred type is a string
130var toPrimitive = function (input, PREFERRED_STRING) {
131 if (!isObject(input)) return input;
132 var fn, val;
133 if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
134 if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
135 if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
136 throw TypeError("Can't convert object to primitive value");
137};
138
139var hasOwnProperty = {}.hasOwnProperty;
140
141var has = function (it, key) {
142 return hasOwnProperty.call(it, key);
143};
144
145var document$1 = global_1.document;
146// typeof document.createElement is 'object' in old IE
147var EXISTS = isObject(document$1) && isObject(document$1.createElement);
148
149var documentCreateElement = function (it) {
150 return EXISTS ? document$1.createElement(it) : {};
151};
152
153// Thank's IE8 for his funny defineProperty
154var ie8DomDefine = !descriptors && !fails(function () {
155 return Object.defineProperty(documentCreateElement('div'), 'a', {
156 get: function () { return 7; }
157 }).a != 7;
158});
159
160var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
161
162// `Object.getOwnPropertyDescriptor` method
163// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor
164var f$1 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
165 O = toIndexedObject(O);
166 P = toPrimitive(P, true);
167 if (ie8DomDefine) try {
168 return nativeGetOwnPropertyDescriptor(O, P);
169 } catch (error) { /* empty */ }
170 if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
171};
172
173var objectGetOwnPropertyDescriptor = {
174 f: f$1
175};
176
177var anObject = function (it) {
178 if (!isObject(it)) {
179 throw TypeError(String(it) + ' is not an object');
180 } return it;
181};
182
183var nativeDefineProperty = Object.defineProperty;
184
185// `Object.defineProperty` method
186// https://tc39.github.io/ecma262/#sec-object.defineproperty
187var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
188 anObject(O);
189 P = toPrimitive(P, true);
190 anObject(Attributes);
191 if (ie8DomDefine) try {
192 return nativeDefineProperty(O, P, Attributes);
193 } catch (error) { /* empty */ }
194 if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
195 if ('value' in Attributes) O[P] = Attributes.value;
196 return O;
197};
198
199var objectDefineProperty = {
200 f: f$2
201};
202
203var hide = descriptors ? function (object, key, value) {
204 return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
205} : function (object, key, value) {
206 object[key] = value;
207 return object;
208};
209
210var setGlobal = function (key, value) {
211 try {
212 hide(global_1, key, value);
213 } catch (error) {
214 global_1[key] = value;
215 } return value;
216};
217
218var shared = createCommonjsModule(function (module) {
219var SHARED = '__core-js_shared__';
220var store = global_1[SHARED] || setGlobal(SHARED, {});
221
222(module.exports = function (key, value) {
223 return store[key] || (store[key] = value !== undefined ? value : {});
224})('versions', []).push({
225 version: '3.2.1',
226 mode: 'global',
227 copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
228});
229});
230
231var functionToString = shared('native-function-to-string', Function.toString);
232
233var WeakMap = global_1.WeakMap;
234
235var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(functionToString.call(WeakMap));
236
237var id = 0;
238var postfix = Math.random();
239
240var uid = function (key) {
241 return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
242};
243
244var keys = shared('keys');
245
246var sharedKey = function (key) {
247 return keys[key] || (keys[key] = uid(key));
248};
249
250var hiddenKeys = {};
251
252var WeakMap$1 = global_1.WeakMap;
253var set, get, has$1;
254
255var enforce = function (it) {
256 return has$1(it) ? get(it) : set(it, {});
257};
258
259var getterFor = function (TYPE) {
260 return function (it) {
261 var state;
262 if (!isObject(it) || (state = get(it)).type !== TYPE) {
263 throw TypeError('Incompatible receiver, ' + TYPE + ' required');
264 } return state;
265 };
266};
267
268if (nativeWeakMap) {
269 var store = new WeakMap$1();
270 var wmget = store.get;
271 var wmhas = store.has;
272 var wmset = store.set;
273 set = function (it, metadata) {
274 wmset.call(store, it, metadata);
275 return metadata;
276 };
277 get = function (it) {
278 return wmget.call(store, it) || {};
279 };
280 has$1 = function (it) {
281 return wmhas.call(store, it);
282 };
283} else {
284 var STATE = sharedKey('state');
285 hiddenKeys[STATE] = true;
286 set = function (it, metadata) {
287 hide(it, STATE, metadata);
288 return metadata;
289 };
290 get = function (it) {
291 return has(it, STATE) ? it[STATE] : {};
292 };
293 has$1 = function (it) {
294 return has(it, STATE);
295 };
296}
297
298var internalState = {
299 set: set,
300 get: get,
301 has: has$1,
302 enforce: enforce,
303 getterFor: getterFor
304};
305
306var redefine = createCommonjsModule(function (module) {
307var getInternalState = internalState.get;
308var enforceInternalState = internalState.enforce;
309var TEMPLATE = String(functionToString).split('toString');
310
311shared('inspectSource', function (it) {
312 return functionToString.call(it);
313});
314
315(module.exports = function (O, key, value, options) {
316 var unsafe = options ? !!options.unsafe : false;
317 var simple = options ? !!options.enumerable : false;
318 var noTargetGet = options ? !!options.noTargetGet : false;
319 if (typeof value == 'function') {
320 if (typeof key == 'string' && !has(value, 'name')) hide(value, 'name', key);
321 enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
322 }
323 if (O === global_1) {
324 if (simple) O[key] = value;
325 else setGlobal(key, value);
326 return;
327 } else if (!unsafe) {
328 delete O[key];
329 } else if (!noTargetGet && O[key]) {
330 simple = true;
331 }
332 if (simple) O[key] = value;
333 else hide(O, key, value);
334// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
335})(Function.prototype, 'toString', function toString() {
336 return typeof this == 'function' && getInternalState(this).source || functionToString.call(this);
337});
338});
339
340var path = global_1;
341
342var aFunction = function (variable) {
343 return typeof variable == 'function' ? variable : undefined;
344};
345
346var getBuiltIn = function (namespace, method) {
347 return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
348 : path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
349};
350
351var ceil = Math.ceil;
352var floor = Math.floor;
353
354// `ToInteger` abstract operation
355// https://tc39.github.io/ecma262/#sec-tointeger
356var toInteger = function (argument) {
357 return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
358};
359
360var min = Math.min;
361
362// `ToLength` abstract operation
363// https://tc39.github.io/ecma262/#sec-tolength
364var toLength = function (argument) {
365 return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
366};
367
368var max = Math.max;
369var min$1 = Math.min;
370
371// Helper for a popular repeating case of the spec:
372// Let integer be ? ToInteger(index).
373// If integer < 0, let result be max((length + integer), 0); else let result be min(length, length).
374var toAbsoluteIndex = function (index, length) {
375 var integer = toInteger(index);
376 return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
377};
378
379// `Array.prototype.{ indexOf, includes }` methods implementation
380var createMethod = function (IS_INCLUDES) {
381 return function ($this, el, fromIndex) {
382 var O = toIndexedObject($this);
383 var length = toLength(O.length);
384 var index = toAbsoluteIndex(fromIndex, length);
385 var value;
386 // Array#includes uses SameValueZero equality algorithm
387 // eslint-disable-next-line no-self-compare
388 if (IS_INCLUDES && el != el) while (length > index) {
389 value = O[index++];
390 // eslint-disable-next-line no-self-compare
391 if (value != value) return true;
392 // Array#indexOf ignores holes, Array#includes - not
393 } else for (;length > index; index++) {
394 if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
395 } return !IS_INCLUDES && -1;
396 };
397};
398
399var arrayIncludes = {
400 // `Array.prototype.includes` method
401 // https://tc39.github.io/ecma262/#sec-array.prototype.includes
402 includes: createMethod(true),
403 // `Array.prototype.indexOf` method
404 // https://tc39.github.io/ecma262/#sec-array.prototype.indexof
405 indexOf: createMethod(false)
406};
407
408var indexOf = arrayIncludes.indexOf;
409
410
411var objectKeysInternal = function (object, names) {
412 var O = toIndexedObject(object);
413 var i = 0;
414 var result = [];
415 var key;
416 for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
417 // Don't enum bug & hidden keys
418 while (names.length > i) if (has(O, key = names[i++])) {
419 ~indexOf(result, key) || result.push(key);
420 }
421 return result;
422};
423
424// IE8- don't enum bug keys
425var enumBugKeys = [
426 'constructor',
427 'hasOwnProperty',
428 'isPrototypeOf',
429 'propertyIsEnumerable',
430 'toLocaleString',
431 'toString',
432 'valueOf'
433];
434
435var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype');
436
437// `Object.getOwnPropertyNames` method
438// https://tc39.github.io/ecma262/#sec-object.getownpropertynames
439var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
440 return objectKeysInternal(O, hiddenKeys$1);
441};
442
443var objectGetOwnPropertyNames = {
444 f: f$3
445};
446
447var f$4 = Object.getOwnPropertySymbols;
448
449var objectGetOwnPropertySymbols = {
450 f: f$4
451};
452
453// all object keys, includes non-enumerable and symbols
454var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
455 var keys = objectGetOwnPropertyNames.f(anObject(it));
456 var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
457 return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
458};
459
460var copyConstructorProperties = function (target, source) {
461 var keys = ownKeys(source);
462 var defineProperty = objectDefineProperty.f;
463 var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
464 for (var i = 0; i < keys.length; i++) {
465 var key = keys[i];
466 if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
467 }
468};
469
470var replacement = /#|\.prototype\./;
471
472var isForced = function (feature, detection) {
473 var value = data[normalize(feature)];
474 return value == POLYFILL ? true
475 : value == NATIVE ? false
476 : typeof detection == 'function' ? fails(detection)
477 : !!detection;
478};
479
480var normalize = isForced.normalize = function (string) {
481 return String(string).replace(replacement, '.').toLowerCase();
482};
483
484var data = isForced.data = {};
485var NATIVE = isForced.NATIVE = 'N';
486var POLYFILL = isForced.POLYFILL = 'P';
487
488var isForced_1 = isForced;
489
490var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
491
492
493
494
495
496
497/*
498 options.target - name of the target object
499 options.global - target is the global object
500 options.stat - export as static methods of target
501 options.proto - export as prototype methods of target
502 options.real - real prototype method for the `pure` version
503 options.forced - export even if the native feature is available
504 options.bind - bind methods to the target, required for the `pure` version
505 options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
506 options.unsafe - use the simple assignment of property instead of delete + defineProperty
507 options.sham - add a flag to not completely full polyfills
508 options.enumerable - export as enumerable property
509 options.noTargetGet - prevent calling a getter on target
510*/
511var _export = function (options, source) {
512 var TARGET = options.target;
513 var GLOBAL = options.global;
514 var STATIC = options.stat;
515 var FORCED, target, key, targetProperty, sourceProperty, descriptor;
516 if (GLOBAL) {
517 target = global_1;
518 } else if (STATIC) {
519 target = global_1[TARGET] || setGlobal(TARGET, {});
520 } else {
521 target = (global_1[TARGET] || {}).prototype;
522 }
523 if (target) for (key in source) {
524 sourceProperty = source[key];
525 if (options.noTargetGet) {
526 descriptor = getOwnPropertyDescriptor$1(target, key);
527 targetProperty = descriptor && descriptor.value;
528 } else targetProperty = target[key];
529 FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
530 // contained in target
531 if (!FORCED && targetProperty !== undefined) {
532 if (typeof sourceProperty === typeof targetProperty) continue;
533 copyConstructorProperties(sourceProperty, targetProperty);
534 }
535 // add a flag to not completely full polyfills
536 if (options.sham || (targetProperty && targetProperty.sham)) {
537 hide(sourceProperty, 'sham', true);
538 }
539 // extend global
540 redefine(target, key, sourceProperty, options);
541 }
542};
543
544var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
545 // Chrome 38 Symbol has incorrect toString conversion
546 // eslint-disable-next-line no-undef
547 return !String(Symbol());
548});
549
550// `IsArray` abstract operation
551// https://tc39.github.io/ecma262/#sec-isarray
552var isArray = Array.isArray || function isArray(arg) {
553 return classofRaw(arg) == 'Array';
554};
555
556// `ToObject` abstract operation
557// https://tc39.github.io/ecma262/#sec-toobject
558var toObject = function (argument) {
559 return Object(requireObjectCoercible(argument));
560};
561
562// `Object.keys` method
563// https://tc39.github.io/ecma262/#sec-object.keys
564var objectKeys = Object.keys || function keys(O) {
565 return objectKeysInternal(O, enumBugKeys);
566};
567
568// `Object.defineProperties` method
569// https://tc39.github.io/ecma262/#sec-object.defineproperties
570var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
571 anObject(O);
572 var keys = objectKeys(Properties);
573 var length = keys.length;
574 var index = 0;
575 var key;
576 while (length > index) objectDefineProperty.f(O, key = keys[index++], Properties[key]);
577 return O;
578};
579
580var html = getBuiltIn('document', 'documentElement');
581
582var IE_PROTO = sharedKey('IE_PROTO');
583
584var PROTOTYPE = 'prototype';
585var Empty = function () { /* empty */ };
586
587// Create object with fake `null` prototype: use iframe Object with cleared prototype
588var createDict = function () {
589 // Thrash, waste and sodomy: IE GC bug
590 var iframe = documentCreateElement('iframe');
591 var length = enumBugKeys.length;
592 var lt = '<';
593 var script = 'script';
594 var gt = '>';
595 var js = 'java' + script + ':';
596 var iframeDocument;
597 iframe.style.display = 'none';
598 html.appendChild(iframe);
599 iframe.src = String(js);
600 iframeDocument = iframe.contentWindow.document;
601 iframeDocument.open();
602 iframeDocument.write(lt + script + gt + 'document.F=Object' + lt + '/' + script + gt);
603 iframeDocument.close();
604 createDict = iframeDocument.F;
605 while (length--) delete createDict[PROTOTYPE][enumBugKeys[length]];
606 return createDict();
607};
608
609// `Object.create` method
610// https://tc39.github.io/ecma262/#sec-object.create
611var objectCreate = Object.create || function create(O, Properties) {
612 var result;
613 if (O !== null) {
614 Empty[PROTOTYPE] = anObject(O);
615 result = new Empty();
616 Empty[PROTOTYPE] = null;
617 // add "__proto__" for Object.getPrototypeOf polyfill
618 result[IE_PROTO] = O;
619 } else result = createDict();
620 return Properties === undefined ? result : objectDefineProperties(result, Properties);
621};
622
623hiddenKeys[IE_PROTO] = true;
624
625var nativeGetOwnPropertyNames = objectGetOwnPropertyNames.f;
626
627var toString$1 = {}.toString;
628
629var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
630 ? Object.getOwnPropertyNames(window) : [];
631
632var getWindowNames = function (it) {
633 try {
634 return nativeGetOwnPropertyNames(it);
635 } catch (error) {
636 return windowNames.slice();
637 }
638};
639
640// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
641var f$5 = function getOwnPropertyNames(it) {
642 return windowNames && toString$1.call(it) == '[object Window]'
643 ? getWindowNames(it)
644 : nativeGetOwnPropertyNames(toIndexedObject(it));
645};
646
647var objectGetOwnPropertyNamesExternal = {
648 f: f$5
649};
650
651var Symbol$1 = global_1.Symbol;
652var store$1 = shared('wks');
653
654var wellKnownSymbol = function (name) {
655 return store$1[name] || (store$1[name] = nativeSymbol && Symbol$1[name]
656 || (nativeSymbol ? Symbol$1 : uid)('Symbol.' + name));
657};
658
659var f$6 = wellKnownSymbol;
660
661var wrappedWellKnownSymbol = {
662 f: f$6
663};
664
665var defineProperty = objectDefineProperty.f;
666
667var defineWellKnownSymbol = function (NAME) {
668 var Symbol = path.Symbol || (path.Symbol = {});
669 if (!has(Symbol, NAME)) defineProperty(Symbol, NAME, {
670 value: wrappedWellKnownSymbol.f(NAME)
671 });
672};
673
674var defineProperty$1 = objectDefineProperty.f;
675
676
677
678var TO_STRING_TAG = wellKnownSymbol('toStringTag');
679
680var setToStringTag = function (it, TAG, STATIC) {
681 if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {
682 defineProperty$1(it, TO_STRING_TAG, { configurable: true, value: TAG });
683 }
684};
685
686var aFunction$1 = function (it) {
687 if (typeof it != 'function') {
688 throw TypeError(String(it) + ' is not a function');
689 } return it;
690};
691
692// optional / simple context binding
693var bindContext = function (fn, that, length) {
694 aFunction$1(fn);
695 if (that === undefined) return fn;
696 switch (length) {
697 case 0: return function () {
698 return fn.call(that);
699 };
700 case 1: return function (a) {
701 return fn.call(that, a);
702 };
703 case 2: return function (a, b) {
704 return fn.call(that, a, b);
705 };
706 case 3: return function (a, b, c) {
707 return fn.call(that, a, b, c);
708 };
709 }
710 return function (/* ...args */) {
711 return fn.apply(that, arguments);
712 };
713};
714
715var SPECIES = wellKnownSymbol('species');
716
717// `ArraySpeciesCreate` abstract operation
718// https://tc39.github.io/ecma262/#sec-arrayspeciescreate
719var arraySpeciesCreate = function (originalArray, length) {
720 var C;
721 if (isArray(originalArray)) {
722 C = originalArray.constructor;
723 // cross-realm fallback
724 if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
725 else if (isObject(C)) {
726 C = C[SPECIES];
727 if (C === null) C = undefined;
728 }
729 } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
730};
731
732var push = [].push;
733
734// `Array.prototype.{ forEach, map, filter, some, every, find, findIndex }` methods implementation
735var createMethod$1 = function (TYPE) {
736 var IS_MAP = TYPE == 1;
737 var IS_FILTER = TYPE == 2;
738 var IS_SOME = TYPE == 3;
739 var IS_EVERY = TYPE == 4;
740 var IS_FIND_INDEX = TYPE == 6;
741 var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
742 return function ($this, callbackfn, that, specificCreate) {
743 var O = toObject($this);
744 var self = indexedObject(O);
745 var boundFunction = bindContext(callbackfn, that, 3);
746 var length = toLength(self.length);
747 var index = 0;
748 var create = specificCreate || arraySpeciesCreate;
749 var target = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
750 var value, result;
751 for (;length > index; index++) if (NO_HOLES || index in self) {
752 value = self[index];
753 result = boundFunction(value, index, O);
754 if (TYPE) {
755 if (IS_MAP) target[index] = result; // map
756 else if (result) switch (TYPE) {
757 case 3: return true; // some
758 case 5: return value; // find
759 case 6: return index; // findIndex
760 case 2: push.call(target, value); // filter
761 } else if (IS_EVERY) return false; // every
762 }
763 }
764 return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
765 };
766};
767
768var arrayIteration = {
769 // `Array.prototype.forEach` method
770 // https://tc39.github.io/ecma262/#sec-array.prototype.foreach
771 forEach: createMethod$1(0),
772 // `Array.prototype.map` method
773 // https://tc39.github.io/ecma262/#sec-array.prototype.map
774 map: createMethod$1(1),
775 // `Array.prototype.filter` method
776 // https://tc39.github.io/ecma262/#sec-array.prototype.filter
777 filter: createMethod$1(2),
778 // `Array.prototype.some` method
779 // https://tc39.github.io/ecma262/#sec-array.prototype.some
780 some: createMethod$1(3),
781 // `Array.prototype.every` method
782 // https://tc39.github.io/ecma262/#sec-array.prototype.every
783 every: createMethod$1(4),
784 // `Array.prototype.find` method
785 // https://tc39.github.io/ecma262/#sec-array.prototype.find
786 find: createMethod$1(5),
787 // `Array.prototype.findIndex` method
788 // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
789 findIndex: createMethod$1(6)
790};
791
792var $forEach = arrayIteration.forEach;
793
794var HIDDEN = sharedKey('hidden');
795var SYMBOL = 'Symbol';
796var PROTOTYPE$1 = 'prototype';
797var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
798var setInternalState = internalState.set;
799var getInternalState = internalState.getterFor(SYMBOL);
800var ObjectPrototype = Object[PROTOTYPE$1];
801var $Symbol = global_1.Symbol;
802var JSON$1 = global_1.JSON;
803var nativeJSONStringify = JSON$1 && JSON$1.stringify;
804var nativeGetOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
805var nativeDefineProperty$1 = objectDefineProperty.f;
806var nativeGetOwnPropertyNames$1 = objectGetOwnPropertyNamesExternal.f;
807var nativePropertyIsEnumerable$1 = objectPropertyIsEnumerable.f;
808var AllSymbols = shared('symbols');
809var ObjectPrototypeSymbols = shared('op-symbols');
810var StringToSymbolRegistry = shared('string-to-symbol-registry');
811var SymbolToStringRegistry = shared('symbol-to-string-registry');
812var WellKnownSymbolsStore = shared('wks');
813var QObject = global_1.QObject;
814// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
815var USE_SETTER = !QObject || !QObject[PROTOTYPE$1] || !QObject[PROTOTYPE$1].findChild;
816
817// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
818var setSymbolDescriptor = descriptors && fails(function () {
819 return objectCreate(nativeDefineProperty$1({}, 'a', {
820 get: function () { return nativeDefineProperty$1(this, 'a', { value: 7 }).a; }
821 })).a != 7;
822}) ? function (O, P, Attributes) {
823 var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor$1(ObjectPrototype, P);
824 if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];
825 nativeDefineProperty$1(O, P, Attributes);
826 if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {
827 nativeDefineProperty$1(ObjectPrototype, P, ObjectPrototypeDescriptor);
828 }
829} : nativeDefineProperty$1;
830
831var wrap = function (tag, description) {
832 var symbol = AllSymbols[tag] = objectCreate($Symbol[PROTOTYPE$1]);
833 setInternalState(symbol, {
834 type: SYMBOL,
835 tag: tag,
836 description: description
837 });
838 if (!descriptors) symbol.description = description;
839 return symbol;
840};
841
842var isSymbol = nativeSymbol && typeof $Symbol.iterator == 'symbol' ? function (it) {
843 return typeof it == 'symbol';
844} : function (it) {
845 return Object(it) instanceof $Symbol;
846};
847
848var $defineProperty = function defineProperty(O, P, Attributes) {
849 if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
850 anObject(O);
851 var key = toPrimitive(P, true);
852 anObject(Attributes);
853 if (has(AllSymbols, key)) {
854 if (!Attributes.enumerable) {
855 if (!has(O, HIDDEN)) nativeDefineProperty$1(O, HIDDEN, createPropertyDescriptor(1, {}));
856 O[HIDDEN][key] = true;
857 } else {
858 if (has(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
859 Attributes = objectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });
860 } return setSymbolDescriptor(O, key, Attributes);
861 } return nativeDefineProperty$1(O, key, Attributes);
862};
863
864var $defineProperties = function defineProperties(O, Properties) {
865 anObject(O);
866 var properties = toIndexedObject(Properties);
867 var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));
868 $forEach(keys, function (key) {
869 if (!descriptors || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]);
870 });
871 return O;
872};
873
874var $create = function create(O, Properties) {
875 return Properties === undefined ? objectCreate(O) : $defineProperties(objectCreate(O), Properties);
876};
877
878var $propertyIsEnumerable = function propertyIsEnumerable(V) {
879 var P = toPrimitive(V, true);
880 var enumerable = nativePropertyIsEnumerable$1.call(this, P);
881 if (this === ObjectPrototype && has(AllSymbols, P) && !has(ObjectPrototypeSymbols, P)) return false;
882 return enumerable || !has(this, P) || !has(AllSymbols, P) || has(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true;
883};
884
885var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
886 var it = toIndexedObject(O);
887 var key = toPrimitive(P, true);
888 if (it === ObjectPrototype && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return;
889 var descriptor = nativeGetOwnPropertyDescriptor$1(it, key);
890 if (descriptor && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) {
891 descriptor.enumerable = true;
892 }
893 return descriptor;
894};
895
896var $getOwnPropertyNames = function getOwnPropertyNames(O) {
897 var names = nativeGetOwnPropertyNames$1(toIndexedObject(O));
898 var result = [];
899 $forEach(names, function (key) {
900 if (!has(AllSymbols, key) && !has(hiddenKeys, key)) result.push(key);
901 });
902 return result;
903};
904
905var $getOwnPropertySymbols = function getOwnPropertySymbols(O) {
906 var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;
907 var names = nativeGetOwnPropertyNames$1(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
908 var result = [];
909 $forEach(names, function (key) {
910 if (has(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has(ObjectPrototype, key))) {
911 result.push(AllSymbols[key]);
912 }
913 });
914 return result;
915};
916
917// `Symbol` constructor
918// https://tc39.github.io/ecma262/#sec-symbol-constructor
919if (!nativeSymbol) {
920 $Symbol = function Symbol() {
921 if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
922 var description = !arguments.length || arguments[0] === undefined ? undefined : String(arguments[0]);
923 var tag = uid(description);
924 var setter = function (value) {
925 if (this === ObjectPrototype) setter.call(ObjectPrototypeSymbols, value);
926 if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
927 setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
928 };
929 if (descriptors && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });
930 return wrap(tag, description);
931 };
932
933 redefine($Symbol[PROTOTYPE$1], 'toString', function toString() {
934 return getInternalState(this).tag;
935 });
936
937 objectPropertyIsEnumerable.f = $propertyIsEnumerable;
938 objectDefineProperty.f = $defineProperty;
939 objectGetOwnPropertyDescriptor.f = $getOwnPropertyDescriptor;
940 objectGetOwnPropertyNames.f = objectGetOwnPropertyNamesExternal.f = $getOwnPropertyNames;
941 objectGetOwnPropertySymbols.f = $getOwnPropertySymbols;
942
943 if (descriptors) {
944 // https://github.com/tc39/proposal-Symbol-description
945 nativeDefineProperty$1($Symbol[PROTOTYPE$1], 'description', {
946 configurable: true,
947 get: function description() {
948 return getInternalState(this).description;
949 }
950 });
951 {
952 redefine(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });
953 }
954 }
955
956 wrappedWellKnownSymbol.f = function (name) {
957 return wrap(wellKnownSymbol(name), name);
958 };
959}
960
961_export({ global: true, wrap: true, forced: !nativeSymbol, sham: !nativeSymbol }, {
962 Symbol: $Symbol
963});
964
965$forEach(objectKeys(WellKnownSymbolsStore), function (name) {
966 defineWellKnownSymbol(name);
967});
968
969_export({ target: SYMBOL, stat: true, forced: !nativeSymbol }, {
970 // `Symbol.for` method
971 // https://tc39.github.io/ecma262/#sec-symbol.for
972 'for': function (key) {
973 var string = String(key);
974 if (has(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
975 var symbol = $Symbol(string);
976 StringToSymbolRegistry[string] = symbol;
977 SymbolToStringRegistry[symbol] = string;
978 return symbol;
979 },
980 // `Symbol.keyFor` method
981 // https://tc39.github.io/ecma262/#sec-symbol.keyfor
982 keyFor: function keyFor(sym) {
983 if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
984 if (has(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
985 },
986 useSetter: function () { USE_SETTER = true; },
987 useSimple: function () { USE_SETTER = false; }
988});
989
990_export({ target: 'Object', stat: true, forced: !nativeSymbol, sham: !descriptors }, {
991 // `Object.create` method
992 // https://tc39.github.io/ecma262/#sec-object.create
993 create: $create,
994 // `Object.defineProperty` method
995 // https://tc39.github.io/ecma262/#sec-object.defineproperty
996 defineProperty: $defineProperty,
997 // `Object.defineProperties` method
998 // https://tc39.github.io/ecma262/#sec-object.defineproperties
999 defineProperties: $defineProperties,
1000 // `Object.getOwnPropertyDescriptor` method
1001 // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
1002 getOwnPropertyDescriptor: $getOwnPropertyDescriptor
1003});
1004
1005_export({ target: 'Object', stat: true, forced: !nativeSymbol }, {
1006 // `Object.getOwnPropertyNames` method
1007 // https://tc39.github.io/ecma262/#sec-object.getownpropertynames
1008 getOwnPropertyNames: $getOwnPropertyNames,
1009 // `Object.getOwnPropertySymbols` method
1010 // https://tc39.github.io/ecma262/#sec-object.getownpropertysymbols
1011 getOwnPropertySymbols: $getOwnPropertySymbols
1012});
1013
1014// Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
1015// https://bugs.chromium.org/p/v8/issues/detail?id=3443
1016_export({ target: 'Object', stat: true, forced: fails(function () { objectGetOwnPropertySymbols.f(1); }) }, {
1017 getOwnPropertySymbols: function getOwnPropertySymbols(it) {
1018 return objectGetOwnPropertySymbols.f(toObject(it));
1019 }
1020});
1021
1022// `JSON.stringify` method behavior with symbols
1023// https://tc39.github.io/ecma262/#sec-json.stringify
1024JSON$1 && _export({ target: 'JSON', stat: true, forced: !nativeSymbol || fails(function () {
1025 var symbol = $Symbol();
1026 // MS Edge converts symbol values to JSON as {}
1027 return nativeJSONStringify([symbol]) != '[null]'
1028 // WebKit converts symbol values to JSON as null
1029 || nativeJSONStringify({ a: symbol }) != '{}'
1030 // V8 throws on boxed symbols
1031 || nativeJSONStringify(Object(symbol)) != '{}';
1032}) }, {
1033 stringify: function stringify(it) {
1034 var args = [it];
1035 var index = 1;
1036 var replacer, $replacer;
1037 while (arguments.length > index) args.push(arguments[index++]);
1038 $replacer = replacer = args[1];
1039 if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
1040 if (!isArray(replacer)) replacer = function (key, value) {
1041 if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
1042 if (!isSymbol(value)) return value;
1043 };
1044 args[1] = replacer;
1045 return nativeJSONStringify.apply(JSON$1, args);
1046 }
1047});
1048
1049// `Symbol.prototype[@@toPrimitive]` method
1050// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@toprimitive
1051if (!$Symbol[PROTOTYPE$1][TO_PRIMITIVE]) hide($Symbol[PROTOTYPE$1], TO_PRIMITIVE, $Symbol[PROTOTYPE$1].valueOf);
1052// `Symbol.prototype[@@toStringTag]` property
1053// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@tostringtag
1054setToStringTag($Symbol, SYMBOL);
1055
1056hiddenKeys[HIDDEN] = true;
1057
1058var defineProperty$2 = objectDefineProperty.f;
1059
1060
1061var NativeSymbol = global_1.Symbol;
1062
1063if (descriptors && typeof NativeSymbol == 'function' && (!('description' in NativeSymbol.prototype) ||
1064 // Safari 12 bug
1065 NativeSymbol().description !== undefined
1066)) {
1067 var EmptyStringDescriptionStore = {};
1068 // wrap Symbol constructor for correct work with undefined description
1069 var SymbolWrapper = function Symbol() {
1070 var description = arguments.length < 1 || arguments[0] === undefined ? undefined : String(arguments[0]);
1071 var result = this instanceof SymbolWrapper
1072 ? new NativeSymbol(description)
1073 // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)'
1074 : description === undefined ? NativeSymbol() : NativeSymbol(description);
1075 if (description === '') EmptyStringDescriptionStore[result] = true;
1076 return result;
1077 };
1078 copyConstructorProperties(SymbolWrapper, NativeSymbol);
1079 var symbolPrototype = SymbolWrapper.prototype = NativeSymbol.prototype;
1080 symbolPrototype.constructor = SymbolWrapper;
1081
1082 var symbolToString = symbolPrototype.toString;
1083 var native = String(NativeSymbol('test')) == 'Symbol(test)';
1084 var regexp = /^Symbol\((.*)\)[^)]+$/;
1085 defineProperty$2(symbolPrototype, 'description', {
1086 configurable: true,
1087 get: function description() {
1088 var symbol = isObject(this) ? this.valueOf() : this;
1089 var string = symbolToString.call(symbol);
1090 if (has(EmptyStringDescriptionStore, symbol)) return '';
1091 var desc = native ? string.slice(7, -1) : string.replace(regexp, '$1');
1092 return desc === '' ? undefined : desc;
1093 }
1094 });
1095
1096 _export({ global: true, forced: true }, {
1097 Symbol: SymbolWrapper
1098 });
1099}
1100
1101// `Symbol.iterator` well-known symbol
1102// https://tc39.github.io/ecma262/#sec-symbol.iterator
1103defineWellKnownSymbol('iterator');
1104
1105var createProperty = function (object, key, value) {
1106 var propertyKey = toPrimitive(key);
1107 if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
1108 else object[propertyKey] = value;
1109};
1110
1111var SPECIES$1 = wellKnownSymbol('species');
1112
1113var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
1114 return !fails(function () {
1115 var array = [];
1116 var constructor = array.constructor = {};
1117 constructor[SPECIES$1] = function () {
1118 return { foo: 1 };
1119 };
1120 return array[METHOD_NAME](Boolean).foo !== 1;
1121 });
1122};
1123
1124var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
1125var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
1126var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
1127
1128var IS_CONCAT_SPREADABLE_SUPPORT = !fails(function () {
1129 var array = [];
1130 array[IS_CONCAT_SPREADABLE] = false;
1131 return array.concat()[0] !== array;
1132});
1133
1134var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
1135
1136var isConcatSpreadable = function (O) {
1137 if (!isObject(O)) return false;
1138 var spreadable = O[IS_CONCAT_SPREADABLE];
1139 return spreadable !== undefined ? !!spreadable : isArray(O);
1140};
1141
1142var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
1143
1144// `Array.prototype.concat` method
1145// https://tc39.github.io/ecma262/#sec-array.prototype.concat
1146// with adding support of @@isConcatSpreadable and @@species
1147_export({ target: 'Array', proto: true, forced: FORCED }, {
1148 concat: function concat(arg) { // eslint-disable-line no-unused-vars
1149 var O = toObject(this);
1150 var A = arraySpeciesCreate(O, 0);
1151 var n = 0;
1152 var i, k, length, len, E;
1153 for (i = -1, length = arguments.length; i < length; i++) {
1154 E = i === -1 ? O : arguments[i];
1155 if (isConcatSpreadable(E)) {
1156 len = toLength(E.length);
1157 if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
1158 for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
1159 } else {
1160 if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
1161 createProperty(A, n++, E);
1162 }
1163 }
1164 A.length = n;
1165 return A;
1166 }
1167});
1168
1169var $filter = arrayIteration.filter;
1170
1171
1172// `Array.prototype.filter` method
1173// https://tc39.github.io/ecma262/#sec-array.prototype.filter
1174// with adding support of @@species
1175_export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('filter') }, {
1176 filter: function filter(callbackfn /* , thisArg */) {
1177 return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
1178 }
1179});
1180
1181var sloppyArrayMethod = function (METHOD_NAME, argument) {
1182 var method = [][METHOD_NAME];
1183 return !method || !fails(function () {
1184 // eslint-disable-next-line no-useless-call,no-throw-literal
1185 method.call(null, argument || function () { throw 1; }, 1);
1186 });
1187};
1188
1189var $forEach$1 = arrayIteration.forEach;
1190
1191
1192// `Array.prototype.forEach` method implementation
1193// https://tc39.github.io/ecma262/#sec-array.prototype.foreach
1194var arrayForEach = sloppyArrayMethod('forEach') ? function forEach(callbackfn /* , thisArg */) {
1195 return $forEach$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
1196} : [].forEach;
1197
1198// `Array.prototype.forEach` method
1199// https://tc39.github.io/ecma262/#sec-array.prototype.foreach
1200_export({ target: 'Array', proto: true, forced: [].forEach != arrayForEach }, {
1201 forEach: arrayForEach
1202});
1203
1204// call something on iterator step with safe closing on error
1205var callWithSafeIterationClosing = function (iterator, fn, value, ENTRIES) {
1206 try {
1207 return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);
1208 // 7.4.6 IteratorClose(iterator, completion)
1209 } catch (error) {
1210 var returnMethod = iterator['return'];
1211 if (returnMethod !== undefined) anObject(returnMethod.call(iterator));
1212 throw error;
1213 }
1214};
1215
1216var iterators = {};
1217
1218var ITERATOR = wellKnownSymbol('iterator');
1219var ArrayPrototype = Array.prototype;
1220
1221// check on default Array iterator
1222var isArrayIteratorMethod = function (it) {
1223 return it !== undefined && (iterators.Array === it || ArrayPrototype[ITERATOR] === it);
1224};
1225
1226var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
1227// ES3 wrong here
1228var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
1229
1230// fallback for IE11 Script Access Denied error
1231var tryGet = function (it, key) {
1232 try {
1233 return it[key];
1234 } catch (error) { /* empty */ }
1235};
1236
1237// getting tag from ES6+ `Object.prototype.toString`
1238var classof = function (it) {
1239 var O, tag, result;
1240 return it === undefined ? 'Undefined' : it === null ? 'Null'
1241 // @@toStringTag case
1242 : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$1)) == 'string' ? tag
1243 // builtinTag case
1244 : CORRECT_ARGUMENTS ? classofRaw(O)
1245 // ES3 arguments fallback
1246 : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
1247};
1248
1249var ITERATOR$1 = wellKnownSymbol('iterator');
1250
1251var getIteratorMethod = function (it) {
1252 if (it != undefined) return it[ITERATOR$1]
1253 || it['@@iterator']
1254 || iterators[classof(it)];
1255};
1256
1257// `Array.from` method implementation
1258// https://tc39.github.io/ecma262/#sec-array.from
1259var arrayFrom = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
1260 var O = toObject(arrayLike);
1261 var C = typeof this == 'function' ? this : Array;
1262 var argumentsLength = arguments.length;
1263 var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
1264 var mapping = mapfn !== undefined;
1265 var index = 0;
1266 var iteratorMethod = getIteratorMethod(O);
1267 var length, result, step, iterator;
1268 if (mapping) mapfn = bindContext(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2);
1269 // if the target is not iterable or it's an array with the default iterator - use a simple case
1270 if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) {
1271 iterator = iteratorMethod.call(O);
1272 result = new C();
1273 for (;!(step = iterator.next()).done; index++) {
1274 createProperty(result, index, mapping
1275 ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true)
1276 : step.value
1277 );
1278 }
1279 } else {
1280 length = toLength(O.length);
1281 result = new C(length);
1282 for (;length > index; index++) {
1283 createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
1284 }
1285 }
1286 result.length = index;
1287 return result;
1288};
1289
1290var ITERATOR$2 = wellKnownSymbol('iterator');
1291var SAFE_CLOSING = false;
1292
1293try {
1294 var called = 0;
1295 var iteratorWithReturn = {
1296 next: function () {
1297 return { done: !!called++ };
1298 },
1299 'return': function () {
1300 SAFE_CLOSING = true;
1301 }
1302 };
1303 iteratorWithReturn[ITERATOR$2] = function () {
1304 return this;
1305 };
1306 // eslint-disable-next-line no-throw-literal
1307 Array.from(iteratorWithReturn, function () { throw 2; });
1308} catch (error) { /* empty */ }
1309
1310var checkCorrectnessOfIteration = function (exec, SKIP_CLOSING) {
1311 if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
1312 var ITERATION_SUPPORT = false;
1313 try {
1314 var object = {};
1315 object[ITERATOR$2] = function () {
1316 return {
1317 next: function () {
1318 return { done: ITERATION_SUPPORT = true };
1319 }
1320 };
1321 };
1322 exec(object);
1323 } catch (error) { /* empty */ }
1324 return ITERATION_SUPPORT;
1325};
1326
1327var INCORRECT_ITERATION = !checkCorrectnessOfIteration(function (iterable) {
1328 Array.from(iterable);
1329});
1330
1331// `Array.from` method
1332// https://tc39.github.io/ecma262/#sec-array.from
1333_export({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, {
1334 from: arrayFrom
1335});
1336
1337var $indexOf = arrayIncludes.indexOf;
1338
1339
1340var nativeIndexOf = [].indexOf;
1341
1342var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
1343var SLOPPY_METHOD = sloppyArrayMethod('indexOf');
1344
1345// `Array.prototype.indexOf` method
1346// https://tc39.github.io/ecma262/#sec-array.prototype.indexof
1347_export({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || SLOPPY_METHOD }, {
1348 indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
1349 return NEGATIVE_ZERO
1350 // convert -0 to +0
1351 ? nativeIndexOf.apply(this, arguments) || 0
1352 : $indexOf(this, searchElement, arguments.length > 1 ? arguments[1] : undefined);
1353 }
1354});
1355
1356var UNSCOPABLES = wellKnownSymbol('unscopables');
1357var ArrayPrototype$1 = Array.prototype;
1358
1359// Array.prototype[@@unscopables]
1360// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
1361if (ArrayPrototype$1[UNSCOPABLES] == undefined) {
1362 hide(ArrayPrototype$1, UNSCOPABLES, objectCreate(null));
1363}
1364
1365// add a key to Array.prototype[@@unscopables]
1366var addToUnscopables = function (key) {
1367 ArrayPrototype$1[UNSCOPABLES][key] = true;
1368};
1369
1370var correctPrototypeGetter = !fails(function () {
1371 function F() { /* empty */ }
1372 F.prototype.constructor = null;
1373 return Object.getPrototypeOf(new F()) !== F.prototype;
1374});
1375
1376var IE_PROTO$1 = sharedKey('IE_PROTO');
1377var ObjectPrototype$1 = Object.prototype;
1378
1379// `Object.getPrototypeOf` method
1380// https://tc39.github.io/ecma262/#sec-object.getprototypeof
1381var objectGetPrototypeOf = correctPrototypeGetter ? Object.getPrototypeOf : function (O) {
1382 O = toObject(O);
1383 if (has(O, IE_PROTO$1)) return O[IE_PROTO$1];
1384 if (typeof O.constructor == 'function' && O instanceof O.constructor) {
1385 return O.constructor.prototype;
1386 } return O instanceof Object ? ObjectPrototype$1 : null;
1387};
1388
1389var ITERATOR$3 = wellKnownSymbol('iterator');
1390var BUGGY_SAFARI_ITERATORS = false;
1391
1392var returnThis = function () { return this; };
1393
1394// `%IteratorPrototype%` object
1395// https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object
1396var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;
1397
1398if ([].keys) {
1399 arrayIterator = [].keys();
1400 // Safari 8 has buggy iterators w/o `next`
1401 if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
1402 else {
1403 PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator));
1404 if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
1405 }
1406}
1407
1408if (IteratorPrototype == undefined) IteratorPrototype = {};
1409
1410// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
1411if ( !has(IteratorPrototype, ITERATOR$3)) hide(IteratorPrototype, ITERATOR$3, returnThis);
1412
1413var iteratorsCore = {
1414 IteratorPrototype: IteratorPrototype,
1415 BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
1416};
1417
1418var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
1419
1420
1421
1422
1423
1424var returnThis$1 = function () { return this; };
1425
1426var createIteratorConstructor = function (IteratorConstructor, NAME, next) {
1427 var TO_STRING_TAG = NAME + ' Iterator';
1428 IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, { next: createPropertyDescriptor(1, next) });
1429 setToStringTag(IteratorConstructor, TO_STRING_TAG, false);
1430 iterators[TO_STRING_TAG] = returnThis$1;
1431 return IteratorConstructor;
1432};
1433
1434var aPossiblePrototype = function (it) {
1435 if (!isObject(it) && it !== null) {
1436 throw TypeError("Can't set " + String(it) + ' as a prototype');
1437 } return it;
1438};
1439
1440// `Object.setPrototypeOf` method
1441// https://tc39.github.io/ecma262/#sec-object.setprototypeof
1442// Works with __proto__ only. Old v8 can't work with null proto objects.
1443/* eslint-disable no-proto */
1444var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
1445 var CORRECT_SETTER = false;
1446 var test = {};
1447 var setter;
1448 try {
1449 setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
1450 setter.call(test, []);
1451 CORRECT_SETTER = test instanceof Array;
1452 } catch (error) { /* empty */ }
1453 return function setPrototypeOf(O, proto) {
1454 anObject(O);
1455 aPossiblePrototype(proto);
1456 if (CORRECT_SETTER) setter.call(O, proto);
1457 else O.__proto__ = proto;
1458 return O;
1459 };
1460}() : undefined);
1461
1462var IteratorPrototype$2 = iteratorsCore.IteratorPrototype;
1463var BUGGY_SAFARI_ITERATORS$1 = iteratorsCore.BUGGY_SAFARI_ITERATORS;
1464var ITERATOR$4 = wellKnownSymbol('iterator');
1465var KEYS = 'keys';
1466var VALUES = 'values';
1467var ENTRIES = 'entries';
1468
1469var returnThis$2 = function () { return this; };
1470
1471var defineIterator = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
1472 createIteratorConstructor(IteratorConstructor, NAME, next);
1473
1474 var getIterationMethod = function (KIND) {
1475 if (KIND === DEFAULT && defaultIterator) return defaultIterator;
1476 if (!BUGGY_SAFARI_ITERATORS$1 && KIND in IterablePrototype) return IterablePrototype[KIND];
1477 switch (KIND) {
1478 case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
1479 case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
1480 case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
1481 } return function () { return new IteratorConstructor(this); };
1482 };
1483
1484 var TO_STRING_TAG = NAME + ' Iterator';
1485 var INCORRECT_VALUES_NAME = false;
1486 var IterablePrototype = Iterable.prototype;
1487 var nativeIterator = IterablePrototype[ITERATOR$4]
1488 || IterablePrototype['@@iterator']
1489 || DEFAULT && IterablePrototype[DEFAULT];
1490 var defaultIterator = !BUGGY_SAFARI_ITERATORS$1 && nativeIterator || getIterationMethod(DEFAULT);
1491 var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
1492 var CurrentIteratorPrototype, methods, KEY;
1493
1494 // fix native
1495 if (anyNativeIterator) {
1496 CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable()));
1497 if (IteratorPrototype$2 !== Object.prototype && CurrentIteratorPrototype.next) {
1498 if ( objectGetPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype$2) {
1499 if (objectSetPrototypeOf) {
1500 objectSetPrototypeOf(CurrentIteratorPrototype, IteratorPrototype$2);
1501 } else if (typeof CurrentIteratorPrototype[ITERATOR$4] != 'function') {
1502 hide(CurrentIteratorPrototype, ITERATOR$4, returnThis$2);
1503 }
1504 }
1505 // Set @@toStringTag to native iterators
1506 setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true);
1507 }
1508 }
1509
1510 // fix Array#{values, @@iterator}.name in V8 / FF
1511 if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
1512 INCORRECT_VALUES_NAME = true;
1513 defaultIterator = function values() { return nativeIterator.call(this); };
1514 }
1515
1516 // define iterator
1517 if ( IterablePrototype[ITERATOR$4] !== defaultIterator) {
1518 hide(IterablePrototype, ITERATOR$4, defaultIterator);
1519 }
1520 iterators[NAME] = defaultIterator;
1521
1522 // export additional methods
1523 if (DEFAULT) {
1524 methods = {
1525 values: getIterationMethod(VALUES),
1526 keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
1527 entries: getIterationMethod(ENTRIES)
1528 };
1529 if (FORCED) for (KEY in methods) {
1530 if (BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
1531 redefine(IterablePrototype, KEY, methods[KEY]);
1532 }
1533 } else _export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME }, methods);
1534 }
1535
1536 return methods;
1537};
1538
1539var ARRAY_ITERATOR = 'Array Iterator';
1540var setInternalState$1 = internalState.set;
1541var getInternalState$1 = internalState.getterFor(ARRAY_ITERATOR);
1542
1543// `Array.prototype.entries` method
1544// https://tc39.github.io/ecma262/#sec-array.prototype.entries
1545// `Array.prototype.keys` method
1546// https://tc39.github.io/ecma262/#sec-array.prototype.keys
1547// `Array.prototype.values` method
1548// https://tc39.github.io/ecma262/#sec-array.prototype.values
1549// `Array.prototype[@@iterator]` method
1550// https://tc39.github.io/ecma262/#sec-array.prototype-@@iterator
1551// `CreateArrayIterator` internal method
1552// https://tc39.github.io/ecma262/#sec-createarrayiterator
1553var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind) {
1554 setInternalState$1(this, {
1555 type: ARRAY_ITERATOR,
1556 target: toIndexedObject(iterated), // target
1557 index: 0, // next index
1558 kind: kind // kind
1559 });
1560// `%ArrayIteratorPrototype%.next` method
1561// https://tc39.github.io/ecma262/#sec-%arrayiteratorprototype%.next
1562}, function () {
1563 var state = getInternalState$1(this);
1564 var target = state.target;
1565 var kind = state.kind;
1566 var index = state.index++;
1567 if (!target || index >= target.length) {
1568 state.target = undefined;
1569 return { value: undefined, done: true };
1570 }
1571 if (kind == 'keys') return { value: index, done: false };
1572 if (kind == 'values') return { value: target[index], done: false };
1573 return { value: [index, target[index]], done: false };
1574}, 'values');
1575
1576// argumentsList[@@iterator] is %ArrayProto_values%
1577// https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
1578// https://tc39.github.io/ecma262/#sec-createmappedargumentsobject
1579iterators.Arguments = iterators.Array;
1580
1581// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
1582addToUnscopables('keys');
1583addToUnscopables('values');
1584addToUnscopables('entries');
1585
1586var nativeJoin = [].join;
1587
1588var ES3_STRINGS = indexedObject != Object;
1589var SLOPPY_METHOD$1 = sloppyArrayMethod('join', ',');
1590
1591// `Array.prototype.join` method
1592// https://tc39.github.io/ecma262/#sec-array.prototype.join
1593_export({ target: 'Array', proto: true, forced: ES3_STRINGS || SLOPPY_METHOD$1 }, {
1594 join: function join(separator) {
1595 return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
1596 }
1597});
1598
1599var $map = arrayIteration.map;
1600
1601
1602// `Array.prototype.map` method
1603// https://tc39.github.io/ecma262/#sec-array.prototype.map
1604// with adding support of @@species
1605_export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('map') }, {
1606 map: function map(callbackfn /* , thisArg */) {
1607 return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
1608 }
1609});
1610
1611var SPECIES$2 = wellKnownSymbol('species');
1612var nativeSlice = [].slice;
1613var max$1 = Math.max;
1614
1615// `Array.prototype.slice` method
1616// https://tc39.github.io/ecma262/#sec-array.prototype.slice
1617// fallback for not array-like ES3 strings and DOM objects
1618_export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('slice') }, {
1619 slice: function slice(start, end) {
1620 var O = toIndexedObject(this);
1621 var length = toLength(O.length);
1622 var k = toAbsoluteIndex(start, length);
1623 var fin = toAbsoluteIndex(end === undefined ? length : end, length);
1624 // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
1625 var Constructor, result, n;
1626 if (isArray(O)) {
1627 Constructor = O.constructor;
1628 // cross-realm fallback
1629 if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
1630 Constructor = undefined;
1631 } else if (isObject(Constructor)) {
1632 Constructor = Constructor[SPECIES$2];
1633 if (Constructor === null) Constructor = undefined;
1634 }
1635 if (Constructor === Array || Constructor === undefined) {
1636 return nativeSlice.call(O, k, fin);
1637 }
1638 }
1639 result = new (Constructor === undefined ? Array : Constructor)(max$1(fin - k, 0));
1640 for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
1641 result.length = n;
1642 return result;
1643 }
1644});
1645
1646var $some = arrayIteration.some;
1647
1648
1649// `Array.prototype.some` method
1650// https://tc39.github.io/ecma262/#sec-array.prototype.some
1651_export({ target: 'Array', proto: true, forced: sloppyArrayMethod('some') }, {
1652 some: function some(callbackfn /* , thisArg */) {
1653 return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
1654 }
1655});
1656
1657var nativeSort = [].sort;
1658var test = [1, 2, 3];
1659
1660// IE8-
1661var FAILS_ON_UNDEFINED = fails(function () {
1662 test.sort(undefined);
1663});
1664// V8 bug
1665var FAILS_ON_NULL = fails(function () {
1666 test.sort(null);
1667});
1668// Old WebKit
1669var SLOPPY_METHOD$2 = sloppyArrayMethod('sort');
1670
1671var FORCED$1 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || SLOPPY_METHOD$2;
1672
1673// `Array.prototype.sort` method
1674// https://tc39.github.io/ecma262/#sec-array.prototype.sort
1675_export({ target: 'Array', proto: true, forced: FORCED$1 }, {
1676 sort: function sort(comparefn) {
1677 return comparefn === undefined
1678 ? nativeSort.call(toObject(this))
1679 : nativeSort.call(toObject(this), aFunction$1(comparefn));
1680 }
1681});
1682
1683var defineProperty$3 = objectDefineProperty.f;
1684
1685
1686
1687
1688
1689var DataView = global_1.DataView;
1690var DataViewPrototype = DataView && DataView.prototype;
1691var Int8Array$1 = global_1.Int8Array;
1692var Int8ArrayPrototype = Int8Array$1 && Int8Array$1.prototype;
1693var Uint8ClampedArray = global_1.Uint8ClampedArray;
1694var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype;
1695var TypedArray = Int8Array$1 && objectGetPrototypeOf(Int8Array$1);
1696var TypedArrayPrototype = Int8ArrayPrototype && objectGetPrototypeOf(Int8ArrayPrototype);
1697var ObjectPrototype$2 = Object.prototype;
1698var isPrototypeOf = ObjectPrototype$2.isPrototypeOf;
1699
1700var TO_STRING_TAG$2 = wellKnownSymbol('toStringTag');
1701var TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG');
1702var NATIVE_ARRAY_BUFFER = !!(global_1.ArrayBuffer && DataView);
1703// Fixing native typed arrays in Opera Presto crashes the browser, see #595
1704var NATIVE_ARRAY_BUFFER_VIEWS = NATIVE_ARRAY_BUFFER && !!objectSetPrototypeOf && classof(global_1.opera) !== 'Opera';
1705var TYPED_ARRAY_TAG_REQIRED = false;
1706var NAME;
1707
1708var TypedArrayConstructorsList = {
1709 Int8Array: 1,
1710 Uint8Array: 1,
1711 Uint8ClampedArray: 1,
1712 Int16Array: 2,
1713 Uint16Array: 2,
1714 Int32Array: 4,
1715 Uint32Array: 4,
1716 Float32Array: 4,
1717 Float64Array: 8
1718};
1719
1720var isView = function isView(it) {
1721 var klass = classof(it);
1722 return klass === 'DataView' || has(TypedArrayConstructorsList, klass);
1723};
1724
1725var isTypedArray = function (it) {
1726 return isObject(it) && has(TypedArrayConstructorsList, classof(it));
1727};
1728
1729var aTypedArray = function (it) {
1730 if (isTypedArray(it)) return it;
1731 throw TypeError('Target is not a typed array');
1732};
1733
1734var aTypedArrayConstructor = function (C) {
1735 if (objectSetPrototypeOf) {
1736 if (isPrototypeOf.call(TypedArray, C)) return C;
1737 } else for (var ARRAY in TypedArrayConstructorsList) if (has(TypedArrayConstructorsList, NAME)) {
1738 var TypedArrayConstructor = global_1[ARRAY];
1739 if (TypedArrayConstructor && (C === TypedArrayConstructor || isPrototypeOf.call(TypedArrayConstructor, C))) {
1740 return C;
1741 }
1742 } throw TypeError('Target is not a typed array constructor');
1743};
1744
1745var exportProto = function (KEY, property, forced) {
1746 if (!descriptors) return;
1747 if (forced) for (var ARRAY in TypedArrayConstructorsList) {
1748 var TypedArrayConstructor = global_1[ARRAY];
1749 if (TypedArrayConstructor && has(TypedArrayConstructor.prototype, KEY)) {
1750 delete TypedArrayConstructor.prototype[KEY];
1751 }
1752 }
1753 if (!TypedArrayPrototype[KEY] || forced) {
1754 redefine(TypedArrayPrototype, KEY, forced ? property
1755 : NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property);
1756 }
1757};
1758
1759var exportStatic = function (KEY, property, forced) {
1760 var ARRAY, TypedArrayConstructor;
1761 if (!descriptors) return;
1762 if (objectSetPrototypeOf) {
1763 if (forced) for (ARRAY in TypedArrayConstructorsList) {
1764 TypedArrayConstructor = global_1[ARRAY];
1765 if (TypedArrayConstructor && has(TypedArrayConstructor, KEY)) {
1766 delete TypedArrayConstructor[KEY];
1767 }
1768 }
1769 if (!TypedArray[KEY] || forced) {
1770 // V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable
1771 try {
1772 return redefine(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && Int8Array$1[KEY] || property);
1773 } catch (error) { /* empty */ }
1774 } else return;
1775 }
1776 for (ARRAY in TypedArrayConstructorsList) {
1777 TypedArrayConstructor = global_1[ARRAY];
1778 if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) {
1779 redefine(TypedArrayConstructor, KEY, property);
1780 }
1781 }
1782};
1783
1784for (NAME in TypedArrayConstructorsList) {
1785 if (!global_1[NAME]) NATIVE_ARRAY_BUFFER_VIEWS = false;
1786}
1787
1788// WebKit bug - typed arrays constructors prototype is Object.prototype
1789if (!NATIVE_ARRAY_BUFFER_VIEWS || typeof TypedArray != 'function' || TypedArray === Function.prototype) {
1790 // eslint-disable-next-line no-shadow
1791 TypedArray = function TypedArray() {
1792 throw TypeError('Incorrect invocation');
1793 };
1794 if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
1795 if (global_1[NAME]) objectSetPrototypeOf(global_1[NAME], TypedArray);
1796 }
1797}
1798
1799if (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype$2) {
1800 TypedArrayPrototype = TypedArray.prototype;
1801 if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
1802 if (global_1[NAME]) objectSetPrototypeOf(global_1[NAME].prototype, TypedArrayPrototype);
1803 }
1804}
1805
1806// WebKit bug - one more object in Uint8ClampedArray prototype chain
1807if (NATIVE_ARRAY_BUFFER_VIEWS && objectGetPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) {
1808 objectSetPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype);
1809}
1810
1811if (descriptors && !has(TypedArrayPrototype, TO_STRING_TAG$2)) {
1812 TYPED_ARRAY_TAG_REQIRED = true;
1813 defineProperty$3(TypedArrayPrototype, TO_STRING_TAG$2, { get: function () {
1814 return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined;
1815 } });
1816 for (NAME in TypedArrayConstructorsList) if (global_1[NAME]) {
1817 hide(global_1[NAME], TYPED_ARRAY_TAG, NAME);
1818 }
1819}
1820
1821// WebKit bug - the same parent prototype for typed arrays and data view
1822if (NATIVE_ARRAY_BUFFER && objectSetPrototypeOf && objectGetPrototypeOf(DataViewPrototype) !== ObjectPrototype$2) {
1823 objectSetPrototypeOf(DataViewPrototype, ObjectPrototype$2);
1824}
1825
1826var arrayBufferViewCore = {
1827 NATIVE_ARRAY_BUFFER: NATIVE_ARRAY_BUFFER,
1828 NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS,
1829 TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQIRED && TYPED_ARRAY_TAG,
1830 aTypedArray: aTypedArray,
1831 aTypedArrayConstructor: aTypedArrayConstructor,
1832 exportProto: exportProto,
1833 exportStatic: exportStatic,
1834 isView: isView,
1835 isTypedArray: isTypedArray,
1836 TypedArray: TypedArray,
1837 TypedArrayPrototype: TypedArrayPrototype
1838};
1839
1840var redefineAll = function (target, src, options) {
1841 for (var key in src) redefine(target, key, src[key], options);
1842 return target;
1843};
1844
1845var anInstance = function (it, Constructor, name) {
1846 if (!(it instanceof Constructor)) {
1847 throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
1848 } return it;
1849};
1850
1851// `ToIndex` abstract operation
1852// https://tc39.github.io/ecma262/#sec-toindex
1853var toIndex = function (it) {
1854 if (it === undefined) return 0;
1855 var number = toInteger(it);
1856 var length = toLength(number);
1857 if (number !== length) throw RangeError('Wrong length or index');
1858 return length;
1859};
1860
1861// `Array.prototype.fill` method implementation
1862// https://tc39.github.io/ecma262/#sec-array.prototype.fill
1863var arrayFill = function fill(value /* , start = 0, end = @length */) {
1864 var O = toObject(this);
1865 var length = toLength(O.length);
1866 var argumentsLength = arguments.length;
1867 var index = toAbsoluteIndex(argumentsLength > 1 ? arguments[1] : undefined, length);
1868 var end = argumentsLength > 2 ? arguments[2] : undefined;
1869 var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
1870 while (endPos > index) O[index++] = value;
1871 return O;
1872};
1873
1874var arrayBuffer = createCommonjsModule(function (module, exports) {
1875
1876
1877var NATIVE_ARRAY_BUFFER = arrayBufferViewCore.NATIVE_ARRAY_BUFFER;
1878
1879
1880
1881
1882
1883
1884
1885var getOwnPropertyNames = objectGetOwnPropertyNames.f;
1886var defineProperty = objectDefineProperty.f;
1887
1888
1889
1890
1891var getInternalState = internalState.get;
1892var setInternalState = internalState.set;
1893var ARRAY_BUFFER = 'ArrayBuffer';
1894var DATA_VIEW = 'DataView';
1895var PROTOTYPE = 'prototype';
1896var WRONG_LENGTH = 'Wrong length';
1897var WRONG_INDEX = 'Wrong index';
1898var NativeArrayBuffer = global_1[ARRAY_BUFFER];
1899var $ArrayBuffer = NativeArrayBuffer;
1900var $DataView = global_1[DATA_VIEW];
1901var Math = global_1.Math;
1902var RangeError = global_1.RangeError;
1903// eslint-disable-next-line no-shadow-restricted-names
1904var Infinity = 1 / 0;
1905var abs = Math.abs;
1906var pow = Math.pow;
1907var floor = Math.floor;
1908var log = Math.log;
1909var LN2 = Math.LN2;
1910
1911// IEEE754 conversions based on https://github.com/feross/ieee754
1912var packIEEE754 = function (number, mantissaLength, bytes) {
1913 var buffer = new Array(bytes);
1914 var exponentLength = bytes * 8 - mantissaLength - 1;
1915 var eMax = (1 << exponentLength) - 1;
1916 var eBias = eMax >> 1;
1917 var rt = mantissaLength === 23 ? pow(2, -24) - pow(2, -77) : 0;
1918 var sign = number < 0 || number === 0 && 1 / number < 0 ? 1 : 0;
1919 var index = 0;
1920 var exponent, mantissa, c;
1921 number = abs(number);
1922 // eslint-disable-next-line no-self-compare
1923 if (number != number || number === Infinity) {
1924 // eslint-disable-next-line no-self-compare
1925 mantissa = number != number ? 1 : 0;
1926 exponent = eMax;
1927 } else {
1928 exponent = floor(log(number) / LN2);
1929 if (number * (c = pow(2, -exponent)) < 1) {
1930 exponent--;
1931 c *= 2;
1932 }
1933 if (exponent + eBias >= 1) {
1934 number += rt / c;
1935 } else {
1936 number += rt * pow(2, 1 - eBias);
1937 }
1938 if (number * c >= 2) {
1939 exponent++;
1940 c /= 2;
1941 }
1942 if (exponent + eBias >= eMax) {
1943 mantissa = 0;
1944 exponent = eMax;
1945 } else if (exponent + eBias >= 1) {
1946 mantissa = (number * c - 1) * pow(2, mantissaLength);
1947 exponent = exponent + eBias;
1948 } else {
1949 mantissa = number * pow(2, eBias - 1) * pow(2, mantissaLength);
1950 exponent = 0;
1951 }
1952 }
1953 for (; mantissaLength >= 8; buffer[index++] = mantissa & 255, mantissa /= 256, mantissaLength -= 8);
1954 exponent = exponent << mantissaLength | mantissa;
1955 exponentLength += mantissaLength;
1956 for (; exponentLength > 0; buffer[index++] = exponent & 255, exponent /= 256, exponentLength -= 8);
1957 buffer[--index] |= sign * 128;
1958 return buffer;
1959};
1960
1961var unpackIEEE754 = function (buffer, mantissaLength) {
1962 var bytes = buffer.length;
1963 var exponentLength = bytes * 8 - mantissaLength - 1;
1964 var eMax = (1 << exponentLength) - 1;
1965 var eBias = eMax >> 1;
1966 var nBits = exponentLength - 7;
1967 var index = bytes - 1;
1968 var sign = buffer[index--];
1969 var exponent = sign & 127;
1970 var mantissa;
1971 sign >>= 7;
1972 for (; nBits > 0; exponent = exponent * 256 + buffer[index], index--, nBits -= 8);
1973 mantissa = exponent & (1 << -nBits) - 1;
1974 exponent >>= -nBits;
1975 nBits += mantissaLength;
1976 for (; nBits > 0; mantissa = mantissa * 256 + buffer[index], index--, nBits -= 8);
1977 if (exponent === 0) {
1978 exponent = 1 - eBias;
1979 } else if (exponent === eMax) {
1980 return mantissa ? NaN : sign ? -Infinity : Infinity;
1981 } else {
1982 mantissa = mantissa + pow(2, mantissaLength);
1983 exponent = exponent - eBias;
1984 } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);
1985};
1986
1987var unpackInt32 = function (buffer) {
1988 return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
1989};
1990
1991var packInt8 = function (number) {
1992 return [number & 0xFF];
1993};
1994
1995var packInt16 = function (number) {
1996 return [number & 0xFF, number >> 8 & 0xFF];
1997};
1998
1999var packInt32 = function (number) {
2000 return [number & 0xFF, number >> 8 & 0xFF, number >> 16 & 0xFF, number >> 24 & 0xFF];
2001};
2002
2003var packFloat32 = function (number) {
2004 return packIEEE754(number, 23, 4);
2005};
2006
2007var packFloat64 = function (number) {
2008 return packIEEE754(number, 52, 8);
2009};
2010
2011var addGetter = function (Constructor, key) {
2012 defineProperty(Constructor[PROTOTYPE], key, { get: function () { return getInternalState(this)[key]; } });
2013};
2014
2015var get = function (view, count, index, isLittleEndian) {
2016 var numIndex = +index;
2017 var intIndex = toIndex(numIndex);
2018 var store = getInternalState(view);
2019 if (intIndex + count > store.byteLength) throw RangeError(WRONG_INDEX);
2020 var bytes = getInternalState(store.buffer).bytes;
2021 var start = intIndex + store.byteOffset;
2022 var pack = bytes.slice(start, start + count);
2023 return isLittleEndian ? pack : pack.reverse();
2024};
2025
2026var set = function (view, count, index, conversion, value, isLittleEndian) {
2027 var numIndex = +index;
2028 var intIndex = toIndex(numIndex);
2029 var store = getInternalState(view);
2030 if (intIndex + count > store.byteLength) throw RangeError(WRONG_INDEX);
2031 var bytes = getInternalState(store.buffer).bytes;
2032 var start = intIndex + store.byteOffset;
2033 var pack = conversion(+value);
2034 for (var i = 0; i < count; i++) bytes[start + i] = pack[isLittleEndian ? i : count - i - 1];
2035};
2036
2037if (!NATIVE_ARRAY_BUFFER) {
2038 $ArrayBuffer = function ArrayBuffer(length) {
2039 anInstance(this, $ArrayBuffer, ARRAY_BUFFER);
2040 var byteLength = toIndex(length);
2041 setInternalState(this, {
2042 bytes: arrayFill.call(new Array(byteLength), 0),
2043 byteLength: byteLength
2044 });
2045 if (!descriptors) this.byteLength = byteLength;
2046 };
2047
2048 $DataView = function DataView(buffer, byteOffset, byteLength) {
2049 anInstance(this, $DataView, DATA_VIEW);
2050 anInstance(buffer, $ArrayBuffer, DATA_VIEW);
2051 var bufferLength = getInternalState(buffer).byteLength;
2052 var offset = toInteger(byteOffset);
2053 if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset');
2054 byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
2055 if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH);
2056 setInternalState(this, {
2057 buffer: buffer,
2058 byteLength: byteLength,
2059 byteOffset: offset
2060 });
2061 if (!descriptors) {
2062 this.buffer = buffer;
2063 this.byteLength = byteLength;
2064 this.byteOffset = offset;
2065 }
2066 };
2067
2068 if (descriptors) {
2069 addGetter($ArrayBuffer, 'byteLength');
2070 addGetter($DataView, 'buffer');
2071 addGetter($DataView, 'byteLength');
2072 addGetter($DataView, 'byteOffset');
2073 }
2074
2075 redefineAll($DataView[PROTOTYPE], {
2076 getInt8: function getInt8(byteOffset) {
2077 return get(this, 1, byteOffset)[0] << 24 >> 24;
2078 },
2079 getUint8: function getUint8(byteOffset) {
2080 return get(this, 1, byteOffset)[0];
2081 },
2082 getInt16: function getInt16(byteOffset /* , littleEndian */) {
2083 var bytes = get(this, 2, byteOffset, arguments.length > 1 ? arguments[1] : undefined);
2084 return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
2085 },
2086 getUint16: function getUint16(byteOffset /* , littleEndian */) {
2087 var bytes = get(this, 2, byteOffset, arguments.length > 1 ? arguments[1] : undefined);
2088 return bytes[1] << 8 | bytes[0];
2089 },
2090 getInt32: function getInt32(byteOffset /* , littleEndian */) {
2091 return unpackInt32(get(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined));
2092 },
2093 getUint32: function getUint32(byteOffset /* , littleEndian */) {
2094 return unpackInt32(get(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined)) >>> 0;
2095 },
2096 getFloat32: function getFloat32(byteOffset /* , littleEndian */) {
2097 return unpackIEEE754(get(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined), 23);
2098 },
2099 getFloat64: function getFloat64(byteOffset /* , littleEndian */) {
2100 return unpackIEEE754(get(this, 8, byteOffset, arguments.length > 1 ? arguments[1] : undefined), 52);
2101 },
2102 setInt8: function setInt8(byteOffset, value) {
2103 set(this, 1, byteOffset, packInt8, value);
2104 },
2105 setUint8: function setUint8(byteOffset, value) {
2106 set(this, 1, byteOffset, packInt8, value);
2107 },
2108 setInt16: function setInt16(byteOffset, value /* , littleEndian */) {
2109 set(this, 2, byteOffset, packInt16, value, arguments.length > 2 ? arguments[2] : undefined);
2110 },
2111 setUint16: function setUint16(byteOffset, value /* , littleEndian */) {
2112 set(this, 2, byteOffset, packInt16, value, arguments.length > 2 ? arguments[2] : undefined);
2113 },
2114 setInt32: function setInt32(byteOffset, value /* , littleEndian */) {
2115 set(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : undefined);
2116 },
2117 setUint32: function setUint32(byteOffset, value /* , littleEndian */) {
2118 set(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : undefined);
2119 },
2120 setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {
2121 set(this, 4, byteOffset, packFloat32, value, arguments.length > 2 ? arguments[2] : undefined);
2122 },
2123 setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {
2124 set(this, 8, byteOffset, packFloat64, value, arguments.length > 2 ? arguments[2] : undefined);
2125 }
2126 });
2127} else {
2128 if (!fails(function () {
2129 NativeArrayBuffer(1);
2130 }) || !fails(function () {
2131 new NativeArrayBuffer(-1); // eslint-disable-line no-new
2132 }) || fails(function () {
2133 new NativeArrayBuffer(); // eslint-disable-line no-new
2134 new NativeArrayBuffer(1.5); // eslint-disable-line no-new
2135 new NativeArrayBuffer(NaN); // eslint-disable-line no-new
2136 return NativeArrayBuffer.name != ARRAY_BUFFER;
2137 })) {
2138 $ArrayBuffer = function ArrayBuffer(length) {
2139 anInstance(this, $ArrayBuffer);
2140 return new NativeArrayBuffer(toIndex(length));
2141 };
2142 var ArrayBufferPrototype = $ArrayBuffer[PROTOTYPE] = NativeArrayBuffer[PROTOTYPE];
2143 for (var keys = getOwnPropertyNames(NativeArrayBuffer), j = 0, key; keys.length > j;) {
2144 if (!((key = keys[j++]) in $ArrayBuffer)) hide($ArrayBuffer, key, NativeArrayBuffer[key]);
2145 }
2146 ArrayBufferPrototype.constructor = $ArrayBuffer;
2147 }
2148 // iOS Safari 7.x bug
2149 var testView = new $DataView(new $ArrayBuffer(2));
2150 var nativeSetInt8 = $DataView[PROTOTYPE].setInt8;
2151 testView.setInt8(0, 2147483648);
2152 testView.setInt8(1, 2147483649);
2153 if (testView.getInt8(0) || !testView.getInt8(1)) redefineAll($DataView[PROTOTYPE], {
2154 setInt8: function setInt8(byteOffset, value) {
2155 nativeSetInt8.call(this, byteOffset, value << 24 >> 24);
2156 },
2157 setUint8: function setUint8(byteOffset, value) {
2158 nativeSetInt8.call(this, byteOffset, value << 24 >> 24);
2159 }
2160 }, { unsafe: true });
2161}
2162
2163setToStringTag($ArrayBuffer, ARRAY_BUFFER);
2164setToStringTag($DataView, DATA_VIEW);
2165exports[ARRAY_BUFFER] = $ArrayBuffer;
2166exports[DATA_VIEW] = $DataView;
2167});
2168
2169var SPECIES$3 = wellKnownSymbol('species');
2170
2171// `SpeciesConstructor` abstract operation
2172// https://tc39.github.io/ecma262/#sec-speciesconstructor
2173var speciesConstructor = function (O, defaultConstructor) {
2174 var C = anObject(O).constructor;
2175 var S;
2176 return C === undefined || (S = anObject(C)[SPECIES$3]) == undefined ? defaultConstructor : aFunction$1(S);
2177};
2178
2179var ArrayBuffer = arrayBuffer.ArrayBuffer;
2180var DataView$1 = arrayBuffer.DataView;
2181var nativeArrayBufferSlice = ArrayBuffer.prototype.slice;
2182
2183var INCORRECT_SLICE = fails(function () {
2184 return !new ArrayBuffer(2).slice(1, undefined).byteLength;
2185});
2186
2187// `ArrayBuffer.prototype.slice` method
2188// https://tc39.github.io/ecma262/#sec-arraybuffer.prototype.slice
2189_export({ target: 'ArrayBuffer', proto: true, unsafe: true, forced: INCORRECT_SLICE }, {
2190 slice: function slice(start, end) {
2191 if (nativeArrayBufferSlice !== undefined && end === undefined) {
2192 return nativeArrayBufferSlice.call(anObject(this), start); // FF fix
2193 }
2194 var length = anObject(this).byteLength;
2195 var first = toAbsoluteIndex(start, length);
2196 var fin = toAbsoluteIndex(end === undefined ? length : end, length);
2197 var result = new (speciesConstructor(this, ArrayBuffer))(toLength(fin - first));
2198 var viewSource = new DataView$1(this);
2199 var viewTarget = new DataView$1(result);
2200 var index = 0;
2201 while (first < fin) {
2202 viewTarget.setUint8(index++, viewSource.getUint8(first++));
2203 } return result;
2204 }
2205});
2206
2207// `String.prototype.repeat` method implementation
2208// https://tc39.github.io/ecma262/#sec-string.prototype.repeat
2209var stringRepeat = ''.repeat || function repeat(count) {
2210 var str = String(requireObjectCoercible(this));
2211 var result = '';
2212 var n = toInteger(count);
2213 if (n < 0 || n == Infinity) throw RangeError('Wrong number of repetitions');
2214 for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str;
2215 return result;
2216};
2217
2218// https://github.com/tc39/proposal-string-pad-start-end
2219
2220
2221
2222
2223var ceil$1 = Math.ceil;
2224
2225// `String.prototype.{ padStart, padEnd }` methods implementation
2226var createMethod$2 = function (IS_END) {
2227 return function ($this, maxLength, fillString) {
2228 var S = String(requireObjectCoercible($this));
2229 var stringLength = S.length;
2230 var fillStr = fillString === undefined ? ' ' : String(fillString);
2231 var intMaxLength = toLength(maxLength);
2232 var fillLen, stringFiller;
2233 if (intMaxLength <= stringLength || fillStr == '') return S;
2234 fillLen = intMaxLength - stringLength;
2235 stringFiller = stringRepeat.call(fillStr, ceil$1(fillLen / fillStr.length));
2236 if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);
2237 return IS_END ? S + stringFiller : stringFiller + S;
2238 };
2239};
2240
2241var stringPad = {
2242 // `String.prototype.padStart` method
2243 // https://tc39.github.io/ecma262/#sec-string.prototype.padstart
2244 start: createMethod$2(false),
2245 // `String.prototype.padEnd` method
2246 // https://tc39.github.io/ecma262/#sec-string.prototype.padend
2247 end: createMethod$2(true)
2248};
2249
2250var padStart = stringPad.start;
2251
2252var abs = Math.abs;
2253var DatePrototype = Date.prototype;
2254var getTime = DatePrototype.getTime;
2255var nativeDateToISOString = DatePrototype.toISOString;
2256
2257// `Date.prototype.toISOString` method implementation
2258// https://tc39.github.io/ecma262/#sec-date.prototype.toisostring
2259// PhantomJS / old WebKit fails here:
2260var dateToIsoString = (fails(function () {
2261 return nativeDateToISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z';
2262}) || !fails(function () {
2263 nativeDateToISOString.call(new Date(NaN));
2264})) ? function toISOString() {
2265 if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value');
2266 var date = this;
2267 var year = date.getUTCFullYear();
2268 var milliseconds = date.getUTCMilliseconds();
2269 var sign = year < 0 ? '-' : year > 9999 ? '+' : '';
2270 return sign + padStart(abs(year), sign ? 6 : 4, 0) +
2271 '-' + padStart(date.getUTCMonth() + 1, 2, 0) +
2272 '-' + padStart(date.getUTCDate(), 2, 0) +
2273 'T' + padStart(date.getUTCHours(), 2, 0) +
2274 ':' + padStart(date.getUTCMinutes(), 2, 0) +
2275 ':' + padStart(date.getUTCSeconds(), 2, 0) +
2276 '.' + padStart(milliseconds, 3, 0) +
2277 'Z';
2278} : nativeDateToISOString;
2279
2280// `Date.prototype.toISOString` method
2281// https://tc39.github.io/ecma262/#sec-date.prototype.toisostring
2282// PhantomJS / old WebKit has a broken implementations
2283_export({ target: 'Date', proto: true, forced: Date.prototype.toISOString !== dateToIsoString }, {
2284 toISOString: dateToIsoString
2285});
2286
2287var FORCED$2 = fails(function () {
2288 return new Date(NaN).toJSON() !== null
2289 || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1;
2290});
2291
2292// `Date.prototype.toJSON` method
2293// https://tc39.github.io/ecma262/#sec-date.prototype.tojson
2294_export({ target: 'Date', proto: true, forced: FORCED$2 }, {
2295 // eslint-disable-next-line no-unused-vars
2296 toJSON: function toJSON(key) {
2297 var O = toObject(this);
2298 var pv = toPrimitive(O);
2299 return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
2300 }
2301});
2302
2303var DatePrototype$1 = Date.prototype;
2304var INVALID_DATE = 'Invalid Date';
2305var TO_STRING = 'toString';
2306var nativeDateToString = DatePrototype$1[TO_STRING];
2307var getTime$1 = DatePrototype$1.getTime;
2308
2309// `Date.prototype.toString` method
2310// https://tc39.github.io/ecma262/#sec-date.prototype.tostring
2311if (new Date(NaN) + '' != INVALID_DATE) {
2312 redefine(DatePrototype$1, TO_STRING, function toString() {
2313 var value = getTime$1.call(this);
2314 // eslint-disable-next-line no-self-compare
2315 return value === value ? nativeDateToString.call(this) : INVALID_DATE;
2316 });
2317}
2318
2319var defineProperty$4 = objectDefineProperty.f;
2320
2321var FunctionPrototype = Function.prototype;
2322var FunctionPrototypeToString = FunctionPrototype.toString;
2323var nameRE = /^\s*function ([^ (]*)/;
2324var NAME$1 = 'name';
2325
2326// Function instances `.name` property
2327// https://tc39.github.io/ecma262/#sec-function-instances-name
2328if (descriptors && !(NAME$1 in FunctionPrototype)) {
2329 defineProperty$4(FunctionPrototype, NAME$1, {
2330 configurable: true,
2331 get: function () {
2332 try {
2333 return FunctionPrototypeToString.call(this).match(nameRE)[1];
2334 } catch (error) {
2335 return '';
2336 }
2337 }
2338 });
2339}
2340
2341// makes subclassing work correct for wrapped built-ins
2342var inheritIfRequired = function ($this, dummy, Wrapper) {
2343 var NewTarget, NewTargetPrototype;
2344 if (
2345 // it can work only with native `setPrototypeOf`
2346 objectSetPrototypeOf &&
2347 // we haven't completely correct pre-ES6 way for getting `new.target`, so use this
2348 typeof (NewTarget = dummy.constructor) == 'function' &&
2349 NewTarget !== Wrapper &&
2350 isObject(NewTargetPrototype = NewTarget.prototype) &&
2351 NewTargetPrototype !== Wrapper.prototype
2352 ) objectSetPrototypeOf($this, NewTargetPrototype);
2353 return $this;
2354};
2355
2356// a string of all valid unicode whitespaces
2357// eslint-disable-next-line max-len
2358var 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';
2359
2360var whitespace = '[' + whitespaces + ']';
2361var ltrim = RegExp('^' + whitespace + whitespace + '*');
2362var rtrim = RegExp(whitespace + whitespace + '*$');
2363
2364// `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
2365var createMethod$3 = function (TYPE) {
2366 return function ($this) {
2367 var string = String(requireObjectCoercible($this));
2368 if (TYPE & 1) string = string.replace(ltrim, '');
2369 if (TYPE & 2) string = string.replace(rtrim, '');
2370 return string;
2371 };
2372};
2373
2374var stringTrim = {
2375 // `String.prototype.{ trimLeft, trimStart }` methods
2376 // https://tc39.github.io/ecma262/#sec-string.prototype.trimstart
2377 start: createMethod$3(1),
2378 // `String.prototype.{ trimRight, trimEnd }` methods
2379 // https://tc39.github.io/ecma262/#sec-string.prototype.trimend
2380 end: createMethod$3(2),
2381 // `String.prototype.trim` method
2382 // https://tc39.github.io/ecma262/#sec-string.prototype.trim
2383 trim: createMethod$3(3)
2384};
2385
2386var getOwnPropertyNames = objectGetOwnPropertyNames.f;
2387var getOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f;
2388var defineProperty$5 = objectDefineProperty.f;
2389var trim = stringTrim.trim;
2390
2391var NUMBER = 'Number';
2392var NativeNumber = global_1[NUMBER];
2393var NumberPrototype = NativeNumber.prototype;
2394
2395// Opera ~12 has broken Object#toString
2396var BROKEN_CLASSOF = classofRaw(objectCreate(NumberPrototype)) == NUMBER;
2397
2398// `ToNumber` abstract operation
2399// https://tc39.github.io/ecma262/#sec-tonumber
2400var toNumber = function (argument) {
2401 var it = toPrimitive(argument, false);
2402 var first, third, radix, maxCode, digits, length, index, code;
2403 if (typeof it == 'string' && it.length > 2) {
2404 it = trim(it);
2405 first = it.charCodeAt(0);
2406 if (first === 43 || first === 45) {
2407 third = it.charCodeAt(2);
2408 if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
2409 } else if (first === 48) {
2410 switch (it.charCodeAt(1)) {
2411 case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i
2412 case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i
2413 default: return +it;
2414 }
2415 digits = it.slice(2);
2416 length = digits.length;
2417 for (index = 0; index < length; index++) {
2418 code = digits.charCodeAt(index);
2419 // parseInt parses a string to a first unavailable symbol
2420 // but ToNumber should return NaN if a string contains unavailable symbols
2421 if (code < 48 || code > maxCode) return NaN;
2422 } return parseInt(digits, radix);
2423 }
2424 } return +it;
2425};
2426
2427// `Number` constructor
2428// https://tc39.github.io/ecma262/#sec-number-constructor
2429if (isForced_1(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {
2430 var NumberWrapper = function Number(value) {
2431 var it = arguments.length < 1 ? 0 : value;
2432 var dummy = this;
2433 return dummy instanceof NumberWrapper
2434 // check on 1..constructor(foo) case
2435 && (BROKEN_CLASSOF ? fails(function () { NumberPrototype.valueOf.call(dummy); }) : classofRaw(dummy) != NUMBER)
2436 ? inheritIfRequired(new NativeNumber(toNumber(it)), dummy, NumberWrapper) : toNumber(it);
2437 };
2438 for (var keys$1 = descriptors ? getOwnPropertyNames(NativeNumber) : (
2439 // ES3:
2440 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
2441 // ES2015 (in case, if modules with ES2015 Number statics required before):
2442 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
2443 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
2444 ).split(','), j = 0, key; keys$1.length > j; j++) {
2445 if (has(NativeNumber, key = keys$1[j]) && !has(NumberWrapper, key)) {
2446 defineProperty$5(NumberWrapper, key, getOwnPropertyDescriptor$2(NativeNumber, key));
2447 }
2448 }
2449 NumberWrapper.prototype = NumberPrototype;
2450 NumberPrototype.constructor = NumberWrapper;
2451 redefine(global_1, NUMBER, NumberWrapper);
2452}
2453
2454// `thisNumberValue` abstract operation
2455// https://tc39.github.io/ecma262/#sec-thisnumbervalue
2456var thisNumberValue = function (value) {
2457 if (typeof value != 'number' && classofRaw(value) != 'Number') {
2458 throw TypeError('Incorrect invocation');
2459 }
2460 return +value;
2461};
2462
2463var nativeToFixed = 1.0.toFixed;
2464var floor$1 = Math.floor;
2465
2466var pow = function (x, n, acc) {
2467 return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
2468};
2469
2470var log = function (x) {
2471 var n = 0;
2472 var x2 = x;
2473 while (x2 >= 4096) {
2474 n += 12;
2475 x2 /= 4096;
2476 }
2477 while (x2 >= 2) {
2478 n += 1;
2479 x2 /= 2;
2480 } return n;
2481};
2482
2483var FORCED$3 = nativeToFixed && (
2484 0.00008.toFixed(3) !== '0.000' ||
2485 0.9.toFixed(0) !== '1' ||
2486 1.255.toFixed(2) !== '1.25' ||
2487 1000000000000000128.0.toFixed(0) !== '1000000000000000128'
2488) || !fails(function () {
2489 // V8 ~ Android 4.3-
2490 nativeToFixed.call({});
2491});
2492
2493// `Number.prototype.toFixed` method
2494// https://tc39.github.io/ecma262/#sec-number.prototype.tofixed
2495_export({ target: 'Number', proto: true, forced: FORCED$3 }, {
2496 // eslint-disable-next-line max-statements
2497 toFixed: function toFixed(fractionDigits) {
2498 var number = thisNumberValue(this);
2499 var fractDigits = toInteger(fractionDigits);
2500 var data = [0, 0, 0, 0, 0, 0];
2501 var sign = '';
2502 var result = '0';
2503 var e, z, j, k;
2504
2505 var multiply = function (n, c) {
2506 var index = -1;
2507 var c2 = c;
2508 while (++index < 6) {
2509 c2 += n * data[index];
2510 data[index] = c2 % 1e7;
2511 c2 = floor$1(c2 / 1e7);
2512 }
2513 };
2514
2515 var divide = function (n) {
2516 var index = 6;
2517 var c = 0;
2518 while (--index >= 0) {
2519 c += data[index];
2520 data[index] = floor$1(c / n);
2521 c = (c % n) * 1e7;
2522 }
2523 };
2524
2525 var dataToString = function () {
2526 var index = 6;
2527 var s = '';
2528 while (--index >= 0) {
2529 if (s !== '' || index === 0 || data[index] !== 0) {
2530 var t = String(data[index]);
2531 s = s === '' ? t : s + stringRepeat.call('0', 7 - t.length) + t;
2532 }
2533 } return s;
2534 };
2535
2536 if (fractDigits < 0 || fractDigits > 20) throw RangeError('Incorrect fraction digits');
2537 // eslint-disable-next-line no-self-compare
2538 if (number != number) return 'NaN';
2539 if (number <= -1e21 || number >= 1e21) return String(number);
2540 if (number < 0) {
2541 sign = '-';
2542 number = -number;
2543 }
2544 if (number > 1e-21) {
2545 e = log(number * pow(2, 69, 1)) - 69;
2546 z = e < 0 ? number * pow(2, -e, 1) : number / pow(2, e, 1);
2547 z *= 0x10000000000000;
2548 e = 52 - e;
2549 if (e > 0) {
2550 multiply(0, z);
2551 j = fractDigits;
2552 while (j >= 7) {
2553 multiply(1e7, 0);
2554 j -= 7;
2555 }
2556 multiply(pow(10, j, 1), 0);
2557 j = e - 1;
2558 while (j >= 23) {
2559 divide(1 << 23);
2560 j -= 23;
2561 }
2562 divide(1 << j);
2563 multiply(1, 1);
2564 divide(2);
2565 result = dataToString();
2566 } else {
2567 multiply(0, z);
2568 multiply(1 << -e, 0);
2569 result = dataToString() + stringRepeat.call('0', fractDigits);
2570 }
2571 }
2572 if (fractDigits > 0) {
2573 k = result.length;
2574 result = sign + (k <= fractDigits
2575 ? '0.' + stringRepeat.call('0', fractDigits - k) + result
2576 : result.slice(0, k - fractDigits) + '.' + result.slice(k - fractDigits));
2577 } else {
2578 result = sign + result;
2579 } return result;
2580 }
2581});
2582
2583var nativeAssign = Object.assign;
2584
2585// `Object.assign` method
2586// https://tc39.github.io/ecma262/#sec-object.assign
2587// should work with symbols and should have deterministic property order (V8 bug)
2588var objectAssign = !nativeAssign || fails(function () {
2589 var A = {};
2590 var B = {};
2591 // eslint-disable-next-line no-undef
2592 var symbol = Symbol();
2593 var alphabet = 'abcdefghijklmnopqrst';
2594 A[symbol] = 7;
2595 alphabet.split('').forEach(function (chr) { B[chr] = chr; });
2596 return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
2597}) ? function assign(target, source) { // eslint-disable-line no-unused-vars
2598 var T = toObject(target);
2599 var argumentsLength = arguments.length;
2600 var index = 1;
2601 var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
2602 var propertyIsEnumerable = objectPropertyIsEnumerable.f;
2603 while (argumentsLength > index) {
2604 var S = indexedObject(arguments[index++]);
2605 var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
2606 var length = keys.length;
2607 var j = 0;
2608 var key;
2609 while (length > j) {
2610 key = keys[j++];
2611 if (!descriptors || propertyIsEnumerable.call(S, key)) T[key] = S[key];
2612 }
2613 } return T;
2614} : nativeAssign;
2615
2616// `Object.assign` method
2617// https://tc39.github.io/ecma262/#sec-object.assign
2618_export({ target: 'Object', stat: true, forced: Object.assign !== objectAssign }, {
2619 assign: objectAssign
2620});
2621
2622// `Object.defineProperties` method
2623// https://tc39.github.io/ecma262/#sec-object.defineproperties
2624_export({ target: 'Object', stat: true, forced: !descriptors, sham: !descriptors }, {
2625 defineProperties: objectDefineProperties
2626});
2627
2628// `Object.defineProperty` method
2629// https://tc39.github.io/ecma262/#sec-object.defineproperty
2630_export({ target: 'Object', stat: true, forced: !descriptors, sham: !descriptors }, {
2631 defineProperty: objectDefineProperty.f
2632});
2633
2634var freezing = !fails(function () {
2635 return Object.isExtensible(Object.preventExtensions({}));
2636});
2637
2638var internalMetadata = createCommonjsModule(function (module) {
2639var defineProperty = objectDefineProperty.f;
2640
2641
2642
2643var METADATA = uid('meta');
2644var id = 0;
2645
2646var isExtensible = Object.isExtensible || function () {
2647 return true;
2648};
2649
2650var setMetadata = function (it) {
2651 defineProperty(it, METADATA, { value: {
2652 objectID: 'O' + ++id, // object ID
2653 weakData: {} // weak collections IDs
2654 } });
2655};
2656
2657var fastKey = function (it, create) {
2658 // return a primitive with prefix
2659 if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
2660 if (!has(it, METADATA)) {
2661 // can't set metadata to uncaught frozen object
2662 if (!isExtensible(it)) return 'F';
2663 // not necessary to add metadata
2664 if (!create) return 'E';
2665 // add missing metadata
2666 setMetadata(it);
2667 // return object ID
2668 } return it[METADATA].objectID;
2669};
2670
2671var getWeakData = function (it, create) {
2672 if (!has(it, METADATA)) {
2673 // can't set metadata to uncaught frozen object
2674 if (!isExtensible(it)) return true;
2675 // not necessary to add metadata
2676 if (!create) return false;
2677 // add missing metadata
2678 setMetadata(it);
2679 // return the store of weak collections IDs
2680 } return it[METADATA].weakData;
2681};
2682
2683// add metadata on freeze-family methods calling
2684var onFreeze = function (it) {
2685 if (freezing && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);
2686 return it;
2687};
2688
2689var meta = module.exports = {
2690 REQUIRED: false,
2691 fastKey: fastKey,
2692 getWeakData: getWeakData,
2693 onFreeze: onFreeze
2694};
2695
2696hiddenKeys[METADATA] = true;
2697});
2698var internalMetadata_1 = internalMetadata.REQUIRED;
2699var internalMetadata_2 = internalMetadata.fastKey;
2700var internalMetadata_3 = internalMetadata.getWeakData;
2701var internalMetadata_4 = internalMetadata.onFreeze;
2702
2703var onFreeze = internalMetadata.onFreeze;
2704
2705var nativeFreeze = Object.freeze;
2706var FAILS_ON_PRIMITIVES = fails(function () { nativeFreeze(1); });
2707
2708// `Object.freeze` method
2709// https://tc39.github.io/ecma262/#sec-object.freeze
2710_export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES, sham: !freezing }, {
2711 freeze: function freeze(it) {
2712 return nativeFreeze && isObject(it) ? nativeFreeze(onFreeze(it)) : it;
2713 }
2714});
2715
2716var nativeGetOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f;
2717
2718
2719var FAILS_ON_PRIMITIVES$1 = fails(function () { nativeGetOwnPropertyDescriptor$2(1); });
2720var FORCED$4 = !descriptors || FAILS_ON_PRIMITIVES$1;
2721
2722// `Object.getOwnPropertyDescriptor` method
2723// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor
2724_export({ target: 'Object', stat: true, forced: FORCED$4, sham: !descriptors }, {
2725 getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {
2726 return nativeGetOwnPropertyDescriptor$2(toIndexedObject(it), key);
2727 }
2728});
2729
2730// `Object.getOwnPropertyDescriptors` method
2731// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
2732_export({ target: 'Object', stat: true, sham: !descriptors }, {
2733 getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {
2734 var O = toIndexedObject(object);
2735 var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
2736 var keys = ownKeys(O);
2737 var result = {};
2738 var index = 0;
2739 var key, descriptor;
2740 while (keys.length > index) {
2741 descriptor = getOwnPropertyDescriptor(O, key = keys[index++]);
2742 if (descriptor !== undefined) createProperty(result, key, descriptor);
2743 }
2744 return result;
2745 }
2746});
2747
2748var nativeGetOwnPropertyNames$2 = objectGetOwnPropertyNamesExternal.f;
2749
2750var FAILS_ON_PRIMITIVES$2 = fails(function () { return !Object.getOwnPropertyNames(1); });
2751
2752// `Object.getOwnPropertyNames` method
2753// https://tc39.github.io/ecma262/#sec-object.getownpropertynames
2754_export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$2 }, {
2755 getOwnPropertyNames: nativeGetOwnPropertyNames$2
2756});
2757
2758var nativeIsFrozen = Object.isFrozen;
2759var FAILS_ON_PRIMITIVES$3 = fails(function () { nativeIsFrozen(1); });
2760
2761// `Object.isFrozen` method
2762// https://tc39.github.io/ecma262/#sec-object.isfrozen
2763_export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$3 }, {
2764 isFrozen: function isFrozen(it) {
2765 return isObject(it) ? nativeIsFrozen ? nativeIsFrozen(it) : false : true;
2766 }
2767});
2768
2769var FAILS_ON_PRIMITIVES$4 = fails(function () { objectKeys(1); });
2770
2771// `Object.keys` method
2772// https://tc39.github.io/ecma262/#sec-object.keys
2773_export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$4 }, {
2774 keys: function keys(it) {
2775 return objectKeys(toObject(it));
2776 }
2777});
2778
2779var TO_STRING_TAG$3 = wellKnownSymbol('toStringTag');
2780var test$1 = {};
2781
2782test$1[TO_STRING_TAG$3] = 'z';
2783
2784// `Object.prototype.toString` method implementation
2785// https://tc39.github.io/ecma262/#sec-object.prototype.tostring
2786var objectToString = String(test$1) !== '[object z]' ? function toString() {
2787 return '[object ' + classof(this) + ']';
2788} : test$1.toString;
2789
2790var ObjectPrototype$3 = Object.prototype;
2791
2792// `Object.prototype.toString` method
2793// https://tc39.github.io/ecma262/#sec-object.prototype.tostring
2794if (objectToString !== ObjectPrototype$3.toString) {
2795 redefine(ObjectPrototype$3, 'toString', objectToString, { unsafe: true });
2796}
2797
2798var propertyIsEnumerable = objectPropertyIsEnumerable.f;
2799
2800// `Object.{ entries, values }` methods implementation
2801var createMethod$4 = function (TO_ENTRIES) {
2802 return function (it) {
2803 var O = toIndexedObject(it);
2804 var keys = objectKeys(O);
2805 var length = keys.length;
2806 var i = 0;
2807 var result = [];
2808 var key;
2809 while (length > i) {
2810 key = keys[i++];
2811 if (!descriptors || propertyIsEnumerable.call(O, key)) {
2812 result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
2813 }
2814 }
2815 return result;
2816 };
2817};
2818
2819var objectToArray = {
2820 // `Object.entries` method
2821 // https://tc39.github.io/ecma262/#sec-object.entries
2822 entries: createMethod$4(true),
2823 // `Object.values` method
2824 // https://tc39.github.io/ecma262/#sec-object.values
2825 values: createMethod$4(false)
2826};
2827
2828var $values = objectToArray.values;
2829
2830// `Object.values` method
2831// https://tc39.github.io/ecma262/#sec-object.values
2832_export({ target: 'Object', stat: true }, {
2833 values: function values(O) {
2834 return $values(O);
2835 }
2836});
2837
2838var trim$1 = stringTrim.trim;
2839
2840
2841var nativeParseFloat = global_1.parseFloat;
2842var FORCED$5 = 1 / nativeParseFloat(whitespaces + '-0') !== -Infinity;
2843
2844// `parseFloat` method
2845// https://tc39.github.io/ecma262/#sec-parsefloat-string
2846var _parseFloat = FORCED$5 ? function parseFloat(string) {
2847 var trimmedString = trim$1(String(string));
2848 var result = nativeParseFloat(trimmedString);
2849 return result === 0 && trimmedString.charAt(0) == '-' ? -0 : result;
2850} : nativeParseFloat;
2851
2852// `parseFloat` method
2853// https://tc39.github.io/ecma262/#sec-parsefloat-string
2854_export({ global: true, forced: parseFloat != _parseFloat }, {
2855 parseFloat: _parseFloat
2856});
2857
2858var trim$2 = stringTrim.trim;
2859
2860
2861var nativeParseInt = global_1.parseInt;
2862var hex = /^[+-]?0[Xx]/;
2863var FORCED$6 = nativeParseInt(whitespaces + '08') !== 8 || nativeParseInt(whitespaces + '0x16') !== 22;
2864
2865// `parseInt` method
2866// https://tc39.github.io/ecma262/#sec-parseint-string-radix
2867var _parseInt = FORCED$6 ? function parseInt(string, radix) {
2868 var S = trim$2(String(string));
2869 return nativeParseInt(S, (radix >>> 0) || (hex.test(S) ? 16 : 10));
2870} : nativeParseInt;
2871
2872// `parseInt` method
2873// https://tc39.github.io/ecma262/#sec-parseint-string-radix
2874_export({ global: true, forced: parseInt != _parseInt }, {
2875 parseInt: _parseInt
2876});
2877
2878var MATCH = wellKnownSymbol('match');
2879
2880// `IsRegExp` abstract operation
2881// https://tc39.github.io/ecma262/#sec-isregexp
2882var isRegexp = function (it) {
2883 var isRegExp;
2884 return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp');
2885};
2886
2887// `RegExp.prototype.flags` getter implementation
2888// https://tc39.github.io/ecma262/#sec-get-regexp.prototype.flags
2889var regexpFlags = function () {
2890 var that = anObject(this);
2891 var result = '';
2892 if (that.global) result += 'g';
2893 if (that.ignoreCase) result += 'i';
2894 if (that.multiline) result += 'm';
2895 if (that.dotAll) result += 's';
2896 if (that.unicode) result += 'u';
2897 if (that.sticky) result += 'y';
2898 return result;
2899};
2900
2901var SPECIES$4 = wellKnownSymbol('species');
2902
2903var setSpecies = function (CONSTRUCTOR_NAME) {
2904 var Constructor = getBuiltIn(CONSTRUCTOR_NAME);
2905 var defineProperty = objectDefineProperty.f;
2906
2907 if (descriptors && Constructor && !Constructor[SPECIES$4]) {
2908 defineProperty(Constructor, SPECIES$4, {
2909 configurable: true,
2910 get: function () { return this; }
2911 });
2912 }
2913};
2914
2915var defineProperty$6 = objectDefineProperty.f;
2916var getOwnPropertyNames$1 = objectGetOwnPropertyNames.f;
2917
2918
2919
2920
2921
2922
2923
2924var MATCH$1 = wellKnownSymbol('match');
2925var NativeRegExp = global_1.RegExp;
2926var RegExpPrototype = NativeRegExp.prototype;
2927var re1 = /a/g;
2928var re2 = /a/g;
2929
2930// "new" should create a new object, old webkit bug
2931var CORRECT_NEW = new NativeRegExp(re1) !== re1;
2932
2933var FORCED$7 = descriptors && isForced_1('RegExp', (!CORRECT_NEW || fails(function () {
2934 re2[MATCH$1] = false;
2935 // RegExp constructor can alter flags and IsRegExp works correct with @@match
2936 return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';
2937})));
2938
2939// `RegExp` constructor
2940// https://tc39.github.io/ecma262/#sec-regexp-constructor
2941if (FORCED$7) {
2942 var RegExpWrapper = function RegExp(pattern, flags) {
2943 var thisIsRegExp = this instanceof RegExpWrapper;
2944 var patternIsRegExp = isRegexp(pattern);
2945 var flagsAreUndefined = flags === undefined;
2946 return !thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined ? pattern
2947 : inheritIfRequired(CORRECT_NEW
2948 ? new NativeRegExp(patternIsRegExp && !flagsAreUndefined ? pattern.source : pattern, flags)
2949 : NativeRegExp((patternIsRegExp = pattern instanceof RegExpWrapper)
2950 ? pattern.source
2951 : pattern, patternIsRegExp && flagsAreUndefined ? regexpFlags.call(pattern) : flags)
2952 , thisIsRegExp ? this : RegExpPrototype, RegExpWrapper);
2953 };
2954 var proxy = function (key) {
2955 key in RegExpWrapper || defineProperty$6(RegExpWrapper, key, {
2956 configurable: true,
2957 get: function () { return NativeRegExp[key]; },
2958 set: function (it) { NativeRegExp[key] = it; }
2959 });
2960 };
2961 var keys$2 = getOwnPropertyNames$1(NativeRegExp);
2962 var index = 0;
2963 while (keys$2.length > index) proxy(keys$2[index++]);
2964 RegExpPrototype.constructor = RegExpWrapper;
2965 RegExpWrapper.prototype = RegExpPrototype;
2966 redefine(global_1, 'RegExp', RegExpWrapper);
2967}
2968
2969// https://tc39.github.io/ecma262/#sec-get-regexp-@@species
2970setSpecies('RegExp');
2971
2972var nativeExec = RegExp.prototype.exec;
2973// This always refers to the native implementation, because the
2974// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
2975// which loads this file before patching the method.
2976var nativeReplace = String.prototype.replace;
2977
2978var patchedExec = nativeExec;
2979
2980var UPDATES_LAST_INDEX_WRONG = (function () {
2981 var re1 = /a/;
2982 var re2 = /b*/g;
2983 nativeExec.call(re1, 'a');
2984 nativeExec.call(re2, 'a');
2985 return re1.lastIndex !== 0 || re2.lastIndex !== 0;
2986})();
2987
2988// nonparticipating capturing group, copied from es5-shim's String#split patch.
2989var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
2990
2991var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
2992
2993if (PATCH) {
2994 patchedExec = function exec(str) {
2995 var re = this;
2996 var lastIndex, reCopy, match, i;
2997
2998 if (NPCG_INCLUDED) {
2999 reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re));
3000 }
3001 if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
3002
3003 match = nativeExec.call(re, str);
3004
3005 if (UPDATES_LAST_INDEX_WRONG && match) {
3006 re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
3007 }
3008 if (NPCG_INCLUDED && match && match.length > 1) {
3009 // Fix browsers whose `exec` methods don't consistently return `undefined`
3010 // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
3011 nativeReplace.call(match[0], reCopy, function () {
3012 for (i = 1; i < arguments.length - 2; i++) {
3013 if (arguments[i] === undefined) match[i] = undefined;
3014 }
3015 });
3016 }
3017
3018 return match;
3019 };
3020}
3021
3022var regexpExec = patchedExec;
3023
3024_export({ target: 'RegExp', proto: true, forced: /./.exec !== regexpExec }, {
3025 exec: regexpExec
3026});
3027
3028var TO_STRING$1 = 'toString';
3029var RegExpPrototype$1 = RegExp.prototype;
3030var nativeToString = RegExpPrototype$1[TO_STRING$1];
3031
3032var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
3033// FF44- RegExp#toString has a wrong name
3034var INCORRECT_NAME = nativeToString.name != TO_STRING$1;
3035
3036// `RegExp.prototype.toString` method
3037// https://tc39.github.io/ecma262/#sec-regexp.prototype.tostring
3038if (NOT_GENERIC || INCORRECT_NAME) {
3039 redefine(RegExp.prototype, TO_STRING$1, function toString() {
3040 var R = anObject(this);
3041 var p = String(R.source);
3042 var rf = R.flags;
3043 var f = String(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype$1) ? regexpFlags.call(R) : rf);
3044 return '/' + p + '/' + f;
3045 }, { unsafe: true });
3046}
3047
3048// `String.prototype.{ codePointAt, at }` methods implementation
3049var createMethod$5 = function (CONVERT_TO_STRING) {
3050 return function ($this, pos) {
3051 var S = String(requireObjectCoercible($this));
3052 var position = toInteger(pos);
3053 var size = S.length;
3054 var first, second;
3055 if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
3056 first = S.charCodeAt(position);
3057 return first < 0xD800 || first > 0xDBFF || position + 1 === size
3058 || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
3059 ? CONVERT_TO_STRING ? S.charAt(position) : first
3060 : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
3061 };
3062};
3063
3064var stringMultibyte = {
3065 // `String.prototype.codePointAt` method
3066 // https://tc39.github.io/ecma262/#sec-string.prototype.codepointat
3067 codeAt: createMethod$5(false),
3068 // `String.prototype.at` method
3069 // https://github.com/mathiasbynens/String.prototype.at
3070 charAt: createMethod$5(true)
3071};
3072
3073var charAt = stringMultibyte.charAt;
3074
3075
3076
3077var STRING_ITERATOR = 'String Iterator';
3078var setInternalState$2 = internalState.set;
3079var getInternalState$2 = internalState.getterFor(STRING_ITERATOR);
3080
3081// `String.prototype[@@iterator]` method
3082// https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator
3083defineIterator(String, 'String', function (iterated) {
3084 setInternalState$2(this, {
3085 type: STRING_ITERATOR,
3086 string: String(iterated),
3087 index: 0
3088 });
3089// `%StringIteratorPrototype%.next` method
3090// https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next
3091}, function next() {
3092 var state = getInternalState$2(this);
3093 var string = state.string;
3094 var index = state.index;
3095 var point;
3096 if (index >= string.length) return { value: undefined, done: true };
3097 point = charAt(string, index);
3098 state.index += point.length;
3099 return { value: point, done: false };
3100});
3101
3102var SPECIES$5 = wellKnownSymbol('species');
3103
3104var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
3105 // #replace needs built-in support for named groups.
3106 // #match works fine because it just return the exec results, even if it has
3107 // a "grops" property.
3108 var re = /./;
3109 re.exec = function () {
3110 var result = [];
3111 result.groups = { a: '7' };
3112 return result;
3113 };
3114 return ''.replace(re, '$<a>') !== '7';
3115});
3116
3117// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
3118// Weex JS has frozen built-in prototypes, so use try / catch wrapper
3119var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
3120 var re = /(?:)/;
3121 var originalExec = re.exec;
3122 re.exec = function () { return originalExec.apply(this, arguments); };
3123 var result = 'ab'.split(re);
3124 return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
3125});
3126
3127var fixRegexpWellKnownSymbolLogic = function (KEY, length, exec, sham) {
3128 var SYMBOL = wellKnownSymbol(KEY);
3129
3130 var DELEGATES_TO_SYMBOL = !fails(function () {
3131 // String methods call symbol-named RegEp methods
3132 var O = {};
3133 O[SYMBOL] = function () { return 7; };
3134 return ''[KEY](O) != 7;
3135 });
3136
3137 var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
3138 // Symbol-named RegExp methods call .exec
3139 var execCalled = false;
3140 var re = /a/;
3141 re.exec = function () { execCalled = true; return null; };
3142
3143 if (KEY === 'split') {
3144 // RegExp[@@split] doesn't call the regex's exec method, but first creates
3145 // a new one. We need to return the patched regex when creating the new one.
3146 re.constructor = {};
3147 re.constructor[SPECIES$5] = function () { return re; };
3148 }
3149
3150 re[SYMBOL]('');
3151 return !execCalled;
3152 });
3153
3154 if (
3155 !DELEGATES_TO_SYMBOL ||
3156 !DELEGATES_TO_EXEC ||
3157 (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||
3158 (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
3159 ) {
3160 var nativeRegExpMethod = /./[SYMBOL];
3161 var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
3162 if (regexp.exec === regexpExec) {
3163 if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
3164 // The native String method already delegates to @@method (this
3165 // polyfilled function), leasing to infinite recursion.
3166 // We avoid it by directly calling the native @@method method.
3167 return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
3168 }
3169 return { done: true, value: nativeMethod.call(str, regexp, arg2) };
3170 }
3171 return { done: false };
3172 });
3173 var stringMethod = methods[0];
3174 var regexMethod = methods[1];
3175
3176 redefine(String.prototype, KEY, stringMethod);
3177 redefine(RegExp.prototype, SYMBOL, length == 2
3178 // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
3179 // 21.2.5.11 RegExp.prototype[@@split](string, limit)
3180 ? function (string, arg) { return regexMethod.call(string, this, arg); }
3181 // 21.2.5.6 RegExp.prototype[@@match](string)
3182 // 21.2.5.9 RegExp.prototype[@@search](string)
3183 : function (string) { return regexMethod.call(string, this); }
3184 );
3185 if (sham) hide(RegExp.prototype[SYMBOL], 'sham', true);
3186 }
3187};
3188
3189var charAt$1 = stringMultibyte.charAt;
3190
3191// `AdvanceStringIndex` abstract operation
3192// https://tc39.github.io/ecma262/#sec-advancestringindex
3193var advanceStringIndex = function (S, index, unicode) {
3194 return index + (unicode ? charAt$1(S, index).length : 1);
3195};
3196
3197// `RegExpExec` abstract operation
3198// https://tc39.github.io/ecma262/#sec-regexpexec
3199var regexpExecAbstract = function (R, S) {
3200 var exec = R.exec;
3201 if (typeof exec === 'function') {
3202 var result = exec.call(R, S);
3203 if (typeof result !== 'object') {
3204 throw TypeError('RegExp exec method returned something other than an Object or null');
3205 }
3206 return result;
3207 }
3208
3209 if (classofRaw(R) !== 'RegExp') {
3210 throw TypeError('RegExp#exec called on incompatible receiver');
3211 }
3212
3213 return regexpExec.call(R, S);
3214};
3215
3216// @@match logic
3217fixRegexpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {
3218 return [
3219 // `String.prototype.match` method
3220 // https://tc39.github.io/ecma262/#sec-string.prototype.match
3221 function match(regexp) {
3222 var O = requireObjectCoercible(this);
3223 var matcher = regexp == undefined ? undefined : regexp[MATCH];
3224 return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
3225 },
3226 // `RegExp.prototype[@@match]` method
3227 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match
3228 function (regexp) {
3229 var res = maybeCallNative(nativeMatch, regexp, this);
3230 if (res.done) return res.value;
3231
3232 var rx = anObject(regexp);
3233 var S = String(this);
3234
3235 if (!rx.global) return regexpExecAbstract(rx, S);
3236
3237 var fullUnicode = rx.unicode;
3238 rx.lastIndex = 0;
3239 var A = [];
3240 var n = 0;
3241 var result;
3242 while ((result = regexpExecAbstract(rx, S)) !== null) {
3243 var matchStr = String(result[0]);
3244 A[n] = matchStr;
3245 if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
3246 n++;
3247 }
3248 return n === 0 ? null : A;
3249 }
3250 ];
3251});
3252
3253var max$2 = Math.max;
3254var min$2 = Math.min;
3255var floor$2 = Math.floor;
3256var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d\d?|<[^>]*>)/g;
3257var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d\d?)/g;
3258
3259var maybeToString = function (it) {
3260 return it === undefined ? it : String(it);
3261};
3262
3263// @@replace logic
3264fixRegexpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative) {
3265 return [
3266 // `String.prototype.replace` method
3267 // https://tc39.github.io/ecma262/#sec-string.prototype.replace
3268 function replace(searchValue, replaceValue) {
3269 var O = requireObjectCoercible(this);
3270 var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
3271 return replacer !== undefined
3272 ? replacer.call(searchValue, O, replaceValue)
3273 : nativeReplace.call(String(O), searchValue, replaceValue);
3274 },
3275 // `RegExp.prototype[@@replace]` method
3276 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
3277 function (regexp, replaceValue) {
3278 var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
3279 if (res.done) return res.value;
3280
3281 var rx = anObject(regexp);
3282 var S = String(this);
3283
3284 var functionalReplace = typeof replaceValue === 'function';
3285 if (!functionalReplace) replaceValue = String(replaceValue);
3286
3287 var global = rx.global;
3288 if (global) {
3289 var fullUnicode = rx.unicode;
3290 rx.lastIndex = 0;
3291 }
3292 var results = [];
3293 while (true) {
3294 var result = regexpExecAbstract(rx, S);
3295 if (result === null) break;
3296
3297 results.push(result);
3298 if (!global) break;
3299
3300 var matchStr = String(result[0]);
3301 if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
3302 }
3303
3304 var accumulatedResult = '';
3305 var nextSourcePosition = 0;
3306 for (var i = 0; i < results.length; i++) {
3307 result = results[i];
3308
3309 var matched = String(result[0]);
3310 var position = max$2(min$2(toInteger(result.index), S.length), 0);
3311 var captures = [];
3312 // NOTE: This is equivalent to
3313 // captures = result.slice(1).map(maybeToString)
3314 // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
3315 // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
3316 // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
3317 for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
3318 var namedCaptures = result.groups;
3319 if (functionalReplace) {
3320 var replacerArgs = [matched].concat(captures, position, S);
3321 if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
3322 var replacement = String(replaceValue.apply(undefined, replacerArgs));
3323 } else {
3324 replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
3325 }
3326 if (position >= nextSourcePosition) {
3327 accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
3328 nextSourcePosition = position + matched.length;
3329 }
3330 }
3331 return accumulatedResult + S.slice(nextSourcePosition);
3332 }
3333 ];
3334
3335 // https://tc39.github.io/ecma262/#sec-getsubstitution
3336 function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
3337 var tailPos = position + matched.length;
3338 var m = captures.length;
3339 var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
3340 if (namedCaptures !== undefined) {
3341 namedCaptures = toObject(namedCaptures);
3342 symbols = SUBSTITUTION_SYMBOLS;
3343 }
3344 return nativeReplace.call(replacement, symbols, function (match, ch) {
3345 var capture;
3346 switch (ch.charAt(0)) {
3347 case '$': return '$';
3348 case '&': return matched;
3349 case '`': return str.slice(0, position);
3350 case "'": return str.slice(tailPos);
3351 case '<':
3352 capture = namedCaptures[ch.slice(1, -1)];
3353 break;
3354 default: // \d\d?
3355 var n = +ch;
3356 if (n === 0) return match;
3357 if (n > m) {
3358 var f = floor$2(n / 10);
3359 if (f === 0) return match;
3360 if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
3361 return match;
3362 }
3363 capture = captures[n - 1];
3364 }
3365 return capture === undefined ? '' : capture;
3366 });
3367 }
3368});
3369
3370var arrayPush = [].push;
3371var min$3 = Math.min;
3372var MAX_UINT32 = 0xFFFFFFFF;
3373
3374// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
3375var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });
3376
3377// @@split logic
3378fixRegexpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
3379 var internalSplit;
3380 if (
3381 'abbc'.split(/(b)*/)[1] == 'c' ||
3382 'test'.split(/(?:)/, -1).length != 4 ||
3383 'ab'.split(/(?:ab)*/).length != 2 ||
3384 '.'.split(/(.?)(.?)/).length != 4 ||
3385 '.'.split(/()()/).length > 1 ||
3386 ''.split(/.?/).length
3387 ) {
3388 // based on es5-shim implementation, need to rework it
3389 internalSplit = function (separator, limit) {
3390 var string = String(requireObjectCoercible(this));
3391 var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
3392 if (lim === 0) return [];
3393 if (separator === undefined) return [string];
3394 // If `separator` is not a regex, use native split
3395 if (!isRegexp(separator)) {
3396 return nativeSplit.call(string, separator, lim);
3397 }
3398 var output = [];
3399 var flags = (separator.ignoreCase ? 'i' : '') +
3400 (separator.multiline ? 'm' : '') +
3401 (separator.unicode ? 'u' : '') +
3402 (separator.sticky ? 'y' : '');
3403 var lastLastIndex = 0;
3404 // Make `global` and avoid `lastIndex` issues by working with a copy
3405 var separatorCopy = new RegExp(separator.source, flags + 'g');
3406 var match, lastIndex, lastLength;
3407 while (match = regexpExec.call(separatorCopy, string)) {
3408 lastIndex = separatorCopy.lastIndex;
3409 if (lastIndex > lastLastIndex) {
3410 output.push(string.slice(lastLastIndex, match.index));
3411 if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
3412 lastLength = match[0].length;
3413 lastLastIndex = lastIndex;
3414 if (output.length >= lim) break;
3415 }
3416 if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
3417 }
3418 if (lastLastIndex === string.length) {
3419 if (lastLength || !separatorCopy.test('')) output.push('');
3420 } else output.push(string.slice(lastLastIndex));
3421 return output.length > lim ? output.slice(0, lim) : output;
3422 };
3423 // Chakra, V8
3424 } else if ('0'.split(undefined, 0).length) {
3425 internalSplit = function (separator, limit) {
3426 return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
3427 };
3428 } else internalSplit = nativeSplit;
3429
3430 return [
3431 // `String.prototype.split` method
3432 // https://tc39.github.io/ecma262/#sec-string.prototype.split
3433 function split(separator, limit) {
3434 var O = requireObjectCoercible(this);
3435 var splitter = separator == undefined ? undefined : separator[SPLIT];
3436 return splitter !== undefined
3437 ? splitter.call(separator, O, limit)
3438 : internalSplit.call(String(O), separator, limit);
3439 },
3440 // `RegExp.prototype[@@split]` method
3441 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
3442 //
3443 // NOTE: This cannot be properly polyfilled in engines that don't support
3444 // the 'y' flag.
3445 function (regexp, limit) {
3446 var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
3447 if (res.done) return res.value;
3448
3449 var rx = anObject(regexp);
3450 var S = String(this);
3451 var C = speciesConstructor(rx, RegExp);
3452
3453 var unicodeMatching = rx.unicode;
3454 var flags = (rx.ignoreCase ? 'i' : '') +
3455 (rx.multiline ? 'm' : '') +
3456 (rx.unicode ? 'u' : '') +
3457 (SUPPORTS_Y ? 'y' : 'g');
3458
3459 // ^(? + rx + ) is needed, in combination with some S slicing, to
3460 // simulate the 'y' flag.
3461 var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
3462 var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
3463 if (lim === 0) return [];
3464 if (S.length === 0) return regexpExecAbstract(splitter, S) === null ? [S] : [];
3465 var p = 0;
3466 var q = 0;
3467 var A = [];
3468 while (q < S.length) {
3469 splitter.lastIndex = SUPPORTS_Y ? q : 0;
3470 var z = regexpExecAbstract(splitter, SUPPORTS_Y ? S : S.slice(q));
3471 var e;
3472 if (
3473 z === null ||
3474 (e = min$3(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
3475 ) {
3476 q = advanceStringIndex(S, q, unicodeMatching);
3477 } else {
3478 A.push(S.slice(p, q));
3479 if (A.length === lim) return A;
3480 for (var i = 1; i <= z.length - 1; i++) {
3481 A.push(z[i]);
3482 if (A.length === lim) return A;
3483 }
3484 q = p = e;
3485 }
3486 }
3487 A.push(S.slice(p));
3488 return A;
3489 }
3490 ];
3491}, !SUPPORTS_Y);
3492
3493var non = '\u200B\u0085\u180E';
3494
3495// check that a method works with the correct list
3496// of whitespaces and has a correct name
3497var forcedStringTrimMethod = function (METHOD_NAME) {
3498 return fails(function () {
3499 return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;
3500 });
3501};
3502
3503var $trim = stringTrim.trim;
3504
3505
3506// `String.prototype.trim` method
3507// https://tc39.github.io/ecma262/#sec-string.prototype.trim
3508_export({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, {
3509 trim: function trim() {
3510 return $trim(this);
3511 }
3512});
3513
3514/* eslint-disable no-new */
3515
3516
3517
3518var NATIVE_ARRAY_BUFFER_VIEWS$1 = arrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;
3519
3520var ArrayBuffer$1 = global_1.ArrayBuffer;
3521var Int8Array$2 = global_1.Int8Array;
3522
3523var typedArraysConstructorsRequiresWrappers = !NATIVE_ARRAY_BUFFER_VIEWS$1 || !fails(function () {
3524 Int8Array$2(1);
3525}) || !fails(function () {
3526 new Int8Array$2(-1);
3527}) || !checkCorrectnessOfIteration(function (iterable) {
3528 new Int8Array$2();
3529 new Int8Array$2(null);
3530 new Int8Array$2(1.5);
3531 new Int8Array$2(iterable);
3532}, true) || fails(function () {
3533 // Safari 11 bug
3534 return new Int8Array$2(new ArrayBuffer$1(2), 1, undefined).length !== 1;
3535});
3536
3537var toOffset = function (it, BYTES) {
3538 var offset = toInteger(it);
3539 if (offset < 0 || offset % BYTES) throw RangeError('Wrong offset');
3540 return offset;
3541};
3542
3543var aTypedArrayConstructor$1 = arrayBufferViewCore.aTypedArrayConstructor;
3544
3545var typedArrayFrom = function from(source /* , mapfn, thisArg */) {
3546 var O = toObject(source);
3547 var argumentsLength = arguments.length;
3548 var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
3549 var mapping = mapfn !== undefined;
3550 var iteratorMethod = getIteratorMethod(O);
3551 var i, length, result, step, iterator;
3552 if (iteratorMethod != undefined && !isArrayIteratorMethod(iteratorMethod)) {
3553 iterator = iteratorMethod.call(O);
3554 O = [];
3555 while (!(step = iterator.next()).done) {
3556 O.push(step.value);
3557 }
3558 }
3559 if (mapping && argumentsLength > 2) {
3560 mapfn = bindContext(mapfn, arguments[2], 2);
3561 }
3562 length = toLength(O.length);
3563 result = new (aTypedArrayConstructor$1(this))(length);
3564 for (i = 0; length > i; i++) {
3565 result[i] = mapping ? mapfn(O[i], i) : O[i];
3566 }
3567 return result;
3568};
3569
3570var typedArrayConstructor = createCommonjsModule(function (module) {
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589var getOwnPropertyNames = objectGetOwnPropertyNames.f;
3590
3591var forEach = arrayIteration.forEach;
3592
3593
3594
3595
3596
3597var getInternalState = internalState.get;
3598var setInternalState = internalState.set;
3599var nativeDefineProperty = objectDefineProperty.f;
3600var nativeGetOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
3601var round = Math.round;
3602var RangeError = global_1.RangeError;
3603var ArrayBuffer = arrayBuffer.ArrayBuffer;
3604var DataView = arrayBuffer.DataView;
3605var NATIVE_ARRAY_BUFFER_VIEWS = arrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;
3606var TYPED_ARRAY_TAG = arrayBufferViewCore.TYPED_ARRAY_TAG;
3607var TypedArray = arrayBufferViewCore.TypedArray;
3608var TypedArrayPrototype = arrayBufferViewCore.TypedArrayPrototype;
3609var aTypedArrayConstructor = arrayBufferViewCore.aTypedArrayConstructor;
3610var isTypedArray = arrayBufferViewCore.isTypedArray;
3611var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';
3612var WRONG_LENGTH = 'Wrong length';
3613
3614var fromList = function (C, list) {
3615 var index = 0;
3616 var length = list.length;
3617 var result = new (aTypedArrayConstructor(C))(length);
3618 while (length > index) result[index] = list[index++];
3619 return result;
3620};
3621
3622var addGetter = function (it, key) {
3623 nativeDefineProperty(it, key, { get: function () {
3624 return getInternalState(this)[key];
3625 } });
3626};
3627
3628var isArrayBuffer = function (it) {
3629 var klass;
3630 return it instanceof ArrayBuffer || (klass = classof(it)) == 'ArrayBuffer' || klass == 'SharedArrayBuffer';
3631};
3632
3633var isTypedArrayIndex = function (target, key) {
3634 return isTypedArray(target)
3635 && typeof key != 'symbol'
3636 && key in target
3637 && String(+key) == String(key);
3638};
3639
3640var wrappedGetOwnPropertyDescriptor = function getOwnPropertyDescriptor(target, key) {
3641 return isTypedArrayIndex(target, key = toPrimitive(key, true))
3642 ? createPropertyDescriptor(2, target[key])
3643 : nativeGetOwnPropertyDescriptor(target, key);
3644};
3645
3646var wrappedDefineProperty = function defineProperty(target, key, descriptor) {
3647 if (isTypedArrayIndex(target, key = toPrimitive(key, true))
3648 && isObject(descriptor)
3649 && has(descriptor, 'value')
3650 && !has(descriptor, 'get')
3651 && !has(descriptor, 'set')
3652 // TODO: add validation descriptor w/o calling accessors
3653 && !descriptor.configurable
3654 && (!has(descriptor, 'writable') || descriptor.writable)
3655 && (!has(descriptor, 'enumerable') || descriptor.enumerable)
3656 ) {
3657 target[key] = descriptor.value;
3658 return target;
3659 } return nativeDefineProperty(target, key, descriptor);
3660};
3661
3662if (descriptors) {
3663 if (!NATIVE_ARRAY_BUFFER_VIEWS) {
3664 objectGetOwnPropertyDescriptor.f = wrappedGetOwnPropertyDescriptor;
3665 objectDefineProperty.f = wrappedDefineProperty;
3666 addGetter(TypedArrayPrototype, 'buffer');
3667 addGetter(TypedArrayPrototype, 'byteOffset');
3668 addGetter(TypedArrayPrototype, 'byteLength');
3669 addGetter(TypedArrayPrototype, 'length');
3670 }
3671
3672 _export({ target: 'Object', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, {
3673 getOwnPropertyDescriptor: wrappedGetOwnPropertyDescriptor,
3674 defineProperty: wrappedDefineProperty
3675 });
3676
3677 // eslint-disable-next-line max-statements
3678 module.exports = function (TYPE, BYTES, wrapper, CLAMPED) {
3679 var CONSTRUCTOR_NAME = TYPE + (CLAMPED ? 'Clamped' : '') + 'Array';
3680 var GETTER = 'get' + TYPE;
3681 var SETTER = 'set' + TYPE;
3682 var NativeTypedArrayConstructor = global_1[CONSTRUCTOR_NAME];
3683 var TypedArrayConstructor = NativeTypedArrayConstructor;
3684 var TypedArrayConstructorPrototype = TypedArrayConstructor && TypedArrayConstructor.prototype;
3685 var exported = {};
3686
3687 var getter = function (that, index) {
3688 var data = getInternalState(that);
3689 return data.view[GETTER](index * BYTES + data.byteOffset, true);
3690 };
3691
3692 var setter = function (that, index, value) {
3693 var data = getInternalState(that);
3694 if (CLAMPED) value = (value = round(value)) < 0 ? 0 : value > 0xFF ? 0xFF : value & 0xFF;
3695 data.view[SETTER](index * BYTES + data.byteOffset, value, true);
3696 };
3697
3698 var addElement = function (that, index) {
3699 nativeDefineProperty(that, index, {
3700 get: function () {
3701 return getter(this, index);
3702 },
3703 set: function (value) {
3704 return setter(this, index, value);
3705 },
3706 enumerable: true
3707 });
3708 };
3709
3710 if (!NATIVE_ARRAY_BUFFER_VIEWS) {
3711 TypedArrayConstructor = wrapper(function (that, data, offset, $length) {
3712 anInstance(that, TypedArrayConstructor, CONSTRUCTOR_NAME);
3713 var index = 0;
3714 var byteOffset = 0;
3715 var buffer, byteLength, length;
3716 if (!isObject(data)) {
3717 length = toIndex(data);
3718 byteLength = length * BYTES;
3719 buffer = new ArrayBuffer(byteLength);
3720 } else if (isArrayBuffer(data)) {
3721 buffer = data;
3722 byteOffset = toOffset(offset, BYTES);
3723 var $len = data.byteLength;
3724 if ($length === undefined) {
3725 if ($len % BYTES) throw RangeError(WRONG_LENGTH);
3726 byteLength = $len - byteOffset;
3727 if (byteLength < 0) throw RangeError(WRONG_LENGTH);
3728 } else {
3729 byteLength = toLength($length) * BYTES;
3730 if (byteLength + byteOffset > $len) throw RangeError(WRONG_LENGTH);
3731 }
3732 length = byteLength / BYTES;
3733 } else if (isTypedArray(data)) {
3734 return fromList(TypedArrayConstructor, data);
3735 } else {
3736 return typedArrayFrom.call(TypedArrayConstructor, data);
3737 }
3738 setInternalState(that, {
3739 buffer: buffer,
3740 byteOffset: byteOffset,
3741 byteLength: byteLength,
3742 length: length,
3743 view: new DataView(buffer)
3744 });
3745 while (index < length) addElement(that, index++);
3746 });
3747
3748 if (objectSetPrototypeOf) objectSetPrototypeOf(TypedArrayConstructor, TypedArray);
3749 TypedArrayConstructorPrototype = TypedArrayConstructor.prototype = objectCreate(TypedArrayPrototype);
3750 } else if (typedArraysConstructorsRequiresWrappers) {
3751 TypedArrayConstructor = wrapper(function (dummy, data, typedArrayOffset, $length) {
3752 anInstance(dummy, TypedArrayConstructor, CONSTRUCTOR_NAME);
3753 if (!isObject(data)) return new NativeTypedArrayConstructor(toIndex(data));
3754 if (isArrayBuffer(data)) return $length !== undefined
3755 ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES), $length)
3756 : typedArrayOffset !== undefined
3757 ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES))
3758 : new NativeTypedArrayConstructor(data);
3759 if (isTypedArray(data)) return fromList(TypedArrayConstructor, data);
3760 return typedArrayFrom.call(TypedArrayConstructor, data);
3761 });
3762
3763 if (objectSetPrototypeOf) objectSetPrototypeOf(TypedArrayConstructor, TypedArray);
3764 forEach(getOwnPropertyNames(NativeTypedArrayConstructor), function (key) {
3765 if (!(key in TypedArrayConstructor)) hide(TypedArrayConstructor, key, NativeTypedArrayConstructor[key]);
3766 });
3767 TypedArrayConstructor.prototype = TypedArrayConstructorPrototype;
3768 }
3769
3770 if (TypedArrayConstructorPrototype.constructor !== TypedArrayConstructor) {
3771 hide(TypedArrayConstructorPrototype, 'constructor', TypedArrayConstructor);
3772 }
3773
3774 if (TYPED_ARRAY_TAG) hide(TypedArrayConstructorPrototype, TYPED_ARRAY_TAG, CONSTRUCTOR_NAME);
3775
3776 exported[CONSTRUCTOR_NAME] = TypedArrayConstructor;
3777
3778 _export({
3779 global: true, forced: TypedArrayConstructor != NativeTypedArrayConstructor, sham: !NATIVE_ARRAY_BUFFER_VIEWS
3780 }, exported);
3781
3782 if (!(BYTES_PER_ELEMENT in TypedArrayConstructor)) {
3783 hide(TypedArrayConstructor, BYTES_PER_ELEMENT, BYTES);
3784 }
3785
3786 if (!(BYTES_PER_ELEMENT in TypedArrayConstructorPrototype)) {
3787 hide(TypedArrayConstructorPrototype, BYTES_PER_ELEMENT, BYTES);
3788 }
3789
3790 setSpecies(CONSTRUCTOR_NAME);
3791 };
3792} else module.exports = function () { /* empty */ };
3793});
3794
3795// `Uint8Array` constructor
3796// https://tc39.github.io/ecma262/#sec-typedarray-objects
3797typedArrayConstructor('Uint8', 1, function (init) {
3798 return function Uint8Array(data, byteOffset, length) {
3799 return init(this, data, byteOffset, length);
3800 };
3801});
3802
3803var min$4 = Math.min;
3804
3805// `Array.prototype.copyWithin` method implementation
3806// https://tc39.github.io/ecma262/#sec-array.prototype.copywithin
3807var arrayCopyWithin = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {
3808 var O = toObject(this);
3809 var len = toLength(O.length);
3810 var to = toAbsoluteIndex(target, len);
3811 var from = toAbsoluteIndex(start, len);
3812 var end = arguments.length > 2 ? arguments[2] : undefined;
3813 var count = min$4((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);
3814 var inc = 1;
3815 if (from < to && to < from + count) {
3816 inc = -1;
3817 from += count - 1;
3818 to += count - 1;
3819 }
3820 while (count-- > 0) {
3821 if (from in O) O[to] = O[from];
3822 else delete O[to];
3823 to += inc;
3824 from += inc;
3825 } return O;
3826};
3827
3828var aTypedArray$1 = arrayBufferViewCore.aTypedArray;
3829
3830// `%TypedArray%.prototype.copyWithin` method
3831// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.copywithin
3832arrayBufferViewCore.exportProto('copyWithin', function copyWithin(target, start /* , end */) {
3833 return arrayCopyWithin.call(aTypedArray$1(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
3834});
3835
3836var $every = arrayIteration.every;
3837
3838var aTypedArray$2 = arrayBufferViewCore.aTypedArray;
3839
3840// `%TypedArray%.prototype.every` method
3841// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.every
3842arrayBufferViewCore.exportProto('every', function every(callbackfn /* , thisArg */) {
3843 return $every(aTypedArray$2(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
3844});
3845
3846var aTypedArray$3 = arrayBufferViewCore.aTypedArray;
3847
3848// `%TypedArray%.prototype.fill` method
3849// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.fill
3850// eslint-disable-next-line no-unused-vars
3851arrayBufferViewCore.exportProto('fill', function fill(value /* , start, end */) {
3852 return arrayFill.apply(aTypedArray$3(this), arguments);
3853});
3854
3855var $filter$1 = arrayIteration.filter;
3856
3857
3858var aTypedArray$4 = arrayBufferViewCore.aTypedArray;
3859var aTypedArrayConstructor$2 = arrayBufferViewCore.aTypedArrayConstructor;
3860
3861// `%TypedArray%.prototype.filter` method
3862// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.filter
3863arrayBufferViewCore.exportProto('filter', function filter(callbackfn /* , thisArg */) {
3864 var list = $filter$1(aTypedArray$4(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
3865 var C = speciesConstructor(this, this.constructor);
3866 var index = 0;
3867 var length = list.length;
3868 var result = new (aTypedArrayConstructor$2(C))(length);
3869 while (length > index) result[index] = list[index++];
3870 return result;
3871});
3872
3873var $find = arrayIteration.find;
3874
3875var aTypedArray$5 = arrayBufferViewCore.aTypedArray;
3876
3877// `%TypedArray%.prototype.find` method
3878// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.find
3879arrayBufferViewCore.exportProto('find', function find(predicate /* , thisArg */) {
3880 return $find(aTypedArray$5(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
3881});
3882
3883var $findIndex = arrayIteration.findIndex;
3884
3885var aTypedArray$6 = arrayBufferViewCore.aTypedArray;
3886
3887// `%TypedArray%.prototype.findIndex` method
3888// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.findindex
3889arrayBufferViewCore.exportProto('findIndex', function findIndex(predicate /* , thisArg */) {
3890 return $findIndex(aTypedArray$6(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
3891});
3892
3893var $forEach$2 = arrayIteration.forEach;
3894
3895var aTypedArray$7 = arrayBufferViewCore.aTypedArray;
3896
3897// `%TypedArray%.prototype.forEach` method
3898// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.foreach
3899arrayBufferViewCore.exportProto('forEach', function forEach(callbackfn /* , thisArg */) {
3900 $forEach$2(aTypedArray$7(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
3901});
3902
3903var $includes = arrayIncludes.includes;
3904
3905var aTypedArray$8 = arrayBufferViewCore.aTypedArray;
3906
3907// `%TypedArray%.prototype.includes` method
3908// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.includes
3909arrayBufferViewCore.exportProto('includes', function includes(searchElement /* , fromIndex */) {
3910 return $includes(aTypedArray$8(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
3911});
3912
3913var $indexOf$1 = arrayIncludes.indexOf;
3914
3915var aTypedArray$9 = arrayBufferViewCore.aTypedArray;
3916
3917// `%TypedArray%.prototype.indexOf` method
3918// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.indexof
3919arrayBufferViewCore.exportProto('indexOf', function indexOf(searchElement /* , fromIndex */) {
3920 return $indexOf$1(aTypedArray$9(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
3921});
3922
3923var ITERATOR$5 = wellKnownSymbol('iterator');
3924var Uint8Array$1 = global_1.Uint8Array;
3925var arrayValues = es_array_iterator.values;
3926var arrayKeys = es_array_iterator.keys;
3927var arrayEntries = es_array_iterator.entries;
3928var aTypedArray$a = arrayBufferViewCore.aTypedArray;
3929var exportProto$1 = arrayBufferViewCore.exportProto;
3930var nativeTypedArrayIterator = Uint8Array$1 && Uint8Array$1.prototype[ITERATOR$5];
3931
3932var CORRECT_ITER_NAME = !!nativeTypedArrayIterator
3933 && (nativeTypedArrayIterator.name == 'values' || nativeTypedArrayIterator.name == undefined);
3934
3935var typedArrayValues = function values() {
3936 return arrayValues.call(aTypedArray$a(this));
3937};
3938
3939// `%TypedArray%.prototype.entries` method
3940// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.entries
3941exportProto$1('entries', function entries() {
3942 return arrayEntries.call(aTypedArray$a(this));
3943});
3944// `%TypedArray%.prototype.keys` method
3945// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.keys
3946exportProto$1('keys', function keys() {
3947 return arrayKeys.call(aTypedArray$a(this));
3948});
3949// `%TypedArray%.prototype.values` method
3950// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.values
3951exportProto$1('values', typedArrayValues, !CORRECT_ITER_NAME);
3952// `%TypedArray%.prototype[@@iterator]` method
3953// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype-@@iterator
3954exportProto$1(ITERATOR$5, typedArrayValues, !CORRECT_ITER_NAME);
3955
3956var aTypedArray$b = arrayBufferViewCore.aTypedArray;
3957var $join = [].join;
3958
3959// `%TypedArray%.prototype.join` method
3960// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.join
3961// eslint-disable-next-line no-unused-vars
3962arrayBufferViewCore.exportProto('join', function join(separator) {
3963 return $join.apply(aTypedArray$b(this), arguments);
3964});
3965
3966var min$5 = Math.min;
3967var nativeLastIndexOf = [].lastIndexOf;
3968var NEGATIVE_ZERO$1 = !!nativeLastIndexOf && 1 / [1].lastIndexOf(1, -0) < 0;
3969var SLOPPY_METHOD$3 = sloppyArrayMethod('lastIndexOf');
3970
3971// `Array.prototype.lastIndexOf` method implementation
3972// https://tc39.github.io/ecma262/#sec-array.prototype.lastindexof
3973var arrayLastIndexOf = (NEGATIVE_ZERO$1 || SLOPPY_METHOD$3) ? function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {
3974 // convert -0 to +0
3975 if (NEGATIVE_ZERO$1) return nativeLastIndexOf.apply(this, arguments) || 0;
3976 var O = toIndexedObject(this);
3977 var length = toLength(O.length);
3978 var index = length - 1;
3979 if (arguments.length > 1) index = min$5(index, toInteger(arguments[1]));
3980 if (index < 0) index = length + index;
3981 for (;index >= 0; index--) if (index in O && O[index] === searchElement) return index || 0;
3982 return -1;
3983} : nativeLastIndexOf;
3984
3985var aTypedArray$c = arrayBufferViewCore.aTypedArray;
3986
3987// `%TypedArray%.prototype.lastIndexOf` method
3988// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.lastindexof
3989// eslint-disable-next-line no-unused-vars
3990arrayBufferViewCore.exportProto('lastIndexOf', function lastIndexOf(searchElement /* , fromIndex */) {
3991 return arrayLastIndexOf.apply(aTypedArray$c(this), arguments);
3992});
3993
3994var $map$1 = arrayIteration.map;
3995
3996
3997var aTypedArray$d = arrayBufferViewCore.aTypedArray;
3998var aTypedArrayConstructor$3 = arrayBufferViewCore.aTypedArrayConstructor;
3999
4000// `%TypedArray%.prototype.map` method
4001// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.map
4002arrayBufferViewCore.exportProto('map', function map(mapfn /* , thisArg */) {
4003 return $map$1(aTypedArray$d(this), mapfn, arguments.length > 1 ? arguments[1] : undefined, function (O, length) {
4004 return new (aTypedArrayConstructor$3(speciesConstructor(O, O.constructor)))(length);
4005 });
4006});
4007
4008// `Array.prototype.{ reduce, reduceRight }` methods implementation
4009var createMethod$6 = function (IS_RIGHT) {
4010 return function (that, callbackfn, argumentsLength, memo) {
4011 aFunction$1(callbackfn);
4012 var O = toObject(that);
4013 var self = indexedObject(O);
4014 var length = toLength(O.length);
4015 var index = IS_RIGHT ? length - 1 : 0;
4016 var i = IS_RIGHT ? -1 : 1;
4017 if (argumentsLength < 2) while (true) {
4018 if (index in self) {
4019 memo = self[index];
4020 index += i;
4021 break;
4022 }
4023 index += i;
4024 if (IS_RIGHT ? index < 0 : length <= index) {
4025 throw TypeError('Reduce of empty array with no initial value');
4026 }
4027 }
4028 for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {
4029 memo = callbackfn(memo, self[index], index, O);
4030 }
4031 return memo;
4032 };
4033};
4034
4035var arrayReduce = {
4036 // `Array.prototype.reduce` method
4037 // https://tc39.github.io/ecma262/#sec-array.prototype.reduce
4038 left: createMethod$6(false),
4039 // `Array.prototype.reduceRight` method
4040 // https://tc39.github.io/ecma262/#sec-array.prototype.reduceright
4041 right: createMethod$6(true)
4042};
4043
4044var $reduce = arrayReduce.left;
4045
4046var aTypedArray$e = arrayBufferViewCore.aTypedArray;
4047
4048// `%TypedArray%.prototype.reduce` method
4049// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduce
4050arrayBufferViewCore.exportProto('reduce', function reduce(callbackfn /* , initialValue */) {
4051 return $reduce(aTypedArray$e(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
4052});
4053
4054var $reduceRight = arrayReduce.right;
4055
4056var aTypedArray$f = arrayBufferViewCore.aTypedArray;
4057
4058// `%TypedArray%.prototype.reduceRicht` method
4059// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduceright
4060arrayBufferViewCore.exportProto('reduceRight', function reduceRight(callbackfn /* , initialValue */) {
4061 return $reduceRight(aTypedArray$f(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
4062});
4063
4064var aTypedArray$g = arrayBufferViewCore.aTypedArray;
4065var floor$3 = Math.floor;
4066
4067// `%TypedArray%.prototype.reverse` method
4068// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reverse
4069arrayBufferViewCore.exportProto('reverse', function reverse() {
4070 var that = this;
4071 var length = aTypedArray$g(that).length;
4072 var middle = floor$3(length / 2);
4073 var index = 0;
4074 var value;
4075 while (index < middle) {
4076 value = that[index];
4077 that[index++] = that[--length];
4078 that[length] = value;
4079 } return that;
4080});
4081
4082var aTypedArray$h = arrayBufferViewCore.aTypedArray;
4083
4084var FORCED$8 = fails(function () {
4085 // eslint-disable-next-line no-undef
4086 new Int8Array(1).set({});
4087});
4088
4089// `%TypedArray%.prototype.set` method
4090// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.set
4091arrayBufferViewCore.exportProto('set', function set(arrayLike /* , offset */) {
4092 aTypedArray$h(this);
4093 var offset = toOffset(arguments.length > 1 ? arguments[1] : undefined, 1);
4094 var length = this.length;
4095 var src = toObject(arrayLike);
4096 var len = toLength(src.length);
4097 var index = 0;
4098 if (len + offset > length) throw RangeError('Wrong length');
4099 while (index < len) this[offset + index] = src[index++];
4100}, FORCED$8);
4101
4102var aTypedArray$i = arrayBufferViewCore.aTypedArray;
4103var aTypedArrayConstructor$4 = arrayBufferViewCore.aTypedArrayConstructor;
4104var $slice = [].slice;
4105
4106var FORCED$9 = fails(function () {
4107 // eslint-disable-next-line no-undef
4108 new Int8Array(1).slice();
4109});
4110
4111// `%TypedArray%.prototype.slice` method
4112// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.slice
4113arrayBufferViewCore.exportProto('slice', function slice(start, end) {
4114 var list = $slice.call(aTypedArray$i(this), start, end);
4115 var C = speciesConstructor(this, this.constructor);
4116 var index = 0;
4117 var length = list.length;
4118 var result = new (aTypedArrayConstructor$4(C))(length);
4119 while (length > index) result[index] = list[index++];
4120 return result;
4121}, FORCED$9);
4122
4123var $some$1 = arrayIteration.some;
4124
4125var aTypedArray$j = arrayBufferViewCore.aTypedArray;
4126
4127// `%TypedArray%.prototype.some` method
4128// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.some
4129arrayBufferViewCore.exportProto('some', function some(callbackfn /* , thisArg */) {
4130 return $some$1(aTypedArray$j(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
4131});
4132
4133var aTypedArray$k = arrayBufferViewCore.aTypedArray;
4134var $sort = [].sort;
4135
4136// `%TypedArray%.prototype.sort` method
4137// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.sort
4138arrayBufferViewCore.exportProto('sort', function sort(comparefn) {
4139 return $sort.call(aTypedArray$k(this), comparefn);
4140});
4141
4142var aTypedArray$l = arrayBufferViewCore.aTypedArray;
4143
4144// `%TypedArray%.prototype.subarray` method
4145// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.subarray
4146arrayBufferViewCore.exportProto('subarray', function subarray(begin, end) {
4147 var O = aTypedArray$l(this);
4148 var length = O.length;
4149 var beginIndex = toAbsoluteIndex(begin, length);
4150 return new (speciesConstructor(O, O.constructor))(
4151 O.buffer,
4152 O.byteOffset + beginIndex * O.BYTES_PER_ELEMENT,
4153 toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - beginIndex)
4154 );
4155});
4156
4157var Int8Array$3 = global_1.Int8Array;
4158var aTypedArray$m = arrayBufferViewCore.aTypedArray;
4159var $toLocaleString = [].toLocaleString;
4160var $slice$1 = [].slice;
4161
4162// iOS Safari 6.x fails here
4163var TO_LOCALE_STRING_BUG = !!Int8Array$3 && fails(function () {
4164 $toLocaleString.call(new Int8Array$3(1));
4165});
4166
4167var FORCED$a = fails(function () {
4168 return [1, 2].toLocaleString() != new Int8Array$3([1, 2]).toLocaleString();
4169}) || !fails(function () {
4170 Int8Array$3.prototype.toLocaleString.call([1, 2]);
4171});
4172
4173// `%TypedArray%.prototype.toLocaleString` method
4174// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tolocalestring
4175arrayBufferViewCore.exportProto('toLocaleString', function toLocaleString() {
4176 return $toLocaleString.apply(TO_LOCALE_STRING_BUG ? $slice$1.call(aTypedArray$m(this)) : aTypedArray$m(this), arguments);
4177}, FORCED$a);
4178
4179var Uint8Array$2 = global_1.Uint8Array;
4180var Uint8ArrayPrototype = Uint8Array$2 && Uint8Array$2.prototype;
4181var arrayToString = [].toString;
4182var arrayJoin = [].join;
4183
4184if (fails(function () { arrayToString.call({}); })) {
4185 arrayToString = function toString() {
4186 return arrayJoin.call(this);
4187 };
4188}
4189
4190// `%TypedArray%.prototype.toString` method
4191// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tostring
4192arrayBufferViewCore.exportProto('toString', arrayToString, (Uint8ArrayPrototype || {}).toString != arrayToString);
4193
4194// iterable DOM collections
4195// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
4196var domIterables = {
4197 CSSRuleList: 0,
4198 CSSStyleDeclaration: 0,
4199 CSSValueList: 0,
4200 ClientRectList: 0,
4201 DOMRectList: 0,
4202 DOMStringList: 0,
4203 DOMTokenList: 1,
4204 DataTransferItemList: 0,
4205 FileList: 0,
4206 HTMLAllCollection: 0,
4207 HTMLCollection: 0,
4208 HTMLFormElement: 0,
4209 HTMLSelectElement: 0,
4210 MediaList: 0,
4211 MimeTypeArray: 0,
4212 NamedNodeMap: 0,
4213 NodeList: 1,
4214 PaintRequestList: 0,
4215 Plugin: 0,
4216 PluginArray: 0,
4217 SVGLengthList: 0,
4218 SVGNumberList: 0,
4219 SVGPathSegList: 0,
4220 SVGPointList: 0,
4221 SVGStringList: 0,
4222 SVGTransformList: 0,
4223 SourceBufferList: 0,
4224 StyleSheetList: 0,
4225 TextTrackCueList: 0,
4226 TextTrackList: 0,
4227 TouchList: 0
4228};
4229
4230for (var COLLECTION_NAME in domIterables) {
4231 var Collection = global_1[COLLECTION_NAME];
4232 var CollectionPrototype = Collection && Collection.prototype;
4233 // some Chrome versions have non-configurable methods on DOMTokenList
4234 if (CollectionPrototype && CollectionPrototype.forEach !== arrayForEach) try {
4235 hide(CollectionPrototype, 'forEach', arrayForEach);
4236 } catch (error) {
4237 CollectionPrototype.forEach = arrayForEach;
4238 }
4239}
4240
4241var ITERATOR$6 = wellKnownSymbol('iterator');
4242var TO_STRING_TAG$4 = wellKnownSymbol('toStringTag');
4243var ArrayValues = es_array_iterator.values;
4244
4245for (var COLLECTION_NAME$1 in domIterables) {
4246 var Collection$1 = global_1[COLLECTION_NAME$1];
4247 var CollectionPrototype$1 = Collection$1 && Collection$1.prototype;
4248 if (CollectionPrototype$1) {
4249 // some Chrome versions have non-configurable methods on DOMTokenList
4250 if (CollectionPrototype$1[ITERATOR$6] !== ArrayValues) try {
4251 hide(CollectionPrototype$1, ITERATOR$6, ArrayValues);
4252 } catch (error) {
4253 CollectionPrototype$1[ITERATOR$6] = ArrayValues;
4254 }
4255 if (!CollectionPrototype$1[TO_STRING_TAG$4]) hide(CollectionPrototype$1, TO_STRING_TAG$4, COLLECTION_NAME$1);
4256 if (domIterables[COLLECTION_NAME$1]) for (var METHOD_NAME in es_array_iterator) {
4257 // some Chrome versions have non-configurable methods on DOMTokenList
4258 if (CollectionPrototype$1[METHOD_NAME] !== es_array_iterator[METHOD_NAME]) try {
4259 hide(CollectionPrototype$1, METHOD_NAME, es_array_iterator[METHOD_NAME]);
4260 } catch (error) {
4261 CollectionPrototype$1[METHOD_NAME] = es_array_iterator[METHOD_NAME];
4262 }
4263 }
4264 }
4265}
4266
4267// `URL.prototype.toJSON` method
4268// https://url.spec.whatwg.org/#dom-url-tojson
4269_export({ target: 'URL', proto: true, enumerable: true }, {
4270 toJSON: function toJSON() {
4271 return URL.prototype.toString.call(this);
4272 }
4273});
4274
4275function _typeof(obj) {
4276 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
4277 _typeof = function (obj) {
4278 return typeof obj;
4279 };
4280 } else {
4281 _typeof = function (obj) {
4282 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
4283 };
4284 }
4285
4286 return _typeof(obj);
4287}
4288
4289function _classCallCheck(instance, Constructor) {
4290 if (!(instance instanceof Constructor)) {
4291 throw new TypeError("Cannot call a class as a function");
4292 }
4293}
4294
4295function _defineProperties(target, props) {
4296 for (var i = 0; i < props.length; i++) {
4297 var descriptor = props[i];
4298 descriptor.enumerable = descriptor.enumerable || false;
4299 descriptor.configurable = true;
4300 if ("value" in descriptor) descriptor.writable = true;
4301 Object.defineProperty(target, descriptor.key, descriptor);
4302 }
4303}
4304
4305function _createClass(Constructor, protoProps, staticProps) {
4306 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
4307 if (staticProps) _defineProperties(Constructor, staticProps);
4308 return Constructor;
4309}
4310
4311function _inherits(subClass, superClass) {
4312 if (typeof superClass !== "function" && superClass !== null) {
4313 throw new TypeError("Super expression must either be null or a function");
4314 }
4315
4316 subClass.prototype = Object.create(superClass && superClass.prototype, {
4317 constructor: {
4318 value: subClass,
4319 writable: true,
4320 configurable: true
4321 }
4322 });
4323 if (superClass) _setPrototypeOf(subClass, superClass);
4324}
4325
4326function _getPrototypeOf(o) {
4327 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
4328 return o.__proto__ || Object.getPrototypeOf(o);
4329 };
4330 return _getPrototypeOf(o);
4331}
4332
4333function _setPrototypeOf(o, p) {
4334 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
4335 o.__proto__ = p;
4336 return o;
4337 };
4338
4339 return _setPrototypeOf(o, p);
4340}
4341
4342function _assertThisInitialized(self) {
4343 if (self === void 0) {
4344 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
4345 }
4346
4347 return self;
4348}
4349
4350function _possibleConstructorReturn(self, call) {
4351 if (call && (typeof call === "object" || typeof call === "function")) {
4352 return call;
4353 }
4354
4355 return _assertThisInitialized(self);
4356}
4357
4358function _toConsumableArray(arr) {
4359 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
4360}
4361
4362function _arrayWithoutHoles(arr) {
4363 if (Array.isArray(arr)) {
4364 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
4365
4366 return arr2;
4367 }
4368}
4369
4370function _iterableToArray(iter) {
4371 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
4372}
4373
4374function _nonIterableSpread() {
4375 throw new TypeError("Invalid attempt to spread non-iterable instance");
4376}
4377
4378function _defineProperty(obj, key, value) {
4379 if (key in obj) {
4380 Object.defineProperty(obj, key, {
4381 value: value,
4382 enumerable: true,
4383 configurable: true,
4384 writable: true
4385 });
4386 } else {
4387 obj[key] = value;
4388 }
4389
4390 return obj;
4391}
4392
4393var defineProperty$7 = _defineProperty;
4394
4395function _arrayWithoutHoles$1(arr) {
4396 if (Array.isArray(arr)) {
4397 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
4398 arr2[i] = arr[i];
4399 }
4400
4401 return arr2;
4402 }
4403}
4404
4405var arrayWithoutHoles = _arrayWithoutHoles$1;
4406
4407function _iterableToArray$1(iter) {
4408 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
4409}
4410
4411var iterableToArray = _iterableToArray$1;
4412
4413function _nonIterableSpread$1() {
4414 throw new TypeError("Invalid attempt to spread non-iterable instance");
4415}
4416
4417var nonIterableSpread = _nonIterableSpread$1;
4418
4419function _toConsumableArray$1(arr) {
4420 return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
4421}
4422
4423var toConsumableArray = _toConsumableArray$1;
4424var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
4425
4426function commonjsRequire$1() {
4427 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
4428}
4429
4430function createCommonjsModule$1(fn, module) {
4431 return module = {
4432 exports: {}
4433 }, fn(module, module.exports), module.exports;
4434}
4435
4436var _typeof_1 = createCommonjsModule$1(function (module) {
4437 function _typeof2(obj) {
4438 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
4439 _typeof2 = function _typeof2(obj) {
4440 return _typeof(obj);
4441 };
4442 } else {
4443 _typeof2 = function _typeof2(obj) {
4444 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
4445 };
4446 }
4447
4448 return _typeof2(obj);
4449 }
4450
4451 function _typeof$1(obj) {
4452 if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
4453 module.exports = _typeof$1 = function _typeof(obj) {
4454 return _typeof2(obj);
4455 };
4456 } else {
4457 module.exports = _typeof$1 = function _typeof(obj) {
4458 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
4459 };
4460 }
4461
4462 return _typeof$1(obj);
4463 }
4464
4465 module.exports = _typeof$1;
4466});
4467
4468var moment = createCommonjsModule$1(function (module, exports) {
4469 (function (global, factory) {
4470 module.exports = factory();
4471 })(commonjsGlobal$1, function () {
4472 var hookCallback;
4473
4474 function hooks() {
4475 return hookCallback.apply(null, arguments);
4476 } // This is done to register the method called with moment()
4477 // without creating circular dependencies.
4478
4479
4480 function setHookCallback(callback) {
4481 hookCallback = callback;
4482 }
4483
4484 function isArray(input) {
4485 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
4486 }
4487
4488 function isObject(input) {
4489 // IE8 will treat undefined and null as object if it wasn't for
4490 // input != null
4491 return input != null && Object.prototype.toString.call(input) === '[object Object]';
4492 }
4493
4494 function isObjectEmpty(obj) {
4495 if (Object.getOwnPropertyNames) {
4496 return Object.getOwnPropertyNames(obj).length === 0;
4497 } else {
4498 var k;
4499
4500 for (k in obj) {
4501 if (obj.hasOwnProperty(k)) {
4502 return false;
4503 }
4504 }
4505
4506 return true;
4507 }
4508 }
4509
4510 function isUndefined(input) {
4511 return input === void 0;
4512 }
4513
4514 function isNumber(input) {
4515 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
4516 }
4517
4518 function isDate(input) {
4519 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
4520 }
4521
4522 function map(arr, fn) {
4523 var res = [],
4524 i;
4525
4526 for (i = 0; i < arr.length; ++i) {
4527 res.push(fn(arr[i], i));
4528 }
4529
4530 return res;
4531 }
4532
4533 function hasOwnProp(a, b) {
4534 return Object.prototype.hasOwnProperty.call(a, b);
4535 }
4536
4537 function extend(a, b) {
4538 for (var i in b) {
4539 if (hasOwnProp(b, i)) {
4540 a[i] = b[i];
4541 }
4542 }
4543
4544 if (hasOwnProp(b, 'toString')) {
4545 a.toString = b.toString;
4546 }
4547
4548 if (hasOwnProp(b, 'valueOf')) {
4549 a.valueOf = b.valueOf;
4550 }
4551
4552 return a;
4553 }
4554
4555 function createUTC(input, format, locale, strict) {
4556 return createLocalOrUTC(input, format, locale, strict, true).utc();
4557 }
4558
4559 function defaultParsingFlags() {
4560 // We need to deep clone this object.
4561 return {
4562 empty: false,
4563 unusedTokens: [],
4564 unusedInput: [],
4565 overflow: -2,
4566 charsLeftOver: 0,
4567 nullInput: false,
4568 invalidMonth: null,
4569 invalidFormat: false,
4570 userInvalidated: false,
4571 iso: false,
4572 parsedDateParts: [],
4573 meridiem: null,
4574 rfc2822: false,
4575 weekdayMismatch: false
4576 };
4577 }
4578
4579 function getParsingFlags(m) {
4580 if (m._pf == null) {
4581 m._pf = defaultParsingFlags();
4582 }
4583
4584 return m._pf;
4585 }
4586
4587 var some;
4588
4589 if (Array.prototype.some) {
4590 some = Array.prototype.some;
4591 } else {
4592 some = function some(fun) {
4593 var t = Object(this);
4594 var len = t.length >>> 0;
4595
4596 for (var i = 0; i < len; i++) {
4597 if (i in t && fun.call(this, t[i], i, t)) {
4598 return true;
4599 }
4600 }
4601
4602 return false;
4603 };
4604 }
4605
4606 function isValid(m) {
4607 if (m._isValid == null) {
4608 var flags = getParsingFlags(m);
4609 var parsedParts = some.call(flags.parsedDateParts, function (i) {
4610 return i != null;
4611 });
4612 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);
4613
4614 if (m._strict) {
4615 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
4616 }
4617
4618 if (Object.isFrozen == null || !Object.isFrozen(m)) {
4619 m._isValid = isNowValid;
4620 } else {
4621 return isNowValid;
4622 }
4623 }
4624
4625 return m._isValid;
4626 }
4627
4628 function createInvalid(flags) {
4629 var m = createUTC(NaN);
4630
4631 if (flags != null) {
4632 extend(getParsingFlags(m), flags);
4633 } else {
4634 getParsingFlags(m).userInvalidated = true;
4635 }
4636
4637 return m;
4638 } // Plugins that add properties should also add the key here (null value),
4639 // so we can properly clone ourselves.
4640
4641
4642 var momentProperties = hooks.momentProperties = [];
4643
4644 function copyConfig(to, from) {
4645 var i, prop, val;
4646
4647 if (!isUndefined(from._isAMomentObject)) {
4648 to._isAMomentObject = from._isAMomentObject;
4649 }
4650
4651 if (!isUndefined(from._i)) {
4652 to._i = from._i;
4653 }
4654
4655 if (!isUndefined(from._f)) {
4656 to._f = from._f;
4657 }
4658
4659 if (!isUndefined(from._l)) {
4660 to._l = from._l;
4661 }
4662
4663 if (!isUndefined(from._strict)) {
4664 to._strict = from._strict;
4665 }
4666
4667 if (!isUndefined(from._tzm)) {
4668 to._tzm = from._tzm;
4669 }
4670
4671 if (!isUndefined(from._isUTC)) {
4672 to._isUTC = from._isUTC;
4673 }
4674
4675 if (!isUndefined(from._offset)) {
4676 to._offset = from._offset;
4677 }
4678
4679 if (!isUndefined(from._pf)) {
4680 to._pf = getParsingFlags(from);
4681 }
4682
4683 if (!isUndefined(from._locale)) {
4684 to._locale = from._locale;
4685 }
4686
4687 if (momentProperties.length > 0) {
4688 for (i = 0; i < momentProperties.length; i++) {
4689 prop = momentProperties[i];
4690 val = from[prop];
4691
4692 if (!isUndefined(val)) {
4693 to[prop] = val;
4694 }
4695 }
4696 }
4697
4698 return to;
4699 }
4700
4701 var updateInProgress = false; // Moment prototype object
4702
4703 function Moment(config) {
4704 copyConfig(this, config);
4705 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
4706
4707 if (!this.isValid()) {
4708 this._d = new Date(NaN);
4709 } // Prevent infinite loop in case updateOffset creates new moment
4710 // objects.
4711
4712
4713 if (updateInProgress === false) {
4714 updateInProgress = true;
4715 hooks.updateOffset(this);
4716 updateInProgress = false;
4717 }
4718 }
4719
4720 function isMoment(obj) {
4721 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
4722 }
4723
4724 function absFloor(number) {
4725 if (number < 0) {
4726 // -0 -> 0
4727 return Math.ceil(number) || 0;
4728 } else {
4729 return Math.floor(number);
4730 }
4731 }
4732
4733 function toInt(argumentForCoercion) {
4734 var coercedNumber = +argumentForCoercion,
4735 value = 0;
4736
4737 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
4738 value = absFloor(coercedNumber);
4739 }
4740
4741 return value;
4742 } // compare two arrays, return the number of differences
4743
4744
4745 function compareArrays(array1, array2, dontConvert) {
4746 var len = Math.min(array1.length, array2.length),
4747 lengthDiff = Math.abs(array1.length - array2.length),
4748 diffs = 0,
4749 i;
4750
4751 for (i = 0; i < len; i++) {
4752 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
4753 diffs++;
4754 }
4755 }
4756
4757 return diffs + lengthDiff;
4758 }
4759
4760 function warn(msg) {
4761 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
4762 console.warn('Deprecation warning: ' + msg);
4763 }
4764 }
4765
4766 function deprecate(msg, fn) {
4767 var firstTime = true;
4768 return extend(function () {
4769 if (hooks.deprecationHandler != null) {
4770 hooks.deprecationHandler(null, msg);
4771 }
4772
4773 if (firstTime) {
4774 var args = [];
4775 var arg;
4776
4777 for (var i = 0; i < arguments.length; i++) {
4778 arg = '';
4779
4780 if (_typeof(arguments[i]) === 'object') {
4781 arg += '\n[' + i + '] ';
4782
4783 for (var key in arguments[0]) {
4784 arg += key + ': ' + arguments[0][key] + ', ';
4785 }
4786
4787 arg = arg.slice(0, -2); // Remove trailing comma and space
4788 } else {
4789 arg = arguments[i];
4790 }
4791
4792 args.push(arg);
4793 }
4794
4795 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
4796 firstTime = false;
4797 }
4798
4799 return fn.apply(this, arguments);
4800 }, fn);
4801 }
4802
4803 var deprecations = {};
4804
4805 function deprecateSimple(name, msg) {
4806 if (hooks.deprecationHandler != null) {
4807 hooks.deprecationHandler(name, msg);
4808 }
4809
4810 if (!deprecations[name]) {
4811 warn(msg);
4812 deprecations[name] = true;
4813 }
4814 }
4815
4816 hooks.suppressDeprecationWarnings = false;
4817 hooks.deprecationHandler = null;
4818
4819 function isFunction(input) {
4820 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
4821 }
4822
4823 function set(config) {
4824 var prop, i;
4825
4826 for (i in config) {
4827 prop = config[i];
4828
4829 if (isFunction(prop)) {
4830 this[i] = prop;
4831 } else {
4832 this['_' + i] = prop;
4833 }
4834 }
4835
4836 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
4837 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
4838 // TODO: Remove "ordinalParse" fallback in next major release.
4839
4840 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
4841 }
4842
4843 function mergeConfigs(parentConfig, childConfig) {
4844 var res = extend({}, parentConfig),
4845 prop;
4846
4847 for (prop in childConfig) {
4848 if (hasOwnProp(childConfig, prop)) {
4849 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
4850 res[prop] = {};
4851 extend(res[prop], parentConfig[prop]);
4852 extend(res[prop], childConfig[prop]);
4853 } else if (childConfig[prop] != null) {
4854 res[prop] = childConfig[prop];
4855 } else {
4856 delete res[prop];
4857 }
4858 }
4859 }
4860
4861 for (prop in parentConfig) {
4862 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
4863 // make sure changes to properties don't modify parent config
4864 res[prop] = extend({}, res[prop]);
4865 }
4866 }
4867
4868 return res;
4869 }
4870
4871 function Locale(config) {
4872 if (config != null) {
4873 this.set(config);
4874 }
4875 }
4876
4877 var keys;
4878
4879 if (Object.keys) {
4880 keys = Object.keys;
4881 } else {
4882 keys = function keys(obj) {
4883 var i,
4884 res = [];
4885
4886 for (i in obj) {
4887 if (hasOwnProp(obj, i)) {
4888 res.push(i);
4889 }
4890 }
4891
4892 return res;
4893 };
4894 }
4895
4896 var defaultCalendar = {
4897 sameDay: '[Today at] LT',
4898 nextDay: '[Tomorrow at] LT',
4899 nextWeek: 'dddd [at] LT',
4900 lastDay: '[Yesterday at] LT',
4901 lastWeek: '[Last] dddd [at] LT',
4902 sameElse: 'L'
4903 };
4904
4905 function calendar(key, mom, now) {
4906 var output = this._calendar[key] || this._calendar['sameElse'];
4907 return isFunction(output) ? output.call(mom, now) : output;
4908 }
4909
4910 var defaultLongDateFormat = {
4911 LTS: 'h:mm:ss A',
4912 LT: 'h:mm A',
4913 L: 'MM/DD/YYYY',
4914 LL: 'MMMM D, YYYY',
4915 LLL: 'MMMM D, YYYY h:mm A',
4916 LLLL: 'dddd, MMMM D, YYYY h:mm A'
4917 };
4918
4919 function longDateFormat(key) {
4920 var format = this._longDateFormat[key],
4921 formatUpper = this._longDateFormat[key.toUpperCase()];
4922
4923 if (format || !formatUpper) {
4924 return format;
4925 }
4926
4927 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
4928 return val.slice(1);
4929 });
4930 return this._longDateFormat[key];
4931 }
4932
4933 var defaultInvalidDate = 'Invalid date';
4934
4935 function invalidDate() {
4936 return this._invalidDate;
4937 }
4938
4939 var defaultOrdinal = '%d';
4940 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
4941
4942 function ordinal(number) {
4943 return this._ordinal.replace('%d', number);
4944 }
4945
4946 var defaultRelativeTime = {
4947 future: 'in %s',
4948 past: '%s ago',
4949 s: 'a few seconds',
4950 ss: '%d seconds',
4951 m: 'a minute',
4952 mm: '%d minutes',
4953 h: 'an hour',
4954 hh: '%d hours',
4955 d: 'a day',
4956 dd: '%d days',
4957 M: 'a month',
4958 MM: '%d months',
4959 y: 'a year',
4960 yy: '%d years'
4961 };
4962
4963 function relativeTime(number, withoutSuffix, string, isFuture) {
4964 var output = this._relativeTime[string];
4965 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
4966 }
4967
4968 function pastFuture(diff, output) {
4969 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
4970 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
4971 }
4972
4973 var aliases = {};
4974
4975 function addUnitAlias(unit, shorthand) {
4976 var lowerCase = unit.toLowerCase();
4977 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
4978 }
4979
4980 function normalizeUnits(units) {
4981 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
4982 }
4983
4984 function normalizeObjectUnits(inputObject) {
4985 var normalizedInput = {},
4986 normalizedProp,
4987 prop;
4988
4989 for (prop in inputObject) {
4990 if (hasOwnProp(inputObject, prop)) {
4991 normalizedProp = normalizeUnits(prop);
4992
4993 if (normalizedProp) {
4994 normalizedInput[normalizedProp] = inputObject[prop];
4995 }
4996 }
4997 }
4998
4999 return normalizedInput;
5000 }
5001
5002 var priorities = {};
5003
5004 function addUnitPriority(unit, priority) {
5005 priorities[unit] = priority;
5006 }
5007
5008 function getPrioritizedUnits(unitsObj) {
5009 var units = [];
5010
5011 for (var u in unitsObj) {
5012 units.push({
5013 unit: u,
5014 priority: priorities[u]
5015 });
5016 }
5017
5018 units.sort(function (a, b) {
5019 return a.priority - b.priority;
5020 });
5021 return units;
5022 }
5023
5024 function zeroFill(number, targetLength, forceSign) {
5025 var absNumber = '' + Math.abs(number),
5026 zerosToFill = targetLength - absNumber.length,
5027 sign = number >= 0;
5028 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
5029 }
5030
5031 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;
5032 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
5033 var formatFunctions = {};
5034 var formatTokenFunctions = {}; // token: 'M'
5035 // padded: ['MM', 2]
5036 // ordinal: 'Mo'
5037 // callback: function () { this.month() + 1 }
5038
5039 function addFormatToken(token, padded, ordinal, callback) {
5040 var func = callback;
5041
5042 if (typeof callback === 'string') {
5043 func = function func() {
5044 return this[callback]();
5045 };
5046 }
5047
5048 if (token) {
5049 formatTokenFunctions[token] = func;
5050 }
5051
5052 if (padded) {
5053 formatTokenFunctions[padded[0]] = function () {
5054 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
5055 };
5056 }
5057
5058 if (ordinal) {
5059 formatTokenFunctions[ordinal] = function () {
5060 return this.localeData().ordinal(func.apply(this, arguments), token);
5061 };
5062 }
5063 }
5064
5065 function removeFormattingTokens(input) {
5066 if (input.match(/\[[\s\S]/)) {
5067 return input.replace(/^\[|\]$/g, '');
5068 }
5069
5070 return input.replace(/\\/g, '');
5071 }
5072
5073 function makeFormatFunction(format) {
5074 var array = format.match(formattingTokens),
5075 i,
5076 length;
5077
5078 for (i = 0, length = array.length; i < length; i++) {
5079 if (formatTokenFunctions[array[i]]) {
5080 array[i] = formatTokenFunctions[array[i]];
5081 } else {
5082 array[i] = removeFormattingTokens(array[i]);
5083 }
5084 }
5085
5086 return function (mom) {
5087 var output = '',
5088 i;
5089
5090 for (i = 0; i < length; i++) {
5091 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
5092 }
5093
5094 return output;
5095 };
5096 } // format date using native date object
5097
5098
5099 function formatMoment(m, format) {
5100 if (!m.isValid()) {
5101 return m.localeData().invalidDate();
5102 }
5103
5104 format = expandFormat(format, m.localeData());
5105 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
5106 return formatFunctions[format](m);
5107 }
5108
5109 function expandFormat(format, locale) {
5110 var i = 5;
5111
5112 function replaceLongDateFormatTokens(input) {
5113 return locale.longDateFormat(input) || input;
5114 }
5115
5116 localFormattingTokens.lastIndex = 0;
5117
5118 while (i >= 0 && localFormattingTokens.test(format)) {
5119 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
5120 localFormattingTokens.lastIndex = 0;
5121 i -= 1;
5122 }
5123
5124 return format;
5125 }
5126
5127 var match1 = /\d/; // 0 - 9
5128
5129 var match2 = /\d\d/; // 00 - 99
5130
5131 var match3 = /\d{3}/; // 000 - 999
5132
5133 var match4 = /\d{4}/; // 0000 - 9999
5134
5135 var match6 = /[+-]?\d{6}/; // -999999 - 999999
5136
5137 var match1to2 = /\d\d?/; // 0 - 99
5138
5139 var match3to4 = /\d\d\d\d?/; // 999 - 9999
5140
5141 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
5142
5143 var match1to3 = /\d{1,3}/; // 0 - 999
5144
5145 var match1to4 = /\d{1,4}/; // 0 - 9999
5146
5147 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
5148
5149 var matchUnsigned = /\d+/; // 0 - inf
5150
5151 var matchSigned = /[+-]?\d+/; // -inf - inf
5152
5153 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
5154
5155 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
5156
5157 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
5158 // any word (or two) characters or numbers including two/three word month in arabic.
5159 // includes scottish gaelic two word and hyphenated months
5160
5161 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;
5162 var regexes = {};
5163
5164 function addRegexToken(token, regex, strictRegex) {
5165 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
5166 return isStrict && strictRegex ? strictRegex : regex;
5167 };
5168 }
5169
5170 function getParseRegexForToken(token, config) {
5171 if (!hasOwnProp(regexes, token)) {
5172 return new RegExp(unescapeFormat(token));
5173 }
5174
5175 return regexes[token](config._strict, config._locale);
5176 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
5177
5178
5179 function unescapeFormat(s) {
5180 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
5181 return p1 || p2 || p3 || p4;
5182 }));
5183 }
5184
5185 function regexEscape(s) {
5186 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
5187 }
5188
5189 var tokens = {};
5190
5191 function addParseToken(token, callback) {
5192 var i,
5193 func = callback;
5194
5195 if (typeof token === 'string') {
5196 token = [token];
5197 }
5198
5199 if (isNumber(callback)) {
5200 func = function func(input, array) {
5201 array[callback] = toInt(input);
5202 };
5203 }
5204
5205 for (i = 0; i < token.length; i++) {
5206 tokens[token[i]] = func;
5207 }
5208 }
5209
5210 function addWeekParseToken(token, callback) {
5211 addParseToken(token, function (input, array, config, token) {
5212 config._w = config._w || {};
5213 callback(input, config._w, config, token);
5214 });
5215 }
5216
5217 function addTimeToArrayFromToken(token, input, config) {
5218 if (input != null && hasOwnProp(tokens, token)) {
5219 tokens[token](input, config._a, config, token);
5220 }
5221 }
5222
5223 var YEAR = 0;
5224 var MONTH = 1;
5225 var DATE = 2;
5226 var HOUR = 3;
5227 var MINUTE = 4;
5228 var SECOND = 5;
5229 var MILLISECOND = 6;
5230 var WEEK = 7;
5231 var WEEKDAY = 8; // FORMATTING
5232
5233 addFormatToken('Y', 0, 0, function () {
5234 var y = this.year();
5235 return y <= 9999 ? '' + y : '+' + y;
5236 });
5237 addFormatToken(0, ['YY', 2], 0, function () {
5238 return this.year() % 100;
5239 });
5240 addFormatToken(0, ['YYYY', 4], 0, 'year');
5241 addFormatToken(0, ['YYYYY', 5], 0, 'year');
5242 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
5243
5244 addUnitAlias('year', 'y'); // PRIORITIES
5245
5246 addUnitPriority('year', 1); // PARSING
5247
5248 addRegexToken('Y', matchSigned);
5249 addRegexToken('YY', match1to2, match2);
5250 addRegexToken('YYYY', match1to4, match4);
5251 addRegexToken('YYYYY', match1to6, match6);
5252 addRegexToken('YYYYYY', match1to6, match6);
5253 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
5254 addParseToken('YYYY', function (input, array) {
5255 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
5256 });
5257 addParseToken('YY', function (input, array) {
5258 array[YEAR] = hooks.parseTwoDigitYear(input);
5259 });
5260 addParseToken('Y', function (input, array) {
5261 array[YEAR] = parseInt(input, 10);
5262 }); // HELPERS
5263
5264 function daysInYear(year) {
5265 return isLeapYear(year) ? 366 : 365;
5266 }
5267
5268 function isLeapYear(year) {
5269 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
5270 } // HOOKS
5271
5272
5273 hooks.parseTwoDigitYear = function (input) {
5274 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
5275 }; // MOMENTS
5276
5277
5278 var getSetYear = makeGetSet('FullYear', true);
5279
5280 function getIsLeapYear() {
5281 return isLeapYear(this.year());
5282 }
5283
5284 function makeGetSet(unit, keepTime) {
5285 return function (value) {
5286 if (value != null) {
5287 set$1(this, unit, value);
5288 hooks.updateOffset(this, keepTime);
5289 return this;
5290 } else {
5291 return get(this, unit);
5292 }
5293 };
5294 }
5295
5296 function get(mom, unit) {
5297 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
5298 }
5299
5300 function set$1(mom, unit, value) {
5301 if (mom.isValid() && !isNaN(value)) {
5302 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
5303 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
5304 } else {
5305 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
5306 }
5307 }
5308 } // MOMENTS
5309
5310
5311 function stringGet(units) {
5312 units = normalizeUnits(units);
5313
5314 if (isFunction(this[units])) {
5315 return this[units]();
5316 }
5317
5318 return this;
5319 }
5320
5321 function stringSet(units, value) {
5322 if (_typeof(units) === 'object') {
5323 units = normalizeObjectUnits(units);
5324 var prioritized = getPrioritizedUnits(units);
5325
5326 for (var i = 0; i < prioritized.length; i++) {
5327 this[prioritized[i].unit](units[prioritized[i].unit]);
5328 }
5329 } else {
5330 units = normalizeUnits(units);
5331
5332 if (isFunction(this[units])) {
5333 return this[units](value);
5334 }
5335 }
5336
5337 return this;
5338 }
5339
5340 function mod(n, x) {
5341 return (n % x + x) % x;
5342 }
5343
5344 var indexOf;
5345
5346 if (Array.prototype.indexOf) {
5347 indexOf = Array.prototype.indexOf;
5348 } else {
5349 indexOf = function indexOf(o) {
5350 // I know
5351 var i;
5352
5353 for (i = 0; i < this.length; ++i) {
5354 if (this[i] === o) {
5355 return i;
5356 }
5357 }
5358
5359 return -1;
5360 };
5361 }
5362
5363 function daysInMonth(year, month) {
5364 if (isNaN(year) || isNaN(month)) {
5365 return NaN;
5366 }
5367
5368 var modMonth = mod(month, 12);
5369 year += (month - modMonth) / 12;
5370 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
5371 } // FORMATTING
5372
5373
5374 addFormatToken('M', ['MM', 2], 'Mo', function () {
5375 return this.month() + 1;
5376 });
5377 addFormatToken('MMM', 0, 0, function (format) {
5378 return this.localeData().monthsShort(this, format);
5379 });
5380 addFormatToken('MMMM', 0, 0, function (format) {
5381 return this.localeData().months(this, format);
5382 }); // ALIASES
5383
5384 addUnitAlias('month', 'M'); // PRIORITY
5385
5386 addUnitPriority('month', 8); // PARSING
5387
5388 addRegexToken('M', match1to2);
5389 addRegexToken('MM', match1to2, match2);
5390 addRegexToken('MMM', function (isStrict, locale) {
5391 return locale.monthsShortRegex(isStrict);
5392 });
5393 addRegexToken('MMMM', function (isStrict, locale) {
5394 return locale.monthsRegex(isStrict);
5395 });
5396 addParseToken(['M', 'MM'], function (input, array) {
5397 array[MONTH] = toInt(input) - 1;
5398 });
5399 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
5400 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
5401
5402
5403 if (month != null) {
5404 array[MONTH] = month;
5405 } else {
5406 getParsingFlags(config).invalidMonth = input;
5407 }
5408 }); // LOCALES
5409
5410 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
5411 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
5412
5413 function localeMonths(m, format) {
5414 if (!m) {
5415 return isArray(this._months) ? this._months : this._months['standalone'];
5416 }
5417
5418 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
5419 }
5420
5421 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
5422
5423 function localeMonthsShort(m, format) {
5424 if (!m) {
5425 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
5426 }
5427
5428 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
5429 }
5430
5431 function handleStrictParse(monthName, format, strict) {
5432 var i,
5433 ii,
5434 mom,
5435 llc = monthName.toLocaleLowerCase();
5436
5437 if (!this._monthsParse) {
5438 // this is not used
5439 this._monthsParse = [];
5440 this._longMonthsParse = [];
5441 this._shortMonthsParse = [];
5442
5443 for (i = 0; i < 12; ++i) {
5444 mom = createUTC([2000, i]);
5445 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
5446 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
5447 }
5448 }
5449
5450 if (strict) {
5451 if (format === 'MMM') {
5452 ii = indexOf.call(this._shortMonthsParse, llc);
5453 return ii !== -1 ? ii : null;
5454 } else {
5455 ii = indexOf.call(this._longMonthsParse, llc);
5456 return ii !== -1 ? ii : null;
5457 }
5458 } else {
5459 if (format === 'MMM') {
5460 ii = indexOf.call(this._shortMonthsParse, llc);
5461
5462 if (ii !== -1) {
5463 return ii;
5464 }
5465
5466 ii = indexOf.call(this._longMonthsParse, llc);
5467 return ii !== -1 ? ii : null;
5468 } else {
5469 ii = indexOf.call(this._longMonthsParse, llc);
5470
5471 if (ii !== -1) {
5472 return ii;
5473 }
5474
5475 ii = indexOf.call(this._shortMonthsParse, llc);
5476 return ii !== -1 ? ii : null;
5477 }
5478 }
5479 }
5480
5481 function localeMonthsParse(monthName, format, strict) {
5482 var i, mom, regex;
5483
5484 if (this._monthsParseExact) {
5485 return handleStrictParse.call(this, monthName, format, strict);
5486 }
5487
5488 if (!this._monthsParse) {
5489 this._monthsParse = [];
5490 this._longMonthsParse = [];
5491 this._shortMonthsParse = [];
5492 } // TODO: add sorting
5493 // Sorting makes sure if one month (or abbr) is a prefix of another
5494 // see sorting in computeMonthsParse
5495
5496
5497 for (i = 0; i < 12; i++) {
5498 // make the regex if we don't have it already
5499 mom = createUTC([2000, i]);
5500
5501 if (strict && !this._longMonthsParse[i]) {
5502 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
5503 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
5504 }
5505
5506 if (!strict && !this._monthsParse[i]) {
5507 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
5508 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
5509 } // test the regex
5510
5511
5512 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
5513 return i;
5514 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
5515 return i;
5516 } else if (!strict && this._monthsParse[i].test(monthName)) {
5517 return i;
5518 }
5519 }
5520 } // MOMENTS
5521
5522
5523 function setMonth(mom, value) {
5524 var dayOfMonth;
5525
5526 if (!mom.isValid()) {
5527 // No op
5528 return mom;
5529 }
5530
5531 if (typeof value === 'string') {
5532 if (/^\d+$/.test(value)) {
5533 value = toInt(value);
5534 } else {
5535 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
5536
5537 if (!isNumber(value)) {
5538 return mom;
5539 }
5540 }
5541 }
5542
5543 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
5544
5545 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
5546
5547 return mom;
5548 }
5549
5550 function getSetMonth(value) {
5551 if (value != null) {
5552 setMonth(this, value);
5553 hooks.updateOffset(this, true);
5554 return this;
5555 } else {
5556 return get(this, 'Month');
5557 }
5558 }
5559
5560 function getDaysInMonth() {
5561 return daysInMonth(this.year(), this.month());
5562 }
5563
5564 var defaultMonthsShortRegex = matchWord;
5565
5566 function monthsShortRegex(isStrict) {
5567 if (this._monthsParseExact) {
5568 if (!hasOwnProp(this, '_monthsRegex')) {
5569 computeMonthsParse.call(this);
5570 }
5571
5572 if (isStrict) {
5573 return this._monthsShortStrictRegex;
5574 } else {
5575 return this._monthsShortRegex;
5576 }
5577 } else {
5578 if (!hasOwnProp(this, '_monthsShortRegex')) {
5579 this._monthsShortRegex = defaultMonthsShortRegex;
5580 }
5581
5582 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
5583 }
5584 }
5585
5586 var defaultMonthsRegex = matchWord;
5587
5588 function monthsRegex(isStrict) {
5589 if (this._monthsParseExact) {
5590 if (!hasOwnProp(this, '_monthsRegex')) {
5591 computeMonthsParse.call(this);
5592 }
5593
5594 if (isStrict) {
5595 return this._monthsStrictRegex;
5596 } else {
5597 return this._monthsRegex;
5598 }
5599 } else {
5600 if (!hasOwnProp(this, '_monthsRegex')) {
5601 this._monthsRegex = defaultMonthsRegex;
5602 }
5603
5604 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
5605 }
5606 }
5607
5608 function computeMonthsParse() {
5609 function cmpLenRev(a, b) {
5610 return b.length - a.length;
5611 }
5612
5613 var shortPieces = [],
5614 longPieces = [],
5615 mixedPieces = [],
5616 i,
5617 mom;
5618
5619 for (i = 0; i < 12; i++) {
5620 // make the regex if we don't have it already
5621 mom = createUTC([2000, i]);
5622 shortPieces.push(this.monthsShort(mom, ''));
5623 longPieces.push(this.months(mom, ''));
5624 mixedPieces.push(this.months(mom, ''));
5625 mixedPieces.push(this.monthsShort(mom, ''));
5626 } // Sorting makes sure if one month (or abbr) is a prefix of another it
5627 // will match the longer piece.
5628
5629
5630 shortPieces.sort(cmpLenRev);
5631 longPieces.sort(cmpLenRev);
5632 mixedPieces.sort(cmpLenRev);
5633
5634 for (i = 0; i < 12; i++) {
5635 shortPieces[i] = regexEscape(shortPieces[i]);
5636 longPieces[i] = regexEscape(longPieces[i]);
5637 }
5638
5639 for (i = 0; i < 24; i++) {
5640 mixedPieces[i] = regexEscape(mixedPieces[i]);
5641 }
5642
5643 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
5644 this._monthsShortRegex = this._monthsRegex;
5645 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
5646 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
5647 }
5648
5649 function createDate(y, m, d, h, M, s, ms) {
5650 // can't just apply() to create a date:
5651 // https://stackoverflow.com/q/181348
5652 var date; // the date constructor remaps years 0-99 to 1900-1999
5653
5654 if (y < 100 && y >= 0) {
5655 // preserve leap years using a full 400 year cycle, then reset
5656 date = new Date(y + 400, m, d, h, M, s, ms);
5657
5658 if (isFinite(date.getFullYear())) {
5659 date.setFullYear(y);
5660 }
5661 } else {
5662 date = new Date(y, m, d, h, M, s, ms);
5663 }
5664
5665 return date;
5666 }
5667
5668 function createUTCDate(y) {
5669 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
5670
5671 if (y < 100 && y >= 0) {
5672 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
5673
5674 args[0] = y + 400;
5675 date = new Date(Date.UTC.apply(null, args));
5676
5677 if (isFinite(date.getUTCFullYear())) {
5678 date.setUTCFullYear(y);
5679 }
5680 } else {
5681 date = new Date(Date.UTC.apply(null, arguments));
5682 }
5683
5684 return date;
5685 } // start-of-first-week - start-of-year
5686
5687
5688 function firstWeekOffset(year, dow, doy) {
5689 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
5690 fwd = 7 + dow - doy,
5691 // first-week day local weekday -- which local weekday is fwd
5692 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
5693 return -fwdlw + fwd - 1;
5694 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
5695
5696
5697 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
5698 var localWeekday = (7 + weekday - dow) % 7,
5699 weekOffset = firstWeekOffset(year, dow, doy),
5700 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
5701 resYear,
5702 resDayOfYear;
5703
5704 if (dayOfYear <= 0) {
5705 resYear = year - 1;
5706 resDayOfYear = daysInYear(resYear) + dayOfYear;
5707 } else if (dayOfYear > daysInYear(year)) {
5708 resYear = year + 1;
5709 resDayOfYear = dayOfYear - daysInYear(year);
5710 } else {
5711 resYear = year;
5712 resDayOfYear = dayOfYear;
5713 }
5714
5715 return {
5716 year: resYear,
5717 dayOfYear: resDayOfYear
5718 };
5719 }
5720
5721 function weekOfYear(mom, dow, doy) {
5722 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
5723 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
5724 resWeek,
5725 resYear;
5726
5727 if (week < 1) {
5728 resYear = mom.year() - 1;
5729 resWeek = week + weeksInYear(resYear, dow, doy);
5730 } else if (week > weeksInYear(mom.year(), dow, doy)) {
5731 resWeek = week - weeksInYear(mom.year(), dow, doy);
5732 resYear = mom.year() + 1;
5733 } else {
5734 resYear = mom.year();
5735 resWeek = week;
5736 }
5737
5738 return {
5739 week: resWeek,
5740 year: resYear
5741 };
5742 }
5743
5744 function weeksInYear(year, dow, doy) {
5745 var weekOffset = firstWeekOffset(year, dow, doy),
5746 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
5747 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
5748 } // FORMATTING
5749
5750
5751 addFormatToken('w', ['ww', 2], 'wo', 'week');
5752 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
5753
5754 addUnitAlias('week', 'w');
5755 addUnitAlias('isoWeek', 'W'); // PRIORITIES
5756
5757 addUnitPriority('week', 5);
5758 addUnitPriority('isoWeek', 5); // PARSING
5759
5760 addRegexToken('w', match1to2);
5761 addRegexToken('ww', match1to2, match2);
5762 addRegexToken('W', match1to2);
5763 addRegexToken('WW', match1to2, match2);
5764 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
5765 week[token.substr(0, 1)] = toInt(input);
5766 }); // HELPERS
5767 // LOCALES
5768
5769 function localeWeek(mom) {
5770 return weekOfYear(mom, this._week.dow, this._week.doy).week;
5771 }
5772
5773 var defaultLocaleWeek = {
5774 dow: 0,
5775 // Sunday is the first day of the week.
5776 doy: 6 // The week that contains Jan 6th is the first week of the year.
5777
5778 };
5779
5780 function localeFirstDayOfWeek() {
5781 return this._week.dow;
5782 }
5783
5784 function localeFirstDayOfYear() {
5785 return this._week.doy;
5786 } // MOMENTS
5787
5788
5789 function getSetWeek(input) {
5790 var week = this.localeData().week(this);
5791 return input == null ? week : this.add((input - week) * 7, 'd');
5792 }
5793
5794 function getSetISOWeek(input) {
5795 var week = weekOfYear(this, 1, 4).week;
5796 return input == null ? week : this.add((input - week) * 7, 'd');
5797 } // FORMATTING
5798
5799
5800 addFormatToken('d', 0, 'do', 'day');
5801 addFormatToken('dd', 0, 0, function (format) {
5802 return this.localeData().weekdaysMin(this, format);
5803 });
5804 addFormatToken('ddd', 0, 0, function (format) {
5805 return this.localeData().weekdaysShort(this, format);
5806 });
5807 addFormatToken('dddd', 0, 0, function (format) {
5808 return this.localeData().weekdays(this, format);
5809 });
5810 addFormatToken('e', 0, 0, 'weekday');
5811 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
5812
5813 addUnitAlias('day', 'd');
5814 addUnitAlias('weekday', 'e');
5815 addUnitAlias('isoWeekday', 'E'); // PRIORITY
5816
5817 addUnitPriority('day', 11);
5818 addUnitPriority('weekday', 11);
5819 addUnitPriority('isoWeekday', 11); // PARSING
5820
5821 addRegexToken('d', match1to2);
5822 addRegexToken('e', match1to2);
5823 addRegexToken('E', match1to2);
5824 addRegexToken('dd', function (isStrict, locale) {
5825 return locale.weekdaysMinRegex(isStrict);
5826 });
5827 addRegexToken('ddd', function (isStrict, locale) {
5828 return locale.weekdaysShortRegex(isStrict);
5829 });
5830 addRegexToken('dddd', function (isStrict, locale) {
5831 return locale.weekdaysRegex(isStrict);
5832 });
5833 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
5834 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
5835
5836
5837 if (weekday != null) {
5838 week.d = weekday;
5839 } else {
5840 getParsingFlags(config).invalidWeekday = input;
5841 }
5842 });
5843 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
5844 week[token] = toInt(input);
5845 }); // HELPERS
5846
5847 function parseWeekday(input, locale) {
5848 if (typeof input !== 'string') {
5849 return input;
5850 }
5851
5852 if (!isNaN(input)) {
5853 return parseInt(input, 10);
5854 }
5855
5856 input = locale.weekdaysParse(input);
5857
5858 if (typeof input === 'number') {
5859 return input;
5860 }
5861
5862 return null;
5863 }
5864
5865 function parseIsoWeekday(input, locale) {
5866 if (typeof input === 'string') {
5867 return locale.weekdaysParse(input) % 7 || 7;
5868 }
5869
5870 return isNaN(input) ? null : input;
5871 } // LOCALES
5872
5873
5874 function shiftWeekdays(ws, n) {
5875 return ws.slice(n, 7).concat(ws.slice(0, n));
5876 }
5877
5878 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
5879
5880 function localeWeekdays(m, format) {
5881 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
5882 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
5883 }
5884
5885 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
5886
5887 function localeWeekdaysShort(m) {
5888 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
5889 }
5890
5891 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
5892
5893 function localeWeekdaysMin(m) {
5894 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
5895 }
5896
5897 function handleStrictParse$1(weekdayName, format, strict) {
5898 var i,
5899 ii,
5900 mom,
5901 llc = weekdayName.toLocaleLowerCase();
5902
5903 if (!this._weekdaysParse) {
5904 this._weekdaysParse = [];
5905 this._shortWeekdaysParse = [];
5906 this._minWeekdaysParse = [];
5907
5908 for (i = 0; i < 7; ++i) {
5909 mom = createUTC([2000, 1]).day(i);
5910 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
5911 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
5912 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
5913 }
5914 }
5915
5916 if (strict) {
5917 if (format === 'dddd') {
5918 ii = indexOf.call(this._weekdaysParse, llc);
5919 return ii !== -1 ? ii : null;
5920 } else if (format === 'ddd') {
5921 ii = indexOf.call(this._shortWeekdaysParse, llc);
5922 return ii !== -1 ? ii : null;
5923 } else {
5924 ii = indexOf.call(this._minWeekdaysParse, llc);
5925 return ii !== -1 ? ii : null;
5926 }
5927 } else {
5928 if (format === 'dddd') {
5929 ii = indexOf.call(this._weekdaysParse, llc);
5930
5931 if (ii !== -1) {
5932 return ii;
5933 }
5934
5935 ii = indexOf.call(this._shortWeekdaysParse, llc);
5936
5937 if (ii !== -1) {
5938 return ii;
5939 }
5940
5941 ii = indexOf.call(this._minWeekdaysParse, llc);
5942 return ii !== -1 ? ii : null;
5943 } else if (format === 'ddd') {
5944 ii = indexOf.call(this._shortWeekdaysParse, llc);
5945
5946 if (ii !== -1) {
5947 return ii;
5948 }
5949
5950 ii = indexOf.call(this._weekdaysParse, llc);
5951
5952 if (ii !== -1) {
5953 return ii;
5954 }
5955
5956 ii = indexOf.call(this._minWeekdaysParse, llc);
5957 return ii !== -1 ? ii : null;
5958 } else {
5959 ii = indexOf.call(this._minWeekdaysParse, llc);
5960
5961 if (ii !== -1) {
5962 return ii;
5963 }
5964
5965 ii = indexOf.call(this._weekdaysParse, llc);
5966
5967 if (ii !== -1) {
5968 return ii;
5969 }
5970
5971 ii = indexOf.call(this._shortWeekdaysParse, llc);
5972 return ii !== -1 ? ii : null;
5973 }
5974 }
5975 }
5976
5977 function localeWeekdaysParse(weekdayName, format, strict) {
5978 var i, mom, regex;
5979
5980 if (this._weekdaysParseExact) {
5981 return handleStrictParse$1.call(this, weekdayName, format, strict);
5982 }
5983
5984 if (!this._weekdaysParse) {
5985 this._weekdaysParse = [];
5986 this._minWeekdaysParse = [];
5987 this._shortWeekdaysParse = [];
5988 this._fullWeekdaysParse = [];
5989 }
5990
5991 for (i = 0; i < 7; i++) {
5992 // make the regex if we don't have it already
5993 mom = createUTC([2000, 1]).day(i);
5994
5995 if (strict && !this._fullWeekdaysParse[i]) {
5996 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
5997 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
5998 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
5999 }
6000
6001 if (!this._weekdaysParse[i]) {
6002 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
6003 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
6004 } // test the regex
6005
6006
6007 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
6008 return i;
6009 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
6010 return i;
6011 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
6012 return i;
6013 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
6014 return i;
6015 }
6016 }
6017 } // MOMENTS
6018
6019
6020 function getSetDayOfWeek(input) {
6021 if (!this.isValid()) {
6022 return input != null ? this : NaN;
6023 }
6024
6025 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
6026
6027 if (input != null) {
6028 input = parseWeekday(input, this.localeData());
6029 return this.add(input - day, 'd');
6030 } else {
6031 return day;
6032 }
6033 }
6034
6035 function getSetLocaleDayOfWeek(input) {
6036 if (!this.isValid()) {
6037 return input != null ? this : NaN;
6038 }
6039
6040 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
6041 return input == null ? weekday : this.add(input - weekday, 'd');
6042 }
6043
6044 function getSetISODayOfWeek(input) {
6045 if (!this.isValid()) {
6046 return input != null ? this : NaN;
6047 } // behaves the same as moment#day except
6048 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
6049 // as a setter, sunday should belong to the previous week.
6050
6051
6052 if (input != null) {
6053 var weekday = parseIsoWeekday(input, this.localeData());
6054 return this.day(this.day() % 7 ? weekday : weekday - 7);
6055 } else {
6056 return this.day() || 7;
6057 }
6058 }
6059
6060 var defaultWeekdaysRegex = matchWord;
6061
6062 function weekdaysRegex(isStrict) {
6063 if (this._weekdaysParseExact) {
6064 if (!hasOwnProp(this, '_weekdaysRegex')) {
6065 computeWeekdaysParse.call(this);
6066 }
6067
6068 if (isStrict) {
6069 return this._weekdaysStrictRegex;
6070 } else {
6071 return this._weekdaysRegex;
6072 }
6073 } else {
6074 if (!hasOwnProp(this, '_weekdaysRegex')) {
6075 this._weekdaysRegex = defaultWeekdaysRegex;
6076 }
6077
6078 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
6079 }
6080 }
6081
6082 var defaultWeekdaysShortRegex = matchWord;
6083
6084 function weekdaysShortRegex(isStrict) {
6085 if (this._weekdaysParseExact) {
6086 if (!hasOwnProp(this, '_weekdaysRegex')) {
6087 computeWeekdaysParse.call(this);
6088 }
6089
6090 if (isStrict) {
6091 return this._weekdaysShortStrictRegex;
6092 } else {
6093 return this._weekdaysShortRegex;
6094 }
6095 } else {
6096 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
6097 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
6098 }
6099
6100 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
6101 }
6102 }
6103
6104 var defaultWeekdaysMinRegex = matchWord;
6105
6106 function weekdaysMinRegex(isStrict) {
6107 if (this._weekdaysParseExact) {
6108 if (!hasOwnProp(this, '_weekdaysRegex')) {
6109 computeWeekdaysParse.call(this);
6110 }
6111
6112 if (isStrict) {
6113 return this._weekdaysMinStrictRegex;
6114 } else {
6115 return this._weekdaysMinRegex;
6116 }
6117 } else {
6118 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
6119 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
6120 }
6121
6122 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
6123 }
6124 }
6125
6126 function computeWeekdaysParse() {
6127 function cmpLenRev(a, b) {
6128 return b.length - a.length;
6129 }
6130
6131 var minPieces = [],
6132 shortPieces = [],
6133 longPieces = [],
6134 mixedPieces = [],
6135 i,
6136 mom,
6137 minp,
6138 shortp,
6139 longp;
6140
6141 for (i = 0; i < 7; i++) {
6142 // make the regex if we don't have it already
6143 mom = createUTC([2000, 1]).day(i);
6144 minp = this.weekdaysMin(mom, '');
6145 shortp = this.weekdaysShort(mom, '');
6146 longp = this.weekdays(mom, '');
6147 minPieces.push(minp);
6148 shortPieces.push(shortp);
6149 longPieces.push(longp);
6150 mixedPieces.push(minp);
6151 mixedPieces.push(shortp);
6152 mixedPieces.push(longp);
6153 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
6154 // will match the longer piece.
6155
6156
6157 minPieces.sort(cmpLenRev);
6158 shortPieces.sort(cmpLenRev);
6159 longPieces.sort(cmpLenRev);
6160 mixedPieces.sort(cmpLenRev);
6161
6162 for (i = 0; i < 7; i++) {
6163 shortPieces[i] = regexEscape(shortPieces[i]);
6164 longPieces[i] = regexEscape(longPieces[i]);
6165 mixedPieces[i] = regexEscape(mixedPieces[i]);
6166 }
6167
6168 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
6169 this._weekdaysShortRegex = this._weekdaysRegex;
6170 this._weekdaysMinRegex = this._weekdaysRegex;
6171 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
6172 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
6173 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
6174 } // FORMATTING
6175
6176
6177 function hFormat() {
6178 return this.hours() % 12 || 12;
6179 }
6180
6181 function kFormat() {
6182 return this.hours() || 24;
6183 }
6184
6185 addFormatToken('H', ['HH', 2], 0, 'hour');
6186 addFormatToken('h', ['hh', 2], 0, hFormat);
6187 addFormatToken('k', ['kk', 2], 0, kFormat);
6188 addFormatToken('hmm', 0, 0, function () {
6189 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
6190 });
6191 addFormatToken('hmmss', 0, 0, function () {
6192 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
6193 });
6194 addFormatToken('Hmm', 0, 0, function () {
6195 return '' + this.hours() + zeroFill(this.minutes(), 2);
6196 });
6197 addFormatToken('Hmmss', 0, 0, function () {
6198 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
6199 });
6200
6201 function meridiem(token, lowercase) {
6202 addFormatToken(token, 0, 0, function () {
6203 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
6204 });
6205 }
6206
6207 meridiem('a', true);
6208 meridiem('A', false); // ALIASES
6209
6210 addUnitAlias('hour', 'h'); // PRIORITY
6211
6212 addUnitPriority('hour', 13); // PARSING
6213
6214 function matchMeridiem(isStrict, locale) {
6215 return locale._meridiemParse;
6216 }
6217
6218 addRegexToken('a', matchMeridiem);
6219 addRegexToken('A', matchMeridiem);
6220 addRegexToken('H', match1to2);
6221 addRegexToken('h', match1to2);
6222 addRegexToken('k', match1to2);
6223 addRegexToken('HH', match1to2, match2);
6224 addRegexToken('hh', match1to2, match2);
6225 addRegexToken('kk', match1to2, match2);
6226 addRegexToken('hmm', match3to4);
6227 addRegexToken('hmmss', match5to6);
6228 addRegexToken('Hmm', match3to4);
6229 addRegexToken('Hmmss', match5to6);
6230 addParseToken(['H', 'HH'], HOUR);
6231 addParseToken(['k', 'kk'], function (input, array, config) {
6232 var kInput = toInt(input);
6233 array[HOUR] = kInput === 24 ? 0 : kInput;
6234 });
6235 addParseToken(['a', 'A'], function (input, array, config) {
6236 config._isPm = config._locale.isPM(input);
6237 config._meridiem = input;
6238 });
6239 addParseToken(['h', 'hh'], function (input, array, config) {
6240 array[HOUR] = toInt(input);
6241 getParsingFlags(config).bigHour = true;
6242 });
6243 addParseToken('hmm', function (input, array, config) {
6244 var pos = input.length - 2;
6245 array[HOUR] = toInt(input.substr(0, pos));
6246 array[MINUTE] = toInt(input.substr(pos));
6247 getParsingFlags(config).bigHour = true;
6248 });
6249 addParseToken('hmmss', function (input, array, config) {
6250 var pos1 = input.length - 4;
6251 var pos2 = input.length - 2;
6252 array[HOUR] = toInt(input.substr(0, pos1));
6253 array[MINUTE] = toInt(input.substr(pos1, 2));
6254 array[SECOND] = toInt(input.substr(pos2));
6255 getParsingFlags(config).bigHour = true;
6256 });
6257 addParseToken('Hmm', function (input, array, config) {
6258 var pos = input.length - 2;
6259 array[HOUR] = toInt(input.substr(0, pos));
6260 array[MINUTE] = toInt(input.substr(pos));
6261 });
6262 addParseToken('Hmmss', function (input, array, config) {
6263 var pos1 = input.length - 4;
6264 var pos2 = input.length - 2;
6265 array[HOUR] = toInt(input.substr(0, pos1));
6266 array[MINUTE] = toInt(input.substr(pos1, 2));
6267 array[SECOND] = toInt(input.substr(pos2));
6268 }); // LOCALES
6269
6270 function localeIsPM(input) {
6271 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
6272 // Using charAt should be more compatible.
6273 return (input + '').toLowerCase().charAt(0) === 'p';
6274 }
6275
6276 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
6277
6278 function localeMeridiem(hours, minutes, isLower) {
6279 if (hours > 11) {
6280 return isLower ? 'pm' : 'PM';
6281 } else {
6282 return isLower ? 'am' : 'AM';
6283 }
6284 } // MOMENTS
6285 // Setting the hour should keep the time, because the user explicitly
6286 // specified which hour they want. So trying to maintain the same hour (in
6287 // a new timezone) makes sense. Adding/subtracting hours does not follow
6288 // this rule.
6289
6290
6291 var getSetHour = makeGetSet('Hours', true);
6292 var baseConfig = {
6293 calendar: defaultCalendar,
6294 longDateFormat: defaultLongDateFormat,
6295 invalidDate: defaultInvalidDate,
6296 ordinal: defaultOrdinal,
6297 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
6298 relativeTime: defaultRelativeTime,
6299 months: defaultLocaleMonths,
6300 monthsShort: defaultLocaleMonthsShort,
6301 week: defaultLocaleWeek,
6302 weekdays: defaultLocaleWeekdays,
6303 weekdaysMin: defaultLocaleWeekdaysMin,
6304 weekdaysShort: defaultLocaleWeekdaysShort,
6305 meridiemParse: defaultLocaleMeridiemParse
6306 }; // internal storage for locale config files
6307
6308 var locales = {};
6309 var localeFamilies = {};
6310 var globalLocale;
6311
6312 function normalizeLocale(key) {
6313 return key ? key.toLowerCase().replace('_', '-') : key;
6314 } // pick the locale from the array
6315 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
6316 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
6317
6318
6319 function chooseLocale(names) {
6320 var i = 0,
6321 j,
6322 next,
6323 locale,
6324 split;
6325
6326 while (i < names.length) {
6327 split = normalizeLocale(names[i]).split('-');
6328 j = split.length;
6329 next = normalizeLocale(names[i + 1]);
6330 next = next ? next.split('-') : null;
6331
6332 while (j > 0) {
6333 locale = loadLocale(split.slice(0, j).join('-'));
6334
6335 if (locale) {
6336 return locale;
6337 }
6338
6339 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
6340 //the next array item is better than a shallower substring of this one
6341 break;
6342 }
6343
6344 j--;
6345 }
6346
6347 i++;
6348 }
6349
6350 return globalLocale;
6351 }
6352
6353 function loadLocale(name) {
6354 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
6355
6356 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
6357 try {
6358 oldLocale = globalLocale._abbr;
6359 var aliasedRequire = commonjsRequire$1;
6360 aliasedRequire('./locale/' + name);
6361 getSetGlobalLocale(oldLocale);
6362 } catch (e) {}
6363 }
6364
6365 return locales[name];
6366 } // This function will load locale and then set the global locale. If
6367 // no arguments are passed in, it will simply return the current global
6368 // locale key.
6369
6370
6371 function getSetGlobalLocale(key, values) {
6372 var data;
6373
6374 if (key) {
6375 if (isUndefined(values)) {
6376 data = getLocale(key);
6377 } else {
6378 data = defineLocale(key, values);
6379 }
6380
6381 if (data) {
6382 // moment.duration._locale = moment._locale = data;
6383 globalLocale = data;
6384 } else {
6385 if (typeof console !== 'undefined' && console.warn) {
6386 //warn user if arguments are passed but the locale could not be set
6387 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
6388 }
6389 }
6390 }
6391
6392 return globalLocale._abbr;
6393 }
6394
6395 function defineLocale(name, config) {
6396 if (config !== null) {
6397 var locale,
6398 parentConfig = baseConfig;
6399 config.abbr = name;
6400
6401 if (locales[name] != null) {
6402 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.');
6403 parentConfig = locales[name]._config;
6404 } else if (config.parentLocale != null) {
6405 if (locales[config.parentLocale] != null) {
6406 parentConfig = locales[config.parentLocale]._config;
6407 } else {
6408 locale = loadLocale(config.parentLocale);
6409
6410 if (locale != null) {
6411 parentConfig = locale._config;
6412 } else {
6413 if (!localeFamilies[config.parentLocale]) {
6414 localeFamilies[config.parentLocale] = [];
6415 }
6416
6417 localeFamilies[config.parentLocale].push({
6418 name: name,
6419 config: config
6420 });
6421 return null;
6422 }
6423 }
6424 }
6425
6426 locales[name] = new Locale(mergeConfigs(parentConfig, config));
6427
6428 if (localeFamilies[name]) {
6429 localeFamilies[name].forEach(function (x) {
6430 defineLocale(x.name, x.config);
6431 });
6432 } // backwards compat for now: also set the locale
6433 // make sure we set the locale AFTER all child locales have been
6434 // created, so we won't end up with the child locale set.
6435
6436
6437 getSetGlobalLocale(name);
6438 return locales[name];
6439 } else {
6440 // useful for testing
6441 delete locales[name];
6442 return null;
6443 }
6444 }
6445
6446 function updateLocale(name, config) {
6447 if (config != null) {
6448 var locale,
6449 tmpLocale,
6450 parentConfig = baseConfig; // MERGE
6451
6452 tmpLocale = loadLocale(name);
6453
6454 if (tmpLocale != null) {
6455 parentConfig = tmpLocale._config;
6456 }
6457
6458 config = mergeConfigs(parentConfig, config);
6459 locale = new Locale(config);
6460 locale.parentLocale = locales[name];
6461 locales[name] = locale; // backwards compat for now: also set the locale
6462
6463 getSetGlobalLocale(name);
6464 } else {
6465 // pass null for config to unupdate, useful for tests
6466 if (locales[name] != null) {
6467 if (locales[name].parentLocale != null) {
6468 locales[name] = locales[name].parentLocale;
6469 } else if (locales[name] != null) {
6470 delete locales[name];
6471 }
6472 }
6473 }
6474
6475 return locales[name];
6476 } // returns locale data
6477
6478
6479 function getLocale(key) {
6480 var locale;
6481
6482 if (key && key._locale && key._locale._abbr) {
6483 key = key._locale._abbr;
6484 }
6485
6486 if (!key) {
6487 return globalLocale;
6488 }
6489
6490 if (!isArray(key)) {
6491 //short-circuit everything else
6492 locale = loadLocale(key);
6493
6494 if (locale) {
6495 return locale;
6496 }
6497
6498 key = [key];
6499 }
6500
6501 return chooseLocale(key);
6502 }
6503
6504 function listLocales() {
6505 return keys(locales);
6506 }
6507
6508 function checkOverflow(m) {
6509 var overflow;
6510 var a = m._a;
6511
6512 if (a && getParsingFlags(m).overflow === -2) {
6513 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;
6514
6515 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
6516 overflow = DATE;
6517 }
6518
6519 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
6520 overflow = WEEK;
6521 }
6522
6523 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
6524 overflow = WEEKDAY;
6525 }
6526
6527 getParsingFlags(m).overflow = overflow;
6528 }
6529
6530 return m;
6531 } // Pick the first defined of two or three arguments.
6532
6533
6534 function defaults(a, b, c) {
6535 if (a != null) {
6536 return a;
6537 }
6538
6539 if (b != null) {
6540 return b;
6541 }
6542
6543 return c;
6544 }
6545
6546 function currentDateArray(config) {
6547 // hooks is actually the exported moment object
6548 var nowValue = new Date(hooks.now());
6549
6550 if (config._useUTC) {
6551 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
6552 }
6553
6554 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
6555 } // convert an array to a date.
6556 // the array should mirror the parameters below
6557 // note: all values past the year are optional and will default to the lowest possible value.
6558 // [year, month, day , hour, minute, second, millisecond]
6559
6560
6561 function configFromArray(config) {
6562 var i,
6563 date,
6564 input = [],
6565 currentDate,
6566 expectedWeekday,
6567 yearToUse;
6568
6569 if (config._d) {
6570 return;
6571 }
6572
6573 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
6574
6575 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
6576 dayOfYearFromWeekInfo(config);
6577 } //if the day of the year is set, figure out what it is
6578
6579
6580 if (config._dayOfYear != null) {
6581 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
6582
6583 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
6584 getParsingFlags(config)._overflowDayOfYear = true;
6585 }
6586
6587 date = createUTCDate(yearToUse, 0, config._dayOfYear);
6588 config._a[MONTH] = date.getUTCMonth();
6589 config._a[DATE] = date.getUTCDate();
6590 } // Default to current date.
6591 // * if no year, month, day of month are given, default to today
6592 // * if day of month is given, default month and year
6593 // * if month is given, default only year
6594 // * if year is given, don't default anything
6595
6596
6597 for (i = 0; i < 3 && config._a[i] == null; ++i) {
6598 config._a[i] = input[i] = currentDate[i];
6599 } // Zero out whatever was not defaulted, including time
6600
6601
6602 for (; i < 7; i++) {
6603 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
6604 } // Check for 24:00:00.000
6605
6606
6607 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
6608 config._nextDay = true;
6609 config._a[HOUR] = 0;
6610 }
6611
6612 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
6613 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
6614 // with parseZone.
6615
6616 if (config._tzm != null) {
6617 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
6618 }
6619
6620 if (config._nextDay) {
6621 config._a[HOUR] = 24;
6622 } // check for mismatching day of week
6623
6624
6625 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
6626 getParsingFlags(config).weekdayMismatch = true;
6627 }
6628 }
6629
6630 function dayOfYearFromWeekInfo(config) {
6631 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
6632 w = config._w;
6633
6634 if (w.GG != null || w.W != null || w.E != null) {
6635 dow = 1;
6636 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
6637 // how we interpret now (local, utc, fixed offset). So create
6638 // a now version of current config (take local/utc/offset flags, and
6639 // create now).
6640
6641 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
6642 week = defaults(w.W, 1);
6643 weekday = defaults(w.E, 1);
6644
6645 if (weekday < 1 || weekday > 7) {
6646 weekdayOverflow = true;
6647 }
6648 } else {
6649 dow = config._locale._week.dow;
6650 doy = config._locale._week.doy;
6651 var curWeek = weekOfYear(createLocal(), dow, doy);
6652 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
6653
6654 week = defaults(w.w, curWeek.week);
6655
6656 if (w.d != null) {
6657 // weekday -- low day numbers are considered next week
6658 weekday = w.d;
6659
6660 if (weekday < 0 || weekday > 6) {
6661 weekdayOverflow = true;
6662 }
6663 } else if (w.e != null) {
6664 // local weekday -- counting starts from beginning of week
6665 weekday = w.e + dow;
6666
6667 if (w.e < 0 || w.e > 6) {
6668 weekdayOverflow = true;
6669 }
6670 } else {
6671 // default to beginning of week
6672 weekday = dow;
6673 }
6674 }
6675
6676 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
6677 getParsingFlags(config)._overflowWeeks = true;
6678 } else if (weekdayOverflow != null) {
6679 getParsingFlags(config)._overflowWeekday = true;
6680 } else {
6681 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
6682 config._a[YEAR] = temp.year;
6683 config._dayOfYear = temp.dayOfYear;
6684 }
6685 } // iso 8601 regex
6686 // 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)
6687
6688
6689 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)?)?$/;
6690 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)?)?$/;
6691 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
6692 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
6693 ['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
6694
6695 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/]];
6696 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
6697
6698 function configFromISO(config) {
6699 var i,
6700 l,
6701 string = config._i,
6702 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
6703 allowTime,
6704 dateFormat,
6705 timeFormat,
6706 tzFormat;
6707
6708 if (match) {
6709 getParsingFlags(config).iso = true;
6710
6711 for (i = 0, l = isoDates.length; i < l; i++) {
6712 if (isoDates[i][1].exec(match[1])) {
6713 dateFormat = isoDates[i][0];
6714 allowTime = isoDates[i][2] !== false;
6715 break;
6716 }
6717 }
6718
6719 if (dateFormat == null) {
6720 config._isValid = false;
6721 return;
6722 }
6723
6724 if (match[3]) {
6725 for (i = 0, l = isoTimes.length; i < l; i++) {
6726 if (isoTimes[i][1].exec(match[3])) {
6727 // match[2] should be 'T' or space
6728 timeFormat = (match[2] || ' ') + isoTimes[i][0];
6729 break;
6730 }
6731 }
6732
6733 if (timeFormat == null) {
6734 config._isValid = false;
6735 return;
6736 }
6737 }
6738
6739 if (!allowTime && timeFormat != null) {
6740 config._isValid = false;
6741 return;
6742 }
6743
6744 if (match[4]) {
6745 if (tzRegex.exec(match[4])) {
6746 tzFormat = 'Z';
6747 } else {
6748 config._isValid = false;
6749 return;
6750 }
6751 }
6752
6753 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
6754 configFromStringAndFormat(config);
6755 } else {
6756 config._isValid = false;
6757 }
6758 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
6759
6760
6761 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}))$/;
6762
6763 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
6764 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
6765
6766 if (secondStr) {
6767 result.push(parseInt(secondStr, 10));
6768 }
6769
6770 return result;
6771 }
6772
6773 function untruncateYear(yearStr) {
6774 var year = parseInt(yearStr, 10);
6775
6776 if (year <= 49) {
6777 return 2000 + year;
6778 } else if (year <= 999) {
6779 return 1900 + year;
6780 }
6781
6782 return year;
6783 }
6784
6785 function preprocessRFC2822(s) {
6786 // Remove comments and folding whitespace and replace multiple-spaces with a single space
6787 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
6788 }
6789
6790 function checkWeekday(weekdayStr, parsedInput, config) {
6791 if (weekdayStr) {
6792 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
6793 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
6794 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
6795
6796 if (weekdayProvided !== weekdayActual) {
6797 getParsingFlags(config).weekdayMismatch = true;
6798 config._isValid = false;
6799 return false;
6800 }
6801 }
6802
6803 return true;
6804 }
6805
6806 var obsOffsets = {
6807 UT: 0,
6808 GMT: 0,
6809 EDT: -4 * 60,
6810 EST: -5 * 60,
6811 CDT: -5 * 60,
6812 CST: -6 * 60,
6813 MDT: -6 * 60,
6814 MST: -7 * 60,
6815 PDT: -7 * 60,
6816 PST: -8 * 60
6817 };
6818
6819 function calculateOffset(obsOffset, militaryOffset, numOffset) {
6820 if (obsOffset) {
6821 return obsOffsets[obsOffset];
6822 } else if (militaryOffset) {
6823 // the only allowed military tz is Z
6824 return 0;
6825 } else {
6826 var hm = parseInt(numOffset, 10);
6827 var m = hm % 100,
6828 h = (hm - m) / 100;
6829 return h * 60 + m;
6830 }
6831 } // date and time from ref 2822 format
6832
6833
6834 function configFromRFC2822(config) {
6835 var match = rfc2822.exec(preprocessRFC2822(config._i));
6836
6837 if (match) {
6838 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
6839
6840 if (!checkWeekday(match[1], parsedArray, config)) {
6841 return;
6842 }
6843
6844 config._a = parsedArray;
6845 config._tzm = calculateOffset(match[8], match[9], match[10]);
6846 config._d = createUTCDate.apply(null, config._a);
6847
6848 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
6849
6850 getParsingFlags(config).rfc2822 = true;
6851 } else {
6852 config._isValid = false;
6853 }
6854 } // date from iso format or fallback
6855
6856
6857 function configFromString(config) {
6858 var matched = aspNetJsonRegex.exec(config._i);
6859
6860 if (matched !== null) {
6861 config._d = new Date(+matched[1]);
6862 return;
6863 }
6864
6865 configFromISO(config);
6866
6867 if (config._isValid === false) {
6868 delete config._isValid;
6869 } else {
6870 return;
6871 }
6872
6873 configFromRFC2822(config);
6874
6875 if (config._isValid === false) {
6876 delete config._isValid;
6877 } else {
6878 return;
6879 } // Final attempt, use Input Fallback
6880
6881
6882 hooks.createFromInputFallback(config);
6883 }
6884
6885 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) {
6886 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
6887 }); // constant that refers to the ISO standard
6888
6889 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
6890
6891
6892 hooks.RFC_2822 = function () {}; // date from string and format string
6893
6894
6895 function configFromStringAndFormat(config) {
6896 // TODO: Move this to another part of the creation flow to prevent circular deps
6897 if (config._f === hooks.ISO_8601) {
6898 configFromISO(config);
6899 return;
6900 }
6901
6902 if (config._f === hooks.RFC_2822) {
6903 configFromRFC2822(config);
6904 return;
6905 }
6906
6907 config._a = [];
6908 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
6909
6910 var string = '' + config._i,
6911 i,
6912 parsedInput,
6913 tokens,
6914 token,
6915 skipped,
6916 stringLength = string.length,
6917 totalParsedInputLength = 0;
6918 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
6919
6920 for (i = 0; i < tokens.length; i++) {
6921 token = tokens[i];
6922 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
6923 // 'regex', getParseRegexForToken(token, config));
6924
6925 if (parsedInput) {
6926 skipped = string.substr(0, string.indexOf(parsedInput));
6927
6928 if (skipped.length > 0) {
6929 getParsingFlags(config).unusedInput.push(skipped);
6930 }
6931
6932 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
6933 totalParsedInputLength += parsedInput.length;
6934 } // don't parse if it's not a known token
6935
6936
6937 if (formatTokenFunctions[token]) {
6938 if (parsedInput) {
6939 getParsingFlags(config).empty = false;
6940 } else {
6941 getParsingFlags(config).unusedTokens.push(token);
6942 }
6943
6944 addTimeToArrayFromToken(token, parsedInput, config);
6945 } else if (config._strict && !parsedInput) {
6946 getParsingFlags(config).unusedTokens.push(token);
6947 }
6948 } // add remaining unparsed input length to the string
6949
6950
6951 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
6952
6953 if (string.length > 0) {
6954 getParsingFlags(config).unusedInput.push(string);
6955 } // clear _12h flag if hour is <= 12
6956
6957
6958 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
6959 getParsingFlags(config).bigHour = undefined;
6960 }
6961
6962 getParsingFlags(config).parsedDateParts = config._a.slice(0);
6963 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
6964
6965 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
6966 configFromArray(config);
6967 checkOverflow(config);
6968 }
6969
6970 function meridiemFixWrap(locale, hour, meridiem) {
6971 var isPm;
6972
6973 if (meridiem == null) {
6974 // nothing to do
6975 return hour;
6976 }
6977
6978 if (locale.meridiemHour != null) {
6979 return locale.meridiemHour(hour, meridiem);
6980 } else if (locale.isPM != null) {
6981 // Fallback
6982 isPm = locale.isPM(meridiem);
6983
6984 if (isPm && hour < 12) {
6985 hour += 12;
6986 }
6987
6988 if (!isPm && hour === 12) {
6989 hour = 0;
6990 }
6991
6992 return hour;
6993 } else {
6994 // this is not supposed to happen
6995 return hour;
6996 }
6997 } // date from string and array of format strings
6998
6999
7000 function configFromStringAndArray(config) {
7001 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
7002
7003 if (config._f.length === 0) {
7004 getParsingFlags(config).invalidFormat = true;
7005 config._d = new Date(NaN);
7006 return;
7007 }
7008
7009 for (i = 0; i < config._f.length; i++) {
7010 currentScore = 0;
7011 tempConfig = copyConfig({}, config);
7012
7013 if (config._useUTC != null) {
7014 tempConfig._useUTC = config._useUTC;
7015 }
7016
7017 tempConfig._f = config._f[i];
7018 configFromStringAndFormat(tempConfig);
7019
7020 if (!isValid(tempConfig)) {
7021 continue;
7022 } // if there is any input that was not parsed add a penalty for that format
7023
7024
7025 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
7026
7027 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
7028 getParsingFlags(tempConfig).score = currentScore;
7029
7030 if (scoreToBeat == null || currentScore < scoreToBeat) {
7031 scoreToBeat = currentScore;
7032 bestMoment = tempConfig;
7033 }
7034 }
7035
7036 extend(config, bestMoment || tempConfig);
7037 }
7038
7039 function configFromObject(config) {
7040 if (config._d) {
7041 return;
7042 }
7043
7044 var i = normalizeObjectUnits(config._i);
7045 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
7046 return obj && parseInt(obj, 10);
7047 });
7048 configFromArray(config);
7049 }
7050
7051 function createFromConfig(config) {
7052 var res = new Moment(checkOverflow(prepareConfig(config)));
7053
7054 if (res._nextDay) {
7055 // Adding is smart enough around DST
7056 res.add(1, 'd');
7057 res._nextDay = undefined;
7058 }
7059
7060 return res;
7061 }
7062
7063 function prepareConfig(config) {
7064 var input = config._i,
7065 format = config._f;
7066 config._locale = config._locale || getLocale(config._l);
7067
7068 if (input === null || format === undefined && input === '') {
7069 return createInvalid({
7070 nullInput: true
7071 });
7072 }
7073
7074 if (typeof input === 'string') {
7075 config._i = input = config._locale.preparse(input);
7076 }
7077
7078 if (isMoment(input)) {
7079 return new Moment(checkOverflow(input));
7080 } else if (isDate(input)) {
7081 config._d = input;
7082 } else if (isArray(format)) {
7083 configFromStringAndArray(config);
7084 } else if (format) {
7085 configFromStringAndFormat(config);
7086 } else {
7087 configFromInput(config);
7088 }
7089
7090 if (!isValid(config)) {
7091 config._d = null;
7092 }
7093
7094 return config;
7095 }
7096
7097 function configFromInput(config) {
7098 var input = config._i;
7099
7100 if (isUndefined(input)) {
7101 config._d = new Date(hooks.now());
7102 } else if (isDate(input)) {
7103 config._d = new Date(input.valueOf());
7104 } else if (typeof input === 'string') {
7105 configFromString(config);
7106 } else if (isArray(input)) {
7107 config._a = map(input.slice(0), function (obj) {
7108 return parseInt(obj, 10);
7109 });
7110 configFromArray(config);
7111 } else if (isObject(input)) {
7112 configFromObject(config);
7113 } else if (isNumber(input)) {
7114 // from milliseconds
7115 config._d = new Date(input);
7116 } else {
7117 hooks.createFromInputFallback(config);
7118 }
7119 }
7120
7121 function createLocalOrUTC(input, format, locale, strict, isUTC) {
7122 var c = {};
7123
7124 if (locale === true || locale === false) {
7125 strict = locale;
7126 locale = undefined;
7127 }
7128
7129 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
7130 input = undefined;
7131 } // object construction must be done this way.
7132 // https://github.com/moment/moment/issues/1423
7133
7134
7135 c._isAMomentObject = true;
7136 c._useUTC = c._isUTC = isUTC;
7137 c._l = locale;
7138 c._i = input;
7139 c._f = format;
7140 c._strict = strict;
7141 return createFromConfig(c);
7142 }
7143
7144 function createLocal(input, format, locale, strict) {
7145 return createLocalOrUTC(input, format, locale, strict, false);
7146 }
7147
7148 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
7149 var other = createLocal.apply(null, arguments);
7150
7151 if (this.isValid() && other.isValid()) {
7152 return other < this ? this : other;
7153 } else {
7154 return createInvalid();
7155 }
7156 });
7157 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
7158 var other = createLocal.apply(null, arguments);
7159
7160 if (this.isValid() && other.isValid()) {
7161 return other > this ? this : other;
7162 } else {
7163 return createInvalid();
7164 }
7165 }); // Pick a moment m from moments so that m[fn](other) is true for all
7166 // other. This relies on the function fn to be transitive.
7167 //
7168 // moments should either be an array of moment objects or an array, whose
7169 // first element is an array of moment objects.
7170
7171 function pickBy(fn, moments) {
7172 var res, i;
7173
7174 if (moments.length === 1 && isArray(moments[0])) {
7175 moments = moments[0];
7176 }
7177
7178 if (!moments.length) {
7179 return createLocal();
7180 }
7181
7182 res = moments[0];
7183
7184 for (i = 1; i < moments.length; ++i) {
7185 if (!moments[i].isValid() || moments[i][fn](res)) {
7186 res = moments[i];
7187 }
7188 }
7189
7190 return res;
7191 } // TODO: Use [].sort instead?
7192
7193
7194 function min() {
7195 var args = [].slice.call(arguments, 0);
7196 return pickBy('isBefore', args);
7197 }
7198
7199 function max() {
7200 var args = [].slice.call(arguments, 0);
7201 return pickBy('isAfter', args);
7202 }
7203
7204 var now = function now() {
7205 return Date.now ? Date.now() : +new Date();
7206 };
7207
7208 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
7209
7210 function isDurationValid(m) {
7211 for (var key in m) {
7212 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
7213 return false;
7214 }
7215 }
7216
7217 var unitHasDecimal = false;
7218
7219 for (var i = 0; i < ordering.length; ++i) {
7220 if (m[ordering[i]]) {
7221 if (unitHasDecimal) {
7222 return false; // only allow non-integers for smallest unit
7223 }
7224
7225 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
7226 unitHasDecimal = true;
7227 }
7228 }
7229 }
7230
7231 return true;
7232 }
7233
7234 function isValid$1() {
7235 return this._isValid;
7236 }
7237
7238 function createInvalid$1() {
7239 return createDuration(NaN);
7240 }
7241
7242 function Duration(duration) {
7243 var normalizedInput = normalizeObjectUnits(duration),
7244 years = normalizedInput.year || 0,
7245 quarters = normalizedInput.quarter || 0,
7246 months = normalizedInput.month || 0,
7247 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
7248 days = normalizedInput.day || 0,
7249 hours = normalizedInput.hour || 0,
7250 minutes = normalizedInput.minute || 0,
7251 seconds = normalizedInput.second || 0,
7252 milliseconds = normalizedInput.millisecond || 0;
7253 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
7254
7255 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
7256 minutes * 6e4 + // 1000 * 60
7257 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
7258 // Because of dateAddRemove treats 24 hours as different from a
7259 // day when working around DST, we need to store them separately
7260
7261 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
7262 // which months you are are talking about, so we have to store
7263 // it separately.
7264
7265 this._months = +months + quarters * 3 + years * 12;
7266 this._data = {};
7267 this._locale = getLocale();
7268
7269 this._bubble();
7270 }
7271
7272 function isDuration(obj) {
7273 return obj instanceof Duration;
7274 }
7275
7276 function absRound(number) {
7277 if (number < 0) {
7278 return Math.round(-1 * number) * -1;
7279 } else {
7280 return Math.round(number);
7281 }
7282 } // FORMATTING
7283
7284
7285 function offset(token, separator) {
7286 addFormatToken(token, 0, 0, function () {
7287 var offset = this.utcOffset();
7288 var sign = '+';
7289
7290 if (offset < 0) {
7291 offset = -offset;
7292 sign = '-';
7293 }
7294
7295 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
7296 });
7297 }
7298
7299 offset('Z', ':');
7300 offset('ZZ', ''); // PARSING
7301
7302 addRegexToken('Z', matchShortOffset);
7303 addRegexToken('ZZ', matchShortOffset);
7304 addParseToken(['Z', 'ZZ'], function (input, array, config) {
7305 config._useUTC = true;
7306 config._tzm = offsetFromString(matchShortOffset, input);
7307 }); // HELPERS
7308 // timezone chunker
7309 // '+10:00' > ['10', '00']
7310 // '-1530' > ['-15', '30']
7311
7312 var chunkOffset = /([\+\-]|\d\d)/gi;
7313
7314 function offsetFromString(matcher, string) {
7315 var matches = (string || '').match(matcher);
7316
7317 if (matches === null) {
7318 return null;
7319 }
7320
7321 var chunk = matches[matches.length - 1] || [];
7322 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
7323 var minutes = +(parts[1] * 60) + toInt(parts[2]);
7324 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
7325 } // Return a moment from input, that is local/utc/zone equivalent to model.
7326
7327
7328 function cloneWithOffset(input, model) {
7329 var res, diff;
7330
7331 if (model._isUTC) {
7332 res = model.clone();
7333 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
7334
7335 res._d.setTime(res._d.valueOf() + diff);
7336
7337 hooks.updateOffset(res, false);
7338 return res;
7339 } else {
7340 return createLocal(input).local();
7341 }
7342 }
7343
7344 function getDateOffset(m) {
7345 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
7346 // https://github.com/moment/moment/pull/1871
7347 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
7348 } // HOOKS
7349 // This function will be called whenever a moment is mutated.
7350 // It is intended to keep the offset in sync with the timezone.
7351
7352
7353 hooks.updateOffset = function () {}; // MOMENTS
7354 // keepLocalTime = true means only change the timezone, without
7355 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
7356 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
7357 // +0200, so we adjust the time as needed, to be valid.
7358 //
7359 // Keeping the time actually adds/subtracts (one hour)
7360 // from the actual represented time. That is why we call updateOffset
7361 // a second time. In case it wants us to change the offset again
7362 // _changeInProgress == true case, then we have to adjust, because
7363 // there is no such time in the given timezone.
7364
7365
7366 function getSetOffset(input, keepLocalTime, keepMinutes) {
7367 var offset = this._offset || 0,
7368 localAdjust;
7369
7370 if (!this.isValid()) {
7371 return input != null ? this : NaN;
7372 }
7373
7374 if (input != null) {
7375 if (typeof input === 'string') {
7376 input = offsetFromString(matchShortOffset, input);
7377
7378 if (input === null) {
7379 return this;
7380 }
7381 } else if (Math.abs(input) < 16 && !keepMinutes) {
7382 input = input * 60;
7383 }
7384
7385 if (!this._isUTC && keepLocalTime) {
7386 localAdjust = getDateOffset(this);
7387 }
7388
7389 this._offset = input;
7390 this._isUTC = true;
7391
7392 if (localAdjust != null) {
7393 this.add(localAdjust, 'm');
7394 }
7395
7396 if (offset !== input) {
7397 if (!keepLocalTime || this._changeInProgress) {
7398 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
7399 } else if (!this._changeInProgress) {
7400 this._changeInProgress = true;
7401 hooks.updateOffset(this, true);
7402 this._changeInProgress = null;
7403 }
7404 }
7405
7406 return this;
7407 } else {
7408 return this._isUTC ? offset : getDateOffset(this);
7409 }
7410 }
7411
7412 function getSetZone(input, keepLocalTime) {
7413 if (input != null) {
7414 if (typeof input !== 'string') {
7415 input = -input;
7416 }
7417
7418 this.utcOffset(input, keepLocalTime);
7419 return this;
7420 } else {
7421 return -this.utcOffset();
7422 }
7423 }
7424
7425 function setOffsetToUTC(keepLocalTime) {
7426 return this.utcOffset(0, keepLocalTime);
7427 }
7428
7429 function setOffsetToLocal(keepLocalTime) {
7430 if (this._isUTC) {
7431 this.utcOffset(0, keepLocalTime);
7432 this._isUTC = false;
7433
7434 if (keepLocalTime) {
7435 this.subtract(getDateOffset(this), 'm');
7436 }
7437 }
7438
7439 return this;
7440 }
7441
7442 function setOffsetToParsedOffset() {
7443 if (this._tzm != null) {
7444 this.utcOffset(this._tzm, false, true);
7445 } else if (typeof this._i === 'string') {
7446 var tZone = offsetFromString(matchOffset, this._i);
7447
7448 if (tZone != null) {
7449 this.utcOffset(tZone);
7450 } else {
7451 this.utcOffset(0, true);
7452 }
7453 }
7454
7455 return this;
7456 }
7457
7458 function hasAlignedHourOffset(input) {
7459 if (!this.isValid()) {
7460 return false;
7461 }
7462
7463 input = input ? createLocal(input).utcOffset() : 0;
7464 return (this.utcOffset() - input) % 60 === 0;
7465 }
7466
7467 function isDaylightSavingTime() {
7468 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
7469 }
7470
7471 function isDaylightSavingTimeShifted() {
7472 if (!isUndefined(this._isDSTShifted)) {
7473 return this._isDSTShifted;
7474 }
7475
7476 var c = {};
7477 copyConfig(c, this);
7478 c = prepareConfig(c);
7479
7480 if (c._a) {
7481 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
7482 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
7483 } else {
7484 this._isDSTShifted = false;
7485 }
7486
7487 return this._isDSTShifted;
7488 }
7489
7490 function isLocal() {
7491 return this.isValid() ? !this._isUTC : false;
7492 }
7493
7494 function isUtcOffset() {
7495 return this.isValid() ? this._isUTC : false;
7496 }
7497
7498 function isUtc() {
7499 return this.isValid() ? this._isUTC && this._offset === 0 : false;
7500 } // ASP.NET json date format regex
7501
7502
7503 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
7504 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
7505 // and further modified to allow for strings containing both week and day
7506
7507 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)?)?$/;
7508
7509 function createDuration(input, key) {
7510 var duration = input,
7511 // matching against regexp is expensive, do it on demand
7512 match = null,
7513 sign,
7514 ret,
7515 diffRes;
7516
7517 if (isDuration(input)) {
7518 duration = {
7519 ms: input._milliseconds,
7520 d: input._days,
7521 M: input._months
7522 };
7523 } else if (isNumber(input)) {
7524 duration = {};
7525
7526 if (key) {
7527 duration[key] = input;
7528 } else {
7529 duration.milliseconds = input;
7530 }
7531 } else if (!!(match = aspNetRegex.exec(input))) {
7532 sign = match[1] === '-' ? -1 : 1;
7533 duration = {
7534 y: 0,
7535 d: toInt(match[DATE]) * sign,
7536 h: toInt(match[HOUR]) * sign,
7537 m: toInt(match[MINUTE]) * sign,
7538 s: toInt(match[SECOND]) * sign,
7539 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
7540
7541 };
7542 } else if (!!(match = isoRegex.exec(input))) {
7543 sign = match[1] === '-' ? -1 : 1;
7544 duration = {
7545 y: parseIso(match[2], sign),
7546 M: parseIso(match[3], sign),
7547 w: parseIso(match[4], sign),
7548 d: parseIso(match[5], sign),
7549 h: parseIso(match[6], sign),
7550 m: parseIso(match[7], sign),
7551 s: parseIso(match[8], sign)
7552 };
7553 } else if (duration == null) {
7554 // checks for null or undefined
7555 duration = {};
7556 } else if (_typeof(duration) === 'object' && ('from' in duration || 'to' in duration)) {
7557 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
7558 duration = {};
7559 duration.ms = diffRes.milliseconds;
7560 duration.M = diffRes.months;
7561 }
7562
7563 ret = new Duration(duration);
7564
7565 if (isDuration(input) && hasOwnProp(input, '_locale')) {
7566 ret._locale = input._locale;
7567 }
7568
7569 return ret;
7570 }
7571
7572 createDuration.fn = Duration.prototype;
7573 createDuration.invalid = createInvalid$1;
7574
7575 function parseIso(inp, sign) {
7576 // We'd normally use ~~inp for this, but unfortunately it also
7577 // converts floats to ints.
7578 // inp may be undefined, so careful calling replace on it.
7579 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
7580
7581 return (isNaN(res) ? 0 : res) * sign;
7582 }
7583
7584 function positiveMomentsDifference(base, other) {
7585 var res = {};
7586 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
7587
7588 if (base.clone().add(res.months, 'M').isAfter(other)) {
7589 --res.months;
7590 }
7591
7592 res.milliseconds = +other - +base.clone().add(res.months, 'M');
7593 return res;
7594 }
7595
7596 function momentsDifference(base, other) {
7597 var res;
7598
7599 if (!(base.isValid() && other.isValid())) {
7600 return {
7601 milliseconds: 0,
7602 months: 0
7603 };
7604 }
7605
7606 other = cloneWithOffset(other, base);
7607
7608 if (base.isBefore(other)) {
7609 res = positiveMomentsDifference(base, other);
7610 } else {
7611 res = positiveMomentsDifference(other, base);
7612 res.milliseconds = -res.milliseconds;
7613 res.months = -res.months;
7614 }
7615
7616 return res;
7617 } // TODO: remove 'name' arg after deprecation is removed
7618
7619
7620 function createAdder(direction, name) {
7621 return function (val, period) {
7622 var dur, tmp; //invert the arguments, but complain about it
7623
7624 if (period !== null && !isNaN(+period)) {
7625 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.');
7626 tmp = val;
7627 val = period;
7628 period = tmp;
7629 }
7630
7631 val = typeof val === 'string' ? +val : val;
7632 dur = createDuration(val, period);
7633 addSubtract(this, dur, direction);
7634 return this;
7635 };
7636 }
7637
7638 function addSubtract(mom, duration, isAdding, updateOffset) {
7639 var milliseconds = duration._milliseconds,
7640 days = absRound(duration._days),
7641 months = absRound(duration._months);
7642
7643 if (!mom.isValid()) {
7644 // No op
7645 return;
7646 }
7647
7648 updateOffset = updateOffset == null ? true : updateOffset;
7649
7650 if (months) {
7651 setMonth(mom, get(mom, 'Month') + months * isAdding);
7652 }
7653
7654 if (days) {
7655 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
7656 }
7657
7658 if (milliseconds) {
7659 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
7660 }
7661
7662 if (updateOffset) {
7663 hooks.updateOffset(mom, days || months);
7664 }
7665 }
7666
7667 var add = createAdder(1, 'add');
7668 var subtract = createAdder(-1, 'subtract');
7669
7670 function getCalendarFormat(myMoment, now) {
7671 var diff = myMoment.diff(now, 'days', true);
7672 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
7673 }
7674
7675 function calendar$1(time, formats) {
7676 // We want to compare the start of today, vs this.
7677 // Getting start-of-today depends on whether we're local/utc/offset or not.
7678 var now = time || createLocal(),
7679 sod = cloneWithOffset(now, this).startOf('day'),
7680 format = hooks.calendarFormat(this, sod) || 'sameElse';
7681 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
7682 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
7683 }
7684
7685 function clone() {
7686 return new Moment(this);
7687 }
7688
7689 function isAfter(input, units) {
7690 var localInput = isMoment(input) ? input : createLocal(input);
7691
7692 if (!(this.isValid() && localInput.isValid())) {
7693 return false;
7694 }
7695
7696 units = normalizeUnits(units) || 'millisecond';
7697
7698 if (units === 'millisecond') {
7699 return this.valueOf() > localInput.valueOf();
7700 } else {
7701 return localInput.valueOf() < this.clone().startOf(units).valueOf();
7702 }
7703 }
7704
7705 function isBefore(input, units) {
7706 var localInput = isMoment(input) ? input : createLocal(input);
7707
7708 if (!(this.isValid() && localInput.isValid())) {
7709 return false;
7710 }
7711
7712 units = normalizeUnits(units) || 'millisecond';
7713
7714 if (units === 'millisecond') {
7715 return this.valueOf() < localInput.valueOf();
7716 } else {
7717 return this.clone().endOf(units).valueOf() < localInput.valueOf();
7718 }
7719 }
7720
7721 function isBetween(from, to, units, inclusivity) {
7722 var localFrom = isMoment(from) ? from : createLocal(from),
7723 localTo = isMoment(to) ? to : createLocal(to);
7724
7725 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
7726 return false;
7727 }
7728
7729 inclusivity = inclusivity || '()';
7730 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
7731 }
7732
7733 function isSame(input, units) {
7734 var localInput = isMoment(input) ? input : createLocal(input),
7735 inputMs;
7736
7737 if (!(this.isValid() && localInput.isValid())) {
7738 return false;
7739 }
7740
7741 units = normalizeUnits(units) || 'millisecond';
7742
7743 if (units === 'millisecond') {
7744 return this.valueOf() === localInput.valueOf();
7745 } else {
7746 inputMs = localInput.valueOf();
7747 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
7748 }
7749 }
7750
7751 function isSameOrAfter(input, units) {
7752 return this.isSame(input, units) || this.isAfter(input, units);
7753 }
7754
7755 function isSameOrBefore(input, units) {
7756 return this.isSame(input, units) || this.isBefore(input, units);
7757 }
7758
7759 function diff(input, units, asFloat) {
7760 var that, zoneDelta, output;
7761
7762 if (!this.isValid()) {
7763 return NaN;
7764 }
7765
7766 that = cloneWithOffset(input, this);
7767
7768 if (!that.isValid()) {
7769 return NaN;
7770 }
7771
7772 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
7773 units = normalizeUnits(units);
7774
7775 switch (units) {
7776 case 'year':
7777 output = monthDiff(this, that) / 12;
7778 break;
7779
7780 case 'month':
7781 output = monthDiff(this, that);
7782 break;
7783
7784 case 'quarter':
7785 output = monthDiff(this, that) / 3;
7786 break;
7787
7788 case 'second':
7789 output = (this - that) / 1e3;
7790 break;
7791 // 1000
7792
7793 case 'minute':
7794 output = (this - that) / 6e4;
7795 break;
7796 // 1000 * 60
7797
7798 case 'hour':
7799 output = (this - that) / 36e5;
7800 break;
7801 // 1000 * 60 * 60
7802
7803 case 'day':
7804 output = (this - that - zoneDelta) / 864e5;
7805 break;
7806 // 1000 * 60 * 60 * 24, negate dst
7807
7808 case 'week':
7809 output = (this - that - zoneDelta) / 6048e5;
7810 break;
7811 // 1000 * 60 * 60 * 24 * 7, negate dst
7812
7813 default:
7814 output = this - that;
7815 }
7816
7817 return asFloat ? output : absFloor(output);
7818 }
7819
7820 function monthDiff(a, b) {
7821 // difference in months
7822 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
7823 // b is in (anchor - 1 month, anchor + 1 month)
7824 anchor = a.clone().add(wholeMonthDiff, 'months'),
7825 anchor2,
7826 adjust;
7827
7828 if (b - anchor < 0) {
7829 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
7830
7831 adjust = (b - anchor) / (anchor - anchor2);
7832 } else {
7833 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
7834
7835 adjust = (b - anchor) / (anchor2 - anchor);
7836 } //check for negative zero, return zero if negative zero
7837
7838
7839 return -(wholeMonthDiff + adjust) || 0;
7840 }
7841
7842 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
7843 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
7844
7845 function toString() {
7846 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
7847 }
7848
7849 function toISOString(keepOffset) {
7850 if (!this.isValid()) {
7851 return null;
7852 }
7853
7854 var utc = keepOffset !== true;
7855 var m = utc ? this.clone().utc() : this;
7856
7857 if (m.year() < 0 || m.year() > 9999) {
7858 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
7859 }
7860
7861 if (isFunction(Date.prototype.toISOString)) {
7862 // native implementation is ~50x faster, use it when we can
7863 if (utc) {
7864 return this.toDate().toISOString();
7865 } else {
7866 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
7867 }
7868 }
7869
7870 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
7871 }
7872 /**
7873 * Return a human readable representation of a moment that can
7874 * also be evaluated to get a new moment which is the same
7875 *
7876 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
7877 */
7878
7879
7880 function inspect() {
7881 if (!this.isValid()) {
7882 return 'moment.invalid(/* ' + this._i + ' */)';
7883 }
7884
7885 var func = 'moment';
7886 var zone = '';
7887
7888 if (!this.isLocal()) {
7889 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
7890 zone = 'Z';
7891 }
7892
7893 var prefix = '[' + func + '("]';
7894 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
7895 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
7896 var suffix = zone + '[")]';
7897 return this.format(prefix + year + datetime + suffix);
7898 }
7899
7900 function format(inputString) {
7901 if (!inputString) {
7902 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
7903 }
7904
7905 var output = formatMoment(this, inputString);
7906 return this.localeData().postformat(output);
7907 }
7908
7909 function from(time, withoutSuffix) {
7910 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
7911 return createDuration({
7912 to: this,
7913 from: time
7914 }).locale(this.locale()).humanize(!withoutSuffix);
7915 } else {
7916 return this.localeData().invalidDate();
7917 }
7918 }
7919
7920 function fromNow(withoutSuffix) {
7921 return this.from(createLocal(), withoutSuffix);
7922 }
7923
7924 function to(time, withoutSuffix) {
7925 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
7926 return createDuration({
7927 from: this,
7928 to: time
7929 }).locale(this.locale()).humanize(!withoutSuffix);
7930 } else {
7931 return this.localeData().invalidDate();
7932 }
7933 }
7934
7935 function toNow(withoutSuffix) {
7936 return this.to(createLocal(), withoutSuffix);
7937 } // If passed a locale key, it will set the locale for this
7938 // instance. Otherwise, it will return the locale configuration
7939 // variables for this instance.
7940
7941
7942 function locale(key) {
7943 var newLocaleData;
7944
7945 if (key === undefined) {
7946 return this._locale._abbr;
7947 } else {
7948 newLocaleData = getLocale(key);
7949
7950 if (newLocaleData != null) {
7951 this._locale = newLocaleData;
7952 }
7953
7954 return this;
7955 }
7956 }
7957
7958 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
7959 if (key === undefined) {
7960 return this.localeData();
7961 } else {
7962 return this.locale(key);
7963 }
7964 });
7965
7966 function localeData() {
7967 return this._locale;
7968 }
7969
7970 var MS_PER_SECOND = 1000;
7971 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
7972 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
7973 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
7974
7975 function mod$1(dividend, divisor) {
7976 return (dividend % divisor + divisor) % divisor;
7977 }
7978
7979 function localStartOfDate(y, m, d) {
7980 // the date constructor remaps years 0-99 to 1900-1999
7981 if (y < 100 && y >= 0) {
7982 // preserve leap years using a full 400 year cycle, then reset
7983 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
7984 } else {
7985 return new Date(y, m, d).valueOf();
7986 }
7987 }
7988
7989 function utcStartOfDate(y, m, d) {
7990 // Date.UTC remaps years 0-99 to 1900-1999
7991 if (y < 100 && y >= 0) {
7992 // preserve leap years using a full 400 year cycle, then reset
7993 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
7994 } else {
7995 return Date.UTC(y, m, d);
7996 }
7997 }
7998
7999 function startOf(units) {
8000 var time;
8001 units = normalizeUnits(units);
8002
8003 if (units === undefined || units === 'millisecond' || !this.isValid()) {
8004 return this;
8005 }
8006
8007 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
8008
8009 switch (units) {
8010 case 'year':
8011 time = startOfDate(this.year(), 0, 1);
8012 break;
8013
8014 case 'quarter':
8015 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
8016 break;
8017
8018 case 'month':
8019 time = startOfDate(this.year(), this.month(), 1);
8020 break;
8021
8022 case 'week':
8023 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
8024 break;
8025
8026 case 'isoWeek':
8027 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
8028 break;
8029
8030 case 'day':
8031 case 'date':
8032 time = startOfDate(this.year(), this.month(), this.date());
8033 break;
8034
8035 case 'hour':
8036 time = this._d.valueOf();
8037 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
8038 break;
8039
8040 case 'minute':
8041 time = this._d.valueOf();
8042 time -= mod$1(time, MS_PER_MINUTE);
8043 break;
8044
8045 case 'second':
8046 time = this._d.valueOf();
8047 time -= mod$1(time, MS_PER_SECOND);
8048 break;
8049 }
8050
8051 this._d.setTime(time);
8052
8053 hooks.updateOffset(this, true);
8054 return this;
8055 }
8056
8057 function endOf(units) {
8058 var time;
8059 units = normalizeUnits(units);
8060
8061 if (units === undefined || units === 'millisecond' || !this.isValid()) {
8062 return this;
8063 }
8064
8065 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
8066
8067 switch (units) {
8068 case 'year':
8069 time = startOfDate(this.year() + 1, 0, 1) - 1;
8070 break;
8071
8072 case 'quarter':
8073 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
8074 break;
8075
8076 case 'month':
8077 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
8078 break;
8079
8080 case 'week':
8081 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
8082 break;
8083
8084 case 'isoWeek':
8085 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
8086 break;
8087
8088 case 'day':
8089 case 'date':
8090 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
8091 break;
8092
8093 case 'hour':
8094 time = this._d.valueOf();
8095 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
8096 break;
8097
8098 case 'minute':
8099 time = this._d.valueOf();
8100 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
8101 break;
8102
8103 case 'second':
8104 time = this._d.valueOf();
8105 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
8106 break;
8107 }
8108
8109 this._d.setTime(time);
8110
8111 hooks.updateOffset(this, true);
8112 return this;
8113 }
8114
8115 function valueOf() {
8116 return this._d.valueOf() - (this._offset || 0) * 60000;
8117 }
8118
8119 function unix() {
8120 return Math.floor(this.valueOf() / 1000);
8121 }
8122
8123 function toDate() {
8124 return new Date(this.valueOf());
8125 }
8126
8127 function toArray() {
8128 var m = this;
8129 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
8130 }
8131
8132 function toObject() {
8133 var m = this;
8134 return {
8135 years: m.year(),
8136 months: m.month(),
8137 date: m.date(),
8138 hours: m.hours(),
8139 minutes: m.minutes(),
8140 seconds: m.seconds(),
8141 milliseconds: m.milliseconds()
8142 };
8143 }
8144
8145 function toJSON() {
8146 // new Date(NaN).toJSON() === null
8147 return this.isValid() ? this.toISOString() : null;
8148 }
8149
8150 function isValid$2() {
8151 return isValid(this);
8152 }
8153
8154 function parsingFlags() {
8155 return extend({}, getParsingFlags(this));
8156 }
8157
8158 function invalidAt() {
8159 return getParsingFlags(this).overflow;
8160 }
8161
8162 function creationData() {
8163 return {
8164 input: this._i,
8165 format: this._f,
8166 locale: this._locale,
8167 isUTC: this._isUTC,
8168 strict: this._strict
8169 };
8170 } // FORMATTING
8171
8172
8173 addFormatToken(0, ['gg', 2], 0, function () {
8174 return this.weekYear() % 100;
8175 });
8176 addFormatToken(0, ['GG', 2], 0, function () {
8177 return this.isoWeekYear() % 100;
8178 });
8179
8180 function addWeekYearFormatToken(token, getter) {
8181 addFormatToken(0, [token, token.length], 0, getter);
8182 }
8183
8184 addWeekYearFormatToken('gggg', 'weekYear');
8185 addWeekYearFormatToken('ggggg', 'weekYear');
8186 addWeekYearFormatToken('GGGG', 'isoWeekYear');
8187 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
8188
8189 addUnitAlias('weekYear', 'gg');
8190 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
8191
8192 addUnitPriority('weekYear', 1);
8193 addUnitPriority('isoWeekYear', 1); // PARSING
8194
8195 addRegexToken('G', matchSigned);
8196 addRegexToken('g', matchSigned);
8197 addRegexToken('GG', match1to2, match2);
8198 addRegexToken('gg', match1to2, match2);
8199 addRegexToken('GGGG', match1to4, match4);
8200 addRegexToken('gggg', match1to4, match4);
8201 addRegexToken('GGGGG', match1to6, match6);
8202 addRegexToken('ggggg', match1to6, match6);
8203 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
8204 week[token.substr(0, 2)] = toInt(input);
8205 });
8206 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
8207 week[token] = hooks.parseTwoDigitYear(input);
8208 }); // MOMENTS
8209
8210 function getSetWeekYear(input) {
8211 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
8212 }
8213
8214 function getSetISOWeekYear(input) {
8215 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
8216 }
8217
8218 function getISOWeeksInYear() {
8219 return weeksInYear(this.year(), 1, 4);
8220 }
8221
8222 function getWeeksInYear() {
8223 var weekInfo = this.localeData()._week;
8224
8225 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
8226 }
8227
8228 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
8229 var weeksTarget;
8230
8231 if (input == null) {
8232 return weekOfYear(this, dow, doy).year;
8233 } else {
8234 weeksTarget = weeksInYear(input, dow, doy);
8235
8236 if (week > weeksTarget) {
8237 week = weeksTarget;
8238 }
8239
8240 return setWeekAll.call(this, input, week, weekday, dow, doy);
8241 }
8242 }
8243
8244 function setWeekAll(weekYear, week, weekday, dow, doy) {
8245 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
8246 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
8247 this.year(date.getUTCFullYear());
8248 this.month(date.getUTCMonth());
8249 this.date(date.getUTCDate());
8250 return this;
8251 } // FORMATTING
8252
8253
8254 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
8255
8256 addUnitAlias('quarter', 'Q'); // PRIORITY
8257
8258 addUnitPriority('quarter', 7); // PARSING
8259
8260 addRegexToken('Q', match1);
8261 addParseToken('Q', function (input, array) {
8262 array[MONTH] = (toInt(input) - 1) * 3;
8263 }); // MOMENTS
8264
8265 function getSetQuarter(input) {
8266 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
8267 } // FORMATTING
8268
8269
8270 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
8271
8272 addUnitAlias('date', 'D'); // PRIORITY
8273
8274 addUnitPriority('date', 9); // PARSING
8275
8276 addRegexToken('D', match1to2);
8277 addRegexToken('DD', match1to2, match2);
8278 addRegexToken('Do', function (isStrict, locale) {
8279 // TODO: Remove "ordinalParse" fallback in next major release.
8280 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
8281 });
8282 addParseToken(['D', 'DD'], DATE);
8283 addParseToken('Do', function (input, array) {
8284 array[DATE] = toInt(input.match(match1to2)[0]);
8285 }); // MOMENTS
8286
8287 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
8288
8289 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
8290
8291 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
8292
8293 addUnitPriority('dayOfYear', 4); // PARSING
8294
8295 addRegexToken('DDD', match1to3);
8296 addRegexToken('DDDD', match3);
8297 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
8298 config._dayOfYear = toInt(input);
8299 }); // HELPERS
8300 // MOMENTS
8301
8302 function getSetDayOfYear(input) {
8303 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
8304 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
8305 } // FORMATTING
8306
8307
8308 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
8309
8310 addUnitAlias('minute', 'm'); // PRIORITY
8311
8312 addUnitPriority('minute', 14); // PARSING
8313
8314 addRegexToken('m', match1to2);
8315 addRegexToken('mm', match1to2, match2);
8316 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
8317
8318 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
8319
8320 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
8321
8322 addUnitAlias('second', 's'); // PRIORITY
8323
8324 addUnitPriority('second', 15); // PARSING
8325
8326 addRegexToken('s', match1to2);
8327 addRegexToken('ss', match1to2, match2);
8328 addParseToken(['s', 'ss'], SECOND); // MOMENTS
8329
8330 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
8331
8332 addFormatToken('S', 0, 0, function () {
8333 return ~~(this.millisecond() / 100);
8334 });
8335 addFormatToken(0, ['SS', 2], 0, function () {
8336 return ~~(this.millisecond() / 10);
8337 });
8338 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
8339 addFormatToken(0, ['SSSS', 4], 0, function () {
8340 return this.millisecond() * 10;
8341 });
8342 addFormatToken(0, ['SSSSS', 5], 0, function () {
8343 return this.millisecond() * 100;
8344 });
8345 addFormatToken(0, ['SSSSSS', 6], 0, function () {
8346 return this.millisecond() * 1000;
8347 });
8348 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
8349 return this.millisecond() * 10000;
8350 });
8351 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
8352 return this.millisecond() * 100000;
8353 });
8354 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
8355 return this.millisecond() * 1000000;
8356 }); // ALIASES
8357
8358 addUnitAlias('millisecond', 'ms'); // PRIORITY
8359
8360 addUnitPriority('millisecond', 16); // PARSING
8361
8362 addRegexToken('S', match1to3, match1);
8363 addRegexToken('SS', match1to3, match2);
8364 addRegexToken('SSS', match1to3, match3);
8365 var token;
8366
8367 for (token = 'SSSS'; token.length <= 9; token += 'S') {
8368 addRegexToken(token, matchUnsigned);
8369 }
8370
8371 function parseMs(input, array) {
8372 array[MILLISECOND] = toInt(('0.' + input) * 1000);
8373 }
8374
8375 for (token = 'S'; token.length <= 9; token += 'S') {
8376 addParseToken(token, parseMs);
8377 } // MOMENTS
8378
8379
8380 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
8381
8382 addFormatToken('z', 0, 0, 'zoneAbbr');
8383 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
8384
8385 function getZoneAbbr() {
8386 return this._isUTC ? 'UTC' : '';
8387 }
8388
8389 function getZoneName() {
8390 return this._isUTC ? 'Coordinated Universal Time' : '';
8391 }
8392
8393 var proto = Moment.prototype;
8394 proto.add = add;
8395 proto.calendar = calendar$1;
8396 proto.clone = clone;
8397 proto.diff = diff;
8398 proto.endOf = endOf;
8399 proto.format = format;
8400 proto.from = from;
8401 proto.fromNow = fromNow;
8402 proto.to = to;
8403 proto.toNow = toNow;
8404 proto.get = stringGet;
8405 proto.invalidAt = invalidAt;
8406 proto.isAfter = isAfter;
8407 proto.isBefore = isBefore;
8408 proto.isBetween = isBetween;
8409 proto.isSame = isSame;
8410 proto.isSameOrAfter = isSameOrAfter;
8411 proto.isSameOrBefore = isSameOrBefore;
8412 proto.isValid = isValid$2;
8413 proto.lang = lang;
8414 proto.locale = locale;
8415 proto.localeData = localeData;
8416 proto.max = prototypeMax;
8417 proto.min = prototypeMin;
8418 proto.parsingFlags = parsingFlags;
8419 proto.set = stringSet;
8420 proto.startOf = startOf;
8421 proto.subtract = subtract;
8422 proto.toArray = toArray;
8423 proto.toObject = toObject;
8424 proto.toDate = toDate;
8425 proto.toISOString = toISOString;
8426 proto.inspect = inspect;
8427 proto.toJSON = toJSON;
8428 proto.toString = toString;
8429 proto.unix = unix;
8430 proto.valueOf = valueOf;
8431 proto.creationData = creationData;
8432 proto.year = getSetYear;
8433 proto.isLeapYear = getIsLeapYear;
8434 proto.weekYear = getSetWeekYear;
8435 proto.isoWeekYear = getSetISOWeekYear;
8436 proto.quarter = proto.quarters = getSetQuarter;
8437 proto.month = getSetMonth;
8438 proto.daysInMonth = getDaysInMonth;
8439 proto.week = proto.weeks = getSetWeek;
8440 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
8441 proto.weeksInYear = getWeeksInYear;
8442 proto.isoWeeksInYear = getISOWeeksInYear;
8443 proto.date = getSetDayOfMonth;
8444 proto.day = proto.days = getSetDayOfWeek;
8445 proto.weekday = getSetLocaleDayOfWeek;
8446 proto.isoWeekday = getSetISODayOfWeek;
8447 proto.dayOfYear = getSetDayOfYear;
8448 proto.hour = proto.hours = getSetHour;
8449 proto.minute = proto.minutes = getSetMinute;
8450 proto.second = proto.seconds = getSetSecond;
8451 proto.millisecond = proto.milliseconds = getSetMillisecond;
8452 proto.utcOffset = getSetOffset;
8453 proto.utc = setOffsetToUTC;
8454 proto.local = setOffsetToLocal;
8455 proto.parseZone = setOffsetToParsedOffset;
8456 proto.hasAlignedHourOffset = hasAlignedHourOffset;
8457 proto.isDST = isDaylightSavingTime;
8458 proto.isLocal = isLocal;
8459 proto.isUtcOffset = isUtcOffset;
8460 proto.isUtc = isUtc;
8461 proto.isUTC = isUtc;
8462 proto.zoneAbbr = getZoneAbbr;
8463 proto.zoneName = getZoneName;
8464 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
8465 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
8466 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
8467 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
8468 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
8469
8470 function createUnix(input) {
8471 return createLocal(input * 1000);
8472 }
8473
8474 function createInZone() {
8475 return createLocal.apply(null, arguments).parseZone();
8476 }
8477
8478 function preParsePostFormat(string) {
8479 return string;
8480 }
8481
8482 var proto$1 = Locale.prototype;
8483 proto$1.calendar = calendar;
8484 proto$1.longDateFormat = longDateFormat;
8485 proto$1.invalidDate = invalidDate;
8486 proto$1.ordinal = ordinal;
8487 proto$1.preparse = preParsePostFormat;
8488 proto$1.postformat = preParsePostFormat;
8489 proto$1.relativeTime = relativeTime;
8490 proto$1.pastFuture = pastFuture;
8491 proto$1.set = set;
8492 proto$1.months = localeMonths;
8493 proto$1.monthsShort = localeMonthsShort;
8494 proto$1.monthsParse = localeMonthsParse;
8495 proto$1.monthsRegex = monthsRegex;
8496 proto$1.monthsShortRegex = monthsShortRegex;
8497 proto$1.week = localeWeek;
8498 proto$1.firstDayOfYear = localeFirstDayOfYear;
8499 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
8500 proto$1.weekdays = localeWeekdays;
8501 proto$1.weekdaysMin = localeWeekdaysMin;
8502 proto$1.weekdaysShort = localeWeekdaysShort;
8503 proto$1.weekdaysParse = localeWeekdaysParse;
8504 proto$1.weekdaysRegex = weekdaysRegex;
8505 proto$1.weekdaysShortRegex = weekdaysShortRegex;
8506 proto$1.weekdaysMinRegex = weekdaysMinRegex;
8507 proto$1.isPM = localeIsPM;
8508 proto$1.meridiem = localeMeridiem;
8509
8510 function get$1(format, index, field, setter) {
8511 var locale = getLocale();
8512 var utc = createUTC().set(setter, index);
8513 return locale[field](utc, format);
8514 }
8515
8516 function listMonthsImpl(format, index, field) {
8517 if (isNumber(format)) {
8518 index = format;
8519 format = undefined;
8520 }
8521
8522 format = format || '';
8523
8524 if (index != null) {
8525 return get$1(format, index, field, 'month');
8526 }
8527
8528 var i;
8529 var out = [];
8530
8531 for (i = 0; i < 12; i++) {
8532 out[i] = get$1(format, i, field, 'month');
8533 }
8534
8535 return out;
8536 } // ()
8537 // (5)
8538 // (fmt, 5)
8539 // (fmt)
8540 // (true)
8541 // (true, 5)
8542 // (true, fmt, 5)
8543 // (true, fmt)
8544
8545
8546 function listWeekdaysImpl(localeSorted, format, index, field) {
8547 if (typeof localeSorted === 'boolean') {
8548 if (isNumber(format)) {
8549 index = format;
8550 format = undefined;
8551 }
8552
8553 format = format || '';
8554 } else {
8555 format = localeSorted;
8556 index = format;
8557 localeSorted = false;
8558
8559 if (isNumber(format)) {
8560 index = format;
8561 format = undefined;
8562 }
8563
8564 format = format || '';
8565 }
8566
8567 var locale = getLocale(),
8568 shift = localeSorted ? locale._week.dow : 0;
8569
8570 if (index != null) {
8571 return get$1(format, (index + shift) % 7, field, 'day');
8572 }
8573
8574 var i;
8575 var out = [];
8576
8577 for (i = 0; i < 7; i++) {
8578 out[i] = get$1(format, (i + shift) % 7, field, 'day');
8579 }
8580
8581 return out;
8582 }
8583
8584 function listMonths(format, index) {
8585 return listMonthsImpl(format, index, 'months');
8586 }
8587
8588 function listMonthsShort(format, index) {
8589 return listMonthsImpl(format, index, 'monthsShort');
8590 }
8591
8592 function listWeekdays(localeSorted, format, index) {
8593 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
8594 }
8595
8596 function listWeekdaysShort(localeSorted, format, index) {
8597 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
8598 }
8599
8600 function listWeekdaysMin(localeSorted, format, index) {
8601 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
8602 }
8603
8604 getSetGlobalLocale('en', {
8605 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
8606 ordinal: function ordinal(number) {
8607 var b = number % 10,
8608 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
8609 return number + output;
8610 }
8611 }); // Side effect imports
8612
8613 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
8614 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
8615 var mathAbs = Math.abs;
8616
8617 function abs() {
8618 var data = this._data;
8619 this._milliseconds = mathAbs(this._milliseconds);
8620 this._days = mathAbs(this._days);
8621 this._months = mathAbs(this._months);
8622 data.milliseconds = mathAbs(data.milliseconds);
8623 data.seconds = mathAbs(data.seconds);
8624 data.minutes = mathAbs(data.minutes);
8625 data.hours = mathAbs(data.hours);
8626 data.months = mathAbs(data.months);
8627 data.years = mathAbs(data.years);
8628 return this;
8629 }
8630
8631 function addSubtract$1(duration, input, value, direction) {
8632 var other = createDuration(input, value);
8633 duration._milliseconds += direction * other._milliseconds;
8634 duration._days += direction * other._days;
8635 duration._months += direction * other._months;
8636 return duration._bubble();
8637 } // supports only 2.0-style add(1, 's') or add(duration)
8638
8639
8640 function add$1(input, value) {
8641 return addSubtract$1(this, input, value, 1);
8642 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
8643
8644
8645 function subtract$1(input, value) {
8646 return addSubtract$1(this, input, value, -1);
8647 }
8648
8649 function absCeil(number) {
8650 if (number < 0) {
8651 return Math.floor(number);
8652 } else {
8653 return Math.ceil(number);
8654 }
8655 }
8656
8657 function bubble() {
8658 var milliseconds = this._milliseconds;
8659 var days = this._days;
8660 var months = this._months;
8661 var data = this._data;
8662 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
8663 // check: https://github.com/moment/moment/issues/2166
8664
8665 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
8666 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
8667 days = 0;
8668 months = 0;
8669 } // The following code bubbles up values, see the tests for
8670 // examples of what that means.
8671
8672
8673 data.milliseconds = milliseconds % 1000;
8674 seconds = absFloor(milliseconds / 1000);
8675 data.seconds = seconds % 60;
8676 minutes = absFloor(seconds / 60);
8677 data.minutes = minutes % 60;
8678 hours = absFloor(minutes / 60);
8679 data.hours = hours % 24;
8680 days += absFloor(hours / 24); // convert days to months
8681
8682 monthsFromDays = absFloor(daysToMonths(days));
8683 months += monthsFromDays;
8684 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
8685
8686 years = absFloor(months / 12);
8687 months %= 12;
8688 data.days = days;
8689 data.months = months;
8690 data.years = years;
8691 return this;
8692 }
8693
8694 function daysToMonths(days) {
8695 // 400 years have 146097 days (taking into account leap year rules)
8696 // 400 years have 12 months === 4800
8697 return days * 4800 / 146097;
8698 }
8699
8700 function monthsToDays(months) {
8701 // the reverse of daysToMonths
8702 return months * 146097 / 4800;
8703 }
8704
8705 function as(units) {
8706 if (!this.isValid()) {
8707 return NaN;
8708 }
8709
8710 var days;
8711 var months;
8712 var milliseconds = this._milliseconds;
8713 units = normalizeUnits(units);
8714
8715 if (units === 'month' || units === 'quarter' || units === 'year') {
8716 days = this._days + milliseconds / 864e5;
8717 months = this._months + daysToMonths(days);
8718
8719 switch (units) {
8720 case 'month':
8721 return months;
8722
8723 case 'quarter':
8724 return months / 3;
8725
8726 case 'year':
8727 return months / 12;
8728 }
8729 } else {
8730 // handle milliseconds separately because of floating point math errors (issue #1867)
8731 days = this._days + Math.round(monthsToDays(this._months));
8732
8733 switch (units) {
8734 case 'week':
8735 return days / 7 + milliseconds / 6048e5;
8736
8737 case 'day':
8738 return days + milliseconds / 864e5;
8739
8740 case 'hour':
8741 return days * 24 + milliseconds / 36e5;
8742
8743 case 'minute':
8744 return days * 1440 + milliseconds / 6e4;
8745
8746 case 'second':
8747 return days * 86400 + milliseconds / 1000;
8748 // Math.floor prevents floating point math errors here
8749
8750 case 'millisecond':
8751 return Math.floor(days * 864e5) + milliseconds;
8752
8753 default:
8754 throw new Error('Unknown unit ' + units);
8755 }
8756 }
8757 } // TODO: Use this.as('ms')?
8758
8759
8760 function valueOf$1() {
8761 if (!this.isValid()) {
8762 return NaN;
8763 }
8764
8765 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
8766 }
8767
8768 function makeAs(alias) {
8769 return function () {
8770 return this.as(alias);
8771 };
8772 }
8773
8774 var asMilliseconds = makeAs('ms');
8775 var asSeconds = makeAs('s');
8776 var asMinutes = makeAs('m');
8777 var asHours = makeAs('h');
8778 var asDays = makeAs('d');
8779 var asWeeks = makeAs('w');
8780 var asMonths = makeAs('M');
8781 var asQuarters = makeAs('Q');
8782 var asYears = makeAs('y');
8783
8784 function clone$1() {
8785 return createDuration(this);
8786 }
8787
8788 function get$2(units) {
8789 units = normalizeUnits(units);
8790 return this.isValid() ? this[units + 's']() : NaN;
8791 }
8792
8793 function makeGetter(name) {
8794 return function () {
8795 return this.isValid() ? this._data[name] : NaN;
8796 };
8797 }
8798
8799 var milliseconds = makeGetter('milliseconds');
8800 var seconds = makeGetter('seconds');
8801 var minutes = makeGetter('minutes');
8802 var hours = makeGetter('hours');
8803 var days = makeGetter('days');
8804 var months = makeGetter('months');
8805 var years = makeGetter('years');
8806
8807 function weeks() {
8808 return absFloor(this.days() / 7);
8809 }
8810
8811 var round = Math.round;
8812 var thresholds = {
8813 ss: 44,
8814 // a few seconds to seconds
8815 s: 45,
8816 // seconds to minute
8817 m: 45,
8818 // minutes to hour
8819 h: 22,
8820 // hours to day
8821 d: 26,
8822 // days to month
8823 M: 11 // months to year
8824
8825 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
8826
8827 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
8828 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
8829 }
8830
8831 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
8832 var duration = createDuration(posNegDuration).abs();
8833 var seconds = round(duration.as('s'));
8834 var minutes = round(duration.as('m'));
8835 var hours = round(duration.as('h'));
8836 var days = round(duration.as('d'));
8837 var months = round(duration.as('M'));
8838 var years = round(duration.as('y'));
8839 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];
8840 a[2] = withoutSuffix;
8841 a[3] = +posNegDuration > 0;
8842 a[4] = locale;
8843 return substituteTimeAgo.apply(null, a);
8844 } // This function allows you to set the rounding function for relative time strings
8845
8846
8847 function getSetRelativeTimeRounding(roundingFunction) {
8848 if (roundingFunction === undefined) {
8849 return round;
8850 }
8851
8852 if (typeof roundingFunction === 'function') {
8853 round = roundingFunction;
8854 return true;
8855 }
8856
8857 return false;
8858 } // This function allows you to set a threshold for relative time strings
8859
8860
8861 function getSetRelativeTimeThreshold(threshold, limit) {
8862 if (thresholds[threshold] === undefined) {
8863 return false;
8864 }
8865
8866 if (limit === undefined) {
8867 return thresholds[threshold];
8868 }
8869
8870 thresholds[threshold] = limit;
8871
8872 if (threshold === 's') {
8873 thresholds.ss = limit - 1;
8874 }
8875
8876 return true;
8877 }
8878
8879 function humanize(withSuffix) {
8880 if (!this.isValid()) {
8881 return this.localeData().invalidDate();
8882 }
8883
8884 var locale = this.localeData();
8885 var output = relativeTime$1(this, !withSuffix, locale);
8886
8887 if (withSuffix) {
8888 output = locale.pastFuture(+this, output);
8889 }
8890
8891 return locale.postformat(output);
8892 }
8893
8894 var abs$1 = Math.abs;
8895
8896 function sign(x) {
8897 return (x > 0) - (x < 0) || +x;
8898 }
8899
8900 function toISOString$1() {
8901 // for ISO strings we do not use the normal bubbling rules:
8902 // * milliseconds bubble up until they become hours
8903 // * days do not bubble at all
8904 // * months bubble up until they become years
8905 // This is because there is no context-free conversion between hours and days
8906 // (think of clock changes)
8907 // and also not between days and months (28-31 days per month)
8908 if (!this.isValid()) {
8909 return this.localeData().invalidDate();
8910 }
8911
8912 var seconds = abs$1(this._milliseconds) / 1000;
8913 var days = abs$1(this._days);
8914 var months = abs$1(this._months);
8915 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
8916
8917 minutes = absFloor(seconds / 60);
8918 hours = absFloor(minutes / 60);
8919 seconds %= 60;
8920 minutes %= 60; // 12 months -> 1 year
8921
8922 years = absFloor(months / 12);
8923 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
8924
8925 var Y = years;
8926 var M = months;
8927 var D = days;
8928 var h = hours;
8929 var m = minutes;
8930 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
8931 var total = this.asSeconds();
8932
8933 if (!total) {
8934 // this is the same as C#'s (Noda) and python (isodate)...
8935 // but not other JS (goog.date)
8936 return 'P0D';
8937 }
8938
8939 var totalSign = total < 0 ? '-' : '';
8940 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
8941 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
8942 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
8943 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' : '');
8944 }
8945
8946 var proto$2 = Duration.prototype;
8947 proto$2.isValid = isValid$1;
8948 proto$2.abs = abs;
8949 proto$2.add = add$1;
8950 proto$2.subtract = subtract$1;
8951 proto$2.as = as;
8952 proto$2.asMilliseconds = asMilliseconds;
8953 proto$2.asSeconds = asSeconds;
8954 proto$2.asMinutes = asMinutes;
8955 proto$2.asHours = asHours;
8956 proto$2.asDays = asDays;
8957 proto$2.asWeeks = asWeeks;
8958 proto$2.asMonths = asMonths;
8959 proto$2.asQuarters = asQuarters;
8960 proto$2.asYears = asYears;
8961 proto$2.valueOf = valueOf$1;
8962 proto$2._bubble = bubble;
8963 proto$2.clone = clone$1;
8964 proto$2.get = get$2;
8965 proto$2.milliseconds = milliseconds;
8966 proto$2.seconds = seconds;
8967 proto$2.minutes = minutes;
8968 proto$2.hours = hours;
8969 proto$2.days = days;
8970 proto$2.weeks = weeks;
8971 proto$2.months = months;
8972 proto$2.years = years;
8973 proto$2.humanize = humanize;
8974 proto$2.toISOString = toISOString$1;
8975 proto$2.toString = toISOString$1;
8976 proto$2.toJSON = toISOString$1;
8977 proto$2.locale = locale;
8978 proto$2.localeData = localeData;
8979 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
8980 proto$2.lang = lang; // Side effect imports
8981 // FORMATTING
8982
8983 addFormatToken('X', 0, 0, 'unix');
8984 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
8985
8986 addRegexToken('x', matchSigned);
8987 addRegexToken('X', matchTimestamp);
8988 addParseToken('X', function (input, array, config) {
8989 config._d = new Date(parseFloat(input, 10) * 1000);
8990 });
8991 addParseToken('x', function (input, array, config) {
8992 config._d = new Date(toInt(input));
8993 }); // Side effect imports
8994
8995 hooks.version = '2.24.0';
8996 setHookCallback(createLocal);
8997 hooks.fn = proto;
8998 hooks.min = min;
8999 hooks.max = max;
9000 hooks.now = now;
9001 hooks.utc = createUTC;
9002 hooks.unix = createUnix;
9003 hooks.months = listMonths;
9004 hooks.isDate = isDate;
9005 hooks.locale = getSetGlobalLocale;
9006 hooks.invalid = createInvalid;
9007 hooks.duration = createDuration;
9008 hooks.isMoment = isMoment;
9009 hooks.weekdays = listWeekdays;
9010 hooks.parseZone = createInZone;
9011 hooks.localeData = getLocale;
9012 hooks.isDuration = isDuration;
9013 hooks.monthsShort = listMonthsShort;
9014 hooks.weekdaysMin = listWeekdaysMin;
9015 hooks.defineLocale = defineLocale;
9016 hooks.updateLocale = updateLocale;
9017 hooks.locales = listLocales;
9018 hooks.weekdaysShort = listWeekdaysShort;
9019 hooks.normalizeUnits = normalizeUnits;
9020 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
9021 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
9022 hooks.calendarFormat = getCalendarFormat;
9023 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
9024
9025 hooks.HTML5_FMT = {
9026 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
9027 // <input type="datetime-local" />
9028 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
9029 // <input type="datetime-local" step="1" />
9030 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
9031 // <input type="datetime-local" step="0.001" />
9032 DATE: 'YYYY-MM-DD',
9033 // <input type="date" />
9034 TIME: 'HH:mm',
9035 // <input type="time" />
9036 TIME_SECONDS: 'HH:mm:ss',
9037 // <input type="time" step="1" />
9038 TIME_MS: 'HH:mm:ss.SSS',
9039 // <input type="time" step="0.001" />
9040 WEEK: 'GGGG-[W]WW',
9041 // <input type="week" />
9042 MONTH: 'YYYY-MM' // <input type="month" />
9043
9044 };
9045 return hooks;
9046 });
9047}); // Maps for number <-> hex string conversion
9048
9049var byteToHex = [];
9050
9051for (var i = 0; i < 256; i++) {
9052 byteToHex[i] = (i + 0x100).toString(16).substr(1);
9053}
9054/**
9055 * Represent binary UUID into it's string representation.
9056 *
9057 * @param buf - Buffer containing UUID bytes.
9058 * @param offset - Offset from the start of the buffer where the UUID is saved (not needed if the buffer starts with the UUID).
9059 *
9060 * @returns String representation of the UUID.
9061 */
9062
9063
9064function stringifyUUID(buf, offset) {
9065 var i = offset || 0;
9066 var bth = byteToHex;
9067 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++]];
9068}
9069/**
9070 * Generate 16 random bytes to be used as a base for UUID.
9071 *
9072 * @ignore
9073 */
9074
9075
9076var random = function () {
9077 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
9078 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
9079 // Moderately fast, high quality
9080 var _rnds8 = new Uint8Array(16);
9081
9082 return function whatwgRNG() {
9083 crypto.getRandomValues(_rnds8);
9084 return _rnds8;
9085 };
9086 } // Math.random()-based (RNG)
9087 //
9088 // If all else fails, use Math.random().
9089 // It's fast, but is of unspecified quality.
9090
9091
9092 var _rnds = new Array(16);
9093
9094 return function () {
9095 for (var i = 0, r; i < 16; i++) {
9096 if ((i & 0x03) === 0) {
9097 r = Math.random() * 0x100000000;
9098 }
9099
9100 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
9101 }
9102
9103 return _rnds;
9104 }; // uuid.js
9105 //
9106 // Copyright (c) 2010-2012 Robert Kieffer
9107 // MIT License - http://opensource.org/licenses/mit-license.php
9108 // Unique ID creation requires a high quality random # generator. We feature
9109 // detect to determine the best RNG source, normalizing to a function that
9110 // returns 128-bits of randomness, since that's what's usually required
9111 // return require('./rng');
9112}();
9113
9114var byteToHex$1 = [];
9115
9116for (var i$1 = 0; i$1 < 256; i$1++) {
9117 byteToHex$1[i$1] = (i$1 + 0x100).toString(16).substr(1);
9118} // **`v1()` - Generate time-based UUID**
9119//
9120// Inspired by https://github.com/LiosK/UUID.js
9121// and http://docs.python.org/library/uuid.html
9122// random #'s we need to init node and clockseq
9123
9124
9125var seedBytes = random(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
9126
9127var defaultNodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; // Per 4.2.2, randomize (14 bit) clockseq
9128
9129var defaultClockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; // Previous uuid creation time
9130
9131/**
9132 * UUIDv4 options.
9133 */
9134
9135/**
9136 * Generate UUIDv4
9137 *
9138 * @param options - Options to be used instead of default generated values.
9139 * String 'binary' is a shorthand for uuid4({}, new Array(16)).
9140 * @param buf - If present the buffer will be filled with the generated UUID.
9141 * @param offset - Offset of the UUID from the start of the buffer.
9142 *
9143 * @returns UUIDv4
9144 */
9145
9146function uuid4() {
9147 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
9148 var buf = arguments.length > 1 ? arguments[1] : undefined;
9149 var offset = arguments.length > 2 ? arguments[2] : undefined; // Deprecated - 'format' argument, as supported in v1.2
9150
9151 var i = buf && offset || 0;
9152
9153 if (typeof options === 'string') {
9154 buf = options === 'binary' ? new Array(16) : undefined;
9155 options = {};
9156 }
9157
9158 var rnds = options.random || (options.rng || random)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
9159
9160 rnds[6] = rnds[6] & 0x0f | 0x40;
9161 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
9162
9163 if (buf) {
9164 for (var ii = 0; ii < 16; ii++) {
9165 buf[i + ii] = rnds[ii];
9166 }
9167 }
9168
9169 return buf || stringifyUUID(rnds);
9170} // Rollup will complain about mixing default and named exports in UMD build,
9171
9172
9173function ownKeys$1(object, enumerableOnly) {
9174 var keys = Object.keys(object);
9175
9176 if (Object.getOwnPropertySymbols) {
9177 keys.push.apply(keys, Object.getOwnPropertySymbols(object));
9178 }
9179
9180 if (enumerableOnly) keys = keys.filter(function (sym) {
9181 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
9182 });
9183 return keys;
9184}
9185
9186function _objectSpread(target) {
9187 for (var i = 1; i < arguments.length; i++) {
9188 var source = arguments[i] != null ? arguments[i] : {};
9189
9190 if (i % 2) {
9191 ownKeys$1(source, true).forEach(function (key) {
9192 defineProperty$7(target, key, source[key]);
9193 });
9194 } else if (Object.getOwnPropertyDescriptors) {
9195 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
9196 } else {
9197 ownKeys$1(source).forEach(function (key) {
9198 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
9199 });
9200 }
9201 }
9202
9203 return target;
9204} // for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
9205// code from http://momentjs.com/
9206
9207
9208var ASPDateRegex = /^\/?Date\((-?\d+)/i; // Hex color
9209
9210var fullHexRE = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
9211var shortHexRE = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
9212/**
9213 * Hue, Saturation, Value.
9214 */
9215
9216/**
9217 * Test whether given object is a number
9218 *
9219 * @param value - Input value of unknown type.
9220 *
9221 * @returns True if number, false otherwise.
9222 */
9223
9224function isNumber(value) {
9225 return value instanceof Number || typeof value === 'number';
9226}
9227/**
9228 * Remove everything in the DOM object
9229 *
9230 * @param DOMobject - Node whose child nodes will be recursively deleted.
9231 */
9232
9233
9234function recursiveDOMDelete(DOMobject) {
9235 if (DOMobject) {
9236 while (DOMobject.hasChildNodes() === true) {
9237 var child = DOMobject.firstChild;
9238
9239 if (child) {
9240 recursiveDOMDelete(child);
9241 DOMobject.removeChild(child);
9242 }
9243 }
9244 }
9245}
9246/**
9247 * Test whether given object is a string
9248 *
9249 * @param value - Input value of unknown type.
9250 *
9251 * @returns True if string, false otherwise.
9252 */
9253
9254
9255function isString(value) {
9256 return value instanceof String || typeof value === 'string';
9257}
9258/**
9259 * Test whether given object is a object (not primitive or null).
9260 *
9261 * @param value - Input value of unknown type.
9262 *
9263 * @returns True if not null object, false otherwise.
9264 */
9265
9266
9267function isObject$1(value) {
9268 return _typeof_1(value) === 'object' && value !== null;
9269}
9270/**
9271 * Test whether given object is a Date, or a String containing a Date
9272 *
9273 * @param value - Input value of unknown type.
9274 *
9275 * @returns True if Date instance or string date representation, false otherwise.
9276 */
9277
9278
9279function isDate(value) {
9280 if (value instanceof Date) {
9281 return true;
9282 } else if (isString(value)) {
9283 // test whether this string contains a date
9284 var match = ASPDateRegex.exec(value);
9285
9286 if (match) {
9287 return true;
9288 } else if (!isNaN(Date.parse(value))) {
9289 return true;
9290 }
9291 }
9292
9293 return false;
9294}
9295/**
9296 * Test whether given object is a Moment date.
9297 * @TODO: This is basically a workaround, if Moment was imported property it wouldn't necessary as moment.isMoment is a TS type guard.
9298 *
9299 * @param value - Input value of unknown type.
9300 *
9301 * @returns True if Moment instance, false otherwise.
9302 */
9303
9304
9305function isMoment(value) {
9306 return moment.isMoment(value);
9307}
9308/**
9309 * Copy property from b to a if property present in a.
9310 * If property in b explicitly set to null, delete it if `allowDeletion` set.
9311 *
9312 * Internal helper routine, should not be exported. Not added to `exports` for that reason.
9313 *
9314 * @param a - Target object.
9315 * @param b - Source object.
9316 * @param prop - Name of property to copy from b to a.
9317 * @param allowDeletion if true, delete property in a if explicitly set to null in b
9318 */
9319
9320
9321function copyOrDelete(a, b, prop, allowDeletion) {
9322 var doDeletion = false;
9323
9324 if (allowDeletion === true) {
9325 doDeletion = b[prop] === null && a[prop] !== undefined;
9326 }
9327
9328 if (doDeletion) {
9329 delete a[prop];
9330 } else {
9331 a[prop] = b[prop]; // Remember, this is a reference copy!
9332 }
9333}
9334/**
9335 * Fill an object with a possibly partially defined other object.
9336 *
9337 * Only copies values for the properties already present in a.
9338 * That means an object is not created on a property if only the b object has it.
9339 *
9340 * @param a - The object that will have it's properties updated.
9341 * @param b - The object with property updates.
9342 * @param allowDeletion - if true, delete properties in a that are explicitly set to null in b
9343 */
9344
9345
9346function fillIfDefined(a, b) {
9347 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; // NOTE: iteration of properties of a
9348 // NOTE: prototype properties iterated over as well
9349
9350 for (var prop in a) {
9351 if (b[prop] !== undefined) {
9352 if (b[prop] === null || _typeof_1(b[prop]) !== 'object') {
9353 // Note: typeof null === 'object'
9354 copyOrDelete(a, b, prop, allowDeletion);
9355 } else {
9356 var aProp = a[prop];
9357 var bProp = b[prop];
9358
9359 if (isObject$1(aProp) && isObject$1(bProp)) {
9360 fillIfDefined(aProp, bProp, allowDeletion);
9361 }
9362 }
9363 }
9364 }
9365}
9366/**
9367 * Copy the values of all of the enumerable own properties from one or more source objects to a
9368 * target object. Returns the target object.
9369 *
9370 * @param target - The target object to copy to.
9371 * @param source - The source object from which to copy properties.
9372 *
9373 * @return The target object.
9374 */
9375
9376
9377var extend = Object.assign;
9378/**
9379 * Extend object a with selected properties of object b or a series of objects
9380 * Only properties with defined values are copied
9381 *
9382 * @param props - Properties to be copied to a.
9383 * @param a - The target.
9384 * @param others - The sources.
9385 *
9386 * @returns Argument a.
9387 */
9388
9389function selectiveExtend(props, a) {
9390 if (!Array.isArray(props)) {
9391 throw new Error('Array with property names expected as first argument');
9392 }
9393
9394 for (var _len = arguments.length, others = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
9395 others[_key - 2] = arguments[_key];
9396 }
9397
9398 for (var _i = 0, _others = others; _i < _others.length; _i++) {
9399 var other = _others[_i];
9400
9401 for (var p = 0; p < props.length; p++) {
9402 var prop = props[p];
9403
9404 if (other && Object.prototype.hasOwnProperty.call(other, prop)) {
9405 a[prop] = other[prop];
9406 }
9407 }
9408 }
9409
9410 return a;
9411}
9412/**
9413 * Extend object a with selected properties of object b.
9414 * Only properties with defined values are copied.
9415 *
9416 * **Note:** Previous version of this routine implied that multiple source objects
9417 * could be used; however, the implementation was **wrong**.
9418 * Since multiple (>1) sources weren't used anywhere in the `vis.js` code,
9419 * this has been removed
9420 *
9421 * @param props - Names of first-level properties to copy over.
9422 * @param a - Target object.
9423 * @param b - Source object.
9424 * @param allowDeletion - If true, delete property in a if explicitly set to null in b.
9425 *
9426 * @returns Argument a.
9427 */
9428
9429
9430function selectiveDeepExtend(props, a, b) {
9431 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TODO: add support for Arrays to deepExtend
9432
9433 if (Array.isArray(b)) {
9434 throw new TypeError('Arrays are not supported by deepExtend');
9435 }
9436
9437 for (var p = 0; p < props.length; p++) {
9438 var prop = props[p];
9439
9440 if (Object.prototype.hasOwnProperty.call(b, prop)) {
9441 if (b[prop] && b[prop].constructor === Object) {
9442 if (a[prop] === undefined) {
9443 a[prop] = {};
9444 }
9445
9446 if (a[prop].constructor === Object) {
9447 deepExtend(a[prop], b[prop], false, allowDeletion);
9448 } else {
9449 copyOrDelete(a, b, prop, allowDeletion);
9450 }
9451 } else if (Array.isArray(b[prop])) {
9452 throw new TypeError('Arrays are not supported by deepExtend');
9453 } else {
9454 copyOrDelete(a, b, prop, allowDeletion);
9455 }
9456 }
9457 }
9458
9459 return a;
9460}
9461/**
9462 * Extend object `a` with properties of object `b`, ignoring properties which are explicitly
9463 * specified to be excluded.
9464 *
9465 * The properties of `b` are considered for copying.
9466 * Properties which are themselves objects are are also extended.
9467 * Only properties with defined values are copied
9468 *
9469 * @param propsToExclude - Names of properties which should *not* be copied.
9470 * @param a - Object to extend.
9471 * @param b - Object to take properties from for extension.
9472 * @param allowDeletion - If true, delete properties in a that are explicitly set to null in b.
9473 *
9474 * @returns Argument a.
9475 */
9476
9477
9478function selectiveNotDeepExtend(propsToExclude, a, b) {
9479 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TODO: add support for Arrays to deepExtend
9480 // NOTE: array properties have an else-below; apparently, there is a problem here.
9481
9482 if (Array.isArray(b)) {
9483 throw new TypeError('Arrays are not supported by deepExtend');
9484 }
9485
9486 for (var prop in b) {
9487 if (!Object.prototype.hasOwnProperty.call(b, prop)) {
9488 continue;
9489 } // Handle local properties only
9490
9491
9492 if (propsToExclude.indexOf(prop) !== -1) {
9493 continue;
9494 } // In exclusion list, skip
9495
9496
9497 if (b[prop] && b[prop].constructor === Object) {
9498 if (a[prop] === undefined) {
9499 a[prop] = {};
9500 }
9501
9502 if (a[prop].constructor === Object) {
9503 deepExtend(a[prop], b[prop]); // NOTE: allowDeletion not propagated!
9504 } else {
9505 copyOrDelete(a, b, prop, allowDeletion);
9506 }
9507 } else if (Array.isArray(b[prop])) {
9508 a[prop] = [];
9509
9510 for (var i = 0; i < b[prop].length; i++) {
9511 a[prop].push(b[prop][i]);
9512 }
9513 } else {
9514 copyOrDelete(a, b, prop, allowDeletion);
9515 }
9516 }
9517
9518 return a;
9519}
9520/**
9521 * Deep extend an object a with the properties of object b
9522 *
9523 * @param a - Target object.
9524 * @param b - Source object.
9525 * @param protoExtend - If true, the prototype values will also be extended
9526 * (ie. the options objects that inherit from others will also get the inherited options).
9527 * @param allowDeletion - If true, the values of fields that are null will be deleted.
9528 *
9529 * @returns Argument a.
9530 */
9531
9532
9533function deepExtend(a, b) {
9534 var protoExtend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
9535 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
9536
9537 for (var prop in b) {
9538 if (Object.prototype.hasOwnProperty.call(b, prop) || protoExtend === true) {
9539 if (b[prop] && b[prop].constructor === Object) {
9540 if (a[prop] === undefined) {
9541 a[prop] = {};
9542 }
9543
9544 if (a[prop].constructor === Object) {
9545 deepExtend(a[prop], b[prop], protoExtend); // NOTE: allowDeletion not propagated!
9546 } else {
9547 copyOrDelete(a, b, prop, allowDeletion);
9548 }
9549 } else if (Array.isArray(b[prop])) {
9550 a[prop] = [];
9551
9552 for (var i = 0; i < b[prop].length; i++) {
9553 a[prop].push(b[prop][i]);
9554 }
9555 } else {
9556 copyOrDelete(a, b, prop, allowDeletion);
9557 }
9558 }
9559 }
9560
9561 return a;
9562}
9563/**
9564 * Test whether all elements in two arrays are equal.
9565 *
9566 * @param a - First array.
9567 * @param b - Second array.
9568 *
9569 * @returns True if both arrays have the same length and same elements (1 = '1').
9570 */
9571
9572
9573function equalArray(a, b) {
9574 if (a.length !== b.length) {
9575 return false;
9576 }
9577
9578 for (var i = 0, len = a.length; i < len; i++) {
9579 if (a[i] != b[i]) {
9580 return false;
9581 }
9582 }
9583
9584 return true;
9585}
9586/**
9587 * Convert an object into another type
9588 *
9589 * @param object - Value of unknown type.
9590 * @param type - Name of the desired type.
9591 *
9592 * @returns Object in the desired type.
9593 * @throws Error
9594 */
9595
9596
9597function convert(object, type) {
9598 var match;
9599
9600 if (object === undefined) {
9601 return undefined;
9602 }
9603
9604 if (object === null) {
9605 return null;
9606 }
9607
9608 if (!type) {
9609 return object;
9610 }
9611
9612 if (!(typeof type === 'string') && !(type instanceof String)) {
9613 throw new Error('Type must be a string');
9614 } //noinspection FallthroughInSwitchStatementJS
9615
9616
9617 switch (type) {
9618 case 'boolean':
9619 case 'Boolean':
9620 return Boolean(object);
9621
9622 case 'number':
9623 case 'Number':
9624 if (isString(object) && !isNaN(Date.parse(object))) {
9625 return moment(object).valueOf();
9626 } else {
9627 // @TODO: I don't think that Number and String constructors are a good idea.
9628 // This could also fail if the object doesn't have valueOf method or if it's redefined.
9629 // For example: Object.create(null) or { valueOf: 7 }.
9630 return Number(object.valueOf());
9631 }
9632
9633 case 'string':
9634 case 'String':
9635 return String(object);
9636
9637 case 'Date':
9638 if (isNumber(object)) {
9639 return new Date(object);
9640 }
9641
9642 if (object instanceof Date) {
9643 return new Date(object.valueOf());
9644 } else if (isMoment(object)) {
9645 return new Date(object.valueOf());
9646 }
9647
9648 if (isString(object)) {
9649 match = ASPDateRegex.exec(object);
9650
9651 if (match) {
9652 // object is an ASP date
9653 return new Date(Number(match[1])); // parse number
9654 } else {
9655 return moment(new Date(object)).toDate(); // parse string
9656 }
9657 } else {
9658 throw new Error('Cannot convert object of type ' + getType(object) + ' to type Date');
9659 }
9660
9661 case 'Moment':
9662 if (isNumber(object)) {
9663 return moment(object);
9664 }
9665
9666 if (object instanceof Date) {
9667 return moment(object.valueOf());
9668 } else if (isMoment(object)) {
9669 return moment(object);
9670 }
9671
9672 if (isString(object)) {
9673 match = ASPDateRegex.exec(object);
9674
9675 if (match) {
9676 // object is an ASP date
9677 return moment(Number(match[1])); // parse number
9678 } else {
9679 return moment(object); // parse string
9680 }
9681 } else {
9682 throw new Error('Cannot convert object of type ' + getType(object) + ' to type Date');
9683 }
9684
9685 case 'ISODate':
9686 if (isNumber(object)) {
9687 return new Date(object);
9688 } else if (object instanceof Date) {
9689 return object.toISOString();
9690 } else if (isMoment(object)) {
9691 return object.toDate().toISOString();
9692 } else if (isString(object)) {
9693 match = ASPDateRegex.exec(object);
9694
9695 if (match) {
9696 // object is an ASP date
9697 return new Date(Number(match[1])).toISOString(); // parse number
9698 } else {
9699 return moment(object).format(); // ISO 8601
9700 }
9701 } else {
9702 throw new Error('Cannot convert object of type ' + getType(object) + ' to type ISODate');
9703 }
9704
9705 case 'ASPDate':
9706 if (isNumber(object)) {
9707 return '/Date(' + object + ')/';
9708 } else if (object instanceof Date || isMoment(object)) {
9709 return '/Date(' + object.valueOf() + ')/';
9710 } else if (isString(object)) {
9711 match = ASPDateRegex.exec(object);
9712
9713 var _value;
9714
9715 if (match) {
9716 // object is an ASP date
9717 _value = new Date(Number(match[1])).valueOf(); // parse number
9718 } else {
9719 _value = new Date(object).valueOf(); // parse string
9720 }
9721
9722 return '/Date(' + _value + ')/';
9723 } else {
9724 throw new Error('Cannot convert object of type ' + getType(object) + ' to type ASPDate');
9725 }
9726
9727 default:
9728 var never = type;
9729 throw new Error("Unknown type ".concat(never));
9730 }
9731}
9732/**
9733 * Get the type of an object, for example exports.getType([]) returns 'Array'
9734 *
9735 * @param object - Input value of unknown type.
9736 *
9737 * @returns Detected type.
9738 */
9739
9740
9741function getType(object) {
9742 var type = _typeof_1(object);
9743
9744 if (type === 'object') {
9745 if (object === null) {
9746 return 'null';
9747 }
9748
9749 if (object instanceof Boolean) {
9750 return 'Boolean';
9751 }
9752
9753 if (object instanceof Number) {
9754 return 'Number';
9755 }
9756
9757 if (object instanceof String) {
9758 return 'String';
9759 }
9760
9761 if (Array.isArray(object)) {
9762 return 'Array';
9763 }
9764
9765 if (object instanceof Date) {
9766 return 'Date';
9767 }
9768
9769 return 'Object';
9770 }
9771
9772 if (type === 'number') {
9773 return 'Number';
9774 }
9775
9776 if (type === 'boolean') {
9777 return 'Boolean';
9778 }
9779
9780 if (type === 'string') {
9781 return 'String';
9782 }
9783
9784 if (type === undefined) {
9785 return 'undefined';
9786 }
9787
9788 return type;
9789}
9790/**
9791 * Used to extend an array and copy it. This is used to propagate paths recursively.
9792 *
9793 * @param arr - First part.
9794 * @param newValue - The value to be aadded into the array.
9795 *
9796 * @returns A new array with all items from arr and newValue (which is last).
9797 */
9798
9799
9800function copyAndExtendArray(arr, newValue) {
9801 return [].concat(toConsumableArray(arr), [newValue]);
9802}
9803/**
9804 * Used to extend an array and copy it. This is used to propagate paths recursively.
9805 *
9806 * @param arr - The array to be copied.
9807 *
9808 * @returns Shallow copy of arr.
9809 */
9810
9811
9812function copyArray(arr) {
9813 return arr.slice();
9814}
9815/**
9816 * Retrieve the absolute left value of a DOM element
9817 *
9818 * @param elem - A dom element, for example a div.
9819 *
9820 * @returns The absolute left position of this element in the browser page.
9821 */
9822
9823
9824function getAbsoluteLeft(elem) {
9825 return elem.getBoundingClientRect().left;
9826}
9827/**
9828 * Retrieve the absolute right value of a DOM element
9829 *
9830 * @param elem - A dom element, for example a div.
9831 *
9832 * @returns The absolute right position of this element in the browser page.
9833 */
9834
9835
9836function getAbsoluteRight(elem) {
9837 return elem.getBoundingClientRect().right;
9838}
9839/**
9840 * Retrieve the absolute top value of a DOM element
9841 *
9842 * @param elem - A dom element, for example a div.
9843 *
9844 * @returns The absolute top position of this element in the browser page.
9845 */
9846
9847
9848function getAbsoluteTop(elem) {
9849 return elem.getBoundingClientRect().top;
9850}
9851/**
9852 * Add a className to the given elements style.
9853 *
9854 * @param elem - The element to which the classes will be added.
9855 * @param classNames - Space separated list of classes.
9856 */
9857
9858
9859function addClassName(elem, classNames) {
9860 var classes = elem.className.split(' ');
9861 var newClasses = classNames.split(' ');
9862 classes = classes.concat(newClasses.filter(function (className) {
9863 return classes.indexOf(className) < 0;
9864 }));
9865 elem.className = classes.join(' ');
9866}
9867/**
9868 * Remove a className from the given elements style.
9869 *
9870 * @param elem - The element from which the classes will be removed.
9871 * @param classNames - Space separated list of classes.
9872 */
9873
9874
9875function removeClassName(elem, classNames) {
9876 var classes = elem.className.split(' ');
9877 var oldClasses = classNames.split(' ');
9878 classes = classes.filter(function (className) {
9879 return oldClasses.indexOf(className) < 0;
9880 });
9881 elem.className = classes.join(' ');
9882}
9883/**
9884 * For each method for both arrays and objects.
9885 * In case of an array, the built-in Array.forEach() is applied (**No, it's not!**).
9886 * In case of an Object, the method loops over all properties of the object.
9887 *
9888 * @param object - An Object or Array to be iterated over.
9889 * @param callback - Array.forEach-like callback.
9890 */
9891
9892
9893function forEach(object, callback) {
9894 if (Array.isArray(object)) {
9895 // array
9896 var len = object.length;
9897
9898 for (var i = 0; i < len; i++) {
9899 callback(object[i], i, object);
9900 }
9901 } else {
9902 // object
9903 for (var _key2 in object) {
9904 if (Object.prototype.hasOwnProperty.call(object, _key2)) {
9905 callback(object[_key2], _key2, object);
9906 }
9907 }
9908 }
9909}
9910/**
9911 * Convert an object into an array: all objects properties are put into the array. The resulting array is unordered.
9912 *
9913 * @param o - Object that contains the properties and methods.
9914 *
9915 * @returns An array of unordered values.
9916 */
9917
9918
9919var toArray = Object.values;
9920/**
9921 * Update a property in an object
9922 *
9923 * @param object - The object whose property will be updated.
9924 * @param key - Name of the property to be updated.
9925 * @param value - The new value to be assigned.
9926 *
9927 * @returns Whether the value was updated (true) or already strictly the same in the original object (false).
9928 */
9929
9930function updateProperty(object, key, value) {
9931 if (object[key] !== value) {
9932 object[key] = value;
9933 return true;
9934 } else {
9935 return false;
9936 }
9937}
9938/**
9939 * Throttle the given function to be only executed once per animation frame.
9940 *
9941 * @param fn - The original function.
9942 *
9943 * @returns The throttled function.
9944 */
9945
9946
9947function throttle(fn) {
9948 var scheduled = false;
9949 return function () {
9950 if (!scheduled) {
9951 scheduled = true;
9952 requestAnimationFrame(function () {
9953 scheduled = false;
9954 fn();
9955 });
9956 }
9957 };
9958}
9959/**
9960 * Add and event listener. Works for all browsers.
9961 *
9962 * @param element - The element to bind the event listener to.
9963 * @param action - Same as Element.addEventListener(action, —, —).
9964 * @param listener - Same as Element.addEventListener(—, listener, —).
9965 * @param useCapture - Same as Element.addEventListener(—, —, useCapture).
9966 */
9967
9968
9969function addEventListener(element, action, listener, useCapture) {
9970 if (element.addEventListener) {
9971 if (useCapture === undefined) {
9972 useCapture = false;
9973 }
9974
9975 if (action === 'mousewheel' && navigator.userAgent.indexOf('Firefox') >= 0) {
9976 action = 'DOMMouseScroll'; // For Firefox
9977 }
9978
9979 element.addEventListener(action, listener, useCapture);
9980 } else {
9981 element.attachEvent('on' + action, listener); // IE browsers
9982 }
9983}
9984/**
9985 * Remove an event listener from an element
9986 *
9987 * @param element - The element to bind the event listener to.
9988 * @param action - Same as Element.removeEventListener(action, —, —).
9989 * @param listener - Same as Element.removeEventListener(—, listener, —).
9990 * @param useCapture - Same as Element.removeEventListener(—, —, useCapture).
9991 */
9992
9993
9994function removeEventListener(element, action, listener, useCapture) {
9995 if (element.removeEventListener) {
9996 // non-IE browsers
9997 if (useCapture === undefined) {
9998 useCapture = false;
9999 }
10000
10001 if (action === 'mousewheel' && navigator.userAgent.indexOf('Firefox') >= 0) {
10002 action = 'DOMMouseScroll'; // For Firefox
10003 }
10004
10005 element.removeEventListener(action, listener, useCapture);
10006 } else {
10007 element.detachEvent('on' + action, listener); // IE browsers
10008 }
10009}
10010/**
10011 * Cancels the event's default action if it is cancelable, without stopping further propagation of the event.
10012 *
10013 * @param event - The event whose default action should be prevented.
10014 */
10015
10016
10017function preventDefault(event) {
10018 if (!event) {
10019 event = window.event;
10020 }
10021
10022 if (!event) ;else if (event.preventDefault) {
10023 event.preventDefault(); // non-IE browsers
10024 } else {
10025 event.returnValue = false; // IE browsers
10026 }
10027}
10028/**
10029 * Get HTML element which is the target of the event.
10030 *
10031 * @param event - The event.
10032 *
10033 * @returns The element or null if not obtainable.
10034 */
10035
10036
10037function getTarget() {
10038 var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.event; // code from http://www.quirksmode.org/js/events_properties.html
10039 // @TODO: EventTarget can be almost anything, is it okay to return only Elements?
10040
10041 var target = null;
10042 if (!event) ;else if (event.target) {
10043 target = event.target;
10044 } else if (event.srcElement) {
10045 target = event.srcElement;
10046 }
10047
10048 if (!(target instanceof Element)) {
10049 return null;
10050 }
10051
10052 if (target.nodeType != null && target.nodeType == 3) {
10053 // defeat Safari bug
10054 target = target.parentNode;
10055
10056 if (!(target instanceof Element)) {
10057 return null;
10058 }
10059 }
10060
10061 return target;
10062}
10063/**
10064 * Check if given element contains given parent somewhere in the DOM tree
10065 *
10066 * @param element - The element to be tested.
10067 * @param parent - The ancestor (not necessarily parent) of the element.
10068 *
10069 * @returns True if parent is an ancestor of the element, false otherwise.
10070 */
10071
10072
10073function hasParent(element, parent) {
10074 var elem = element;
10075
10076 while (elem) {
10077 if (elem === parent) {
10078 return true;
10079 } else if (elem.parentNode) {
10080 elem = elem.parentNode;
10081 } else {
10082 return false;
10083 }
10084 }
10085
10086 return false;
10087}
10088
10089var option = {
10090 /**
10091 * Convert a value into a boolean.
10092 *
10093 * @param value - Value to be converted intoboolean, a function will be executed as (() => unknown).
10094 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
10095 *
10096 * @returns Corresponding boolean value, if none then the default value, if none then null.
10097 */
10098 asBoolean: function asBoolean(value, defaultValue) {
10099 if (typeof value == 'function') {
10100 value = value();
10101 }
10102
10103 if (value != null) {
10104 return value != false;
10105 }
10106
10107 return defaultValue || null;
10108 },
10109
10110 /**
10111 * Convert a value into a number.
10112 *
10113 * @param value - Value to be converted intonumber, a function will be executed as (() => unknown).
10114 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
10115 *
10116 * @returns Corresponding **boxed** number value, if none then the default value, if none then null.
10117 */
10118 asNumber: function asNumber(value, defaultValue) {
10119 if (typeof value == 'function') {
10120 value = value();
10121 }
10122
10123 if (value != null) {
10124 return Number(value) || defaultValue || null;
10125 }
10126
10127 return defaultValue || null;
10128 },
10129
10130 /**
10131 * Convert a value into a string.
10132 *
10133 * @param value - Value to be converted intostring, a function will be executed as (() => unknown).
10134 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
10135 *
10136 * @returns Corresponding **boxed** string value, if none then the default value, if none then null.
10137 */
10138 asString: function asString(value, defaultValue) {
10139 if (typeof value == 'function') {
10140 value = value();
10141 }
10142
10143 if (value != null) {
10144 return String(value);
10145 }
10146
10147 return defaultValue || null;
10148 },
10149
10150 /**
10151 * Convert a value into a size.
10152 *
10153 * @param value - Value to be converted intosize, a function will be executed as (() => unknown).
10154 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
10155 *
10156 * @returns Corresponding string value (number + 'px'), if none then the default value, if none then null.
10157 */
10158 asSize: function asSize(value, defaultValue) {
10159 if (typeof value == 'function') {
10160 value = value();
10161 }
10162
10163 if (isString(value)) {
10164 return value;
10165 } else if (isNumber(value)) {
10166 return value + 'px';
10167 } else {
10168 return defaultValue || null;
10169 }
10170 },
10171
10172 /**
10173 * Convert a value into a DOM Element.
10174 *
10175 * @param value - Value to be converted into DOM Element, a function will be executed as (() => unknown).
10176 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
10177 *
10178 * @returns The DOM Element, if none then the default value, if none then null.
10179 */
10180 asElement: function asElement(value, defaultValue) {
10181 if (typeof value == 'function') {
10182 value = value();
10183 }
10184
10185 return value || defaultValue || null;
10186 }
10187};
10188/**
10189 * Convert hex color string into RGB color object.
10190 * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
10191 *
10192 * @param hex - Hex color string (3 or 6 digits, with or without #).
10193 *
10194 * @returns RGB color object.
10195 */
10196
10197function hexToRGB(hex) {
10198 var result;
10199
10200 switch (hex.length) {
10201 case 3:
10202 case 4:
10203 result = shortHexRE.exec(hex);
10204 return result ? {
10205 r: parseInt(result[1] + result[1], 16),
10206 g: parseInt(result[2] + result[2], 16),
10207 b: parseInt(result[3] + result[3], 16)
10208 } : null;
10209
10210 case 6:
10211 case 7:
10212 result = fullHexRE.exec(hex);
10213 return result ? {
10214 r: parseInt(result[1], 16),
10215 g: parseInt(result[2], 16),
10216 b: parseInt(result[3], 16)
10217 } : null;
10218
10219 default:
10220 return null;
10221 }
10222}
10223/**
10224 * This function takes string color in hex or RGB format and adds the opacity, RGBA is passed through unchanged.
10225 *
10226 * @param color - The color string (hex, RGB, RGBA).
10227 * @param opacity - The new opacity.
10228 *
10229 * @returns RGBA string, for example 'rgba(255, 0, 127, 0.3)'.
10230 */
10231
10232
10233function overrideOpacity(color, opacity) {
10234 if (color.indexOf('rgba') !== -1) {
10235 return color;
10236 } else if (color.indexOf('rgb') !== -1) {
10237 var rgb = color.substr(color.indexOf('(') + 1).replace(')', '').split(',');
10238 return 'rgba(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ',' + opacity + ')';
10239 } else {
10240 var _rgb = hexToRGB(color);
10241
10242 if (_rgb == null) {
10243 return color;
10244 } else {
10245 return 'rgba(' + _rgb.r + ',' + _rgb.g + ',' + _rgb.b + ',' + opacity + ')';
10246 }
10247 }
10248}
10249/**
10250 * Convert RGB <0, 255> into hex color string.
10251 *
10252 * @param red - Red channel.
10253 * @param green - Green channel.
10254 * @param blue - Blue channel.
10255 *
10256 * @returns Hex color string (for example: '#0acdc0').
10257 */
10258
10259
10260function RGBToHex(red, green, blue) {
10261 return '#' + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1);
10262}
10263/**
10264 * Parse a color property into an object with border, background, and highlight colors
10265 *
10266 * @param inputColor - Shorthand color string or input color object.
10267 * @param defaultColor - Full color object to fill in missing values in inputColor.
10268 *
10269 * @returns Color object.
10270 */
10271
10272
10273function parseColor(inputColor, defaultColor) {
10274 if (isString(inputColor)) {
10275 var colorStr = inputColor;
10276
10277 if (isValidRGB(colorStr)) {
10278 var rgb = colorStr.substr(4).substr(0, colorStr.length - 5).split(',').map(function (value) {
10279 return parseInt(value);
10280 });
10281 colorStr = RGBToHex(rgb[0], rgb[1], rgb[2]);
10282 }
10283
10284 if (isValidHex(colorStr) === true) {
10285 var hsv = hexToHSV(colorStr);
10286 var lighterColorHSV = {
10287 h: hsv.h,
10288 s: hsv.s * 0.8,
10289 v: Math.min(1, hsv.v * 1.02)
10290 };
10291 var darkerColorHSV = {
10292 h: hsv.h,
10293 s: Math.min(1, hsv.s * 1.25),
10294 v: hsv.v * 0.8
10295 };
10296 var darkerColorHex = HSVToHex(darkerColorHSV.h, darkerColorHSV.s, darkerColorHSV.v);
10297 var lighterColorHex = HSVToHex(lighterColorHSV.h, lighterColorHSV.s, lighterColorHSV.v);
10298 return {
10299 background: colorStr,
10300 border: darkerColorHex,
10301 highlight: {
10302 background: lighterColorHex,
10303 border: darkerColorHex
10304 },
10305 hover: {
10306 background: lighterColorHex,
10307 border: darkerColorHex
10308 }
10309 };
10310 } else {
10311 return {
10312 background: colorStr,
10313 border: colorStr,
10314 highlight: {
10315 background: colorStr,
10316 border: colorStr
10317 },
10318 hover: {
10319 background: colorStr,
10320 border: colorStr
10321 }
10322 };
10323 }
10324 } else {
10325 if (defaultColor) {
10326 var color = {
10327 background: inputColor.background || defaultColor.background,
10328 border: inputColor.border || defaultColor.border,
10329 highlight: isString(inputColor.highlight) ? {
10330 border: inputColor.highlight,
10331 background: inputColor.highlight
10332 } : {
10333 background: inputColor.highlight && inputColor.highlight.background || defaultColor.highlight.background,
10334 border: inputColor.highlight && inputColor.highlight.border || defaultColor.highlight.border
10335 },
10336 hover: isString(inputColor.hover) ? {
10337 border: inputColor.hover,
10338 background: inputColor.hover
10339 } : {
10340 border: inputColor.hover && inputColor.hover.border || defaultColor.hover.border,
10341 background: inputColor.hover && inputColor.hover.background || defaultColor.hover.background
10342 }
10343 };
10344 return color;
10345 } else {
10346 var _color = {
10347 background: inputColor.background || undefined,
10348 border: inputColor.border || undefined,
10349 highlight: isString(inputColor.highlight) ? {
10350 border: inputColor.highlight,
10351 background: inputColor.highlight
10352 } : {
10353 background: inputColor.highlight && inputColor.highlight.background || undefined,
10354 border: inputColor.highlight && inputColor.highlight.border || undefined
10355 },
10356 hover: isString(inputColor.hover) ? {
10357 border: inputColor.hover,
10358 background: inputColor.hover
10359 } : {
10360 border: inputColor.hover && inputColor.hover.border || undefined,
10361 background: inputColor.hover && inputColor.hover.background || undefined
10362 }
10363 };
10364 return _color;
10365 }
10366 }
10367}
10368/**
10369 * Convert RGB <0, 255> into HSV object.
10370 * http://www.javascripter.net/faq/rgb2hsv.htm
10371 *
10372 * @param red - Red channel.
10373 * @param green - Green channel.
10374 * @param blue - Blue channel.
10375 *
10376 * @returns HSV color object.
10377 */
10378
10379
10380function RGBToHSV(red, green, blue) {
10381 red = red / 255;
10382 green = green / 255;
10383 blue = blue / 255;
10384 var minRGB = Math.min(red, Math.min(green, blue));
10385 var maxRGB = Math.max(red, Math.max(green, blue)); // Black-gray-white
10386
10387 if (minRGB === maxRGB) {
10388 return {
10389 h: 0,
10390 s: 0,
10391 v: minRGB
10392 };
10393 } // Colors other than black-gray-white:
10394
10395
10396 var d = red === minRGB ? green - blue : blue === minRGB ? red - green : blue - red;
10397 var h = red === minRGB ? 3 : blue === minRGB ? 1 : 5;
10398 var hue = 60 * (h - d / (maxRGB - minRGB)) / 360;
10399 var saturation = (maxRGB - minRGB) / maxRGB;
10400 var value = maxRGB;
10401 return {
10402 h: hue,
10403 s: saturation,
10404 v: value
10405 };
10406}
10407
10408var cssUtil = {
10409 // split a string with css styles into an object with key/values
10410 split: function split(cssText) {
10411 var styles = {};
10412 cssText.split(';').forEach(function (style) {
10413 if (style.trim() != '') {
10414 var parts = style.split(':');
10415
10416 var _key3 = parts[0].trim();
10417
10418 var _value2 = parts[1].trim();
10419
10420 styles[_key3] = _value2;
10421 }
10422 });
10423 return styles;
10424 },
10425 // build a css text string from an object with key/values
10426 join: function join(styles) {
10427 return Object.keys(styles).map(function (key) {
10428 return key + ': ' + styles[key];
10429 }).join('; ');
10430 }
10431};
10432/**
10433 * Append a string with css styles to an element
10434 *
10435 * @param element - The element that will receive new styles.
10436 * @param cssText - The styles to be appended.
10437 */
10438
10439function addCssText(element, cssText) {
10440 var currentStyles = cssUtil.split(element.style.cssText);
10441 var newStyles = cssUtil.split(cssText);
10442
10443 var styles = _objectSpread({}, currentStyles, {}, newStyles);
10444
10445 element.style.cssText = cssUtil.join(styles);
10446}
10447/**
10448 * Remove a string with css styles from an element
10449 *
10450 * @param element - The element from which styles should be removed.
10451 * @param cssText - The styles to be removed.
10452 */
10453
10454
10455function removeCssText(element, cssText) {
10456 var styles = cssUtil.split(element.style.cssText);
10457 var removeStyles = cssUtil.split(cssText);
10458
10459 for (var _key4 in removeStyles) {
10460 if (Object.prototype.hasOwnProperty.call(removeStyles, _key4)) {
10461 delete styles[_key4];
10462 }
10463 }
10464
10465 element.style.cssText = cssUtil.join(styles);
10466}
10467/**
10468 * Convert HSV <0, 1> into RGB color object.
10469 * https://gist.github.com/mjijackson/5311256
10470 *
10471 * @param h - Hue
10472 * @param s - Saturation
10473 * @param v - Value
10474 *
10475 * @returns RGB color object.
10476 */
10477
10478
10479function HSVToRGB(h, s, v) {
10480 var r;
10481 var g;
10482 var b;
10483 var i = Math.floor(h * 6);
10484 var f = h * 6 - i;
10485 var p = v * (1 - s);
10486 var q = v * (1 - f * s);
10487 var t = v * (1 - (1 - f) * s);
10488
10489 switch (i % 6) {
10490 case 0:
10491 r = v, g = t, b = p;
10492 break;
10493
10494 case 1:
10495 r = q, g = v, b = p;
10496 break;
10497
10498 case 2:
10499 r = p, g = v, b = t;
10500 break;
10501
10502 case 3:
10503 r = p, g = q, b = v;
10504 break;
10505
10506 case 4:
10507 r = t, g = p, b = v;
10508 break;
10509
10510 case 5:
10511 r = v, g = p, b = q;
10512 break;
10513 }
10514
10515 return {
10516 r: Math.floor(r * 255),
10517 g: Math.floor(g * 255),
10518 b: Math.floor(b * 255)
10519 };
10520}
10521/**
10522 * Convert HSV <0, 1> into hex color string.
10523 *
10524 * @param h - Hue
10525 * @param s - Saturation
10526 * @param v - Value
10527 *
10528 * @returns Hex color string.
10529 */
10530
10531
10532function HSVToHex(h, s, v) {
10533 var rgb = HSVToRGB(h, s, v);
10534 return RGBToHex(rgb.r, rgb.g, rgb.b);
10535}
10536/**
10537 * Convert hex color string into HSV <0, 1>.
10538 *
10539 * @param hex - Hex color string.
10540 *
10541 * @returns HSV color object.
10542 */
10543
10544
10545function hexToHSV(hex) {
10546 var rgb = hexToRGB(hex);
10547
10548 if (!rgb) {
10549 throw new TypeError("'".concat(hex, "' is not a valid color."));
10550 }
10551
10552 return RGBToHSV(rgb.r, rgb.g, rgb.b);
10553}
10554/**
10555 * Validate hex color string.
10556 *
10557 * @param hex - Unknown string that may contain a color.
10558 *
10559 * @returns True if the string is valid, false otherwise.
10560 */
10561
10562
10563function isValidHex(hex) {
10564 var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
10565 return isOk;
10566}
10567/**
10568 * Validate RGB color string.
10569 *
10570 * @param rgb - Unknown string that may contain a color.
10571 *
10572 * @returns True if the string is valid, false otherwise.
10573 */
10574
10575
10576function isValidRGB(rgb) {
10577 rgb = rgb.replace(' ', '');
10578 var isOk = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(rgb);
10579 return isOk;
10580}
10581/**
10582 * Validate RGBA color string.
10583 *
10584 * @param rgba - Unknown string that may contain a color.
10585 *
10586 * @returns True if the string is valid, false otherwise.
10587 */
10588
10589
10590function isValidRGBA(rgba) {
10591 rgba = rgba.replace(' ', '');
10592 var isOk = /rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),(0?.{1,3})\)/i.test(rgba);
10593 return isOk;
10594}
10595/**
10596 * This recursively redirects the prototype of JSON objects to the referenceObject.
10597 * This is used for default options.
10598 *
10599 * @param fields - Names of properties to be bridged.
10600 * @param referenceObject - The original object.
10601 *
10602 * @returns A new object inheriting from the referenceObject.
10603 */
10604
10605
10606function selectiveBridgeObject(fields, referenceObject) {
10607 if (referenceObject !== null && _typeof_1(referenceObject) === 'object') {
10608 // !!! typeof null === 'object'
10609 var objectTo = Object.create(referenceObject);
10610
10611 for (var i = 0; i < fields.length; i++) {
10612 if (Object.prototype.hasOwnProperty.call(referenceObject, fields[i])) {
10613 if (_typeof_1(referenceObject[fields[i]]) == 'object') {
10614 objectTo[fields[i]] = bridgeObject(referenceObject[fields[i]]);
10615 }
10616 }
10617 }
10618
10619 return objectTo;
10620 } else {
10621 return null;
10622 }
10623}
10624/**
10625 * This recursively redirects the prototype of JSON objects to the referenceObject.
10626 * This is used for default options.
10627 *
10628 * @param referenceObject - The original object.
10629 *
10630 * @returns The Element if the referenceObject is an Element, or a new object inheriting from the referenceObject.
10631 */
10632
10633
10634function bridgeObject(referenceObject) {
10635 if (referenceObject === null || _typeof_1(referenceObject) !== 'object') {
10636 return null;
10637 }
10638
10639 if (referenceObject instanceof Element) {
10640 // Avoid bridging DOM objects
10641 return referenceObject;
10642 }
10643
10644 var objectTo = Object.create(referenceObject);
10645
10646 for (var i in referenceObject) {
10647 if (Object.prototype.hasOwnProperty.call(referenceObject, i)) {
10648 if (_typeof_1(referenceObject[i]) == 'object') {
10649 objectTo[i] = bridgeObject(referenceObject[i]);
10650 }
10651 }
10652 }
10653
10654 return objectTo;
10655}
10656/**
10657 * This method provides a stable sort implementation, very fast for presorted data.
10658 *
10659 * @param a - The array to be sorted (in-place).
10660 * @param compare - An order comparator.
10661 *
10662 * @returns The argument a.
10663 */
10664
10665
10666function insertSort(a, compare) {
10667 for (var i = 0; i < a.length; i++) {
10668 var k = a[i];
10669 var j = void 0;
10670
10671 for (j = i; j > 0 && compare(k, a[j - 1]) < 0; j--) {
10672 a[j] = a[j - 1];
10673 }
10674
10675 a[j] = k;
10676 }
10677
10678 return a;
10679}
10680/**
10681 * This is used to set the options of subobjects in the options object.
10682 *
10683 * A requirement of these subobjects is that they have an 'enabled' element
10684 * which is optional for the user but mandatory for the program.
10685 *
10686 * The added value here of the merge is that option 'enabled' is set as required.
10687 *
10688 * @param mergeTarget - Either this.options or the options used for the groups.
10689 * @param options - Options.
10690 * @param option - Option key in the options argument.
10691 * @param globalOptions - Global options, passed in to determine value of option 'enabled'.
10692 */
10693
10694
10695function mergeOptions(mergeTarget, options, option) {
10696 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; // Local helpers
10697
10698 var isPresent = function isPresent(obj) {
10699 return obj !== null && obj !== undefined;
10700 };
10701
10702 var isObject = function isObject(obj) {
10703 return obj !== null && _typeof_1(obj) === 'object';
10704 }; // https://stackoverflow.com/a/34491287/1223531
10705
10706
10707 var isEmpty = function isEmpty(obj) {
10708 for (var x in obj) {
10709 if (Object.prototype.hasOwnProperty.call(obj, x)) {
10710 return false;
10711 }
10712 }
10713
10714 return true;
10715 }; // Guards
10716
10717
10718 if (!isObject(mergeTarget)) {
10719 throw new Error('Parameter mergeTarget must be an object');
10720 }
10721
10722 if (!isObject(options)) {
10723 throw new Error('Parameter options must be an object');
10724 }
10725
10726 if (!isPresent(option)) {
10727 throw new Error('Parameter option must have a value');
10728 }
10729
10730 if (!isObject(globalOptions)) {
10731 throw new Error('Parameter globalOptions must be an object');
10732 } //
10733 // Actual merge routine, separated from main logic
10734 // Only a single level of options is merged. Deeper levels are ref'd. This may actually be an issue.
10735 //
10736
10737
10738 var doMerge = function doMerge(target, options, option) {
10739 if (!isObject(target[option])) {
10740 target[option] = {};
10741 }
10742
10743 var src = options[option];
10744 var dst = target[option];
10745
10746 for (var prop in src) {
10747 if (Object.prototype.hasOwnProperty.call(src, prop)) {
10748 dst[prop] = src[prop];
10749 }
10750 }
10751 }; // Local initialization
10752
10753
10754 var srcOption = options[option];
10755 var globalPassed = isObject(globalOptions) && !isEmpty(globalOptions);
10756 var globalOption = globalPassed ? globalOptions[option] : undefined;
10757 var globalEnabled = globalOption ? globalOption.enabled : undefined; /////////////////////////////////////////
10758 // Main routine
10759 /////////////////////////////////////////
10760
10761 if (srcOption === undefined) {
10762 return; // Nothing to do
10763 }
10764
10765 if (typeof srcOption === 'boolean') {
10766 if (!isObject(mergeTarget[option])) {
10767 mergeTarget[option] = {};
10768 }
10769
10770 mergeTarget[option].enabled = srcOption;
10771 return;
10772 }
10773
10774 if (srcOption === null && !isObject(mergeTarget[option])) {
10775 // If possible, explicit copy from globals
10776 if (isPresent(globalOption)) {
10777 mergeTarget[option] = Object.create(globalOption);
10778 } else {
10779 return; // Nothing to do
10780 }
10781 }
10782
10783 if (!isObject(srcOption)) {
10784 return;
10785 } //
10786 // Ensure that 'enabled' is properly set. It is required internally
10787 // Note that the value from options will always overwrite the existing value
10788 //
10789
10790
10791 var enabled = true; // default value
10792
10793 if (srcOption.enabled !== undefined) {
10794 enabled = srcOption.enabled;
10795 } else {
10796 // Take from globals, if present
10797 if (globalEnabled !== undefined) {
10798 enabled = globalOption.enabled;
10799 }
10800 }
10801
10802 doMerge(mergeTarget, options, option);
10803 mergeTarget[option].enabled = enabled;
10804}
10805/**
10806 * This function does a binary search for a visible item in a sorted list. If we find a visible item, the code that uses
10807 * this function will then iterate in both directions over this sorted list to find all visible items.
10808 *
10809 * @param orderedItems - Items ordered by start
10810 * @param comparator - -1 is lower, 0 is equal, 1 is higher
10811 * @param field - Property name on an item (i.e. item[field]).
10812 * @param field2 - Second property name on an item (i.e. item[field][field2]).
10813 *
10814 * @returns Index of the found item or -1 if nothing was found.
10815 */
10816
10817
10818function binarySearchCustom(orderedItems, comparator, field, field2) {
10819 var maxIterations = 10000;
10820 var iteration = 0;
10821 var low = 0;
10822 var high = orderedItems.length - 1;
10823
10824 while (low <= high && iteration < maxIterations) {
10825 var middle = Math.floor((low + high) / 2);
10826 var item = orderedItems[middle];
10827
10828 var _value3 = field2 === undefined ? item[field] : item[field][field2];
10829
10830 var searchResult = comparator(_value3);
10831
10832 if (searchResult == 0) {
10833 // jihaa, found a visible item!
10834 return middle;
10835 } else if (searchResult == -1) {
10836 // it is too small --> increase low
10837 low = middle + 1;
10838 } else {
10839 // it is too big --> decrease high
10840 high = middle - 1;
10841 }
10842
10843 iteration++;
10844 }
10845
10846 return -1;
10847}
10848/**
10849 * This function does a binary search for a specific value in a sorted array. If it does not exist but is in between of
10850 * two values, we return either the one before or the one after, depending on user input
10851 * If it is found, we return the index, else -1.
10852 *
10853 * @param orderedItems - Sorted array.
10854 * @param target - The searched value.
10855 * @param field - Name of the property in items to be searched.
10856 * @param sidePreference - If the target is between two values, should the index of the before or the after be returned?
10857 * @param comparator - An optional comparator, returning -1, 0, 1 for <, ===, >.
10858 *
10859 * @returns The index of found value or -1 if nothing was found.
10860 */
10861
10862
10863function binarySearchValue(orderedItems, target, field, sidePreference, comparator) {
10864 var maxIterations = 10000;
10865 var iteration = 0;
10866 var low = 0;
10867 var high = orderedItems.length - 1;
10868 var prevValue;
10869 var value;
10870 var nextValue;
10871 var middle;
10872 comparator = comparator != undefined ? comparator : function (a, b) {
10873 return a == b ? 0 : a < b ? -1 : 1;
10874 };
10875
10876 while (low <= high && iteration < maxIterations) {
10877 // get a new guess
10878 middle = Math.floor(0.5 * (high + low));
10879 prevValue = orderedItems[Math.max(0, middle - 1)][field];
10880 value = orderedItems[middle][field];
10881 nextValue = orderedItems[Math.min(orderedItems.length - 1, middle + 1)][field];
10882
10883 if (comparator(value, target) == 0) {
10884 // we found the target
10885 return middle;
10886 } else if (comparator(prevValue, target) < 0 && comparator(value, target) > 0) {
10887 // target is in between of the previous and the current
10888 return sidePreference == 'before' ? Math.max(0, middle - 1) : middle;
10889 } else if (comparator(value, target) < 0 && comparator(nextValue, target) > 0) {
10890 // target is in between of the current and the next
10891 return sidePreference == 'before' ? middle : Math.min(orderedItems.length - 1, middle + 1);
10892 } else {
10893 // didnt find the target, we need to change our boundaries.
10894 if (comparator(value, target) < 0) {
10895 // it is too small --> increase low
10896 low = middle + 1;
10897 } else {
10898 // it is too big --> decrease high
10899 high = middle - 1;
10900 }
10901 }
10902
10903 iteration++;
10904 } // didnt find anything. Return -1.
10905
10906
10907 return -1;
10908}
10909/*
10910 * Easing Functions.
10911 * Only considering the t value for the range [0, 1] => [0, 1].
10912 *
10913 * Inspiration: from http://gizma.com/easing/
10914 * https://gist.github.com/gre/1650294
10915 */
10916
10917
10918var easingFunctions = {
10919 /**
10920 * no easing, no acceleration
10921 *
10922 * @param t - Time.
10923 *
10924 * @returns Value at time t.
10925 */
10926 linear: function linear(t) {
10927 return t;
10928 },
10929
10930 /**
10931 * accelerating from zero velocity
10932 *
10933 * @param t - Time.
10934 *
10935 * @returns Value at time t.
10936 */
10937 easeInQuad: function easeInQuad(t) {
10938 return t * t;
10939 },
10940
10941 /**
10942 * decelerating to zero velocity
10943 *
10944 * @param t - Time.
10945 *
10946 * @returns Value at time t.
10947 */
10948 easeOutQuad: function easeOutQuad(t) {
10949 return t * (2 - t);
10950 },
10951
10952 /**
10953 * acceleration until halfway, then deceleration
10954 *
10955 * @param t - Time.
10956 *
10957 * @returns Value at time t.
10958 */
10959 easeInOutQuad: function easeInOutQuad(t) {
10960 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
10961 },
10962
10963 /**
10964 * accelerating from zero velocity
10965 *
10966 * @param t - Time.
10967 *
10968 * @returns Value at time t.
10969 */
10970 easeInCubic: function easeInCubic(t) {
10971 return t * t * t;
10972 },
10973
10974 /**
10975 * decelerating to zero velocity
10976 *
10977 * @param t - Time.
10978 *
10979 * @returns Value at time t.
10980 */
10981 easeOutCubic: function easeOutCubic(t) {
10982 return --t * t * t + 1;
10983 },
10984
10985 /**
10986 * acceleration until halfway, then deceleration
10987 *
10988 * @param t - Time.
10989 *
10990 * @returns Value at time t.
10991 */
10992 easeInOutCubic: function easeInOutCubic(t) {
10993 return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
10994 },
10995
10996 /**
10997 * accelerating from zero velocity
10998 *
10999 * @param t - Time.
11000 *
11001 * @returns Value at time t.
11002 */
11003 easeInQuart: function easeInQuart(t) {
11004 return t * t * t * t;
11005 },
11006
11007 /**
11008 * decelerating to zero velocity
11009 *
11010 * @param t - Time.
11011 *
11012 * @returns Value at time t.
11013 */
11014 easeOutQuart: function easeOutQuart(t) {
11015 return 1 - --t * t * t * t;
11016 },
11017
11018 /**
11019 * acceleration until halfway, then deceleration
11020 *
11021 * @param t - Time.
11022 *
11023 * @returns Value at time t.
11024 */
11025 easeInOutQuart: function easeInOutQuart(t) {
11026 return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
11027 },
11028
11029 /**
11030 * accelerating from zero velocity
11031 *
11032 * @param t - Time.
11033 *
11034 * @returns Value at time t.
11035 */
11036 easeInQuint: function easeInQuint(t) {
11037 return t * t * t * t * t;
11038 },
11039
11040 /**
11041 * decelerating to zero velocity
11042 *
11043 * @param t - Time.
11044 *
11045 * @returns Value at time t.
11046 */
11047 easeOutQuint: function easeOutQuint(t) {
11048 return 1 + --t * t * t * t * t;
11049 },
11050
11051 /**
11052 * acceleration until halfway, then deceleration
11053 *
11054 * @param t - Time.
11055 *
11056 * @returns Value at time t.
11057 */
11058 easeInOutQuint: function easeInOutQuint(t) {
11059 return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
11060 }
11061};
11062/**
11063 * Experimentaly compute the width of the scrollbar for this browser.
11064 *
11065 * @returns The width in pixels.
11066 */
11067
11068function getScrollBarWidth() {
11069 var inner = document.createElement('p');
11070 inner.style.width = '100%';
11071 inner.style.height = '200px';
11072 var outer = document.createElement('div');
11073 outer.style.position = 'absolute';
11074 outer.style.top = '0px';
11075 outer.style.left = '0px';
11076 outer.style.visibility = 'hidden';
11077 outer.style.width = '200px';
11078 outer.style.height = '150px';
11079 outer.style.overflow = 'hidden';
11080 outer.appendChild(inner);
11081 document.body.appendChild(outer);
11082 var w1 = inner.offsetWidth;
11083 outer.style.overflow = 'scroll';
11084 var w2 = inner.offsetWidth;
11085
11086 if (w1 == w2) {
11087 w2 = outer.clientWidth;
11088 }
11089
11090 document.body.removeChild(outer);
11091 return w1 - w2;
11092} // @TODO: This doesn't work properly.
11093// It works only for single property objects,
11094// otherwise it combines all of the types in a union.
11095// export function topMost<K1 extends string, V1> (
11096// pile: Record<K1, undefined | V1>[],
11097// accessors: K1 | [K1]
11098// ): undefined | V1
11099// export function topMost<K1 extends string, K2 extends string, V1, V2> (
11100// pile: Record<K1, undefined | V1 | Record<K2, undefined | V2>>[],
11101// accessors: [K1, K2]
11102// ): undefined | V1 | V2
11103// export function topMost<K1 extends string, K2 extends string, K3 extends string, V1, V2, V3> (
11104// pile: Record<K1, undefined | V1 | Record<K2, undefined | V2 | Record<K3, undefined | V3>>>[],
11105// accessors: [K1, K2, K3]
11106// ): undefined | V1 | V2 | V3
11107
11108/**
11109 * Get the top most property value from a pile of objects.
11110 *
11111 * @param pile - Array of objects, no required format.
11112 * @param accessors - Array of property names (e.g. object['foo']['bar'] → ['foo', 'bar']).
11113 *
11114 * @returns Value of the property with given accessors path from the first pile item where it's not undefined.
11115 */
11116
11117
11118function topMost(pile, accessors) {
11119 var candidate;
11120
11121 if (!Array.isArray(accessors)) {
11122 accessors = [accessors];
11123 }
11124
11125 var _iteratorNormalCompletion = true;
11126 var _didIteratorError = false;
11127 var _iteratorError = undefined;
11128
11129 try {
11130 for (var _iterator = pile[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
11131 var member = _step.value;
11132
11133 if (member) {
11134 candidate = member[accessors[0]];
11135
11136 for (var i = 1; i < accessors.length; i++) {
11137 if (candidate) {
11138 candidate = candidate[accessors[i]];
11139 }
11140 }
11141
11142 if (typeof candidate !== 'undefined') {
11143 break;
11144 }
11145 }
11146 }
11147 } catch (err) {
11148 _didIteratorError = true;
11149 _iteratorError = err;
11150 } finally {
11151 try {
11152 if (!_iteratorNormalCompletion && _iterator.return != null) {
11153 _iterator.return();
11154 }
11155 } finally {
11156 if (_didIteratorError) {
11157 throw _iteratorError;
11158 }
11159 }
11160 }
11161
11162 return candidate;
11163}
11164
11165var util =
11166/*#__PURE__*/
11167Object.freeze({
11168 isNumber: isNumber,
11169 recursiveDOMDelete: recursiveDOMDelete,
11170 isString: isString,
11171 isObject: isObject$1,
11172 isDate: isDate,
11173 isMoment: isMoment,
11174 fillIfDefined: fillIfDefined,
11175 extend: extend,
11176 selectiveExtend: selectiveExtend,
11177 selectiveDeepExtend: selectiveDeepExtend,
11178 selectiveNotDeepExtend: selectiveNotDeepExtend,
11179 deepExtend: deepExtend,
11180 equalArray: equalArray,
11181 convert: convert,
11182 getType: getType,
11183 copyAndExtendArray: copyAndExtendArray,
11184 copyArray: copyArray,
11185 getAbsoluteLeft: getAbsoluteLeft,
11186 getAbsoluteRight: getAbsoluteRight,
11187 getAbsoluteTop: getAbsoluteTop,
11188 addClassName: addClassName,
11189 removeClassName: removeClassName,
11190 forEach: forEach,
11191 toArray: toArray,
11192 updateProperty: updateProperty,
11193 throttle: throttle,
11194 addEventListener: addEventListener,
11195 removeEventListener: removeEventListener,
11196 preventDefault: preventDefault,
11197 getTarget: getTarget,
11198 hasParent: hasParent,
11199 option: option,
11200 hexToRGB: hexToRGB,
11201 overrideOpacity: overrideOpacity,
11202 RGBToHex: RGBToHex,
11203 parseColor: parseColor,
11204 RGBToHSV: RGBToHSV,
11205 addCssText: addCssText,
11206 removeCssText: removeCssText,
11207 HSVToRGB: HSVToRGB,
11208 HSVToHex: HSVToHex,
11209 hexToHSV: hexToHSV,
11210 isValidHex: isValidHex,
11211 isValidRGB: isValidRGB,
11212 isValidRGBA: isValidRGBA,
11213 selectiveBridgeObject: selectiveBridgeObject,
11214 bridgeObject: bridgeObject,
11215 insertSort: insertSort,
11216 mergeOptions: mergeOptions,
11217 binarySearchCustom: binarySearchCustom,
11218 binarySearchValue: binarySearchValue,
11219 easingFunctions: easingFunctions,
11220 getScrollBarWidth: getScrollBarWidth,
11221 topMost: topMost,
11222 randomUUID: uuid4
11223}); // New API (tree shakeable).
11224
11225// DOM utility methods
11226
11227/**
11228 * this prepares the JSON container for allocating SVG elements
11229 * @param {Object} JSONcontainer
11230 * @private
11231 */
11232function prepareElements(JSONcontainer) {
11233 // cleanup the redundant svgElements;
11234 for (var elementType in JSONcontainer) {
11235 if (JSONcontainer.hasOwnProperty(elementType)) {
11236 JSONcontainer[elementType].redundant = JSONcontainer[elementType].used;
11237 JSONcontainer[elementType].used = [];
11238 }
11239 }
11240}
11241/**
11242 * this cleans up all the unused SVG elements. By asking for the parentNode, we only need to supply the JSON container from
11243 * which to remove the redundant elements.
11244 *
11245 * @param {Object} JSONcontainer
11246 * @private
11247 */
11248
11249function cleanupElements(JSONcontainer) {
11250 // cleanup the redundant svgElements;
11251 for (var elementType in JSONcontainer) {
11252 if (JSONcontainer.hasOwnProperty(elementType)) {
11253 if (JSONcontainer[elementType].redundant) {
11254 for (var i = 0; i < JSONcontainer[elementType].redundant.length; i++) {
11255 JSONcontainer[elementType].redundant[i].parentNode.removeChild(JSONcontainer[elementType].redundant[i]);
11256 }
11257
11258 JSONcontainer[elementType].redundant = [];
11259 }
11260 }
11261 }
11262}
11263/**
11264 * Ensures that all elements are removed first up so they can be recreated cleanly
11265 * @param {Object} JSONcontainer
11266 */
11267
11268function resetElements(JSONcontainer) {
11269 prepareElements(JSONcontainer);
11270 cleanupElements(JSONcontainer);
11271 prepareElements(JSONcontainer);
11272}
11273/**
11274 * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer
11275 * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this.
11276 *
11277 * @param {string} elementType
11278 * @param {Object} JSONcontainer
11279 * @param {Object} svgContainer
11280 * @returns {Element}
11281 * @private
11282 */
11283
11284function getSVGElement(elementType, JSONcontainer, svgContainer) {
11285 var element; // allocate SVG element, if it doesnt yet exist, create one.
11286
11287 if (JSONcontainer.hasOwnProperty(elementType)) {
11288 // this element has been created before
11289 // check if there is an redundant element
11290 if (JSONcontainer[elementType].redundant.length > 0) {
11291 element = JSONcontainer[elementType].redundant[0];
11292 JSONcontainer[elementType].redundant.shift();
11293 } else {
11294 // create a new element and add it to the SVG
11295 element = document.createElementNS('http://www.w3.org/2000/svg', elementType);
11296 svgContainer.appendChild(element);
11297 }
11298 } else {
11299 // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it.
11300 element = document.createElementNS('http://www.w3.org/2000/svg', elementType);
11301 JSONcontainer[elementType] = {
11302 used: [],
11303 redundant: []
11304 };
11305 svgContainer.appendChild(element);
11306 }
11307
11308 JSONcontainer[elementType].used.push(element);
11309 return element;
11310}
11311/**
11312 * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer
11313 * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this.
11314 *
11315 * @param {string} elementType
11316 * @param {Object} JSONcontainer
11317 * @param {Element} DOMContainer
11318 * @param {Element} insertBefore
11319 * @returns {*}
11320 */
11321
11322function getDOMElement(elementType, JSONcontainer, DOMContainer, insertBefore) {
11323 var element; // allocate DOM element, if it doesnt yet exist, create one.
11324
11325 if (JSONcontainer.hasOwnProperty(elementType)) {
11326 // this element has been created before
11327 // check if there is an redundant element
11328 if (JSONcontainer[elementType].redundant.length > 0) {
11329 element = JSONcontainer[elementType].redundant[0];
11330 JSONcontainer[elementType].redundant.shift();
11331 } else {
11332 // create a new element and add it to the SVG
11333 element = document.createElement(elementType);
11334
11335 if (insertBefore !== undefined) {
11336 DOMContainer.insertBefore(element, insertBefore);
11337 } else {
11338 DOMContainer.appendChild(element);
11339 }
11340 }
11341 } else {
11342 // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it.
11343 element = document.createElement(elementType);
11344 JSONcontainer[elementType] = {
11345 used: [],
11346 redundant: []
11347 };
11348
11349 if (insertBefore !== undefined) {
11350 DOMContainer.insertBefore(element, insertBefore);
11351 } else {
11352 DOMContainer.appendChild(element);
11353 }
11354 }
11355
11356 JSONcontainer[elementType].used.push(element);
11357 return element;
11358}
11359/**
11360 * Draw a point object. This is a separate function because it can also be called by the legend.
11361 * The reason the JSONcontainer and the target SVG svgContainer have to be supplied is so the legend can use these functions
11362 * as well.
11363 *
11364 * @param {number} x
11365 * @param {number} y
11366 * @param {Object} groupTemplate: A template containing the necessary information to draw the datapoint e.g., {style: 'circle', size: 5, className: 'className' }
11367 * @param {Object} JSONcontainer
11368 * @param {Object} svgContainer
11369 * @param {Object} labelObj
11370 * @returns {vis.PointItem}
11371 */
11372
11373function drawPoint(x, y, groupTemplate, JSONcontainer, svgContainer, labelObj) {
11374 var point;
11375
11376 if (groupTemplate.style == 'circle') {
11377 point = getSVGElement('circle', JSONcontainer, svgContainer);
11378 point.setAttributeNS(null, "cx", x);
11379 point.setAttributeNS(null, "cy", y);
11380 point.setAttributeNS(null, "r", 0.5 * groupTemplate.size);
11381 } else {
11382 point = getSVGElement('rect', JSONcontainer, svgContainer);
11383 point.setAttributeNS(null, "x", x - 0.5 * groupTemplate.size);
11384 point.setAttributeNS(null, "y", y - 0.5 * groupTemplate.size);
11385 point.setAttributeNS(null, "width", groupTemplate.size);
11386 point.setAttributeNS(null, "height", groupTemplate.size);
11387 }
11388
11389 if (groupTemplate.styles !== undefined) {
11390 point.setAttributeNS(null, "style", groupTemplate.styles);
11391 }
11392
11393 point.setAttributeNS(null, "class", groupTemplate.className + " vis-point"); //handle label
11394
11395 if (labelObj) {
11396 var label = getSVGElement('text', JSONcontainer, svgContainer);
11397
11398 if (labelObj.xOffset) {
11399 x = x + labelObj.xOffset;
11400 }
11401
11402 if (labelObj.yOffset) {
11403 y = y + labelObj.yOffset;
11404 }
11405
11406 if (labelObj.content) {
11407 label.textContent = labelObj.content;
11408 }
11409
11410 if (labelObj.className) {
11411 label.setAttributeNS(null, "class", labelObj.className + " vis-label");
11412 }
11413
11414 label.setAttributeNS(null, "x", x);
11415 label.setAttributeNS(null, "y", y);
11416 }
11417
11418 return point;
11419}
11420/**
11421 * draw a bar SVG element centered on the X coordinate
11422 *
11423 * @param {number} x
11424 * @param {number} y
11425 * @param {number} width
11426 * @param {number} height
11427 * @param {string} className
11428 * @param {Object} JSONcontainer
11429 * @param {Object} svgContainer
11430 * @param {string} style
11431 */
11432
11433function drawBar(x, y, width, height, className, JSONcontainer, svgContainer, style) {
11434 if (height != 0) {
11435 if (height < 0) {
11436 height *= -1;
11437 y -= height;
11438 }
11439
11440 var rect = getSVGElement('rect', JSONcontainer, svgContainer);
11441 rect.setAttributeNS(null, "x", x - 0.5 * width);
11442 rect.setAttributeNS(null, "y", y);
11443 rect.setAttributeNS(null, "width", width);
11444 rect.setAttributeNS(null, "height", height);
11445 rect.setAttributeNS(null, "class", className);
11446
11447 if (style) {
11448 rect.setAttributeNS(null, "style", style);
11449 }
11450 }
11451}
11452
11453var DOMutil = /*#__PURE__*/Object.freeze({
11454 prepareElements: prepareElements,
11455 cleanupElements: cleanupElements,
11456 resetElements: resetElements,
11457 getSVGElement: getSVGElement,
11458 getDOMElement: getDOMElement,
11459 drawPoint: drawPoint,
11460 drawBar: drawBar
11461});
11462
11463var $reduce$1 = arrayReduce.left;
11464
11465
11466// `Array.prototype.reduce` method
11467// https://tc39.github.io/ecma262/#sec-array.prototype.reduce
11468_export({ target: 'Array', proto: true, forced: sloppyArrayMethod('reduce') }, {
11469 reduce: function reduce(callbackfn /* , initialValue */) {
11470 return $reduce$1(this, callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);
11471 }
11472});
11473
11474var max$3 = Math.max;
11475var min$6 = Math.min;
11476var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
11477var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
11478
11479// `Array.prototype.splice` method
11480// https://tc39.github.io/ecma262/#sec-array.prototype.splice
11481// with adding support of @@species
11482_export({ target: 'Array', proto: true, forced: !arrayMethodHasSpeciesSupport('splice') }, {
11483 splice: function splice(start, deleteCount /* , ...items */) {
11484 var O = toObject(this);
11485 var len = toLength(O.length);
11486 var actualStart = toAbsoluteIndex(start, len);
11487 var argumentsLength = arguments.length;
11488 var insertCount, actualDeleteCount, A, k, from, to;
11489 if (argumentsLength === 0) {
11490 insertCount = actualDeleteCount = 0;
11491 } else if (argumentsLength === 1) {
11492 insertCount = 0;
11493 actualDeleteCount = len - actualStart;
11494 } else {
11495 insertCount = argumentsLength - 2;
11496 actualDeleteCount = min$6(max$3(toInteger(deleteCount), 0), len - actualStart);
11497 }
11498 if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER$1) {
11499 throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
11500 }
11501 A = arraySpeciesCreate(O, actualDeleteCount);
11502 for (k = 0; k < actualDeleteCount; k++) {
11503 from = actualStart + k;
11504 if (from in O) createProperty(A, k, O[from]);
11505 }
11506 A.length = actualDeleteCount;
11507 if (insertCount < actualDeleteCount) {
11508 for (k = actualStart; k < len - actualDeleteCount; k++) {
11509 from = k + actualDeleteCount;
11510 to = k + insertCount;
11511 if (from in O) O[to] = O[from];
11512 else delete O[to];
11513 }
11514 for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
11515 } else if (insertCount > actualDeleteCount) {
11516 for (k = len - actualDeleteCount; k > actualStart; k--) {
11517 from = k + actualDeleteCount - 1;
11518 to = k + insertCount - 1;
11519 if (from in O) O[to] = O[from];
11520 else delete O[to];
11521 }
11522 }
11523 for (k = 0; k < insertCount; k++) {
11524 O[k + actualStart] = arguments[k + 2];
11525 }
11526 O.length = len - actualDeleteCount + insertCount;
11527 return A;
11528 }
11529});
11530
11531var FAILS_ON_PRIMITIVES$5 = fails(function () { objectGetPrototypeOf(1); });
11532
11533// `Object.getPrototypeOf` method
11534// https://tc39.github.io/ecma262/#sec-object.getprototypeof
11535_export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$5, sham: !correctPrototypeGetter }, {
11536 getPrototypeOf: function getPrototypeOf(it) {
11537 return objectGetPrototypeOf(toObject(it));
11538 }
11539});
11540
11541// `Object.setPrototypeOf` method
11542// https://tc39.github.io/ecma262/#sec-object.setprototypeof
11543_export({ target: 'Object', stat: true }, {
11544 setPrototypeOf: objectSetPrototypeOf
11545});
11546
11547/**
11548 * vis-data - data
11549 * http://visjs.org/
11550 *
11551 * Manage unstructured data using DataSet. Add, update, and remove data, and listen for changes in the data.
11552 *
11553 * @version 6.1.0
11554 * @date 2019-07-16T13:37:00Z
11555 *
11556 * @copyright (c) 2011-2017 Almende B.V, http://almende.com
11557 * @copyright (c) 2018-2019 visjs contributors, https://github.com/visjs
11558 *
11559 * @license
11560 * vis.js is dual licensed under both
11561 *
11562 * 1. The Apache 2.0 License
11563 * http://www.apache.org/licenses/LICENSE-2.0
11564 *
11565 * and
11566 *
11567 * 2. The MIT License
11568 * http://opensource.org/licenses/MIT
11569 *
11570 * vis.js may be distributed under either license.
11571 */
11572function _defineProperty$1(obj, key, value) {
11573 if (key in obj) {
11574 Object.defineProperty(obj, key, {
11575 value: value,
11576 enumerable: true,
11577 configurable: true,
11578 writable: true
11579 });
11580 } else {
11581 obj[key] = value;
11582 }
11583
11584 return obj;
11585}
11586
11587var defineProperty$8 = _defineProperty$1;
11588
11589function createCommonjsModule$2(fn, module) {
11590 return module = {
11591 exports: {}
11592 }, fn(module, module.exports), module.exports;
11593}
11594
11595var _typeof_1$1 = createCommonjsModule$2(function (module) {
11596 function _typeof2(obj) {
11597 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
11598 _typeof2 = function _typeof2(obj) {
11599 return _typeof(obj);
11600 };
11601 } else {
11602 _typeof2 = function _typeof2(obj) {
11603 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
11604 };
11605 }
11606
11607 return _typeof2(obj);
11608 }
11609
11610 function _typeof$1(obj) {
11611 if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
11612 module.exports = _typeof$1 = function _typeof(obj) {
11613 return _typeof2(obj);
11614 };
11615 } else {
11616 module.exports = _typeof$1 = function _typeof(obj) {
11617 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
11618 };
11619 }
11620
11621 return _typeof$1(obj);
11622 }
11623
11624 module.exports = _typeof$1;
11625});
11626
11627function _classCallCheck$1(instance, Constructor) {
11628 if (!(instance instanceof Constructor)) {
11629 throw new TypeError("Cannot call a class as a function");
11630 }
11631}
11632
11633var classCallCheck = _classCallCheck$1;
11634
11635function _defineProperties$1(target, props) {
11636 for (var i = 0; i < props.length; i++) {
11637 var descriptor = props[i];
11638 descriptor.enumerable = descriptor.enumerable || false;
11639 descriptor.configurable = true;
11640 if ("value" in descriptor) descriptor.writable = true;
11641 Object.defineProperty(target, descriptor.key, descriptor);
11642 }
11643}
11644
11645function _createClass$1(Constructor, protoProps, staticProps) {
11646 if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
11647 if (staticProps) _defineProperties$1(Constructor, staticProps);
11648 return Constructor;
11649}
11650
11651var createClass = _createClass$1;
11652
11653function _assertThisInitialized$1(self) {
11654 if (self === void 0) {
11655 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
11656 }
11657
11658 return self;
11659}
11660
11661var assertThisInitialized = _assertThisInitialized$1;
11662
11663function _possibleConstructorReturn$1(self, call) {
11664 if (call && (_typeof_1$1(call) === "object" || typeof call === "function")) {
11665 return call;
11666 }
11667
11668 return assertThisInitialized(self);
11669}
11670
11671var possibleConstructorReturn = _possibleConstructorReturn$1;
11672var getPrototypeOf = createCommonjsModule$2(function (module) {
11673 function _getPrototypeOf(o) {
11674 module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
11675 return o.__proto__ || Object.getPrototypeOf(o);
11676 };
11677 return _getPrototypeOf(o);
11678 }
11679
11680 module.exports = _getPrototypeOf;
11681});
11682var setPrototypeOf = createCommonjsModule$2(function (module) {
11683 function _setPrototypeOf(o, p) {
11684 module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
11685 o.__proto__ = p;
11686 return o;
11687 };
11688
11689 return _setPrototypeOf(o, p);
11690 }
11691
11692 module.exports = _setPrototypeOf;
11693});
11694
11695function _inherits$1(subClass, superClass) {
11696 if (typeof superClass !== "function" && superClass !== null) {
11697 throw new TypeError("Super expression must either be null or a function");
11698 }
11699
11700 subClass.prototype = Object.create(superClass && superClass.prototype, {
11701 constructor: {
11702 value: subClass,
11703 writable: true,
11704 configurable: true
11705 }
11706 });
11707 if (superClass) setPrototypeOf(subClass, superClass);
11708}
11709
11710var inherits = _inherits$1; // Maps for number <-> hex string conversion
11711
11712var byteToHex$2 = [];
11713
11714for (var i$2 = 0; i$2 < 256; i$2++) {
11715 byteToHex$2[i$2] = (i$2 + 0x100).toString(16).substr(1);
11716}
11717/**
11718 * Represent binary UUID into it's string representation.
11719 *
11720 * @param buf - Buffer containing UUID bytes.
11721 * @param offset - Offset from the start of the buffer where the UUID is saved (not needed if the buffer starts with the UUID).
11722 *
11723 * @returns String representation of the UUID.
11724 */
11725
11726
11727function stringifyUUID$1(buf, offset) {
11728 var i = offset || 0;
11729 var bth = byteToHex$2;
11730 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++]];
11731}
11732/**
11733 * Generate 16 random bytes to be used as a base for UUID.
11734 *
11735 * @ignore
11736 */
11737
11738
11739var random$1 = function () {
11740 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
11741 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
11742 // Moderately fast, high quality
11743 var _rnds8 = new Uint8Array(16);
11744
11745 return function whatwgRNG() {
11746 crypto.getRandomValues(_rnds8);
11747 return _rnds8;
11748 };
11749 } // Math.random()-based (RNG)
11750 //
11751 // If all else fails, use Math.random().
11752 // It's fast, but is of unspecified quality.
11753
11754
11755 var _rnds = new Array(16);
11756
11757 return function () {
11758 for (var i = 0, r; i < 16; i++) {
11759 if ((i & 0x03) === 0) {
11760 r = Math.random() * 0x100000000;
11761 }
11762
11763 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
11764 }
11765
11766 return _rnds;
11767 }; // uuid.js
11768 //
11769 // Copyright (c) 2010-2012 Robert Kieffer
11770 // MIT License - http://opensource.org/licenses/mit-license.php
11771 // Unique ID creation requires a high quality random # generator. We feature
11772 // detect to determine the best RNG source, normalizing to a function that
11773 // returns 128-bits of randomness, since that's what's usually required
11774 // return require('./rng');
11775}();
11776
11777var byteToHex$1$1 = [];
11778
11779for (var i$1$1 = 0; i$1$1 < 256; i$1$1++) {
11780 byteToHex$1$1[i$1$1] = (i$1$1 + 0x100).toString(16).substr(1);
11781} // **`v1()` - Generate time-based UUID**
11782//
11783// Inspired by https://github.com/LiosK/UUID.js
11784// and http://docs.python.org/library/uuid.html
11785// random #'s we need to init node and clockseq
11786
11787
11788var seedBytes$1 = random$1(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
11789
11790var 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
11791
11792var defaultClockseq$1 = (seedBytes$1[6] << 8 | seedBytes$1[7]) & 0x3fff; // Previous uuid creation time
11793
11794/**
11795 * UUIDv4 options.
11796 */
11797
11798/**
11799 * Generate UUIDv4
11800 *
11801 * @param options - Options to be used instead of default generated values.
11802 * String 'binary' is a shorthand for uuid4({}, new Array(16)).
11803 * @param buf - If present the buffer will be filled with the generated UUID.
11804 * @param offset - Offset of the UUID from the start of the buffer.
11805 *
11806 * @returns UUIDv4
11807 */
11808
11809function uuid4$1() {
11810 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11811 var buf = arguments.length > 1 ? arguments[1] : undefined;
11812 var offset = arguments.length > 2 ? arguments[2] : undefined; // Deprecated - 'format' argument, as supported in v1.2
11813
11814 var i = buf && offset || 0;
11815
11816 if (typeof options === 'string') {
11817 buf = options === 'binary' ? new Array(16) : undefined;
11818 options = {};
11819 }
11820
11821 var rnds = options.random || (options.rng || random$1)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
11822
11823 rnds[6] = rnds[6] & 0x0f | 0x40;
11824 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
11825
11826 if (buf) {
11827 for (var ii = 0; ii < 16; ii++) {
11828 buf[i + ii] = rnds[ii];
11829 }
11830 }
11831
11832 return buf || stringifyUUID$1(rnds);
11833} // Rollup will complain about mixing default and named exports in UMD build,
11834
11835
11836function _typeof$1(obj) {
11837 if (typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol") {
11838 _typeof$1 = function _typeof$1(obj) {
11839 return _typeof(obj);
11840 };
11841 } else {
11842 _typeof$1 = function _typeof$1(obj) {
11843 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
11844 };
11845 }
11846
11847 return _typeof$1(obj);
11848}
11849
11850var commonjsGlobal$2 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
11851
11852function commonjsRequire$2() {
11853 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
11854}
11855
11856function createCommonjsModule$1$1(fn, module) {
11857 return module = {
11858 exports: {}
11859 }, fn(module, module.exports), module.exports;
11860}
11861
11862var moment$1 = createCommonjsModule$1$1(function (module, exports) {
11863 (function (global, factory) {
11864 module.exports = factory();
11865 })(commonjsGlobal$2, function () {
11866 var hookCallback;
11867
11868 function hooks() {
11869 return hookCallback.apply(null, arguments);
11870 } // This is done to register the method called with moment()
11871 // without creating circular dependencies.
11872
11873
11874 function setHookCallback(callback) {
11875 hookCallback = callback;
11876 }
11877
11878 function isArray(input) {
11879 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
11880 }
11881
11882 function isObject(input) {
11883 // IE8 will treat undefined and null as object if it wasn't for
11884 // input != null
11885 return input != null && Object.prototype.toString.call(input) === '[object Object]';
11886 }
11887
11888 function isObjectEmpty(obj) {
11889 if (Object.getOwnPropertyNames) {
11890 return Object.getOwnPropertyNames(obj).length === 0;
11891 } else {
11892 var k;
11893
11894 for (k in obj) {
11895 if (obj.hasOwnProperty(k)) {
11896 return false;
11897 }
11898 }
11899
11900 return true;
11901 }
11902 }
11903
11904 function isUndefined(input) {
11905 return input === void 0;
11906 }
11907
11908 function isNumber(input) {
11909 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
11910 }
11911
11912 function isDate(input) {
11913 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
11914 }
11915
11916 function map(arr, fn) {
11917 var res = [],
11918 i;
11919
11920 for (i = 0; i < arr.length; ++i) {
11921 res.push(fn(arr[i], i));
11922 }
11923
11924 return res;
11925 }
11926
11927 function hasOwnProp(a, b) {
11928 return Object.prototype.hasOwnProperty.call(a, b);
11929 }
11930
11931 function extend(a, b) {
11932 for (var i in b) {
11933 if (hasOwnProp(b, i)) {
11934 a[i] = b[i];
11935 }
11936 }
11937
11938 if (hasOwnProp(b, 'toString')) {
11939 a.toString = b.toString;
11940 }
11941
11942 if (hasOwnProp(b, 'valueOf')) {
11943 a.valueOf = b.valueOf;
11944 }
11945
11946 return a;
11947 }
11948
11949 function createUTC(input, format, locale, strict) {
11950 return createLocalOrUTC(input, format, locale, strict, true).utc();
11951 }
11952
11953 function defaultParsingFlags() {
11954 // We need to deep clone this object.
11955 return {
11956 empty: false,
11957 unusedTokens: [],
11958 unusedInput: [],
11959 overflow: -2,
11960 charsLeftOver: 0,
11961 nullInput: false,
11962 invalidMonth: null,
11963 invalidFormat: false,
11964 userInvalidated: false,
11965 iso: false,
11966 parsedDateParts: [],
11967 meridiem: null,
11968 rfc2822: false,
11969 weekdayMismatch: false
11970 };
11971 }
11972
11973 function getParsingFlags(m) {
11974 if (m._pf == null) {
11975 m._pf = defaultParsingFlags();
11976 }
11977
11978 return m._pf;
11979 }
11980
11981 var some;
11982
11983 if (Array.prototype.some) {
11984 some = Array.prototype.some;
11985 } else {
11986 some = function some(fun) {
11987 var t = Object(this);
11988 var len = t.length >>> 0;
11989
11990 for (var i = 0; i < len; i++) {
11991 if (i in t && fun.call(this, t[i], i, t)) {
11992 return true;
11993 }
11994 }
11995
11996 return false;
11997 };
11998 }
11999
12000 function isValid(m) {
12001 if (m._isValid == null) {
12002 var flags = getParsingFlags(m);
12003 var parsedParts = some.call(flags.parsedDateParts, function (i) {
12004 return i != null;
12005 });
12006 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);
12007
12008 if (m._strict) {
12009 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
12010 }
12011
12012 if (Object.isFrozen == null || !Object.isFrozen(m)) {
12013 m._isValid = isNowValid;
12014 } else {
12015 return isNowValid;
12016 }
12017 }
12018
12019 return m._isValid;
12020 }
12021
12022 function createInvalid(flags) {
12023 var m = createUTC(NaN);
12024
12025 if (flags != null) {
12026 extend(getParsingFlags(m), flags);
12027 } else {
12028 getParsingFlags(m).userInvalidated = true;
12029 }
12030
12031 return m;
12032 } // Plugins that add properties should also add the key here (null value),
12033 // so we can properly clone ourselves.
12034
12035
12036 var momentProperties = hooks.momentProperties = [];
12037
12038 function copyConfig(to, from) {
12039 var i, prop, val;
12040
12041 if (!isUndefined(from._isAMomentObject)) {
12042 to._isAMomentObject = from._isAMomentObject;
12043 }
12044
12045 if (!isUndefined(from._i)) {
12046 to._i = from._i;
12047 }
12048
12049 if (!isUndefined(from._f)) {
12050 to._f = from._f;
12051 }
12052
12053 if (!isUndefined(from._l)) {
12054 to._l = from._l;
12055 }
12056
12057 if (!isUndefined(from._strict)) {
12058 to._strict = from._strict;
12059 }
12060
12061 if (!isUndefined(from._tzm)) {
12062 to._tzm = from._tzm;
12063 }
12064
12065 if (!isUndefined(from._isUTC)) {
12066 to._isUTC = from._isUTC;
12067 }
12068
12069 if (!isUndefined(from._offset)) {
12070 to._offset = from._offset;
12071 }
12072
12073 if (!isUndefined(from._pf)) {
12074 to._pf = getParsingFlags(from);
12075 }
12076
12077 if (!isUndefined(from._locale)) {
12078 to._locale = from._locale;
12079 }
12080
12081 if (momentProperties.length > 0) {
12082 for (i = 0; i < momentProperties.length; i++) {
12083 prop = momentProperties[i];
12084 val = from[prop];
12085
12086 if (!isUndefined(val)) {
12087 to[prop] = val;
12088 }
12089 }
12090 }
12091
12092 return to;
12093 }
12094
12095 var updateInProgress = false; // Moment prototype object
12096
12097 function Moment(config) {
12098 copyConfig(this, config);
12099 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
12100
12101 if (!this.isValid()) {
12102 this._d = new Date(NaN);
12103 } // Prevent infinite loop in case updateOffset creates new moment
12104 // objects.
12105
12106
12107 if (updateInProgress === false) {
12108 updateInProgress = true;
12109 hooks.updateOffset(this);
12110 updateInProgress = false;
12111 }
12112 }
12113
12114 function isMoment(obj) {
12115 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
12116 }
12117
12118 function absFloor(number) {
12119 if (number < 0) {
12120 // -0 -> 0
12121 return Math.ceil(number) || 0;
12122 } else {
12123 return Math.floor(number);
12124 }
12125 }
12126
12127 function toInt(argumentForCoercion) {
12128 var coercedNumber = +argumentForCoercion,
12129 value = 0;
12130
12131 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
12132 value = absFloor(coercedNumber);
12133 }
12134
12135 return value;
12136 } // compare two arrays, return the number of differences
12137
12138
12139 function compareArrays(array1, array2, dontConvert) {
12140 var len = Math.min(array1.length, array2.length),
12141 lengthDiff = Math.abs(array1.length - array2.length),
12142 diffs = 0,
12143 i;
12144
12145 for (i = 0; i < len; i++) {
12146 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
12147 diffs++;
12148 }
12149 }
12150
12151 return diffs + lengthDiff;
12152 }
12153
12154 function warn(msg) {
12155 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
12156 console.warn('Deprecation warning: ' + msg);
12157 }
12158 }
12159
12160 function deprecate(msg, fn) {
12161 var firstTime = true;
12162 return extend(function () {
12163 if (hooks.deprecationHandler != null) {
12164 hooks.deprecationHandler(null, msg);
12165 }
12166
12167 if (firstTime) {
12168 var args = [];
12169 var arg;
12170
12171 for (var i = 0; i < arguments.length; i++) {
12172 arg = '';
12173
12174 if (_typeof(arguments[i]) === 'object') {
12175 arg += '\n[' + i + '] ';
12176
12177 for (var key in arguments[0]) {
12178 arg += key + ': ' + arguments[0][key] + ', ';
12179 }
12180
12181 arg = arg.slice(0, -2); // Remove trailing comma and space
12182 } else {
12183 arg = arguments[i];
12184 }
12185
12186 args.push(arg);
12187 }
12188
12189 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
12190 firstTime = false;
12191 }
12192
12193 return fn.apply(this, arguments);
12194 }, fn);
12195 }
12196
12197 var deprecations = {};
12198
12199 function deprecateSimple(name, msg) {
12200 if (hooks.deprecationHandler != null) {
12201 hooks.deprecationHandler(name, msg);
12202 }
12203
12204 if (!deprecations[name]) {
12205 warn(msg);
12206 deprecations[name] = true;
12207 }
12208 }
12209
12210 hooks.suppressDeprecationWarnings = false;
12211 hooks.deprecationHandler = null;
12212
12213 function isFunction(input) {
12214 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
12215 }
12216
12217 function set(config) {
12218 var prop, i;
12219
12220 for (i in config) {
12221 prop = config[i];
12222
12223 if (isFunction(prop)) {
12224 this[i] = prop;
12225 } else {
12226 this['_' + i] = prop;
12227 }
12228 }
12229
12230 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
12231 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
12232 // TODO: Remove "ordinalParse" fallback in next major release.
12233
12234 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
12235 }
12236
12237 function mergeConfigs(parentConfig, childConfig) {
12238 var res = extend({}, parentConfig),
12239 prop;
12240
12241 for (prop in childConfig) {
12242 if (hasOwnProp(childConfig, prop)) {
12243 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
12244 res[prop] = {};
12245 extend(res[prop], parentConfig[prop]);
12246 extend(res[prop], childConfig[prop]);
12247 } else if (childConfig[prop] != null) {
12248 res[prop] = childConfig[prop];
12249 } else {
12250 delete res[prop];
12251 }
12252 }
12253 }
12254
12255 for (prop in parentConfig) {
12256 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
12257 // make sure changes to properties don't modify parent config
12258 res[prop] = extend({}, res[prop]);
12259 }
12260 }
12261
12262 return res;
12263 }
12264
12265 function Locale(config) {
12266 if (config != null) {
12267 this.set(config);
12268 }
12269 }
12270
12271 var keys;
12272
12273 if (Object.keys) {
12274 keys = Object.keys;
12275 } else {
12276 keys = function keys(obj) {
12277 var i,
12278 res = [];
12279
12280 for (i in obj) {
12281 if (hasOwnProp(obj, i)) {
12282 res.push(i);
12283 }
12284 }
12285
12286 return res;
12287 };
12288 }
12289
12290 var defaultCalendar = {
12291 sameDay: '[Today at] LT',
12292 nextDay: '[Tomorrow at] LT',
12293 nextWeek: 'dddd [at] LT',
12294 lastDay: '[Yesterday at] LT',
12295 lastWeek: '[Last] dddd [at] LT',
12296 sameElse: 'L'
12297 };
12298
12299 function calendar(key, mom, now) {
12300 var output = this._calendar[key] || this._calendar['sameElse'];
12301 return isFunction(output) ? output.call(mom, now) : output;
12302 }
12303
12304 var defaultLongDateFormat = {
12305 LTS: 'h:mm:ss A',
12306 LT: 'h:mm A',
12307 L: 'MM/DD/YYYY',
12308 LL: 'MMMM D, YYYY',
12309 LLL: 'MMMM D, YYYY h:mm A',
12310 LLLL: 'dddd, MMMM D, YYYY h:mm A'
12311 };
12312
12313 function longDateFormat(key) {
12314 var format = this._longDateFormat[key],
12315 formatUpper = this._longDateFormat[key.toUpperCase()];
12316
12317 if (format || !formatUpper) {
12318 return format;
12319 }
12320
12321 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
12322 return val.slice(1);
12323 });
12324 return this._longDateFormat[key];
12325 }
12326
12327 var defaultInvalidDate = 'Invalid date';
12328
12329 function invalidDate() {
12330 return this._invalidDate;
12331 }
12332
12333 var defaultOrdinal = '%d';
12334 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
12335
12336 function ordinal(number) {
12337 return this._ordinal.replace('%d', number);
12338 }
12339
12340 var defaultRelativeTime = {
12341 future: 'in %s',
12342 past: '%s ago',
12343 s: 'a few seconds',
12344 ss: '%d seconds',
12345 m: 'a minute',
12346 mm: '%d minutes',
12347 h: 'an hour',
12348 hh: '%d hours',
12349 d: 'a day',
12350 dd: '%d days',
12351 M: 'a month',
12352 MM: '%d months',
12353 y: 'a year',
12354 yy: '%d years'
12355 };
12356
12357 function relativeTime(number, withoutSuffix, string, isFuture) {
12358 var output = this._relativeTime[string];
12359 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
12360 }
12361
12362 function pastFuture(diff, output) {
12363 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
12364 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
12365 }
12366
12367 var aliases = {};
12368
12369 function addUnitAlias(unit, shorthand) {
12370 var lowerCase = unit.toLowerCase();
12371 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
12372 }
12373
12374 function normalizeUnits(units) {
12375 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
12376 }
12377
12378 function normalizeObjectUnits(inputObject) {
12379 var normalizedInput = {},
12380 normalizedProp,
12381 prop;
12382
12383 for (prop in inputObject) {
12384 if (hasOwnProp(inputObject, prop)) {
12385 normalizedProp = normalizeUnits(prop);
12386
12387 if (normalizedProp) {
12388 normalizedInput[normalizedProp] = inputObject[prop];
12389 }
12390 }
12391 }
12392
12393 return normalizedInput;
12394 }
12395
12396 var priorities = {};
12397
12398 function addUnitPriority(unit, priority) {
12399 priorities[unit] = priority;
12400 }
12401
12402 function getPrioritizedUnits(unitsObj) {
12403 var units = [];
12404
12405 for (var u in unitsObj) {
12406 units.push({
12407 unit: u,
12408 priority: priorities[u]
12409 });
12410 }
12411
12412 units.sort(function (a, b) {
12413 return a.priority - b.priority;
12414 });
12415 return units;
12416 }
12417
12418 function zeroFill(number, targetLength, forceSign) {
12419 var absNumber = '' + Math.abs(number),
12420 zerosToFill = targetLength - absNumber.length,
12421 sign = number >= 0;
12422 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
12423 }
12424
12425 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;
12426 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
12427 var formatFunctions = {};
12428 var formatTokenFunctions = {}; // token: 'M'
12429 // padded: ['MM', 2]
12430 // ordinal: 'Mo'
12431 // callback: function () { this.month() + 1 }
12432
12433 function addFormatToken(token, padded, ordinal, callback) {
12434 var func = callback;
12435
12436 if (typeof callback === 'string') {
12437 func = function func() {
12438 return this[callback]();
12439 };
12440 }
12441
12442 if (token) {
12443 formatTokenFunctions[token] = func;
12444 }
12445
12446 if (padded) {
12447 formatTokenFunctions[padded[0]] = function () {
12448 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
12449 };
12450 }
12451
12452 if (ordinal) {
12453 formatTokenFunctions[ordinal] = function () {
12454 return this.localeData().ordinal(func.apply(this, arguments), token);
12455 };
12456 }
12457 }
12458
12459 function removeFormattingTokens(input) {
12460 if (input.match(/\[[\s\S]/)) {
12461 return input.replace(/^\[|\]$/g, '');
12462 }
12463
12464 return input.replace(/\\/g, '');
12465 }
12466
12467 function makeFormatFunction(format) {
12468 var array = format.match(formattingTokens),
12469 i,
12470 length;
12471
12472 for (i = 0, length = array.length; i < length; i++) {
12473 if (formatTokenFunctions[array[i]]) {
12474 array[i] = formatTokenFunctions[array[i]];
12475 } else {
12476 array[i] = removeFormattingTokens(array[i]);
12477 }
12478 }
12479
12480 return function (mom) {
12481 var output = '',
12482 i;
12483
12484 for (i = 0; i < length; i++) {
12485 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
12486 }
12487
12488 return output;
12489 };
12490 } // format date using native date object
12491
12492
12493 function formatMoment(m, format) {
12494 if (!m.isValid()) {
12495 return m.localeData().invalidDate();
12496 }
12497
12498 format = expandFormat(format, m.localeData());
12499 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
12500 return formatFunctions[format](m);
12501 }
12502
12503 function expandFormat(format, locale) {
12504 var i = 5;
12505
12506 function replaceLongDateFormatTokens(input) {
12507 return locale.longDateFormat(input) || input;
12508 }
12509
12510 localFormattingTokens.lastIndex = 0;
12511
12512 while (i >= 0 && localFormattingTokens.test(format)) {
12513 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
12514 localFormattingTokens.lastIndex = 0;
12515 i -= 1;
12516 }
12517
12518 return format;
12519 }
12520
12521 var match1 = /\d/; // 0 - 9
12522
12523 var match2 = /\d\d/; // 00 - 99
12524
12525 var match3 = /\d{3}/; // 000 - 999
12526
12527 var match4 = /\d{4}/; // 0000 - 9999
12528
12529 var match6 = /[+-]?\d{6}/; // -999999 - 999999
12530
12531 var match1to2 = /\d\d?/; // 0 - 99
12532
12533 var match3to4 = /\d\d\d\d?/; // 999 - 9999
12534
12535 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
12536
12537 var match1to3 = /\d{1,3}/; // 0 - 999
12538
12539 var match1to4 = /\d{1,4}/; // 0 - 9999
12540
12541 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
12542
12543 var matchUnsigned = /\d+/; // 0 - inf
12544
12545 var matchSigned = /[+-]?\d+/; // -inf - inf
12546
12547 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
12548
12549 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
12550
12551 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
12552 // any word (or two) characters or numbers including two/three word month in arabic.
12553 // includes scottish gaelic two word and hyphenated months
12554
12555 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;
12556 var regexes = {};
12557
12558 function addRegexToken(token, regex, strictRegex) {
12559 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
12560 return isStrict && strictRegex ? strictRegex : regex;
12561 };
12562 }
12563
12564 function getParseRegexForToken(token, config) {
12565 if (!hasOwnProp(regexes, token)) {
12566 return new RegExp(unescapeFormat(token));
12567 }
12568
12569 return regexes[token](config._strict, config._locale);
12570 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
12571
12572
12573 function unescapeFormat(s) {
12574 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
12575 return p1 || p2 || p3 || p4;
12576 }));
12577 }
12578
12579 function regexEscape(s) {
12580 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
12581 }
12582
12583 var tokens = {};
12584
12585 function addParseToken(token, callback) {
12586 var i,
12587 func = callback;
12588
12589 if (typeof token === 'string') {
12590 token = [token];
12591 }
12592
12593 if (isNumber(callback)) {
12594 func = function func(input, array) {
12595 array[callback] = toInt(input);
12596 };
12597 }
12598
12599 for (i = 0; i < token.length; i++) {
12600 tokens[token[i]] = func;
12601 }
12602 }
12603
12604 function addWeekParseToken(token, callback) {
12605 addParseToken(token, function (input, array, config, token) {
12606 config._w = config._w || {};
12607 callback(input, config._w, config, token);
12608 });
12609 }
12610
12611 function addTimeToArrayFromToken(token, input, config) {
12612 if (input != null && hasOwnProp(tokens, token)) {
12613 tokens[token](input, config._a, config, token);
12614 }
12615 }
12616
12617 var YEAR = 0;
12618 var MONTH = 1;
12619 var DATE = 2;
12620 var HOUR = 3;
12621 var MINUTE = 4;
12622 var SECOND = 5;
12623 var MILLISECOND = 6;
12624 var WEEK = 7;
12625 var WEEKDAY = 8; // FORMATTING
12626
12627 addFormatToken('Y', 0, 0, function () {
12628 var y = this.year();
12629 return y <= 9999 ? '' + y : '+' + y;
12630 });
12631 addFormatToken(0, ['YY', 2], 0, function () {
12632 return this.year() % 100;
12633 });
12634 addFormatToken(0, ['YYYY', 4], 0, 'year');
12635 addFormatToken(0, ['YYYYY', 5], 0, 'year');
12636 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
12637
12638 addUnitAlias('year', 'y'); // PRIORITIES
12639
12640 addUnitPriority('year', 1); // PARSING
12641
12642 addRegexToken('Y', matchSigned);
12643 addRegexToken('YY', match1to2, match2);
12644 addRegexToken('YYYY', match1to4, match4);
12645 addRegexToken('YYYYY', match1to6, match6);
12646 addRegexToken('YYYYYY', match1to6, match6);
12647 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
12648 addParseToken('YYYY', function (input, array) {
12649 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
12650 });
12651 addParseToken('YY', function (input, array) {
12652 array[YEAR] = hooks.parseTwoDigitYear(input);
12653 });
12654 addParseToken('Y', function (input, array) {
12655 array[YEAR] = parseInt(input, 10);
12656 }); // HELPERS
12657
12658 function daysInYear(year) {
12659 return isLeapYear(year) ? 366 : 365;
12660 }
12661
12662 function isLeapYear(year) {
12663 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
12664 } // HOOKS
12665
12666
12667 hooks.parseTwoDigitYear = function (input) {
12668 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
12669 }; // MOMENTS
12670
12671
12672 var getSetYear = makeGetSet('FullYear', true);
12673
12674 function getIsLeapYear() {
12675 return isLeapYear(this.year());
12676 }
12677
12678 function makeGetSet(unit, keepTime) {
12679 return function (value) {
12680 if (value != null) {
12681 set$1(this, unit, value);
12682 hooks.updateOffset(this, keepTime);
12683 return this;
12684 } else {
12685 return get(this, unit);
12686 }
12687 };
12688 }
12689
12690 function get(mom, unit) {
12691 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
12692 }
12693
12694 function set$1(mom, unit, value) {
12695 if (mom.isValid() && !isNaN(value)) {
12696 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
12697 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
12698 } else {
12699 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
12700 }
12701 }
12702 } // MOMENTS
12703
12704
12705 function stringGet(units) {
12706 units = normalizeUnits(units);
12707
12708 if (isFunction(this[units])) {
12709 return this[units]();
12710 }
12711
12712 return this;
12713 }
12714
12715 function stringSet(units, value) {
12716 if (_typeof(units) === 'object') {
12717 units = normalizeObjectUnits(units);
12718 var prioritized = getPrioritizedUnits(units);
12719
12720 for (var i = 0; i < prioritized.length; i++) {
12721 this[prioritized[i].unit](units[prioritized[i].unit]);
12722 }
12723 } else {
12724 units = normalizeUnits(units);
12725
12726 if (isFunction(this[units])) {
12727 return this[units](value);
12728 }
12729 }
12730
12731 return this;
12732 }
12733
12734 function mod(n, x) {
12735 return (n % x + x) % x;
12736 }
12737
12738 var indexOf;
12739
12740 if (Array.prototype.indexOf) {
12741 indexOf = Array.prototype.indexOf;
12742 } else {
12743 indexOf = function indexOf(o) {
12744 // I know
12745 var i;
12746
12747 for (i = 0; i < this.length; ++i) {
12748 if (this[i] === o) {
12749 return i;
12750 }
12751 }
12752
12753 return -1;
12754 };
12755 }
12756
12757 function daysInMonth(year, month) {
12758 if (isNaN(year) || isNaN(month)) {
12759 return NaN;
12760 }
12761
12762 var modMonth = mod(month, 12);
12763 year += (month - modMonth) / 12;
12764 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
12765 } // FORMATTING
12766
12767
12768 addFormatToken('M', ['MM', 2], 'Mo', function () {
12769 return this.month() + 1;
12770 });
12771 addFormatToken('MMM', 0, 0, function (format) {
12772 return this.localeData().monthsShort(this, format);
12773 });
12774 addFormatToken('MMMM', 0, 0, function (format) {
12775 return this.localeData().months(this, format);
12776 }); // ALIASES
12777
12778 addUnitAlias('month', 'M'); // PRIORITY
12779
12780 addUnitPriority('month', 8); // PARSING
12781
12782 addRegexToken('M', match1to2);
12783 addRegexToken('MM', match1to2, match2);
12784 addRegexToken('MMM', function (isStrict, locale) {
12785 return locale.monthsShortRegex(isStrict);
12786 });
12787 addRegexToken('MMMM', function (isStrict, locale) {
12788 return locale.monthsRegex(isStrict);
12789 });
12790 addParseToken(['M', 'MM'], function (input, array) {
12791 array[MONTH] = toInt(input) - 1;
12792 });
12793 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
12794 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
12795
12796
12797 if (month != null) {
12798 array[MONTH] = month;
12799 } else {
12800 getParsingFlags(config).invalidMonth = input;
12801 }
12802 }); // LOCALES
12803
12804 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
12805 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
12806
12807 function localeMonths(m, format) {
12808 if (!m) {
12809 return isArray(this._months) ? this._months : this._months['standalone'];
12810 }
12811
12812 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
12813 }
12814
12815 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
12816
12817 function localeMonthsShort(m, format) {
12818 if (!m) {
12819 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
12820 }
12821
12822 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
12823 }
12824
12825 function handleStrictParse(monthName, format, strict) {
12826 var i,
12827 ii,
12828 mom,
12829 llc = monthName.toLocaleLowerCase();
12830
12831 if (!this._monthsParse) {
12832 // this is not used
12833 this._monthsParse = [];
12834 this._longMonthsParse = [];
12835 this._shortMonthsParse = [];
12836
12837 for (i = 0; i < 12; ++i) {
12838 mom = createUTC([2000, i]);
12839 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
12840 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
12841 }
12842 }
12843
12844 if (strict) {
12845 if (format === 'MMM') {
12846 ii = indexOf.call(this._shortMonthsParse, llc);
12847 return ii !== -1 ? ii : null;
12848 } else {
12849 ii = indexOf.call(this._longMonthsParse, llc);
12850 return ii !== -1 ? ii : null;
12851 }
12852 } else {
12853 if (format === 'MMM') {
12854 ii = indexOf.call(this._shortMonthsParse, llc);
12855
12856 if (ii !== -1) {
12857 return ii;
12858 }
12859
12860 ii = indexOf.call(this._longMonthsParse, llc);
12861 return ii !== -1 ? ii : null;
12862 } else {
12863 ii = indexOf.call(this._longMonthsParse, llc);
12864
12865 if (ii !== -1) {
12866 return ii;
12867 }
12868
12869 ii = indexOf.call(this._shortMonthsParse, llc);
12870 return ii !== -1 ? ii : null;
12871 }
12872 }
12873 }
12874
12875 function localeMonthsParse(monthName, format, strict) {
12876 var i, mom, regex;
12877
12878 if (this._monthsParseExact) {
12879 return handleStrictParse.call(this, monthName, format, strict);
12880 }
12881
12882 if (!this._monthsParse) {
12883 this._monthsParse = [];
12884 this._longMonthsParse = [];
12885 this._shortMonthsParse = [];
12886 } // TODO: add sorting
12887 // Sorting makes sure if one month (or abbr) is a prefix of another
12888 // see sorting in computeMonthsParse
12889
12890
12891 for (i = 0; i < 12; i++) {
12892 // make the regex if we don't have it already
12893 mom = createUTC([2000, i]);
12894
12895 if (strict && !this._longMonthsParse[i]) {
12896 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
12897 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
12898 }
12899
12900 if (!strict && !this._monthsParse[i]) {
12901 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
12902 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
12903 } // test the regex
12904
12905
12906 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
12907 return i;
12908 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
12909 return i;
12910 } else if (!strict && this._monthsParse[i].test(monthName)) {
12911 return i;
12912 }
12913 }
12914 } // MOMENTS
12915
12916
12917 function setMonth(mom, value) {
12918 var dayOfMonth;
12919
12920 if (!mom.isValid()) {
12921 // No op
12922 return mom;
12923 }
12924
12925 if (typeof value === 'string') {
12926 if (/^\d+$/.test(value)) {
12927 value = toInt(value);
12928 } else {
12929 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
12930
12931 if (!isNumber(value)) {
12932 return mom;
12933 }
12934 }
12935 }
12936
12937 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
12938
12939 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
12940
12941 return mom;
12942 }
12943
12944 function getSetMonth(value) {
12945 if (value != null) {
12946 setMonth(this, value);
12947 hooks.updateOffset(this, true);
12948 return this;
12949 } else {
12950 return get(this, 'Month');
12951 }
12952 }
12953
12954 function getDaysInMonth() {
12955 return daysInMonth(this.year(), this.month());
12956 }
12957
12958 var defaultMonthsShortRegex = matchWord;
12959
12960 function monthsShortRegex(isStrict) {
12961 if (this._monthsParseExact) {
12962 if (!hasOwnProp(this, '_monthsRegex')) {
12963 computeMonthsParse.call(this);
12964 }
12965
12966 if (isStrict) {
12967 return this._monthsShortStrictRegex;
12968 } else {
12969 return this._monthsShortRegex;
12970 }
12971 } else {
12972 if (!hasOwnProp(this, '_monthsShortRegex')) {
12973 this._monthsShortRegex = defaultMonthsShortRegex;
12974 }
12975
12976 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
12977 }
12978 }
12979
12980 var defaultMonthsRegex = matchWord;
12981
12982 function monthsRegex(isStrict) {
12983 if (this._monthsParseExact) {
12984 if (!hasOwnProp(this, '_monthsRegex')) {
12985 computeMonthsParse.call(this);
12986 }
12987
12988 if (isStrict) {
12989 return this._monthsStrictRegex;
12990 } else {
12991 return this._monthsRegex;
12992 }
12993 } else {
12994 if (!hasOwnProp(this, '_monthsRegex')) {
12995 this._monthsRegex = defaultMonthsRegex;
12996 }
12997
12998 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
12999 }
13000 }
13001
13002 function computeMonthsParse() {
13003 function cmpLenRev(a, b) {
13004 return b.length - a.length;
13005 }
13006
13007 var shortPieces = [],
13008 longPieces = [],
13009 mixedPieces = [],
13010 i,
13011 mom;
13012
13013 for (i = 0; i < 12; i++) {
13014 // make the regex if we don't have it already
13015 mom = createUTC([2000, i]);
13016 shortPieces.push(this.monthsShort(mom, ''));
13017 longPieces.push(this.months(mom, ''));
13018 mixedPieces.push(this.months(mom, ''));
13019 mixedPieces.push(this.monthsShort(mom, ''));
13020 } // Sorting makes sure if one month (or abbr) is a prefix of another it
13021 // will match the longer piece.
13022
13023
13024 shortPieces.sort(cmpLenRev);
13025 longPieces.sort(cmpLenRev);
13026 mixedPieces.sort(cmpLenRev);
13027
13028 for (i = 0; i < 12; i++) {
13029 shortPieces[i] = regexEscape(shortPieces[i]);
13030 longPieces[i] = regexEscape(longPieces[i]);
13031 }
13032
13033 for (i = 0; i < 24; i++) {
13034 mixedPieces[i] = regexEscape(mixedPieces[i]);
13035 }
13036
13037 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
13038 this._monthsShortRegex = this._monthsRegex;
13039 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
13040 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
13041 }
13042
13043 function createDate(y, m, d, h, M, s, ms) {
13044 // can't just apply() to create a date:
13045 // https://stackoverflow.com/q/181348
13046 var date; // the date constructor remaps years 0-99 to 1900-1999
13047
13048 if (y < 100 && y >= 0) {
13049 // preserve leap years using a full 400 year cycle, then reset
13050 date = new Date(y + 400, m, d, h, M, s, ms);
13051
13052 if (isFinite(date.getFullYear())) {
13053 date.setFullYear(y);
13054 }
13055 } else {
13056 date = new Date(y, m, d, h, M, s, ms);
13057 }
13058
13059 return date;
13060 }
13061
13062 function createUTCDate(y) {
13063 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
13064
13065 if (y < 100 && y >= 0) {
13066 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
13067
13068 args[0] = y + 400;
13069 date = new Date(Date.UTC.apply(null, args));
13070
13071 if (isFinite(date.getUTCFullYear())) {
13072 date.setUTCFullYear(y);
13073 }
13074 } else {
13075 date = new Date(Date.UTC.apply(null, arguments));
13076 }
13077
13078 return date;
13079 } // start-of-first-week - start-of-year
13080
13081
13082 function firstWeekOffset(year, dow, doy) {
13083 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
13084 fwd = 7 + dow - doy,
13085 // first-week day local weekday -- which local weekday is fwd
13086 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
13087 return -fwdlw + fwd - 1;
13088 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
13089
13090
13091 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
13092 var localWeekday = (7 + weekday - dow) % 7,
13093 weekOffset = firstWeekOffset(year, dow, doy),
13094 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
13095 resYear,
13096 resDayOfYear;
13097
13098 if (dayOfYear <= 0) {
13099 resYear = year - 1;
13100 resDayOfYear = daysInYear(resYear) + dayOfYear;
13101 } else if (dayOfYear > daysInYear(year)) {
13102 resYear = year + 1;
13103 resDayOfYear = dayOfYear - daysInYear(year);
13104 } else {
13105 resYear = year;
13106 resDayOfYear = dayOfYear;
13107 }
13108
13109 return {
13110 year: resYear,
13111 dayOfYear: resDayOfYear
13112 };
13113 }
13114
13115 function weekOfYear(mom, dow, doy) {
13116 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
13117 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
13118 resWeek,
13119 resYear;
13120
13121 if (week < 1) {
13122 resYear = mom.year() - 1;
13123 resWeek = week + weeksInYear(resYear, dow, doy);
13124 } else if (week > weeksInYear(mom.year(), dow, doy)) {
13125 resWeek = week - weeksInYear(mom.year(), dow, doy);
13126 resYear = mom.year() + 1;
13127 } else {
13128 resYear = mom.year();
13129 resWeek = week;
13130 }
13131
13132 return {
13133 week: resWeek,
13134 year: resYear
13135 };
13136 }
13137
13138 function weeksInYear(year, dow, doy) {
13139 var weekOffset = firstWeekOffset(year, dow, doy),
13140 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
13141 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
13142 } // FORMATTING
13143
13144
13145 addFormatToken('w', ['ww', 2], 'wo', 'week');
13146 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
13147
13148 addUnitAlias('week', 'w');
13149 addUnitAlias('isoWeek', 'W'); // PRIORITIES
13150
13151 addUnitPriority('week', 5);
13152 addUnitPriority('isoWeek', 5); // PARSING
13153
13154 addRegexToken('w', match1to2);
13155 addRegexToken('ww', match1to2, match2);
13156 addRegexToken('W', match1to2);
13157 addRegexToken('WW', match1to2, match2);
13158 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
13159 week[token.substr(0, 1)] = toInt(input);
13160 }); // HELPERS
13161 // LOCALES
13162
13163 function localeWeek(mom) {
13164 return weekOfYear(mom, this._week.dow, this._week.doy).week;
13165 }
13166
13167 var defaultLocaleWeek = {
13168 dow: 0,
13169 // Sunday is the first day of the week.
13170 doy: 6 // The week that contains Jan 6th is the first week of the year.
13171
13172 };
13173
13174 function localeFirstDayOfWeek() {
13175 return this._week.dow;
13176 }
13177
13178 function localeFirstDayOfYear() {
13179 return this._week.doy;
13180 } // MOMENTS
13181
13182
13183 function getSetWeek(input) {
13184 var week = this.localeData().week(this);
13185 return input == null ? week : this.add((input - week) * 7, 'd');
13186 }
13187
13188 function getSetISOWeek(input) {
13189 var week = weekOfYear(this, 1, 4).week;
13190 return input == null ? week : this.add((input - week) * 7, 'd');
13191 } // FORMATTING
13192
13193
13194 addFormatToken('d', 0, 'do', 'day');
13195 addFormatToken('dd', 0, 0, function (format) {
13196 return this.localeData().weekdaysMin(this, format);
13197 });
13198 addFormatToken('ddd', 0, 0, function (format) {
13199 return this.localeData().weekdaysShort(this, format);
13200 });
13201 addFormatToken('dddd', 0, 0, function (format) {
13202 return this.localeData().weekdays(this, format);
13203 });
13204 addFormatToken('e', 0, 0, 'weekday');
13205 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
13206
13207 addUnitAlias('day', 'd');
13208 addUnitAlias('weekday', 'e');
13209 addUnitAlias('isoWeekday', 'E'); // PRIORITY
13210
13211 addUnitPriority('day', 11);
13212 addUnitPriority('weekday', 11);
13213 addUnitPriority('isoWeekday', 11); // PARSING
13214
13215 addRegexToken('d', match1to2);
13216 addRegexToken('e', match1to2);
13217 addRegexToken('E', match1to2);
13218 addRegexToken('dd', function (isStrict, locale) {
13219 return locale.weekdaysMinRegex(isStrict);
13220 });
13221 addRegexToken('ddd', function (isStrict, locale) {
13222 return locale.weekdaysShortRegex(isStrict);
13223 });
13224 addRegexToken('dddd', function (isStrict, locale) {
13225 return locale.weekdaysRegex(isStrict);
13226 });
13227 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
13228 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
13229
13230
13231 if (weekday != null) {
13232 week.d = weekday;
13233 } else {
13234 getParsingFlags(config).invalidWeekday = input;
13235 }
13236 });
13237 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
13238 week[token] = toInt(input);
13239 }); // HELPERS
13240
13241 function parseWeekday(input, locale) {
13242 if (typeof input !== 'string') {
13243 return input;
13244 }
13245
13246 if (!isNaN(input)) {
13247 return parseInt(input, 10);
13248 }
13249
13250 input = locale.weekdaysParse(input);
13251
13252 if (typeof input === 'number') {
13253 return input;
13254 }
13255
13256 return null;
13257 }
13258
13259 function parseIsoWeekday(input, locale) {
13260 if (typeof input === 'string') {
13261 return locale.weekdaysParse(input) % 7 || 7;
13262 }
13263
13264 return isNaN(input) ? null : input;
13265 } // LOCALES
13266
13267
13268 function shiftWeekdays(ws, n) {
13269 return ws.slice(n, 7).concat(ws.slice(0, n));
13270 }
13271
13272 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
13273
13274 function localeWeekdays(m, format) {
13275 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
13276 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
13277 }
13278
13279 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
13280
13281 function localeWeekdaysShort(m) {
13282 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
13283 }
13284
13285 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
13286
13287 function localeWeekdaysMin(m) {
13288 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
13289 }
13290
13291 function handleStrictParse$1(weekdayName, format, strict) {
13292 var i,
13293 ii,
13294 mom,
13295 llc = weekdayName.toLocaleLowerCase();
13296
13297 if (!this._weekdaysParse) {
13298 this._weekdaysParse = [];
13299 this._shortWeekdaysParse = [];
13300 this._minWeekdaysParse = [];
13301
13302 for (i = 0; i < 7; ++i) {
13303 mom = createUTC([2000, 1]).day(i);
13304 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
13305 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
13306 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
13307 }
13308 }
13309
13310 if (strict) {
13311 if (format === 'dddd') {
13312 ii = indexOf.call(this._weekdaysParse, llc);
13313 return ii !== -1 ? ii : null;
13314 } else if (format === 'ddd') {
13315 ii = indexOf.call(this._shortWeekdaysParse, llc);
13316 return ii !== -1 ? ii : null;
13317 } else {
13318 ii = indexOf.call(this._minWeekdaysParse, llc);
13319 return ii !== -1 ? ii : null;
13320 }
13321 } else {
13322 if (format === 'dddd') {
13323 ii = indexOf.call(this._weekdaysParse, llc);
13324
13325 if (ii !== -1) {
13326 return ii;
13327 }
13328
13329 ii = indexOf.call(this._shortWeekdaysParse, llc);
13330
13331 if (ii !== -1) {
13332 return ii;
13333 }
13334
13335 ii = indexOf.call(this._minWeekdaysParse, llc);
13336 return ii !== -1 ? ii : null;
13337 } else if (format === 'ddd') {
13338 ii = indexOf.call(this._shortWeekdaysParse, llc);
13339
13340 if (ii !== -1) {
13341 return ii;
13342 }
13343
13344 ii = indexOf.call(this._weekdaysParse, llc);
13345
13346 if (ii !== -1) {
13347 return ii;
13348 }
13349
13350 ii = indexOf.call(this._minWeekdaysParse, llc);
13351 return ii !== -1 ? ii : null;
13352 } else {
13353 ii = indexOf.call(this._minWeekdaysParse, llc);
13354
13355 if (ii !== -1) {
13356 return ii;
13357 }
13358
13359 ii = indexOf.call(this._weekdaysParse, llc);
13360
13361 if (ii !== -1) {
13362 return ii;
13363 }
13364
13365 ii = indexOf.call(this._shortWeekdaysParse, llc);
13366 return ii !== -1 ? ii : null;
13367 }
13368 }
13369 }
13370
13371 function localeWeekdaysParse(weekdayName, format, strict) {
13372 var i, mom, regex;
13373
13374 if (this._weekdaysParseExact) {
13375 return handleStrictParse$1.call(this, weekdayName, format, strict);
13376 }
13377
13378 if (!this._weekdaysParse) {
13379 this._weekdaysParse = [];
13380 this._minWeekdaysParse = [];
13381 this._shortWeekdaysParse = [];
13382 this._fullWeekdaysParse = [];
13383 }
13384
13385 for (i = 0; i < 7; i++) {
13386 // make the regex if we don't have it already
13387 mom = createUTC([2000, 1]).day(i);
13388
13389 if (strict && !this._fullWeekdaysParse[i]) {
13390 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
13391 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
13392 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
13393 }
13394
13395 if (!this._weekdaysParse[i]) {
13396 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
13397 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
13398 } // test the regex
13399
13400
13401 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
13402 return i;
13403 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
13404 return i;
13405 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
13406 return i;
13407 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
13408 return i;
13409 }
13410 }
13411 } // MOMENTS
13412
13413
13414 function getSetDayOfWeek(input) {
13415 if (!this.isValid()) {
13416 return input != null ? this : NaN;
13417 }
13418
13419 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
13420
13421 if (input != null) {
13422 input = parseWeekday(input, this.localeData());
13423 return this.add(input - day, 'd');
13424 } else {
13425 return day;
13426 }
13427 }
13428
13429 function getSetLocaleDayOfWeek(input) {
13430 if (!this.isValid()) {
13431 return input != null ? this : NaN;
13432 }
13433
13434 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
13435 return input == null ? weekday : this.add(input - weekday, 'd');
13436 }
13437
13438 function getSetISODayOfWeek(input) {
13439 if (!this.isValid()) {
13440 return input != null ? this : NaN;
13441 } // behaves the same as moment#day except
13442 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
13443 // as a setter, sunday should belong to the previous week.
13444
13445
13446 if (input != null) {
13447 var weekday = parseIsoWeekday(input, this.localeData());
13448 return this.day(this.day() % 7 ? weekday : weekday - 7);
13449 } else {
13450 return this.day() || 7;
13451 }
13452 }
13453
13454 var defaultWeekdaysRegex = matchWord;
13455
13456 function weekdaysRegex(isStrict) {
13457 if (this._weekdaysParseExact) {
13458 if (!hasOwnProp(this, '_weekdaysRegex')) {
13459 computeWeekdaysParse.call(this);
13460 }
13461
13462 if (isStrict) {
13463 return this._weekdaysStrictRegex;
13464 } else {
13465 return this._weekdaysRegex;
13466 }
13467 } else {
13468 if (!hasOwnProp(this, '_weekdaysRegex')) {
13469 this._weekdaysRegex = defaultWeekdaysRegex;
13470 }
13471
13472 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
13473 }
13474 }
13475
13476 var defaultWeekdaysShortRegex = matchWord;
13477
13478 function weekdaysShortRegex(isStrict) {
13479 if (this._weekdaysParseExact) {
13480 if (!hasOwnProp(this, '_weekdaysRegex')) {
13481 computeWeekdaysParse.call(this);
13482 }
13483
13484 if (isStrict) {
13485 return this._weekdaysShortStrictRegex;
13486 } else {
13487 return this._weekdaysShortRegex;
13488 }
13489 } else {
13490 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
13491 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
13492 }
13493
13494 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
13495 }
13496 }
13497
13498 var defaultWeekdaysMinRegex = matchWord;
13499
13500 function weekdaysMinRegex(isStrict) {
13501 if (this._weekdaysParseExact) {
13502 if (!hasOwnProp(this, '_weekdaysRegex')) {
13503 computeWeekdaysParse.call(this);
13504 }
13505
13506 if (isStrict) {
13507 return this._weekdaysMinStrictRegex;
13508 } else {
13509 return this._weekdaysMinRegex;
13510 }
13511 } else {
13512 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
13513 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
13514 }
13515
13516 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
13517 }
13518 }
13519
13520 function computeWeekdaysParse() {
13521 function cmpLenRev(a, b) {
13522 return b.length - a.length;
13523 }
13524
13525 var minPieces = [],
13526 shortPieces = [],
13527 longPieces = [],
13528 mixedPieces = [],
13529 i,
13530 mom,
13531 minp,
13532 shortp,
13533 longp;
13534
13535 for (i = 0; i < 7; i++) {
13536 // make the regex if we don't have it already
13537 mom = createUTC([2000, 1]).day(i);
13538 minp = this.weekdaysMin(mom, '');
13539 shortp = this.weekdaysShort(mom, '');
13540 longp = this.weekdays(mom, '');
13541 minPieces.push(minp);
13542 shortPieces.push(shortp);
13543 longPieces.push(longp);
13544 mixedPieces.push(minp);
13545 mixedPieces.push(shortp);
13546 mixedPieces.push(longp);
13547 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
13548 // will match the longer piece.
13549
13550
13551 minPieces.sort(cmpLenRev);
13552 shortPieces.sort(cmpLenRev);
13553 longPieces.sort(cmpLenRev);
13554 mixedPieces.sort(cmpLenRev);
13555
13556 for (i = 0; i < 7; i++) {
13557 shortPieces[i] = regexEscape(shortPieces[i]);
13558 longPieces[i] = regexEscape(longPieces[i]);
13559 mixedPieces[i] = regexEscape(mixedPieces[i]);
13560 }
13561
13562 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
13563 this._weekdaysShortRegex = this._weekdaysRegex;
13564 this._weekdaysMinRegex = this._weekdaysRegex;
13565 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
13566 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
13567 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
13568 } // FORMATTING
13569
13570
13571 function hFormat() {
13572 return this.hours() % 12 || 12;
13573 }
13574
13575 function kFormat() {
13576 return this.hours() || 24;
13577 }
13578
13579 addFormatToken('H', ['HH', 2], 0, 'hour');
13580 addFormatToken('h', ['hh', 2], 0, hFormat);
13581 addFormatToken('k', ['kk', 2], 0, kFormat);
13582 addFormatToken('hmm', 0, 0, function () {
13583 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
13584 });
13585 addFormatToken('hmmss', 0, 0, function () {
13586 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
13587 });
13588 addFormatToken('Hmm', 0, 0, function () {
13589 return '' + this.hours() + zeroFill(this.minutes(), 2);
13590 });
13591 addFormatToken('Hmmss', 0, 0, function () {
13592 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
13593 });
13594
13595 function meridiem(token, lowercase) {
13596 addFormatToken(token, 0, 0, function () {
13597 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
13598 });
13599 }
13600
13601 meridiem('a', true);
13602 meridiem('A', false); // ALIASES
13603
13604 addUnitAlias('hour', 'h'); // PRIORITY
13605
13606 addUnitPriority('hour', 13); // PARSING
13607
13608 function matchMeridiem(isStrict, locale) {
13609 return locale._meridiemParse;
13610 }
13611
13612 addRegexToken('a', matchMeridiem);
13613 addRegexToken('A', matchMeridiem);
13614 addRegexToken('H', match1to2);
13615 addRegexToken('h', match1to2);
13616 addRegexToken('k', match1to2);
13617 addRegexToken('HH', match1to2, match2);
13618 addRegexToken('hh', match1to2, match2);
13619 addRegexToken('kk', match1to2, match2);
13620 addRegexToken('hmm', match3to4);
13621 addRegexToken('hmmss', match5to6);
13622 addRegexToken('Hmm', match3to4);
13623 addRegexToken('Hmmss', match5to6);
13624 addParseToken(['H', 'HH'], HOUR);
13625 addParseToken(['k', 'kk'], function (input, array, config) {
13626 var kInput = toInt(input);
13627 array[HOUR] = kInput === 24 ? 0 : kInput;
13628 });
13629 addParseToken(['a', 'A'], function (input, array, config) {
13630 config._isPm = config._locale.isPM(input);
13631 config._meridiem = input;
13632 });
13633 addParseToken(['h', 'hh'], function (input, array, config) {
13634 array[HOUR] = toInt(input);
13635 getParsingFlags(config).bigHour = true;
13636 });
13637 addParseToken('hmm', function (input, array, config) {
13638 var pos = input.length - 2;
13639 array[HOUR] = toInt(input.substr(0, pos));
13640 array[MINUTE] = toInt(input.substr(pos));
13641 getParsingFlags(config).bigHour = true;
13642 });
13643 addParseToken('hmmss', function (input, array, config) {
13644 var pos1 = input.length - 4;
13645 var pos2 = input.length - 2;
13646 array[HOUR] = toInt(input.substr(0, pos1));
13647 array[MINUTE] = toInt(input.substr(pos1, 2));
13648 array[SECOND] = toInt(input.substr(pos2));
13649 getParsingFlags(config).bigHour = true;
13650 });
13651 addParseToken('Hmm', function (input, array, config) {
13652 var pos = input.length - 2;
13653 array[HOUR] = toInt(input.substr(0, pos));
13654 array[MINUTE] = toInt(input.substr(pos));
13655 });
13656 addParseToken('Hmmss', function (input, array, config) {
13657 var pos1 = input.length - 4;
13658 var pos2 = input.length - 2;
13659 array[HOUR] = toInt(input.substr(0, pos1));
13660 array[MINUTE] = toInt(input.substr(pos1, 2));
13661 array[SECOND] = toInt(input.substr(pos2));
13662 }); // LOCALES
13663
13664 function localeIsPM(input) {
13665 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
13666 // Using charAt should be more compatible.
13667 return (input + '').toLowerCase().charAt(0) === 'p';
13668 }
13669
13670 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
13671
13672 function localeMeridiem(hours, minutes, isLower) {
13673 if (hours > 11) {
13674 return isLower ? 'pm' : 'PM';
13675 } else {
13676 return isLower ? 'am' : 'AM';
13677 }
13678 } // MOMENTS
13679 // Setting the hour should keep the time, because the user explicitly
13680 // specified which hour they want. So trying to maintain the same hour (in
13681 // a new timezone) makes sense. Adding/subtracting hours does not follow
13682 // this rule.
13683
13684
13685 var getSetHour = makeGetSet('Hours', true);
13686 var baseConfig = {
13687 calendar: defaultCalendar,
13688 longDateFormat: defaultLongDateFormat,
13689 invalidDate: defaultInvalidDate,
13690 ordinal: defaultOrdinal,
13691 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
13692 relativeTime: defaultRelativeTime,
13693 months: defaultLocaleMonths,
13694 monthsShort: defaultLocaleMonthsShort,
13695 week: defaultLocaleWeek,
13696 weekdays: defaultLocaleWeekdays,
13697 weekdaysMin: defaultLocaleWeekdaysMin,
13698 weekdaysShort: defaultLocaleWeekdaysShort,
13699 meridiemParse: defaultLocaleMeridiemParse
13700 }; // internal storage for locale config files
13701
13702 var locales = {};
13703 var localeFamilies = {};
13704 var globalLocale;
13705
13706 function normalizeLocale(key) {
13707 return key ? key.toLowerCase().replace('_', '-') : key;
13708 } // pick the locale from the array
13709 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
13710 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
13711
13712
13713 function chooseLocale(names) {
13714 var i = 0,
13715 j,
13716 next,
13717 locale,
13718 split;
13719
13720 while (i < names.length) {
13721 split = normalizeLocale(names[i]).split('-');
13722 j = split.length;
13723 next = normalizeLocale(names[i + 1]);
13724 next = next ? next.split('-') : null;
13725
13726 while (j > 0) {
13727 locale = loadLocale(split.slice(0, j).join('-'));
13728
13729 if (locale) {
13730 return locale;
13731 }
13732
13733 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
13734 //the next array item is better than a shallower substring of this one
13735 break;
13736 }
13737
13738 j--;
13739 }
13740
13741 i++;
13742 }
13743
13744 return globalLocale;
13745 }
13746
13747 function loadLocale(name) {
13748 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
13749
13750 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
13751 try {
13752 oldLocale = globalLocale._abbr;
13753 var aliasedRequire = commonjsRequire$2;
13754 aliasedRequire('./locale/' + name);
13755 getSetGlobalLocale(oldLocale);
13756 } catch (e) {}
13757 }
13758
13759 return locales[name];
13760 } // This function will load locale and then set the global locale. If
13761 // no arguments are passed in, it will simply return the current global
13762 // locale key.
13763
13764
13765 function getSetGlobalLocale(key, values) {
13766 var data;
13767
13768 if (key) {
13769 if (isUndefined(values)) {
13770 data = getLocale(key);
13771 } else {
13772 data = defineLocale(key, values);
13773 }
13774
13775 if (data) {
13776 // moment.duration._locale = moment._locale = data;
13777 globalLocale = data;
13778 } else {
13779 if (typeof console !== 'undefined' && console.warn) {
13780 //warn user if arguments are passed but the locale could not be set
13781 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
13782 }
13783 }
13784 }
13785
13786 return globalLocale._abbr;
13787 }
13788
13789 function defineLocale(name, config) {
13790 if (config !== null) {
13791 var locale,
13792 parentConfig = baseConfig;
13793 config.abbr = name;
13794
13795 if (locales[name] != null) {
13796 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.');
13797 parentConfig = locales[name]._config;
13798 } else if (config.parentLocale != null) {
13799 if (locales[config.parentLocale] != null) {
13800 parentConfig = locales[config.parentLocale]._config;
13801 } else {
13802 locale = loadLocale(config.parentLocale);
13803
13804 if (locale != null) {
13805 parentConfig = locale._config;
13806 } else {
13807 if (!localeFamilies[config.parentLocale]) {
13808 localeFamilies[config.parentLocale] = [];
13809 }
13810
13811 localeFamilies[config.parentLocale].push({
13812 name: name,
13813 config: config
13814 });
13815 return null;
13816 }
13817 }
13818 }
13819
13820 locales[name] = new Locale(mergeConfigs(parentConfig, config));
13821
13822 if (localeFamilies[name]) {
13823 localeFamilies[name].forEach(function (x) {
13824 defineLocale(x.name, x.config);
13825 });
13826 } // backwards compat for now: also set the locale
13827 // make sure we set the locale AFTER all child locales have been
13828 // created, so we won't end up with the child locale set.
13829
13830
13831 getSetGlobalLocale(name);
13832 return locales[name];
13833 } else {
13834 // useful for testing
13835 delete locales[name];
13836 return null;
13837 }
13838 }
13839
13840 function updateLocale(name, config) {
13841 if (config != null) {
13842 var locale,
13843 tmpLocale,
13844 parentConfig = baseConfig; // MERGE
13845
13846 tmpLocale = loadLocale(name);
13847
13848 if (tmpLocale != null) {
13849 parentConfig = tmpLocale._config;
13850 }
13851
13852 config = mergeConfigs(parentConfig, config);
13853 locale = new Locale(config);
13854 locale.parentLocale = locales[name];
13855 locales[name] = locale; // backwards compat for now: also set the locale
13856
13857 getSetGlobalLocale(name);
13858 } else {
13859 // pass null for config to unupdate, useful for tests
13860 if (locales[name] != null) {
13861 if (locales[name].parentLocale != null) {
13862 locales[name] = locales[name].parentLocale;
13863 } else if (locales[name] != null) {
13864 delete locales[name];
13865 }
13866 }
13867 }
13868
13869 return locales[name];
13870 } // returns locale data
13871
13872
13873 function getLocale(key) {
13874 var locale;
13875
13876 if (key && key._locale && key._locale._abbr) {
13877 key = key._locale._abbr;
13878 }
13879
13880 if (!key) {
13881 return globalLocale;
13882 }
13883
13884 if (!isArray(key)) {
13885 //short-circuit everything else
13886 locale = loadLocale(key);
13887
13888 if (locale) {
13889 return locale;
13890 }
13891
13892 key = [key];
13893 }
13894
13895 return chooseLocale(key);
13896 }
13897
13898 function listLocales() {
13899 return keys(locales);
13900 }
13901
13902 function checkOverflow(m) {
13903 var overflow;
13904 var a = m._a;
13905
13906 if (a && getParsingFlags(m).overflow === -2) {
13907 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;
13908
13909 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
13910 overflow = DATE;
13911 }
13912
13913 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
13914 overflow = WEEK;
13915 }
13916
13917 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
13918 overflow = WEEKDAY;
13919 }
13920
13921 getParsingFlags(m).overflow = overflow;
13922 }
13923
13924 return m;
13925 } // Pick the first defined of two or three arguments.
13926
13927
13928 function defaults(a, b, c) {
13929 if (a != null) {
13930 return a;
13931 }
13932
13933 if (b != null) {
13934 return b;
13935 }
13936
13937 return c;
13938 }
13939
13940 function currentDateArray(config) {
13941 // hooks is actually the exported moment object
13942 var nowValue = new Date(hooks.now());
13943
13944 if (config._useUTC) {
13945 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
13946 }
13947
13948 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
13949 } // convert an array to a date.
13950 // the array should mirror the parameters below
13951 // note: all values past the year are optional and will default to the lowest possible value.
13952 // [year, month, day , hour, minute, second, millisecond]
13953
13954
13955 function configFromArray(config) {
13956 var i,
13957 date,
13958 input = [],
13959 currentDate,
13960 expectedWeekday,
13961 yearToUse;
13962
13963 if (config._d) {
13964 return;
13965 }
13966
13967 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
13968
13969 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
13970 dayOfYearFromWeekInfo(config);
13971 } //if the day of the year is set, figure out what it is
13972
13973
13974 if (config._dayOfYear != null) {
13975 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
13976
13977 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
13978 getParsingFlags(config)._overflowDayOfYear = true;
13979 }
13980
13981 date = createUTCDate(yearToUse, 0, config._dayOfYear);
13982 config._a[MONTH] = date.getUTCMonth();
13983 config._a[DATE] = date.getUTCDate();
13984 } // Default to current date.
13985 // * if no year, month, day of month are given, default to today
13986 // * if day of month is given, default month and year
13987 // * if month is given, default only year
13988 // * if year is given, don't default anything
13989
13990
13991 for (i = 0; i < 3 && config._a[i] == null; ++i) {
13992 config._a[i] = input[i] = currentDate[i];
13993 } // Zero out whatever was not defaulted, including time
13994
13995
13996 for (; i < 7; i++) {
13997 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
13998 } // Check for 24:00:00.000
13999
14000
14001 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
14002 config._nextDay = true;
14003 config._a[HOUR] = 0;
14004 }
14005
14006 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
14007 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
14008 // with parseZone.
14009
14010 if (config._tzm != null) {
14011 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
14012 }
14013
14014 if (config._nextDay) {
14015 config._a[HOUR] = 24;
14016 } // check for mismatching day of week
14017
14018
14019 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
14020 getParsingFlags(config).weekdayMismatch = true;
14021 }
14022 }
14023
14024 function dayOfYearFromWeekInfo(config) {
14025 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
14026 w = config._w;
14027
14028 if (w.GG != null || w.W != null || w.E != null) {
14029 dow = 1;
14030 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
14031 // how we interpret now (local, utc, fixed offset). So create
14032 // a now version of current config (take local/utc/offset flags, and
14033 // create now).
14034
14035 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
14036 week = defaults(w.W, 1);
14037 weekday = defaults(w.E, 1);
14038
14039 if (weekday < 1 || weekday > 7) {
14040 weekdayOverflow = true;
14041 }
14042 } else {
14043 dow = config._locale._week.dow;
14044 doy = config._locale._week.doy;
14045 var curWeek = weekOfYear(createLocal(), dow, doy);
14046 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
14047
14048 week = defaults(w.w, curWeek.week);
14049
14050 if (w.d != null) {
14051 // weekday -- low day numbers are considered next week
14052 weekday = w.d;
14053
14054 if (weekday < 0 || weekday > 6) {
14055 weekdayOverflow = true;
14056 }
14057 } else if (w.e != null) {
14058 // local weekday -- counting starts from beginning of week
14059 weekday = w.e + dow;
14060
14061 if (w.e < 0 || w.e > 6) {
14062 weekdayOverflow = true;
14063 }
14064 } else {
14065 // default to beginning of week
14066 weekday = dow;
14067 }
14068 }
14069
14070 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
14071 getParsingFlags(config)._overflowWeeks = true;
14072 } else if (weekdayOverflow != null) {
14073 getParsingFlags(config)._overflowWeekday = true;
14074 } else {
14075 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
14076 config._a[YEAR] = temp.year;
14077 config._dayOfYear = temp.dayOfYear;
14078 }
14079 } // iso 8601 regex
14080 // 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)
14081
14082
14083 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)?)?$/;
14084 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)?)?$/;
14085 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
14086 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
14087 ['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
14088
14089 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/]];
14090 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
14091
14092 function configFromISO(config) {
14093 var i,
14094 l,
14095 string = config._i,
14096 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
14097 allowTime,
14098 dateFormat,
14099 timeFormat,
14100 tzFormat;
14101
14102 if (match) {
14103 getParsingFlags(config).iso = true;
14104
14105 for (i = 0, l = isoDates.length; i < l; i++) {
14106 if (isoDates[i][1].exec(match[1])) {
14107 dateFormat = isoDates[i][0];
14108 allowTime = isoDates[i][2] !== false;
14109 break;
14110 }
14111 }
14112
14113 if (dateFormat == null) {
14114 config._isValid = false;
14115 return;
14116 }
14117
14118 if (match[3]) {
14119 for (i = 0, l = isoTimes.length; i < l; i++) {
14120 if (isoTimes[i][1].exec(match[3])) {
14121 // match[2] should be 'T' or space
14122 timeFormat = (match[2] || ' ') + isoTimes[i][0];
14123 break;
14124 }
14125 }
14126
14127 if (timeFormat == null) {
14128 config._isValid = false;
14129 return;
14130 }
14131 }
14132
14133 if (!allowTime && timeFormat != null) {
14134 config._isValid = false;
14135 return;
14136 }
14137
14138 if (match[4]) {
14139 if (tzRegex.exec(match[4])) {
14140 tzFormat = 'Z';
14141 } else {
14142 config._isValid = false;
14143 return;
14144 }
14145 }
14146
14147 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
14148 configFromStringAndFormat(config);
14149 } else {
14150 config._isValid = false;
14151 }
14152 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
14153
14154
14155 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}))$/;
14156
14157 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
14158 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
14159
14160 if (secondStr) {
14161 result.push(parseInt(secondStr, 10));
14162 }
14163
14164 return result;
14165 }
14166
14167 function untruncateYear(yearStr) {
14168 var year = parseInt(yearStr, 10);
14169
14170 if (year <= 49) {
14171 return 2000 + year;
14172 } else if (year <= 999) {
14173 return 1900 + year;
14174 }
14175
14176 return year;
14177 }
14178
14179 function preprocessRFC2822(s) {
14180 // Remove comments and folding whitespace and replace multiple-spaces with a single space
14181 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
14182 }
14183
14184 function checkWeekday(weekdayStr, parsedInput, config) {
14185 if (weekdayStr) {
14186 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
14187 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
14188 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
14189
14190 if (weekdayProvided !== weekdayActual) {
14191 getParsingFlags(config).weekdayMismatch = true;
14192 config._isValid = false;
14193 return false;
14194 }
14195 }
14196
14197 return true;
14198 }
14199
14200 var obsOffsets = {
14201 UT: 0,
14202 GMT: 0,
14203 EDT: -4 * 60,
14204 EST: -5 * 60,
14205 CDT: -5 * 60,
14206 CST: -6 * 60,
14207 MDT: -6 * 60,
14208 MST: -7 * 60,
14209 PDT: -7 * 60,
14210 PST: -8 * 60
14211 };
14212
14213 function calculateOffset(obsOffset, militaryOffset, numOffset) {
14214 if (obsOffset) {
14215 return obsOffsets[obsOffset];
14216 } else if (militaryOffset) {
14217 // the only allowed military tz is Z
14218 return 0;
14219 } else {
14220 var hm = parseInt(numOffset, 10);
14221 var m = hm % 100,
14222 h = (hm - m) / 100;
14223 return h * 60 + m;
14224 }
14225 } // date and time from ref 2822 format
14226
14227
14228 function configFromRFC2822(config) {
14229 var match = rfc2822.exec(preprocessRFC2822(config._i));
14230
14231 if (match) {
14232 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
14233
14234 if (!checkWeekday(match[1], parsedArray, config)) {
14235 return;
14236 }
14237
14238 config._a = parsedArray;
14239 config._tzm = calculateOffset(match[8], match[9], match[10]);
14240 config._d = createUTCDate.apply(null, config._a);
14241
14242 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
14243
14244 getParsingFlags(config).rfc2822 = true;
14245 } else {
14246 config._isValid = false;
14247 }
14248 } // date from iso format or fallback
14249
14250
14251 function configFromString(config) {
14252 var matched = aspNetJsonRegex.exec(config._i);
14253
14254 if (matched !== null) {
14255 config._d = new Date(+matched[1]);
14256 return;
14257 }
14258
14259 configFromISO(config);
14260
14261 if (config._isValid === false) {
14262 delete config._isValid;
14263 } else {
14264 return;
14265 }
14266
14267 configFromRFC2822(config);
14268
14269 if (config._isValid === false) {
14270 delete config._isValid;
14271 } else {
14272 return;
14273 } // Final attempt, use Input Fallback
14274
14275
14276 hooks.createFromInputFallback(config);
14277 }
14278
14279 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) {
14280 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
14281 }); // constant that refers to the ISO standard
14282
14283 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
14284
14285
14286 hooks.RFC_2822 = function () {}; // date from string and format string
14287
14288
14289 function configFromStringAndFormat(config) {
14290 // TODO: Move this to another part of the creation flow to prevent circular deps
14291 if (config._f === hooks.ISO_8601) {
14292 configFromISO(config);
14293 return;
14294 }
14295
14296 if (config._f === hooks.RFC_2822) {
14297 configFromRFC2822(config);
14298 return;
14299 }
14300
14301 config._a = [];
14302 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
14303
14304 var string = '' + config._i,
14305 i,
14306 parsedInput,
14307 tokens,
14308 token,
14309 skipped,
14310 stringLength = string.length,
14311 totalParsedInputLength = 0;
14312 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
14313
14314 for (i = 0; i < tokens.length; i++) {
14315 token = tokens[i];
14316 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
14317 // 'regex', getParseRegexForToken(token, config));
14318
14319 if (parsedInput) {
14320 skipped = string.substr(0, string.indexOf(parsedInput));
14321
14322 if (skipped.length > 0) {
14323 getParsingFlags(config).unusedInput.push(skipped);
14324 }
14325
14326 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
14327 totalParsedInputLength += parsedInput.length;
14328 } // don't parse if it's not a known token
14329
14330
14331 if (formatTokenFunctions[token]) {
14332 if (parsedInput) {
14333 getParsingFlags(config).empty = false;
14334 } else {
14335 getParsingFlags(config).unusedTokens.push(token);
14336 }
14337
14338 addTimeToArrayFromToken(token, parsedInput, config);
14339 } else if (config._strict && !parsedInput) {
14340 getParsingFlags(config).unusedTokens.push(token);
14341 }
14342 } // add remaining unparsed input length to the string
14343
14344
14345 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
14346
14347 if (string.length > 0) {
14348 getParsingFlags(config).unusedInput.push(string);
14349 } // clear _12h flag if hour is <= 12
14350
14351
14352 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
14353 getParsingFlags(config).bigHour = undefined;
14354 }
14355
14356 getParsingFlags(config).parsedDateParts = config._a.slice(0);
14357 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
14358
14359 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
14360 configFromArray(config);
14361 checkOverflow(config);
14362 }
14363
14364 function meridiemFixWrap(locale, hour, meridiem) {
14365 var isPm;
14366
14367 if (meridiem == null) {
14368 // nothing to do
14369 return hour;
14370 }
14371
14372 if (locale.meridiemHour != null) {
14373 return locale.meridiemHour(hour, meridiem);
14374 } else if (locale.isPM != null) {
14375 // Fallback
14376 isPm = locale.isPM(meridiem);
14377
14378 if (isPm && hour < 12) {
14379 hour += 12;
14380 }
14381
14382 if (!isPm && hour === 12) {
14383 hour = 0;
14384 }
14385
14386 return hour;
14387 } else {
14388 // this is not supposed to happen
14389 return hour;
14390 }
14391 } // date from string and array of format strings
14392
14393
14394 function configFromStringAndArray(config) {
14395 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
14396
14397 if (config._f.length === 0) {
14398 getParsingFlags(config).invalidFormat = true;
14399 config._d = new Date(NaN);
14400 return;
14401 }
14402
14403 for (i = 0; i < config._f.length; i++) {
14404 currentScore = 0;
14405 tempConfig = copyConfig({}, config);
14406
14407 if (config._useUTC != null) {
14408 tempConfig._useUTC = config._useUTC;
14409 }
14410
14411 tempConfig._f = config._f[i];
14412 configFromStringAndFormat(tempConfig);
14413
14414 if (!isValid(tempConfig)) {
14415 continue;
14416 } // if there is any input that was not parsed add a penalty for that format
14417
14418
14419 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
14420
14421 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
14422 getParsingFlags(tempConfig).score = currentScore;
14423
14424 if (scoreToBeat == null || currentScore < scoreToBeat) {
14425 scoreToBeat = currentScore;
14426 bestMoment = tempConfig;
14427 }
14428 }
14429
14430 extend(config, bestMoment || tempConfig);
14431 }
14432
14433 function configFromObject(config) {
14434 if (config._d) {
14435 return;
14436 }
14437
14438 var i = normalizeObjectUnits(config._i);
14439 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
14440 return obj && parseInt(obj, 10);
14441 });
14442 configFromArray(config);
14443 }
14444
14445 function createFromConfig(config) {
14446 var res = new Moment(checkOverflow(prepareConfig(config)));
14447
14448 if (res._nextDay) {
14449 // Adding is smart enough around DST
14450 res.add(1, 'd');
14451 res._nextDay = undefined;
14452 }
14453
14454 return res;
14455 }
14456
14457 function prepareConfig(config) {
14458 var input = config._i,
14459 format = config._f;
14460 config._locale = config._locale || getLocale(config._l);
14461
14462 if (input === null || format === undefined && input === '') {
14463 return createInvalid({
14464 nullInput: true
14465 });
14466 }
14467
14468 if (typeof input === 'string') {
14469 config._i = input = config._locale.preparse(input);
14470 }
14471
14472 if (isMoment(input)) {
14473 return new Moment(checkOverflow(input));
14474 } else if (isDate(input)) {
14475 config._d = input;
14476 } else if (isArray(format)) {
14477 configFromStringAndArray(config);
14478 } else if (format) {
14479 configFromStringAndFormat(config);
14480 } else {
14481 configFromInput(config);
14482 }
14483
14484 if (!isValid(config)) {
14485 config._d = null;
14486 }
14487
14488 return config;
14489 }
14490
14491 function configFromInput(config) {
14492 var input = config._i;
14493
14494 if (isUndefined(input)) {
14495 config._d = new Date(hooks.now());
14496 } else if (isDate(input)) {
14497 config._d = new Date(input.valueOf());
14498 } else if (typeof input === 'string') {
14499 configFromString(config);
14500 } else if (isArray(input)) {
14501 config._a = map(input.slice(0), function (obj) {
14502 return parseInt(obj, 10);
14503 });
14504 configFromArray(config);
14505 } else if (isObject(input)) {
14506 configFromObject(config);
14507 } else if (isNumber(input)) {
14508 // from milliseconds
14509 config._d = new Date(input);
14510 } else {
14511 hooks.createFromInputFallback(config);
14512 }
14513 }
14514
14515 function createLocalOrUTC(input, format, locale, strict, isUTC) {
14516 var c = {};
14517
14518 if (locale === true || locale === false) {
14519 strict = locale;
14520 locale = undefined;
14521 }
14522
14523 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
14524 input = undefined;
14525 } // object construction must be done this way.
14526 // https://github.com/moment/moment/issues/1423
14527
14528
14529 c._isAMomentObject = true;
14530 c._useUTC = c._isUTC = isUTC;
14531 c._l = locale;
14532 c._i = input;
14533 c._f = format;
14534 c._strict = strict;
14535 return createFromConfig(c);
14536 }
14537
14538 function createLocal(input, format, locale, strict) {
14539 return createLocalOrUTC(input, format, locale, strict, false);
14540 }
14541
14542 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
14543 var other = createLocal.apply(null, arguments);
14544
14545 if (this.isValid() && other.isValid()) {
14546 return other < this ? this : other;
14547 } else {
14548 return createInvalid();
14549 }
14550 });
14551 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
14552 var other = createLocal.apply(null, arguments);
14553
14554 if (this.isValid() && other.isValid()) {
14555 return other > this ? this : other;
14556 } else {
14557 return createInvalid();
14558 }
14559 }); // Pick a moment m from moments so that m[fn](other) is true for all
14560 // other. This relies on the function fn to be transitive.
14561 //
14562 // moments should either be an array of moment objects or an array, whose
14563 // first element is an array of moment objects.
14564
14565 function pickBy(fn, moments) {
14566 var res, i;
14567
14568 if (moments.length === 1 && isArray(moments[0])) {
14569 moments = moments[0];
14570 }
14571
14572 if (!moments.length) {
14573 return createLocal();
14574 }
14575
14576 res = moments[0];
14577
14578 for (i = 1; i < moments.length; ++i) {
14579 if (!moments[i].isValid() || moments[i][fn](res)) {
14580 res = moments[i];
14581 }
14582 }
14583
14584 return res;
14585 } // TODO: Use [].sort instead?
14586
14587
14588 function min() {
14589 var args = [].slice.call(arguments, 0);
14590 return pickBy('isBefore', args);
14591 }
14592
14593 function max() {
14594 var args = [].slice.call(arguments, 0);
14595 return pickBy('isAfter', args);
14596 }
14597
14598 var now = function now() {
14599 return Date.now ? Date.now() : +new Date();
14600 };
14601
14602 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
14603
14604 function isDurationValid(m) {
14605 for (var key in m) {
14606 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
14607 return false;
14608 }
14609 }
14610
14611 var unitHasDecimal = false;
14612
14613 for (var i = 0; i < ordering.length; ++i) {
14614 if (m[ordering[i]]) {
14615 if (unitHasDecimal) {
14616 return false; // only allow non-integers for smallest unit
14617 }
14618
14619 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
14620 unitHasDecimal = true;
14621 }
14622 }
14623 }
14624
14625 return true;
14626 }
14627
14628 function isValid$1() {
14629 return this._isValid;
14630 }
14631
14632 function createInvalid$1() {
14633 return createDuration(NaN);
14634 }
14635
14636 function Duration(duration) {
14637 var normalizedInput = normalizeObjectUnits(duration),
14638 years = normalizedInput.year || 0,
14639 quarters = normalizedInput.quarter || 0,
14640 months = normalizedInput.month || 0,
14641 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
14642 days = normalizedInput.day || 0,
14643 hours = normalizedInput.hour || 0,
14644 minutes = normalizedInput.minute || 0,
14645 seconds = normalizedInput.second || 0,
14646 milliseconds = normalizedInput.millisecond || 0;
14647 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
14648
14649 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
14650 minutes * 6e4 + // 1000 * 60
14651 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
14652 // Because of dateAddRemove treats 24 hours as different from a
14653 // day when working around DST, we need to store them separately
14654
14655 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
14656 // which months you are are talking about, so we have to store
14657 // it separately.
14658
14659 this._months = +months + quarters * 3 + years * 12;
14660 this._data = {};
14661 this._locale = getLocale();
14662
14663 this._bubble();
14664 }
14665
14666 function isDuration(obj) {
14667 return obj instanceof Duration;
14668 }
14669
14670 function absRound(number) {
14671 if (number < 0) {
14672 return Math.round(-1 * number) * -1;
14673 } else {
14674 return Math.round(number);
14675 }
14676 } // FORMATTING
14677
14678
14679 function offset(token, separator) {
14680 addFormatToken(token, 0, 0, function () {
14681 var offset = this.utcOffset();
14682 var sign = '+';
14683
14684 if (offset < 0) {
14685 offset = -offset;
14686 sign = '-';
14687 }
14688
14689 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
14690 });
14691 }
14692
14693 offset('Z', ':');
14694 offset('ZZ', ''); // PARSING
14695
14696 addRegexToken('Z', matchShortOffset);
14697 addRegexToken('ZZ', matchShortOffset);
14698 addParseToken(['Z', 'ZZ'], function (input, array, config) {
14699 config._useUTC = true;
14700 config._tzm = offsetFromString(matchShortOffset, input);
14701 }); // HELPERS
14702 // timezone chunker
14703 // '+10:00' > ['10', '00']
14704 // '-1530' > ['-15', '30']
14705
14706 var chunkOffset = /([\+\-]|\d\d)/gi;
14707
14708 function offsetFromString(matcher, string) {
14709 var matches = (string || '').match(matcher);
14710
14711 if (matches === null) {
14712 return null;
14713 }
14714
14715 var chunk = matches[matches.length - 1] || [];
14716 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
14717 var minutes = +(parts[1] * 60) + toInt(parts[2]);
14718 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
14719 } // Return a moment from input, that is local/utc/zone equivalent to model.
14720
14721
14722 function cloneWithOffset(input, model) {
14723 var res, diff;
14724
14725 if (model._isUTC) {
14726 res = model.clone();
14727 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
14728
14729 res._d.setTime(res._d.valueOf() + diff);
14730
14731 hooks.updateOffset(res, false);
14732 return res;
14733 } else {
14734 return createLocal(input).local();
14735 }
14736 }
14737
14738 function getDateOffset(m) {
14739 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
14740 // https://github.com/moment/moment/pull/1871
14741 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
14742 } // HOOKS
14743 // This function will be called whenever a moment is mutated.
14744 // It is intended to keep the offset in sync with the timezone.
14745
14746
14747 hooks.updateOffset = function () {}; // MOMENTS
14748 // keepLocalTime = true means only change the timezone, without
14749 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
14750 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
14751 // +0200, so we adjust the time as needed, to be valid.
14752 //
14753 // Keeping the time actually adds/subtracts (one hour)
14754 // from the actual represented time. That is why we call updateOffset
14755 // a second time. In case it wants us to change the offset again
14756 // _changeInProgress == true case, then we have to adjust, because
14757 // there is no such time in the given timezone.
14758
14759
14760 function getSetOffset(input, keepLocalTime, keepMinutes) {
14761 var offset = this._offset || 0,
14762 localAdjust;
14763
14764 if (!this.isValid()) {
14765 return input != null ? this : NaN;
14766 }
14767
14768 if (input != null) {
14769 if (typeof input === 'string') {
14770 input = offsetFromString(matchShortOffset, input);
14771
14772 if (input === null) {
14773 return this;
14774 }
14775 } else if (Math.abs(input) < 16 && !keepMinutes) {
14776 input = input * 60;
14777 }
14778
14779 if (!this._isUTC && keepLocalTime) {
14780 localAdjust = getDateOffset(this);
14781 }
14782
14783 this._offset = input;
14784 this._isUTC = true;
14785
14786 if (localAdjust != null) {
14787 this.add(localAdjust, 'm');
14788 }
14789
14790 if (offset !== input) {
14791 if (!keepLocalTime || this._changeInProgress) {
14792 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
14793 } else if (!this._changeInProgress) {
14794 this._changeInProgress = true;
14795 hooks.updateOffset(this, true);
14796 this._changeInProgress = null;
14797 }
14798 }
14799
14800 return this;
14801 } else {
14802 return this._isUTC ? offset : getDateOffset(this);
14803 }
14804 }
14805
14806 function getSetZone(input, keepLocalTime) {
14807 if (input != null) {
14808 if (typeof input !== 'string') {
14809 input = -input;
14810 }
14811
14812 this.utcOffset(input, keepLocalTime);
14813 return this;
14814 } else {
14815 return -this.utcOffset();
14816 }
14817 }
14818
14819 function setOffsetToUTC(keepLocalTime) {
14820 return this.utcOffset(0, keepLocalTime);
14821 }
14822
14823 function setOffsetToLocal(keepLocalTime) {
14824 if (this._isUTC) {
14825 this.utcOffset(0, keepLocalTime);
14826 this._isUTC = false;
14827
14828 if (keepLocalTime) {
14829 this.subtract(getDateOffset(this), 'm');
14830 }
14831 }
14832
14833 return this;
14834 }
14835
14836 function setOffsetToParsedOffset() {
14837 if (this._tzm != null) {
14838 this.utcOffset(this._tzm, false, true);
14839 } else if (typeof this._i === 'string') {
14840 var tZone = offsetFromString(matchOffset, this._i);
14841
14842 if (tZone != null) {
14843 this.utcOffset(tZone);
14844 } else {
14845 this.utcOffset(0, true);
14846 }
14847 }
14848
14849 return this;
14850 }
14851
14852 function hasAlignedHourOffset(input) {
14853 if (!this.isValid()) {
14854 return false;
14855 }
14856
14857 input = input ? createLocal(input).utcOffset() : 0;
14858 return (this.utcOffset() - input) % 60 === 0;
14859 }
14860
14861 function isDaylightSavingTime() {
14862 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
14863 }
14864
14865 function isDaylightSavingTimeShifted() {
14866 if (!isUndefined(this._isDSTShifted)) {
14867 return this._isDSTShifted;
14868 }
14869
14870 var c = {};
14871 copyConfig(c, this);
14872 c = prepareConfig(c);
14873
14874 if (c._a) {
14875 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
14876 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
14877 } else {
14878 this._isDSTShifted = false;
14879 }
14880
14881 return this._isDSTShifted;
14882 }
14883
14884 function isLocal() {
14885 return this.isValid() ? !this._isUTC : false;
14886 }
14887
14888 function isUtcOffset() {
14889 return this.isValid() ? this._isUTC : false;
14890 }
14891
14892 function isUtc() {
14893 return this.isValid() ? this._isUTC && this._offset === 0 : false;
14894 } // ASP.NET json date format regex
14895
14896
14897 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
14898 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
14899 // and further modified to allow for strings containing both week and day
14900
14901 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)?)?$/;
14902
14903 function createDuration(input, key) {
14904 var duration = input,
14905 // matching against regexp is expensive, do it on demand
14906 match = null,
14907 sign,
14908 ret,
14909 diffRes;
14910
14911 if (isDuration(input)) {
14912 duration = {
14913 ms: input._milliseconds,
14914 d: input._days,
14915 M: input._months
14916 };
14917 } else if (isNumber(input)) {
14918 duration = {};
14919
14920 if (key) {
14921 duration[key] = input;
14922 } else {
14923 duration.milliseconds = input;
14924 }
14925 } else if (!!(match = aspNetRegex.exec(input))) {
14926 sign = match[1] === '-' ? -1 : 1;
14927 duration = {
14928 y: 0,
14929 d: toInt(match[DATE]) * sign,
14930 h: toInt(match[HOUR]) * sign,
14931 m: toInt(match[MINUTE]) * sign,
14932 s: toInt(match[SECOND]) * sign,
14933 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
14934
14935 };
14936 } else if (!!(match = isoRegex.exec(input))) {
14937 sign = match[1] === '-' ? -1 : 1;
14938 duration = {
14939 y: parseIso(match[2], sign),
14940 M: parseIso(match[3], sign),
14941 w: parseIso(match[4], sign),
14942 d: parseIso(match[5], sign),
14943 h: parseIso(match[6], sign),
14944 m: parseIso(match[7], sign),
14945 s: parseIso(match[8], sign)
14946 };
14947 } else if (duration == null) {
14948 // checks for null or undefined
14949 duration = {};
14950 } else if (_typeof(duration) === 'object' && ('from' in duration || 'to' in duration)) {
14951 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
14952 duration = {};
14953 duration.ms = diffRes.milliseconds;
14954 duration.M = diffRes.months;
14955 }
14956
14957 ret = new Duration(duration);
14958
14959 if (isDuration(input) && hasOwnProp(input, '_locale')) {
14960 ret._locale = input._locale;
14961 }
14962
14963 return ret;
14964 }
14965
14966 createDuration.fn = Duration.prototype;
14967 createDuration.invalid = createInvalid$1;
14968
14969 function parseIso(inp, sign) {
14970 // We'd normally use ~~inp for this, but unfortunately it also
14971 // converts floats to ints.
14972 // inp may be undefined, so careful calling replace on it.
14973 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
14974
14975 return (isNaN(res) ? 0 : res) * sign;
14976 }
14977
14978 function positiveMomentsDifference(base, other) {
14979 var res = {};
14980 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
14981
14982 if (base.clone().add(res.months, 'M').isAfter(other)) {
14983 --res.months;
14984 }
14985
14986 res.milliseconds = +other - +base.clone().add(res.months, 'M');
14987 return res;
14988 }
14989
14990 function momentsDifference(base, other) {
14991 var res;
14992
14993 if (!(base.isValid() && other.isValid())) {
14994 return {
14995 milliseconds: 0,
14996 months: 0
14997 };
14998 }
14999
15000 other = cloneWithOffset(other, base);
15001
15002 if (base.isBefore(other)) {
15003 res = positiveMomentsDifference(base, other);
15004 } else {
15005 res = positiveMomentsDifference(other, base);
15006 res.milliseconds = -res.milliseconds;
15007 res.months = -res.months;
15008 }
15009
15010 return res;
15011 } // TODO: remove 'name' arg after deprecation is removed
15012
15013
15014 function createAdder(direction, name) {
15015 return function (val, period) {
15016 var dur, tmp; //invert the arguments, but complain about it
15017
15018 if (period !== null && !isNaN(+period)) {
15019 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.');
15020 tmp = val;
15021 val = period;
15022 period = tmp;
15023 }
15024
15025 val = typeof val === 'string' ? +val : val;
15026 dur = createDuration(val, period);
15027 addSubtract(this, dur, direction);
15028 return this;
15029 };
15030 }
15031
15032 function addSubtract(mom, duration, isAdding, updateOffset) {
15033 var milliseconds = duration._milliseconds,
15034 days = absRound(duration._days),
15035 months = absRound(duration._months);
15036
15037 if (!mom.isValid()) {
15038 // No op
15039 return;
15040 }
15041
15042 updateOffset = updateOffset == null ? true : updateOffset;
15043
15044 if (months) {
15045 setMonth(mom, get(mom, 'Month') + months * isAdding);
15046 }
15047
15048 if (days) {
15049 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
15050 }
15051
15052 if (milliseconds) {
15053 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
15054 }
15055
15056 if (updateOffset) {
15057 hooks.updateOffset(mom, days || months);
15058 }
15059 }
15060
15061 var add = createAdder(1, 'add');
15062 var subtract = createAdder(-1, 'subtract');
15063
15064 function getCalendarFormat(myMoment, now) {
15065 var diff = myMoment.diff(now, 'days', true);
15066 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
15067 }
15068
15069 function calendar$1(time, formats) {
15070 // We want to compare the start of today, vs this.
15071 // Getting start-of-today depends on whether we're local/utc/offset or not.
15072 var now = time || createLocal(),
15073 sod = cloneWithOffset(now, this).startOf('day'),
15074 format = hooks.calendarFormat(this, sod) || 'sameElse';
15075 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
15076 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
15077 }
15078
15079 function clone() {
15080 return new Moment(this);
15081 }
15082
15083 function isAfter(input, units) {
15084 var localInput = isMoment(input) ? input : createLocal(input);
15085
15086 if (!(this.isValid() && localInput.isValid())) {
15087 return false;
15088 }
15089
15090 units = normalizeUnits(units) || 'millisecond';
15091
15092 if (units === 'millisecond') {
15093 return this.valueOf() > localInput.valueOf();
15094 } else {
15095 return localInput.valueOf() < this.clone().startOf(units).valueOf();
15096 }
15097 }
15098
15099 function isBefore(input, units) {
15100 var localInput = isMoment(input) ? input : createLocal(input);
15101
15102 if (!(this.isValid() && localInput.isValid())) {
15103 return false;
15104 }
15105
15106 units = normalizeUnits(units) || 'millisecond';
15107
15108 if (units === 'millisecond') {
15109 return this.valueOf() < localInput.valueOf();
15110 } else {
15111 return this.clone().endOf(units).valueOf() < localInput.valueOf();
15112 }
15113 }
15114
15115 function isBetween(from, to, units, inclusivity) {
15116 var localFrom = isMoment(from) ? from : createLocal(from),
15117 localTo = isMoment(to) ? to : createLocal(to);
15118
15119 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
15120 return false;
15121 }
15122
15123 inclusivity = inclusivity || '()';
15124 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
15125 }
15126
15127 function isSame(input, units) {
15128 var localInput = isMoment(input) ? input : createLocal(input),
15129 inputMs;
15130
15131 if (!(this.isValid() && localInput.isValid())) {
15132 return false;
15133 }
15134
15135 units = normalizeUnits(units) || 'millisecond';
15136
15137 if (units === 'millisecond') {
15138 return this.valueOf() === localInput.valueOf();
15139 } else {
15140 inputMs = localInput.valueOf();
15141 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
15142 }
15143 }
15144
15145 function isSameOrAfter(input, units) {
15146 return this.isSame(input, units) || this.isAfter(input, units);
15147 }
15148
15149 function isSameOrBefore(input, units) {
15150 return this.isSame(input, units) || this.isBefore(input, units);
15151 }
15152
15153 function diff(input, units, asFloat) {
15154 var that, zoneDelta, output;
15155
15156 if (!this.isValid()) {
15157 return NaN;
15158 }
15159
15160 that = cloneWithOffset(input, this);
15161
15162 if (!that.isValid()) {
15163 return NaN;
15164 }
15165
15166 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
15167 units = normalizeUnits(units);
15168
15169 switch (units) {
15170 case 'year':
15171 output = monthDiff(this, that) / 12;
15172 break;
15173
15174 case 'month':
15175 output = monthDiff(this, that);
15176 break;
15177
15178 case 'quarter':
15179 output = monthDiff(this, that) / 3;
15180 break;
15181
15182 case 'second':
15183 output = (this - that) / 1e3;
15184 break;
15185 // 1000
15186
15187 case 'minute':
15188 output = (this - that) / 6e4;
15189 break;
15190 // 1000 * 60
15191
15192 case 'hour':
15193 output = (this - that) / 36e5;
15194 break;
15195 // 1000 * 60 * 60
15196
15197 case 'day':
15198 output = (this - that - zoneDelta) / 864e5;
15199 break;
15200 // 1000 * 60 * 60 * 24, negate dst
15201
15202 case 'week':
15203 output = (this - that - zoneDelta) / 6048e5;
15204 break;
15205 // 1000 * 60 * 60 * 24 * 7, negate dst
15206
15207 default:
15208 output = this - that;
15209 }
15210
15211 return asFloat ? output : absFloor(output);
15212 }
15213
15214 function monthDiff(a, b) {
15215 // difference in months
15216 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
15217 // b is in (anchor - 1 month, anchor + 1 month)
15218 anchor = a.clone().add(wholeMonthDiff, 'months'),
15219 anchor2,
15220 adjust;
15221
15222 if (b - anchor < 0) {
15223 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
15224
15225 adjust = (b - anchor) / (anchor - anchor2);
15226 } else {
15227 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
15228
15229 adjust = (b - anchor) / (anchor2 - anchor);
15230 } //check for negative zero, return zero if negative zero
15231
15232
15233 return -(wholeMonthDiff + adjust) || 0;
15234 }
15235
15236 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
15237 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
15238
15239 function toString() {
15240 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
15241 }
15242
15243 function toISOString(keepOffset) {
15244 if (!this.isValid()) {
15245 return null;
15246 }
15247
15248 var utc = keepOffset !== true;
15249 var m = utc ? this.clone().utc() : this;
15250
15251 if (m.year() < 0 || m.year() > 9999) {
15252 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
15253 }
15254
15255 if (isFunction(Date.prototype.toISOString)) {
15256 // native implementation is ~50x faster, use it when we can
15257 if (utc) {
15258 return this.toDate().toISOString();
15259 } else {
15260 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
15261 }
15262 }
15263
15264 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
15265 }
15266 /**
15267 * Return a human readable representation of a moment that can
15268 * also be evaluated to get a new moment which is the same
15269 *
15270 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
15271 */
15272
15273
15274 function inspect() {
15275 if (!this.isValid()) {
15276 return 'moment.invalid(/* ' + this._i + ' */)';
15277 }
15278
15279 var func = 'moment';
15280 var zone = '';
15281
15282 if (!this.isLocal()) {
15283 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
15284 zone = 'Z';
15285 }
15286
15287 var prefix = '[' + func + '("]';
15288 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
15289 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
15290 var suffix = zone + '[")]';
15291 return this.format(prefix + year + datetime + suffix);
15292 }
15293
15294 function format(inputString) {
15295 if (!inputString) {
15296 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
15297 }
15298
15299 var output = formatMoment(this, inputString);
15300 return this.localeData().postformat(output);
15301 }
15302
15303 function from(time, withoutSuffix) {
15304 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
15305 return createDuration({
15306 to: this,
15307 from: time
15308 }).locale(this.locale()).humanize(!withoutSuffix);
15309 } else {
15310 return this.localeData().invalidDate();
15311 }
15312 }
15313
15314 function fromNow(withoutSuffix) {
15315 return this.from(createLocal(), withoutSuffix);
15316 }
15317
15318 function to(time, withoutSuffix) {
15319 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
15320 return createDuration({
15321 from: this,
15322 to: time
15323 }).locale(this.locale()).humanize(!withoutSuffix);
15324 } else {
15325 return this.localeData().invalidDate();
15326 }
15327 }
15328
15329 function toNow(withoutSuffix) {
15330 return this.to(createLocal(), withoutSuffix);
15331 } // If passed a locale key, it will set the locale for this
15332 // instance. Otherwise, it will return the locale configuration
15333 // variables for this instance.
15334
15335
15336 function locale(key) {
15337 var newLocaleData;
15338
15339 if (key === undefined) {
15340 return this._locale._abbr;
15341 } else {
15342 newLocaleData = getLocale(key);
15343
15344 if (newLocaleData != null) {
15345 this._locale = newLocaleData;
15346 }
15347
15348 return this;
15349 }
15350 }
15351
15352 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
15353 if (key === undefined) {
15354 return this.localeData();
15355 } else {
15356 return this.locale(key);
15357 }
15358 });
15359
15360 function localeData() {
15361 return this._locale;
15362 }
15363
15364 var MS_PER_SECOND = 1000;
15365 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
15366 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
15367 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
15368
15369 function mod$1(dividend, divisor) {
15370 return (dividend % divisor + divisor) % divisor;
15371 }
15372
15373 function localStartOfDate(y, m, d) {
15374 // the date constructor remaps years 0-99 to 1900-1999
15375 if (y < 100 && y >= 0) {
15376 // preserve leap years using a full 400 year cycle, then reset
15377 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
15378 } else {
15379 return new Date(y, m, d).valueOf();
15380 }
15381 }
15382
15383 function utcStartOfDate(y, m, d) {
15384 // Date.UTC remaps years 0-99 to 1900-1999
15385 if (y < 100 && y >= 0) {
15386 // preserve leap years using a full 400 year cycle, then reset
15387 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
15388 } else {
15389 return Date.UTC(y, m, d);
15390 }
15391 }
15392
15393 function startOf(units) {
15394 var time;
15395 units = normalizeUnits(units);
15396
15397 if (units === undefined || units === 'millisecond' || !this.isValid()) {
15398 return this;
15399 }
15400
15401 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
15402
15403 switch (units) {
15404 case 'year':
15405 time = startOfDate(this.year(), 0, 1);
15406 break;
15407
15408 case 'quarter':
15409 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
15410 break;
15411
15412 case 'month':
15413 time = startOfDate(this.year(), this.month(), 1);
15414 break;
15415
15416 case 'week':
15417 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
15418 break;
15419
15420 case 'isoWeek':
15421 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
15422 break;
15423
15424 case 'day':
15425 case 'date':
15426 time = startOfDate(this.year(), this.month(), this.date());
15427 break;
15428
15429 case 'hour':
15430 time = this._d.valueOf();
15431 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
15432 break;
15433
15434 case 'minute':
15435 time = this._d.valueOf();
15436 time -= mod$1(time, MS_PER_MINUTE);
15437 break;
15438
15439 case 'second':
15440 time = this._d.valueOf();
15441 time -= mod$1(time, MS_PER_SECOND);
15442 break;
15443 }
15444
15445 this._d.setTime(time);
15446
15447 hooks.updateOffset(this, true);
15448 return this;
15449 }
15450
15451 function endOf(units) {
15452 var time;
15453 units = normalizeUnits(units);
15454
15455 if (units === undefined || units === 'millisecond' || !this.isValid()) {
15456 return this;
15457 }
15458
15459 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
15460
15461 switch (units) {
15462 case 'year':
15463 time = startOfDate(this.year() + 1, 0, 1) - 1;
15464 break;
15465
15466 case 'quarter':
15467 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
15468 break;
15469
15470 case 'month':
15471 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
15472 break;
15473
15474 case 'week':
15475 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
15476 break;
15477
15478 case 'isoWeek':
15479 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
15480 break;
15481
15482 case 'day':
15483 case 'date':
15484 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
15485 break;
15486
15487 case 'hour':
15488 time = this._d.valueOf();
15489 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
15490 break;
15491
15492 case 'minute':
15493 time = this._d.valueOf();
15494 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
15495 break;
15496
15497 case 'second':
15498 time = this._d.valueOf();
15499 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
15500 break;
15501 }
15502
15503 this._d.setTime(time);
15504
15505 hooks.updateOffset(this, true);
15506 return this;
15507 }
15508
15509 function valueOf() {
15510 return this._d.valueOf() - (this._offset || 0) * 60000;
15511 }
15512
15513 function unix() {
15514 return Math.floor(this.valueOf() / 1000);
15515 }
15516
15517 function toDate() {
15518 return new Date(this.valueOf());
15519 }
15520
15521 function toArray() {
15522 var m = this;
15523 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
15524 }
15525
15526 function toObject() {
15527 var m = this;
15528 return {
15529 years: m.year(),
15530 months: m.month(),
15531 date: m.date(),
15532 hours: m.hours(),
15533 minutes: m.minutes(),
15534 seconds: m.seconds(),
15535 milliseconds: m.milliseconds()
15536 };
15537 }
15538
15539 function toJSON() {
15540 // new Date(NaN).toJSON() === null
15541 return this.isValid() ? this.toISOString() : null;
15542 }
15543
15544 function isValid$2() {
15545 return isValid(this);
15546 }
15547
15548 function parsingFlags() {
15549 return extend({}, getParsingFlags(this));
15550 }
15551
15552 function invalidAt() {
15553 return getParsingFlags(this).overflow;
15554 }
15555
15556 function creationData() {
15557 return {
15558 input: this._i,
15559 format: this._f,
15560 locale: this._locale,
15561 isUTC: this._isUTC,
15562 strict: this._strict
15563 };
15564 } // FORMATTING
15565
15566
15567 addFormatToken(0, ['gg', 2], 0, function () {
15568 return this.weekYear() % 100;
15569 });
15570 addFormatToken(0, ['GG', 2], 0, function () {
15571 return this.isoWeekYear() % 100;
15572 });
15573
15574 function addWeekYearFormatToken(token, getter) {
15575 addFormatToken(0, [token, token.length], 0, getter);
15576 }
15577
15578 addWeekYearFormatToken('gggg', 'weekYear');
15579 addWeekYearFormatToken('ggggg', 'weekYear');
15580 addWeekYearFormatToken('GGGG', 'isoWeekYear');
15581 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
15582
15583 addUnitAlias('weekYear', 'gg');
15584 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
15585
15586 addUnitPriority('weekYear', 1);
15587 addUnitPriority('isoWeekYear', 1); // PARSING
15588
15589 addRegexToken('G', matchSigned);
15590 addRegexToken('g', matchSigned);
15591 addRegexToken('GG', match1to2, match2);
15592 addRegexToken('gg', match1to2, match2);
15593 addRegexToken('GGGG', match1to4, match4);
15594 addRegexToken('gggg', match1to4, match4);
15595 addRegexToken('GGGGG', match1to6, match6);
15596 addRegexToken('ggggg', match1to6, match6);
15597 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
15598 week[token.substr(0, 2)] = toInt(input);
15599 });
15600 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
15601 week[token] = hooks.parseTwoDigitYear(input);
15602 }); // MOMENTS
15603
15604 function getSetWeekYear(input) {
15605 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
15606 }
15607
15608 function getSetISOWeekYear(input) {
15609 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
15610 }
15611
15612 function getISOWeeksInYear() {
15613 return weeksInYear(this.year(), 1, 4);
15614 }
15615
15616 function getWeeksInYear() {
15617 var weekInfo = this.localeData()._week;
15618
15619 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
15620 }
15621
15622 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
15623 var weeksTarget;
15624
15625 if (input == null) {
15626 return weekOfYear(this, dow, doy).year;
15627 } else {
15628 weeksTarget = weeksInYear(input, dow, doy);
15629
15630 if (week > weeksTarget) {
15631 week = weeksTarget;
15632 }
15633
15634 return setWeekAll.call(this, input, week, weekday, dow, doy);
15635 }
15636 }
15637
15638 function setWeekAll(weekYear, week, weekday, dow, doy) {
15639 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
15640 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
15641 this.year(date.getUTCFullYear());
15642 this.month(date.getUTCMonth());
15643 this.date(date.getUTCDate());
15644 return this;
15645 } // FORMATTING
15646
15647
15648 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
15649
15650 addUnitAlias('quarter', 'Q'); // PRIORITY
15651
15652 addUnitPriority('quarter', 7); // PARSING
15653
15654 addRegexToken('Q', match1);
15655 addParseToken('Q', function (input, array) {
15656 array[MONTH] = (toInt(input) - 1) * 3;
15657 }); // MOMENTS
15658
15659 function getSetQuarter(input) {
15660 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
15661 } // FORMATTING
15662
15663
15664 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
15665
15666 addUnitAlias('date', 'D'); // PRIORITY
15667
15668 addUnitPriority('date', 9); // PARSING
15669
15670 addRegexToken('D', match1to2);
15671 addRegexToken('DD', match1to2, match2);
15672 addRegexToken('Do', function (isStrict, locale) {
15673 // TODO: Remove "ordinalParse" fallback in next major release.
15674 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
15675 });
15676 addParseToken(['D', 'DD'], DATE);
15677 addParseToken('Do', function (input, array) {
15678 array[DATE] = toInt(input.match(match1to2)[0]);
15679 }); // MOMENTS
15680
15681 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
15682
15683 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
15684
15685 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
15686
15687 addUnitPriority('dayOfYear', 4); // PARSING
15688
15689 addRegexToken('DDD', match1to3);
15690 addRegexToken('DDDD', match3);
15691 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
15692 config._dayOfYear = toInt(input);
15693 }); // HELPERS
15694 // MOMENTS
15695
15696 function getSetDayOfYear(input) {
15697 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
15698 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
15699 } // FORMATTING
15700
15701
15702 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
15703
15704 addUnitAlias('minute', 'm'); // PRIORITY
15705
15706 addUnitPriority('minute', 14); // PARSING
15707
15708 addRegexToken('m', match1to2);
15709 addRegexToken('mm', match1to2, match2);
15710 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
15711
15712 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
15713
15714 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
15715
15716 addUnitAlias('second', 's'); // PRIORITY
15717
15718 addUnitPriority('second', 15); // PARSING
15719
15720 addRegexToken('s', match1to2);
15721 addRegexToken('ss', match1to2, match2);
15722 addParseToken(['s', 'ss'], SECOND); // MOMENTS
15723
15724 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
15725
15726 addFormatToken('S', 0, 0, function () {
15727 return ~~(this.millisecond() / 100);
15728 });
15729 addFormatToken(0, ['SS', 2], 0, function () {
15730 return ~~(this.millisecond() / 10);
15731 });
15732 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
15733 addFormatToken(0, ['SSSS', 4], 0, function () {
15734 return this.millisecond() * 10;
15735 });
15736 addFormatToken(0, ['SSSSS', 5], 0, function () {
15737 return this.millisecond() * 100;
15738 });
15739 addFormatToken(0, ['SSSSSS', 6], 0, function () {
15740 return this.millisecond() * 1000;
15741 });
15742 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
15743 return this.millisecond() * 10000;
15744 });
15745 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
15746 return this.millisecond() * 100000;
15747 });
15748 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
15749 return this.millisecond() * 1000000;
15750 }); // ALIASES
15751
15752 addUnitAlias('millisecond', 'ms'); // PRIORITY
15753
15754 addUnitPriority('millisecond', 16); // PARSING
15755
15756 addRegexToken('S', match1to3, match1);
15757 addRegexToken('SS', match1to3, match2);
15758 addRegexToken('SSS', match1to3, match3);
15759 var token;
15760
15761 for (token = 'SSSS'; token.length <= 9; token += 'S') {
15762 addRegexToken(token, matchUnsigned);
15763 }
15764
15765 function parseMs(input, array) {
15766 array[MILLISECOND] = toInt(('0.' + input) * 1000);
15767 }
15768
15769 for (token = 'S'; token.length <= 9; token += 'S') {
15770 addParseToken(token, parseMs);
15771 } // MOMENTS
15772
15773
15774 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
15775
15776 addFormatToken('z', 0, 0, 'zoneAbbr');
15777 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
15778
15779 function getZoneAbbr() {
15780 return this._isUTC ? 'UTC' : '';
15781 }
15782
15783 function getZoneName() {
15784 return this._isUTC ? 'Coordinated Universal Time' : '';
15785 }
15786
15787 var proto = Moment.prototype;
15788 proto.add = add;
15789 proto.calendar = calendar$1;
15790 proto.clone = clone;
15791 proto.diff = diff;
15792 proto.endOf = endOf;
15793 proto.format = format;
15794 proto.from = from;
15795 proto.fromNow = fromNow;
15796 proto.to = to;
15797 proto.toNow = toNow;
15798 proto.get = stringGet;
15799 proto.invalidAt = invalidAt;
15800 proto.isAfter = isAfter;
15801 proto.isBefore = isBefore;
15802 proto.isBetween = isBetween;
15803 proto.isSame = isSame;
15804 proto.isSameOrAfter = isSameOrAfter;
15805 proto.isSameOrBefore = isSameOrBefore;
15806 proto.isValid = isValid$2;
15807 proto.lang = lang;
15808 proto.locale = locale;
15809 proto.localeData = localeData;
15810 proto.max = prototypeMax;
15811 proto.min = prototypeMin;
15812 proto.parsingFlags = parsingFlags;
15813 proto.set = stringSet;
15814 proto.startOf = startOf;
15815 proto.subtract = subtract;
15816 proto.toArray = toArray;
15817 proto.toObject = toObject;
15818 proto.toDate = toDate;
15819 proto.toISOString = toISOString;
15820 proto.inspect = inspect;
15821 proto.toJSON = toJSON;
15822 proto.toString = toString;
15823 proto.unix = unix;
15824 proto.valueOf = valueOf;
15825 proto.creationData = creationData;
15826 proto.year = getSetYear;
15827 proto.isLeapYear = getIsLeapYear;
15828 proto.weekYear = getSetWeekYear;
15829 proto.isoWeekYear = getSetISOWeekYear;
15830 proto.quarter = proto.quarters = getSetQuarter;
15831 proto.month = getSetMonth;
15832 proto.daysInMonth = getDaysInMonth;
15833 proto.week = proto.weeks = getSetWeek;
15834 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
15835 proto.weeksInYear = getWeeksInYear;
15836 proto.isoWeeksInYear = getISOWeeksInYear;
15837 proto.date = getSetDayOfMonth;
15838 proto.day = proto.days = getSetDayOfWeek;
15839 proto.weekday = getSetLocaleDayOfWeek;
15840 proto.isoWeekday = getSetISODayOfWeek;
15841 proto.dayOfYear = getSetDayOfYear;
15842 proto.hour = proto.hours = getSetHour;
15843 proto.minute = proto.minutes = getSetMinute;
15844 proto.second = proto.seconds = getSetSecond;
15845 proto.millisecond = proto.milliseconds = getSetMillisecond;
15846 proto.utcOffset = getSetOffset;
15847 proto.utc = setOffsetToUTC;
15848 proto.local = setOffsetToLocal;
15849 proto.parseZone = setOffsetToParsedOffset;
15850 proto.hasAlignedHourOffset = hasAlignedHourOffset;
15851 proto.isDST = isDaylightSavingTime;
15852 proto.isLocal = isLocal;
15853 proto.isUtcOffset = isUtcOffset;
15854 proto.isUtc = isUtc;
15855 proto.isUTC = isUtc;
15856 proto.zoneAbbr = getZoneAbbr;
15857 proto.zoneName = getZoneName;
15858 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
15859 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
15860 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
15861 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
15862 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
15863
15864 function createUnix(input) {
15865 return createLocal(input * 1000);
15866 }
15867
15868 function createInZone() {
15869 return createLocal.apply(null, arguments).parseZone();
15870 }
15871
15872 function preParsePostFormat(string) {
15873 return string;
15874 }
15875
15876 var proto$1 = Locale.prototype;
15877 proto$1.calendar = calendar;
15878 proto$1.longDateFormat = longDateFormat;
15879 proto$1.invalidDate = invalidDate;
15880 proto$1.ordinal = ordinal;
15881 proto$1.preparse = preParsePostFormat;
15882 proto$1.postformat = preParsePostFormat;
15883 proto$1.relativeTime = relativeTime;
15884 proto$1.pastFuture = pastFuture;
15885 proto$1.set = set;
15886 proto$1.months = localeMonths;
15887 proto$1.monthsShort = localeMonthsShort;
15888 proto$1.monthsParse = localeMonthsParse;
15889 proto$1.monthsRegex = monthsRegex;
15890 proto$1.monthsShortRegex = monthsShortRegex;
15891 proto$1.week = localeWeek;
15892 proto$1.firstDayOfYear = localeFirstDayOfYear;
15893 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
15894 proto$1.weekdays = localeWeekdays;
15895 proto$1.weekdaysMin = localeWeekdaysMin;
15896 proto$1.weekdaysShort = localeWeekdaysShort;
15897 proto$1.weekdaysParse = localeWeekdaysParse;
15898 proto$1.weekdaysRegex = weekdaysRegex;
15899 proto$1.weekdaysShortRegex = weekdaysShortRegex;
15900 proto$1.weekdaysMinRegex = weekdaysMinRegex;
15901 proto$1.isPM = localeIsPM;
15902 proto$1.meridiem = localeMeridiem;
15903
15904 function get$1(format, index, field, setter) {
15905 var locale = getLocale();
15906 var utc = createUTC().set(setter, index);
15907 return locale[field](utc, format);
15908 }
15909
15910 function listMonthsImpl(format, index, field) {
15911 if (isNumber(format)) {
15912 index = format;
15913 format = undefined;
15914 }
15915
15916 format = format || '';
15917
15918 if (index != null) {
15919 return get$1(format, index, field, 'month');
15920 }
15921
15922 var i;
15923 var out = [];
15924
15925 for (i = 0; i < 12; i++) {
15926 out[i] = get$1(format, i, field, 'month');
15927 }
15928
15929 return out;
15930 } // ()
15931 // (5)
15932 // (fmt, 5)
15933 // (fmt)
15934 // (true)
15935 // (true, 5)
15936 // (true, fmt, 5)
15937 // (true, fmt)
15938
15939
15940 function listWeekdaysImpl(localeSorted, format, index, field) {
15941 if (typeof localeSorted === 'boolean') {
15942 if (isNumber(format)) {
15943 index = format;
15944 format = undefined;
15945 }
15946
15947 format = format || '';
15948 } else {
15949 format = localeSorted;
15950 index = format;
15951 localeSorted = false;
15952
15953 if (isNumber(format)) {
15954 index = format;
15955 format = undefined;
15956 }
15957
15958 format = format || '';
15959 }
15960
15961 var locale = getLocale(),
15962 shift = localeSorted ? locale._week.dow : 0;
15963
15964 if (index != null) {
15965 return get$1(format, (index + shift) % 7, field, 'day');
15966 }
15967
15968 var i;
15969 var out = [];
15970
15971 for (i = 0; i < 7; i++) {
15972 out[i] = get$1(format, (i + shift) % 7, field, 'day');
15973 }
15974
15975 return out;
15976 }
15977
15978 function listMonths(format, index) {
15979 return listMonthsImpl(format, index, 'months');
15980 }
15981
15982 function listMonthsShort(format, index) {
15983 return listMonthsImpl(format, index, 'monthsShort');
15984 }
15985
15986 function listWeekdays(localeSorted, format, index) {
15987 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
15988 }
15989
15990 function listWeekdaysShort(localeSorted, format, index) {
15991 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
15992 }
15993
15994 function listWeekdaysMin(localeSorted, format, index) {
15995 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
15996 }
15997
15998 getSetGlobalLocale('en', {
15999 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
16000 ordinal: function ordinal(number) {
16001 var b = number % 10,
16002 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
16003 return number + output;
16004 }
16005 }); // Side effect imports
16006
16007 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
16008 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
16009 var mathAbs = Math.abs;
16010
16011 function abs() {
16012 var data = this._data;
16013 this._milliseconds = mathAbs(this._milliseconds);
16014 this._days = mathAbs(this._days);
16015 this._months = mathAbs(this._months);
16016 data.milliseconds = mathAbs(data.milliseconds);
16017 data.seconds = mathAbs(data.seconds);
16018 data.minutes = mathAbs(data.minutes);
16019 data.hours = mathAbs(data.hours);
16020 data.months = mathAbs(data.months);
16021 data.years = mathAbs(data.years);
16022 return this;
16023 }
16024
16025 function addSubtract$1(duration, input, value, direction) {
16026 var other = createDuration(input, value);
16027 duration._milliseconds += direction * other._milliseconds;
16028 duration._days += direction * other._days;
16029 duration._months += direction * other._months;
16030 return duration._bubble();
16031 } // supports only 2.0-style add(1, 's') or add(duration)
16032
16033
16034 function add$1(input, value) {
16035 return addSubtract$1(this, input, value, 1);
16036 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
16037
16038
16039 function subtract$1(input, value) {
16040 return addSubtract$1(this, input, value, -1);
16041 }
16042
16043 function absCeil(number) {
16044 if (number < 0) {
16045 return Math.floor(number);
16046 } else {
16047 return Math.ceil(number);
16048 }
16049 }
16050
16051 function bubble() {
16052 var milliseconds = this._milliseconds;
16053 var days = this._days;
16054 var months = this._months;
16055 var data = this._data;
16056 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
16057 // check: https://github.com/moment/moment/issues/2166
16058
16059 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
16060 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
16061 days = 0;
16062 months = 0;
16063 } // The following code bubbles up values, see the tests for
16064 // examples of what that means.
16065
16066
16067 data.milliseconds = milliseconds % 1000;
16068 seconds = absFloor(milliseconds / 1000);
16069 data.seconds = seconds % 60;
16070 minutes = absFloor(seconds / 60);
16071 data.minutes = minutes % 60;
16072 hours = absFloor(minutes / 60);
16073 data.hours = hours % 24;
16074 days += absFloor(hours / 24); // convert days to months
16075
16076 monthsFromDays = absFloor(daysToMonths(days));
16077 months += monthsFromDays;
16078 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
16079
16080 years = absFloor(months / 12);
16081 months %= 12;
16082 data.days = days;
16083 data.months = months;
16084 data.years = years;
16085 return this;
16086 }
16087
16088 function daysToMonths(days) {
16089 // 400 years have 146097 days (taking into account leap year rules)
16090 // 400 years have 12 months === 4800
16091 return days * 4800 / 146097;
16092 }
16093
16094 function monthsToDays(months) {
16095 // the reverse of daysToMonths
16096 return months * 146097 / 4800;
16097 }
16098
16099 function as(units) {
16100 if (!this.isValid()) {
16101 return NaN;
16102 }
16103
16104 var days;
16105 var months;
16106 var milliseconds = this._milliseconds;
16107 units = normalizeUnits(units);
16108
16109 if (units === 'month' || units === 'quarter' || units === 'year') {
16110 days = this._days + milliseconds / 864e5;
16111 months = this._months + daysToMonths(days);
16112
16113 switch (units) {
16114 case 'month':
16115 return months;
16116
16117 case 'quarter':
16118 return months / 3;
16119
16120 case 'year':
16121 return months / 12;
16122 }
16123 } else {
16124 // handle milliseconds separately because of floating point math errors (issue #1867)
16125 days = this._days + Math.round(monthsToDays(this._months));
16126
16127 switch (units) {
16128 case 'week':
16129 return days / 7 + milliseconds / 6048e5;
16130
16131 case 'day':
16132 return days + milliseconds / 864e5;
16133
16134 case 'hour':
16135 return days * 24 + milliseconds / 36e5;
16136
16137 case 'minute':
16138 return days * 1440 + milliseconds / 6e4;
16139
16140 case 'second':
16141 return days * 86400 + milliseconds / 1000;
16142 // Math.floor prevents floating point math errors here
16143
16144 case 'millisecond':
16145 return Math.floor(days * 864e5) + milliseconds;
16146
16147 default:
16148 throw new Error('Unknown unit ' + units);
16149 }
16150 }
16151 } // TODO: Use this.as('ms')?
16152
16153
16154 function valueOf$1() {
16155 if (!this.isValid()) {
16156 return NaN;
16157 }
16158
16159 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
16160 }
16161
16162 function makeAs(alias) {
16163 return function () {
16164 return this.as(alias);
16165 };
16166 }
16167
16168 var asMilliseconds = makeAs('ms');
16169 var asSeconds = makeAs('s');
16170 var asMinutes = makeAs('m');
16171 var asHours = makeAs('h');
16172 var asDays = makeAs('d');
16173 var asWeeks = makeAs('w');
16174 var asMonths = makeAs('M');
16175 var asQuarters = makeAs('Q');
16176 var asYears = makeAs('y');
16177
16178 function clone$1() {
16179 return createDuration(this);
16180 }
16181
16182 function get$2(units) {
16183 units = normalizeUnits(units);
16184 return this.isValid() ? this[units + 's']() : NaN;
16185 }
16186
16187 function makeGetter(name) {
16188 return function () {
16189 return this.isValid() ? this._data[name] : NaN;
16190 };
16191 }
16192
16193 var milliseconds = makeGetter('milliseconds');
16194 var seconds = makeGetter('seconds');
16195 var minutes = makeGetter('minutes');
16196 var hours = makeGetter('hours');
16197 var days = makeGetter('days');
16198 var months = makeGetter('months');
16199 var years = makeGetter('years');
16200
16201 function weeks() {
16202 return absFloor(this.days() / 7);
16203 }
16204
16205 var round = Math.round;
16206 var thresholds = {
16207 ss: 44,
16208 // a few seconds to seconds
16209 s: 45,
16210 // seconds to minute
16211 m: 45,
16212 // minutes to hour
16213 h: 22,
16214 // hours to day
16215 d: 26,
16216 // days to month
16217 M: 11 // months to year
16218
16219 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
16220
16221 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
16222 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
16223 }
16224
16225 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
16226 var duration = createDuration(posNegDuration).abs();
16227 var seconds = round(duration.as('s'));
16228 var minutes = round(duration.as('m'));
16229 var hours = round(duration.as('h'));
16230 var days = round(duration.as('d'));
16231 var months = round(duration.as('M'));
16232 var years = round(duration.as('y'));
16233 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];
16234 a[2] = withoutSuffix;
16235 a[3] = +posNegDuration > 0;
16236 a[4] = locale;
16237 return substituteTimeAgo.apply(null, a);
16238 } // This function allows you to set the rounding function for relative time strings
16239
16240
16241 function getSetRelativeTimeRounding(roundingFunction) {
16242 if (roundingFunction === undefined) {
16243 return round;
16244 }
16245
16246 if (typeof roundingFunction === 'function') {
16247 round = roundingFunction;
16248 return true;
16249 }
16250
16251 return false;
16252 } // This function allows you to set a threshold for relative time strings
16253
16254
16255 function getSetRelativeTimeThreshold(threshold, limit) {
16256 if (thresholds[threshold] === undefined) {
16257 return false;
16258 }
16259
16260 if (limit === undefined) {
16261 return thresholds[threshold];
16262 }
16263
16264 thresholds[threshold] = limit;
16265
16266 if (threshold === 's') {
16267 thresholds.ss = limit - 1;
16268 }
16269
16270 return true;
16271 }
16272
16273 function humanize(withSuffix) {
16274 if (!this.isValid()) {
16275 return this.localeData().invalidDate();
16276 }
16277
16278 var locale = this.localeData();
16279 var output = relativeTime$1(this, !withSuffix, locale);
16280
16281 if (withSuffix) {
16282 output = locale.pastFuture(+this, output);
16283 }
16284
16285 return locale.postformat(output);
16286 }
16287
16288 var abs$1 = Math.abs;
16289
16290 function sign(x) {
16291 return (x > 0) - (x < 0) || +x;
16292 }
16293
16294 function toISOString$1() {
16295 // for ISO strings we do not use the normal bubbling rules:
16296 // * milliseconds bubble up until they become hours
16297 // * days do not bubble at all
16298 // * months bubble up until they become years
16299 // This is because there is no context-free conversion between hours and days
16300 // (think of clock changes)
16301 // and also not between days and months (28-31 days per month)
16302 if (!this.isValid()) {
16303 return this.localeData().invalidDate();
16304 }
16305
16306 var seconds = abs$1(this._milliseconds) / 1000;
16307 var days = abs$1(this._days);
16308 var months = abs$1(this._months);
16309 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
16310
16311 minutes = absFloor(seconds / 60);
16312 hours = absFloor(minutes / 60);
16313 seconds %= 60;
16314 minutes %= 60; // 12 months -> 1 year
16315
16316 years = absFloor(months / 12);
16317 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
16318
16319 var Y = years;
16320 var M = months;
16321 var D = days;
16322 var h = hours;
16323 var m = minutes;
16324 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
16325 var total = this.asSeconds();
16326
16327 if (!total) {
16328 // this is the same as C#'s (Noda) and python (isodate)...
16329 // but not other JS (goog.date)
16330 return 'P0D';
16331 }
16332
16333 var totalSign = total < 0 ? '-' : '';
16334 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
16335 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
16336 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
16337 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' : '');
16338 }
16339
16340 var proto$2 = Duration.prototype;
16341 proto$2.isValid = isValid$1;
16342 proto$2.abs = abs;
16343 proto$2.add = add$1;
16344 proto$2.subtract = subtract$1;
16345 proto$2.as = as;
16346 proto$2.asMilliseconds = asMilliseconds;
16347 proto$2.asSeconds = asSeconds;
16348 proto$2.asMinutes = asMinutes;
16349 proto$2.asHours = asHours;
16350 proto$2.asDays = asDays;
16351 proto$2.asWeeks = asWeeks;
16352 proto$2.asMonths = asMonths;
16353 proto$2.asQuarters = asQuarters;
16354 proto$2.asYears = asYears;
16355 proto$2.valueOf = valueOf$1;
16356 proto$2._bubble = bubble;
16357 proto$2.clone = clone$1;
16358 proto$2.get = get$2;
16359 proto$2.milliseconds = milliseconds;
16360 proto$2.seconds = seconds;
16361 proto$2.minutes = minutes;
16362 proto$2.hours = hours;
16363 proto$2.days = days;
16364 proto$2.weeks = weeks;
16365 proto$2.months = months;
16366 proto$2.years = years;
16367 proto$2.humanize = humanize;
16368 proto$2.toISOString = toISOString$1;
16369 proto$2.toString = toISOString$1;
16370 proto$2.toJSON = toISOString$1;
16371 proto$2.locale = locale;
16372 proto$2.localeData = localeData;
16373 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
16374 proto$2.lang = lang; // Side effect imports
16375 // FORMATTING
16376
16377 addFormatToken('X', 0, 0, 'unix');
16378 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
16379
16380 addRegexToken('x', matchSigned);
16381 addRegexToken('X', matchTimestamp);
16382 addParseToken('X', function (input, array, config) {
16383 config._d = new Date(parseFloat(input, 10) * 1000);
16384 });
16385 addParseToken('x', function (input, array, config) {
16386 config._d = new Date(toInt(input));
16387 }); // Side effect imports
16388
16389 hooks.version = '2.24.0';
16390 setHookCallback(createLocal);
16391 hooks.fn = proto;
16392 hooks.min = min;
16393 hooks.max = max;
16394 hooks.now = now;
16395 hooks.utc = createUTC;
16396 hooks.unix = createUnix;
16397 hooks.months = listMonths;
16398 hooks.isDate = isDate;
16399 hooks.locale = getSetGlobalLocale;
16400 hooks.invalid = createInvalid;
16401 hooks.duration = createDuration;
16402 hooks.isMoment = isMoment;
16403 hooks.weekdays = listWeekdays;
16404 hooks.parseZone = createInZone;
16405 hooks.localeData = getLocale;
16406 hooks.isDuration = isDuration;
16407 hooks.monthsShort = listMonthsShort;
16408 hooks.weekdaysMin = listWeekdaysMin;
16409 hooks.defineLocale = defineLocale;
16410 hooks.updateLocale = updateLocale;
16411 hooks.locales = listLocales;
16412 hooks.weekdaysShort = listWeekdaysShort;
16413 hooks.normalizeUnits = normalizeUnits;
16414 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
16415 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
16416 hooks.calendarFormat = getCalendarFormat;
16417 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
16418
16419 hooks.HTML5_FMT = {
16420 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
16421 // <input type="datetime-local" />
16422 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
16423 // <input type="datetime-local" step="1" />
16424 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
16425 // <input type="datetime-local" step="0.001" />
16426 DATE: 'YYYY-MM-DD',
16427 // <input type="date" />
16428 TIME: 'HH:mm',
16429 // <input type="time" />
16430 TIME_SECONDS: 'HH:mm:ss',
16431 // <input type="time" step="1" />
16432 TIME_MS: 'HH:mm:ss.SSS',
16433 // <input type="time" step="0.001" />
16434 WEEK: 'GGGG-[W]WW',
16435 // <input type="week" />
16436 MONTH: 'YYYY-MM' // <input type="month" />
16437
16438 };
16439 return hooks;
16440 });
16441}); // Maps for number <-> hex string conversion
16442
16443var byteToHex$2$1 = [];
16444
16445for (var i$2$1 = 0; i$2$1 < 256; i$2$1++) {
16446 byteToHex$2$1[i$2$1] = (i$2$1 + 0x100).toString(16).substr(1);
16447}
16448/**
16449 * Generate 16 random bytes to be used as a base for UUID.
16450 *
16451 * @ignore
16452 */
16453
16454
16455var random$1$1 = function () {
16456 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
16457 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
16458 // Moderately fast, high quality
16459 var _rnds8 = new Uint8Array(16);
16460
16461 return function whatwgRNG() {
16462 crypto.getRandomValues(_rnds8);
16463 return _rnds8;
16464 };
16465 } // Math.random()-based (RNG)
16466 //
16467 // If all else fails, use Math.random().
16468 // It's fast, but is of unspecified quality.
16469
16470
16471 var _rnds = new Array(16);
16472
16473 return function () {
16474 for (var i = 0, r; i < 16; i++) {
16475 if ((i & 0x03) === 0) {
16476 r = Math.random() * 0x100000000;
16477 }
16478
16479 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
16480 }
16481
16482 return _rnds;
16483 }; // uuid.js
16484 //
16485 // Copyright (c) 2010-2012 Robert Kieffer
16486 // MIT License - http://opensource.org/licenses/mit-license.php
16487 // Unique ID creation requires a high quality random # generator. We feature
16488 // detect to determine the best RNG source, normalizing to a function that
16489 // returns 128-bits of randomness, since that's what's usually required
16490 // return require('./rng');
16491}();
16492
16493var byteToHex$1$1$1 = [];
16494
16495for (var i$1$1$1 = 0; i$1$1$1 < 256; i$1$1$1++) {
16496 byteToHex$1$1$1[i$1$1$1] = (i$1$1$1 + 0x100).toString(16).substr(1);
16497} // **`v1()` - Generate time-based UUID**
16498//
16499// Inspired by https://github.com/LiosK/UUID.js
16500// and http://docs.python.org/library/uuid.html
16501// random #'s we need to init node and clockseq
16502
16503
16504var seedBytes$1$1 = random$1$1(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
16505
16506var 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
16507
16508var defaultClockseq$1$1 = (seedBytes$1$1[6] << 8 | seedBytes$1$1[7]) & 0x3fff; // Previous uuid creation time
16509// for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
16510// code from http://momentjs.com/
16511
16512var ASPDateRegex$1 = /^\/?Date\((-?\d+)/i; // Hex color
16513
16514/**
16515 * Hue, Saturation, Value.
16516 */
16517
16518/**
16519 * Test whether given object is a number
16520 *
16521 * @param value - Input value of unknown type.
16522 *
16523 * @returns True if number, false otherwise.
16524 */
16525
16526function isNumber$1(value) {
16527 return value instanceof Number || typeof value === 'number';
16528}
16529/**
16530 * Test whether given object is a string
16531 *
16532 * @param value - Input value of unknown type.
16533 *
16534 * @returns True if string, false otherwise.
16535 */
16536
16537
16538function isString$1(value) {
16539 return value instanceof String || typeof value === 'string';
16540}
16541/**
16542 * Test whether given object is a Moment date.
16543 * @TODO: This is basically a workaround, if Moment was imported property it wouldn't necessary as moment.isMoment is a TS type guard.
16544 *
16545 * @param value - Input value of unknown type.
16546 *
16547 * @returns True if Moment instance, false otherwise.
16548 */
16549
16550
16551function isMoment$1(value) {
16552 return moment$1.isMoment(value);
16553}
16554/**
16555 * Convert an object into another type
16556 *
16557 * @param object - Value of unknown type.
16558 * @param type - Name of the desired type.
16559 *
16560 * @returns Object in the desired type.
16561 * @throws Error
16562 */
16563
16564
16565function convert$1(object, type) {
16566 var match;
16567
16568 if (object === undefined) {
16569 return undefined;
16570 }
16571
16572 if (object === null) {
16573 return null;
16574 }
16575
16576 if (!type) {
16577 return object;
16578 }
16579
16580 if (!(typeof type === 'string') && !(type instanceof String)) {
16581 throw new Error('Type must be a string');
16582 } //noinspection FallthroughInSwitchStatementJS
16583
16584
16585 switch (type) {
16586 case 'boolean':
16587 case 'Boolean':
16588 return Boolean(object);
16589
16590 case 'number':
16591 case 'Number':
16592 if (isString$1(object) && !isNaN(Date.parse(object))) {
16593 return moment$1(object).valueOf();
16594 } else {
16595 // @TODO: I don't think that Number and String constructors are a good idea.
16596 // This could also fail if the object doesn't have valueOf method or if it's redefined.
16597 // For example: Object.create(null) or { valueOf: 7 }.
16598 return Number(object.valueOf());
16599 }
16600
16601 case 'string':
16602 case 'String':
16603 return String(object);
16604
16605 case 'Date':
16606 if (isNumber$1(object)) {
16607 return new Date(object);
16608 }
16609
16610 if (object instanceof Date) {
16611 return new Date(object.valueOf());
16612 } else if (isMoment$1(object)) {
16613 return new Date(object.valueOf());
16614 }
16615
16616 if (isString$1(object)) {
16617 match = ASPDateRegex$1.exec(object);
16618
16619 if (match) {
16620 // object is an ASP date
16621 return new Date(Number(match[1])); // parse number
16622 } else {
16623 return moment$1(new Date(object)).toDate(); // parse string
16624 }
16625 } else {
16626 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type Date');
16627 }
16628
16629 case 'Moment':
16630 if (isNumber$1(object)) {
16631 return moment$1(object);
16632 }
16633
16634 if (object instanceof Date) {
16635 return moment$1(object.valueOf());
16636 } else if (isMoment$1(object)) {
16637 return moment$1(object);
16638 }
16639
16640 if (isString$1(object)) {
16641 match = ASPDateRegex$1.exec(object);
16642
16643 if (match) {
16644 // object is an ASP date
16645 return moment$1(Number(match[1])); // parse number
16646 } else {
16647 return moment$1(object); // parse string
16648 }
16649 } else {
16650 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type Date');
16651 }
16652
16653 case 'ISODate':
16654 if (isNumber$1(object)) {
16655 return new Date(object);
16656 } else if (object instanceof Date) {
16657 return object.toISOString();
16658 } else if (isMoment$1(object)) {
16659 return object.toDate().toISOString();
16660 } else if (isString$1(object)) {
16661 match = ASPDateRegex$1.exec(object);
16662
16663 if (match) {
16664 // object is an ASP date
16665 return new Date(Number(match[1])).toISOString(); // parse number
16666 } else {
16667 return moment$1(object).format(); // ISO 8601
16668 }
16669 } else {
16670 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type ISODate');
16671 }
16672
16673 case 'ASPDate':
16674 if (isNumber$1(object)) {
16675 return '/Date(' + object + ')/';
16676 } else if (object instanceof Date) {
16677 return '/Date(' + object.valueOf() + ')/';
16678 } else if (isString$1(object)) {
16679 match = ASPDateRegex$1.exec(object);
16680
16681 var _value;
16682
16683 if (match) {
16684 // object is an ASP date
16685 _value = new Date(Number(match[1])).valueOf(); // parse number
16686 } else {
16687 _value = new Date(object).valueOf(); // parse string
16688 }
16689
16690 return '/Date(' + _value + ')/';
16691 } else {
16692 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type ASPDate');
16693 }
16694
16695 default:
16696 var never = type;
16697 throw new Error("Unknown type ".concat(never));
16698 }
16699}
16700/**
16701 * Get the type of an object, for example exports.getType([]) returns 'Array'
16702 *
16703 * @param object - Input value of unknown type.
16704 *
16705 * @returns Detected type.
16706 */
16707
16708
16709function getType$1(object) {
16710 var type = _typeof$1(object);
16711
16712 if (type === 'object') {
16713 if (object === null) {
16714 return 'null';
16715 }
16716
16717 if (object instanceof Boolean) {
16718 return 'Boolean';
16719 }
16720
16721 if (object instanceof Number) {
16722 return 'Number';
16723 }
16724
16725 if (object instanceof String) {
16726 return 'String';
16727 }
16728
16729 if (Array.isArray(object)) {
16730 return 'Array';
16731 }
16732
16733 if (object instanceof Date) {
16734 return 'Date';
16735 }
16736
16737 return 'Object';
16738 }
16739
16740 if (type === 'number') {
16741 return 'Number';
16742 }
16743
16744 if (type === 'boolean') {
16745 return 'Boolean';
16746 }
16747
16748 if (type === 'string') {
16749 return 'String';
16750 }
16751
16752 if (type === undefined) {
16753 return 'undefined';
16754 }
16755
16756 return type;
16757}
16758/**
16759 * Determine whether a value can be used as an id.
16760 *
16761 * @param value - Input value of unknown type.
16762 *
16763 * @returns True if the value is valid id, false otherwise.
16764 */
16765
16766
16767function isId(value) {
16768 return typeof value === 'string' || typeof value === 'number';
16769}
16770/**
16771 * A queue.
16772 *
16773 * @typeParam T - The type of method names to be replaced by queued versions.
16774 */
16775
16776
16777var Queue =
16778/*#__PURE__*/
16779function () {
16780 /**
16781 * Construct a new Queue.
16782 *
16783 * @param options - Queue configuration.
16784 */
16785 function Queue(options) {
16786 classCallCheck(this, Queue);
16787 this._queue = [];
16788 this._timeout = null;
16789 this._extended = null; // options
16790
16791 this.delay = null;
16792 this.max = Infinity;
16793 this.setOptions(options);
16794 }
16795 /**
16796 * Update the configuration of the queue.
16797 *
16798 * @param options - Queue configuration.
16799 */
16800
16801
16802 createClass(Queue, [{
16803 key: "setOptions",
16804 value: function setOptions(options) {
16805 if (options && typeof options.delay !== 'undefined') {
16806 this.delay = options.delay;
16807 }
16808
16809 if (options && typeof options.max !== 'undefined') {
16810 this.max = options.max;
16811 }
16812
16813 this._flushIfNeeded();
16814 }
16815 /**
16816 * Extend an object with queuing functionality.
16817 * The object will be extended with a function flush, and the methods provided in options.replace will be replaced with queued ones.
16818 *
16819 * @param object - The object to be extended.
16820 * @param options - Additional options.
16821 *
16822 * @returns The created queue.
16823 */
16824
16825 }, {
16826 key: "destroy",
16827
16828 /**
16829 * Destroy the queue. The queue will first flush all queued actions, and in case it has extended an object, will restore the original object.
16830 */
16831 value: function destroy() {
16832 this.flush();
16833
16834 if (this._extended) {
16835 var object = this._extended.object;
16836 var methods = this._extended.methods;
16837
16838 for (var i = 0; i < methods.length; i++) {
16839 var method = methods[i];
16840
16841 if (method.original) {
16842 object[method.name] = method.original;
16843 } else {
16844 // @TODO: better solution?
16845 delete object[method.name];
16846 }
16847 }
16848
16849 this._extended = null;
16850 }
16851 }
16852 /**
16853 * Replace a method on an object with a queued version.
16854 *
16855 * @param object - Object having the method.
16856 * @param method - The method name.
16857 */
16858
16859 }, {
16860 key: "replace",
16861 value: function replace(object, method) {
16862 var me = this;
16863 var original = object[method];
16864
16865 if (!original) {
16866 throw new Error('Method ' + method + ' undefined');
16867 }
16868
16869 object[method] = function () {
16870 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
16871 args[_key] = arguments[_key];
16872 } // add this call to the queue
16873
16874
16875 me.queue({
16876 args: args,
16877 fn: original,
16878 context: this
16879 });
16880 };
16881 }
16882 /**
16883 * Queue a call.
16884 *
16885 * @param entry - The function or entry to be queued.
16886 */
16887
16888 }, {
16889 key: "queue",
16890 value: function queue(entry) {
16891 if (typeof entry === 'function') {
16892 this._queue.push({
16893 fn: entry
16894 });
16895 } else {
16896 this._queue.push(entry);
16897 }
16898
16899 this._flushIfNeeded();
16900 }
16901 /**
16902 * Check whether the queue needs to be flushed.
16903 */
16904
16905 }, {
16906 key: "_flushIfNeeded",
16907 value: function _flushIfNeeded() {
16908 var _this = this; // flush when the maximum is exceeded.
16909
16910
16911 if (this._queue.length > this.max) {
16912 this.flush();
16913 } // flush after a period of inactivity when a delay is configured
16914
16915
16916 if (this._timeout != null) {
16917 clearTimeout(this._timeout);
16918 this._timeout = null;
16919 }
16920
16921 if (this.queue.length > 0 && typeof this.delay === 'number') {
16922 this._timeout = setTimeout(function () {
16923 _this.flush();
16924 }, this.delay);
16925 }
16926 }
16927 /**
16928 * Flush all queued calls
16929 */
16930
16931 }, {
16932 key: "flush",
16933 value: function flush() {
16934 this._queue.splice(0).forEach(function (entry) {
16935 entry.fn.apply(entry.context || entry.fn, entry.args || []);
16936 });
16937 }
16938 }], [{
16939 key: "extend",
16940 value: function extend(object, options) {
16941 var queue = new Queue(options);
16942
16943 if (object.flush !== undefined) {
16944 throw new Error('Target object already has a property flush');
16945 }
16946
16947 object.flush = function () {
16948 queue.flush();
16949 };
16950
16951 var methods = [{
16952 name: 'flush',
16953 original: undefined
16954 }];
16955
16956 if (options && options.replace) {
16957 for (var i = 0; i < options.replace.length; i++) {
16958 var name = options.replace[i];
16959 methods.push({
16960 name: name,
16961 // @TODO: better solution?
16962 original: object[name]
16963 }); // @TODO: better solution?
16964
16965 queue.replace(object, name);
16966 }
16967 }
16968
16969 queue._extended = {
16970 object: object,
16971 methods: methods
16972 };
16973 return queue;
16974 }
16975 }]);
16976 return Queue;
16977}();
16978
16979function _arrayWithoutHoles$2(arr) {
16980 if (Array.isArray(arr)) {
16981 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
16982 arr2[i] = arr[i];
16983 }
16984
16985 return arr2;
16986 }
16987}
16988
16989var arrayWithoutHoles$1 = _arrayWithoutHoles$2;
16990
16991function _iterableToArray$2(iter) {
16992 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
16993}
16994
16995var iterableToArray$1 = _iterableToArray$2;
16996
16997function _nonIterableSpread$2() {
16998 throw new TypeError("Invalid attempt to spread non-iterable instance");
16999}
17000
17001var nonIterableSpread$1 = _nonIterableSpread$2;
17002
17003function _toConsumableArray$2(arr) {
17004 return arrayWithoutHoles$1(arr) || iterableToArray$1(arr) || nonIterableSpread$1();
17005}
17006
17007var toConsumableArray$1 = _toConsumableArray$2;
17008/**
17009 * [[DataSet]] code that can be reused in [[DataView]] or other similar implementations of [[DataInterface]].
17010 *
17011 * @typeParam Item - Item type that may or may not have an id.
17012 * @typeParam IdProp - Name of the property that contains the id.
17013 */
17014
17015var DataSetPart =
17016/*#__PURE__*/
17017function () {
17018 function DataSetPart() {
17019 classCallCheck(this, DataSetPart);
17020 this._subscribers = {
17021 '*': [],
17022 add: [],
17023 remove: [],
17024 update: []
17025 };
17026 /**
17027 * @deprecated Use on instead (PS: DataView.subscribe === DataView.on).
17028 */
17029
17030 this.subscribe = DataSetPart.prototype.on;
17031 /**
17032 * @deprecated Use off instead (PS: DataView.unsubscribe === DataView.off).
17033 */
17034
17035 this.unsubscribe = DataSetPart.prototype.off;
17036 }
17037 /**
17038 * Trigger an event
17039 *
17040 * @param event - Event name.
17041 * @param payload - Event payload.
17042 * @param senderId - Id of the sender.
17043 */
17044
17045
17046 createClass(DataSetPart, [{
17047 key: "_trigger",
17048 value: function _trigger(event, payload, senderId) {
17049 if (event === '*') {
17050 throw new Error('Cannot trigger event *');
17051 }
17052
17053 var subscribers = [].concat(toConsumableArray$1(this._subscribers[event]), toConsumableArray$1(this._subscribers['*']));
17054
17055 for (var i = 0, len = subscribers.length; i < len; i++) {
17056 var subscriber = subscribers[i];
17057
17058 if (subscriber.callback) {
17059 subscriber.callback(event, payload, senderId != null ? senderId : null);
17060 }
17061 }
17062 }
17063 /**
17064 * Subscribe to an event, add an event listener.
17065 *
17066 * @param event - Event name.
17067 * @param callback - Callback method.
17068 */
17069
17070 }, {
17071 key: "on",
17072 value: function on(event, callback) {
17073 this._subscribers[event].push({
17074 callback: callback
17075 });
17076 }
17077 /**
17078 * Unsubscribe from an event, remove an event listener.
17079 *
17080 * @remarks If the same callback was subscribed more than once **all** occurences will be removed.
17081 *
17082 * @param event - Event name.
17083 * @param callback - Callback method.
17084 */
17085
17086 }, {
17087 key: "off",
17088 value: function off(event, callback) {
17089 this._subscribers[event] = this._subscribers[event].filter(function (listener) {
17090 return listener.callback !== callback;
17091 });
17092 }
17093 }]);
17094 return DataSetPart;
17095}();
17096
17097function ownKeys$2(object, enumerableOnly) {
17098 var keys = Object.keys(object);
17099
17100 if (Object.getOwnPropertySymbols) {
17101 keys.push.apply(keys, Object.getOwnPropertySymbols(object));
17102 }
17103
17104 if (enumerableOnly) keys = keys.filter(function (sym) {
17105 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
17106 });
17107 return keys;
17108}
17109
17110function _objectSpread$1(target) {
17111 for (var i = 1; i < arguments.length; i++) {
17112 var source = arguments[i] != null ? arguments[i] : {};
17113
17114 if (i % 2) {
17115 ownKeys$2(source, true).forEach(function (key) {
17116 defineProperty$8(target, key, source[key]);
17117 });
17118 } else if (Object.getOwnPropertyDescriptors) {
17119 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
17120 } else {
17121 ownKeys$2(source).forEach(function (key) {
17122 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
17123 });
17124 }
17125 }
17126
17127 return target;
17128}
17129/**
17130 * # DataSet
17131 *
17132 * 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.
17133 *
17134 * ## Example
17135 *
17136 * The following example shows how to use a DataSet.
17137 *
17138 * ```javascript
17139 * // create a DataSet
17140 * var options = {};
17141 * var data = new vis.DataSet(options);
17142 *
17143 * // add items
17144 * // note that the data items can contain different properties and data formats
17145 * data.add([
17146 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
17147 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
17148 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
17149 * {id: 4, text: 'item 4'}
17150 * ]);
17151 *
17152 * // subscribe to any change in the DataSet
17153 * data.on('*', function (event, properties, senderId) {
17154 * console.log('event', event, properties);
17155 * });
17156 *
17157 * // update an existing item
17158 * data.update({id: 2, group: 1});
17159 *
17160 * // remove an item
17161 * data.remove(4);
17162 *
17163 * // get all ids
17164 * var ids = data.getIds();
17165 * console.log('ids', ids);
17166 *
17167 * // get a specific item
17168 * var item1 = data.get(1);
17169 * console.log('item1', item1);
17170 *
17171 * // retrieve a filtered subset of the data
17172 * var items = data.get({
17173 * filter: function (item) {
17174 * return item.group == 1;
17175 * }
17176 * });
17177 * console.log('filtered items', items);
17178 *
17179 * // retrieve formatted items
17180 * var items = data.get({
17181 * fields: ['id', 'date'],
17182 * type: {
17183 * date: 'ISODate'
17184 * }
17185 * });
17186 * console.log('formatted items', items);
17187 * ```
17188 *
17189 * @typeParam Item - Item type that may or may not have an id.
17190 * @typeParam IdProp - Name of the property that contains the id.
17191 */
17192
17193
17194var DataSet =
17195/*#__PURE__*/
17196function (_DataSetPart) {
17197 inherits(DataSet, _DataSetPart);
17198 /**
17199 * Construct a new DataSet.
17200 *
17201 * @param data - Initial data or options.
17202 * @param options - Options (type error if data is also options).
17203 */
17204
17205 function DataSet(data, options) {
17206 var _this;
17207
17208 classCallCheck(this, DataSet);
17209 _this = possibleConstructorReturn(this, getPrototypeOf(DataSet).call(this)); // correctly read optional arguments
17210
17211 if (data && !Array.isArray(data)) {
17212 options = data;
17213 data = [];
17214 }
17215
17216 _this._options = options || {};
17217 _this._data = Object.create({}); // map with data indexed by id
17218
17219 _this.length = 0; // number of items in the DataSet
17220
17221 _this._idProp = _this._options.fieldId || 'id'; // name of the field containing id
17222
17223 _this._type = {}; // internal field types (NOTE: this can differ from this._options.type)
17224 // all variants of a Date are internally stored as Date, so we can convert
17225 // from everything to everything (also from ISODate to Number for example)
17226
17227 if (_this._options.type) {
17228 var fields = Object.keys(_this._options.type);
17229
17230 for (var i = 0, len = fields.length; i < len; i++) {
17231 var field = fields[i];
17232 var value = _this._options.type[field];
17233
17234 if (value == 'Date' || value == 'ISODate' || value == 'ASPDate') {
17235 _this._type[field] = 'Date';
17236 } else {
17237 _this._type[field] = value;
17238 }
17239 }
17240 } // add initial data when provided
17241
17242
17243 if (data && data.length) {
17244 _this.add(data);
17245 }
17246
17247 _this.setOptions(options);
17248
17249 return _this;
17250 }
17251 /**
17252 * Set new options.
17253 *
17254 * @param options - The new options.
17255 */
17256
17257
17258 createClass(DataSet, [{
17259 key: "setOptions",
17260 value: function setOptions(options) {
17261 if (options && options.queue !== undefined) {
17262 if (options.queue === false) {
17263 // delete queue if loaded
17264 if (this._queue) {
17265 this._queue.destroy();
17266
17267 delete this._queue;
17268 }
17269 } else {
17270 // create queue and update its options
17271 if (!this._queue) {
17272 this._queue = Queue.extend(this, {
17273 replace: ['add', 'update', 'remove']
17274 });
17275 }
17276
17277 if (options.queue && _typeof_1$1(options.queue) === 'object') {
17278 this._queue.setOptions(options.queue);
17279 }
17280 }
17281 }
17282 }
17283 /**
17284 * Add a data item or an array with items.
17285 *
17286 * 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.
17287 *
17288 * ## Example
17289 *
17290 * ```javascript
17291 * // create a DataSet
17292 * const data = new vis.DataSet()
17293 *
17294 * // add items
17295 * const ids = data.add([
17296 * { id: 1, text: 'item 1' },
17297 * { id: 2, text: 'item 2' },
17298 * { text: 'item without an id' }
17299 * ])
17300 *
17301 * console.log(ids) // [1, 2, '<UUIDv4>']
17302 * ```
17303 *
17304 * @param data - Items to be added (ids will be generated if missing).
17305 * @param senderId - Sender id.
17306 *
17307 * @returns addedIds - Array with the ids (generated if not present) of the added items.
17308 *
17309 * @throws When an item with the same id as any of the added items already exists.
17310 */
17311
17312 }, {
17313 key: "add",
17314 value: function add(data, senderId) {
17315 var addedIds = [];
17316 var id;
17317
17318 if (Array.isArray(data)) {
17319 // Array
17320 for (var i = 0, len = data.length; i < len; i++) {
17321 id = this._addItem(data[i]);
17322 addedIds.push(id);
17323 }
17324 } else if (data && _typeof_1$1(data) === 'object') {
17325 // Single item
17326 id = this._addItem(data);
17327 addedIds.push(id);
17328 } else {
17329 throw new Error('Unknown dataType');
17330 }
17331
17332 if (addedIds.length) {
17333 this._trigger('add', {
17334 items: addedIds
17335 }, senderId);
17336 }
17337
17338 return addedIds;
17339 }
17340 /**
17341 * Update existing items. When an item does not exist, it will be created
17342 *
17343 * The provided properties will be merged in the existing item. When an item does not exist, it will be created.
17344 *
17345 * 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.
17346 *
17347 * ## Example
17348 *
17349 * ```javascript
17350 * // create a DataSet
17351 * const data = new vis.DataSet([
17352 * { id: 1, text: 'item 1' },
17353 * { id: 2, text: 'item 2' },
17354 * { id: 3, text: 'item 3' }
17355 * ])
17356 *
17357 * // update items
17358 * const ids = data.update([
17359 * { id: 2, text: 'item 2 (updated)' },
17360 * { id: 4, text: 'item 4 (new)' }
17361 * ])
17362 *
17363 * console.log(ids) // [2, 4]
17364 * ```
17365 *
17366 * @param data - Items to be updated (if the id is already present) or added (if the id is missing).
17367 * @param senderId - Sender id.
17368 *
17369 * @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.
17370 *
17371 * @throws When the supplied data is neither an item nor an array of items.
17372 */
17373
17374 }, {
17375 key: "update",
17376 value: function update(data, senderId) {
17377 var _this2 = this;
17378
17379 var addedIds = [];
17380 var updatedIds = [];
17381 var oldData = [];
17382 var updatedData = [];
17383 var idProp = this._idProp;
17384
17385 var addOrUpdate = function addOrUpdate(item) {
17386 var origId = item[idProp];
17387
17388 if (origId != null && _this2._data[origId]) {
17389 var fullItem = item; // it has an id, therefore it is a fullitem
17390
17391 var oldItem = Object.assign({}, _this2._data[origId]); // update item
17392
17393 var id = _this2._updateItem(fullItem);
17394
17395 updatedIds.push(id);
17396 updatedData.push(fullItem);
17397 oldData.push(oldItem);
17398 } else {
17399 // add new item
17400 var _id = _this2._addItem(item);
17401
17402 addedIds.push(_id);
17403 }
17404 };
17405
17406 if (Array.isArray(data)) {
17407 // Array
17408 for (var i = 0, len = data.length; i < len; i++) {
17409 if (data[i] && _typeof_1$1(data[i]) === 'object') {
17410 addOrUpdate(data[i]);
17411 } else {
17412 console.warn('Ignoring input item, which is not an object at index ' + i);
17413 }
17414 }
17415 } else if (data && _typeof_1$1(data) === 'object') {
17416 // Single item
17417 addOrUpdate(data);
17418 } else {
17419 throw new Error('Unknown dataType');
17420 }
17421
17422 if (addedIds.length) {
17423 this._trigger('add', {
17424 items: addedIds
17425 }, senderId);
17426 }
17427
17428 if (updatedIds.length) {
17429 var props = {
17430 items: updatedIds,
17431 oldData: oldData,
17432 data: updatedData
17433 }; // TODO: remove deprecated property 'data' some day
17434 //Object.defineProperty(props, 'data', {
17435 // 'get': (function() {
17436 // 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');
17437 // return updatedData;
17438 // }).bind(this)
17439 //});
17440
17441 this._trigger('update', props, senderId);
17442 }
17443
17444 return addedIds.concat(updatedIds);
17445 }
17446 /** @inheritdoc */
17447
17448 }, {
17449 key: "get",
17450 value: function get(first, second) {
17451 // @TODO: Woudn't it be better to split this into multiple methods?
17452 // parse the arguments
17453 var id = undefined;
17454 var ids = undefined;
17455 var options = undefined;
17456
17457 if (isId(first)) {
17458 // get(id [, options])
17459 id = first;
17460 options = second;
17461 } else if (Array.isArray(first)) {
17462 // get(ids [, options])
17463 ids = first;
17464 options = second;
17465 } else {
17466 // get([, options])
17467 options = first;
17468 } // determine the return type
17469
17470
17471 var returnType = options && options.returnType === 'Object' ? 'Object' : 'Array'; // @TODO: WTF is this? Or am I missing something?
17472 // var returnType
17473 // if (options && options.returnType) {
17474 // var allowedValues = ['Array', 'Object']
17475 // returnType =
17476 // allowedValues.indexOf(options.returnType) == -1
17477 // ? 'Array'
17478 // : options.returnType
17479 // } else {
17480 // returnType = 'Array'
17481 // }
17482 // build options
17483
17484 var type = options && options.type || this._options.type;
17485 var filter = options && options.filter;
17486 var items = [];
17487 var item = null;
17488 var itemIds = null;
17489 var itemId = null; // convert items
17490
17491 if (id != null) {
17492 // return a single item
17493 item = this._getItem(id, type);
17494
17495 if (item && filter && !filter(item)) {
17496 item = null;
17497 }
17498 } else if (ids != null) {
17499 // return a subset of items
17500 for (var i = 0, len = ids.length; i < len; i++) {
17501 item = this._getItem(ids[i], type);
17502
17503 if (item != null && (!filter || filter(item))) {
17504 items.push(item);
17505 }
17506 }
17507 } else {
17508 // return all items
17509 itemIds = Object.keys(this._data);
17510
17511 for (var _i = 0, _len = itemIds.length; _i < _len; _i++) {
17512 itemId = itemIds[_i];
17513 item = this._getItem(itemId, type);
17514
17515 if (item != null && (!filter || filter(item))) {
17516 items.push(item);
17517 }
17518 }
17519 } // order the results
17520
17521
17522 if (options && options.order && id == undefined) {
17523 this._sort(items, options.order);
17524 } // filter fields of the items
17525
17526
17527 if (options && options.fields) {
17528 var fields = options.fields;
17529
17530 if (id != undefined && item != null) {
17531 item = this._filterFields(item, fields);
17532 } else {
17533 for (var _i2 = 0, _len2 = items.length; _i2 < _len2; _i2++) {
17534 items[_i2] = this._filterFields(items[_i2], fields);
17535 }
17536 }
17537 } // return the results
17538
17539
17540 if (returnType == 'Object') {
17541 var result = {};
17542
17543 for (var _i3 = 0, _len3 = items.length; _i3 < _len3; _i3++) {
17544 var resultant = items[_i3]; // @TODO: Shoudn't this be this._fieldId?
17545 // result[resultant.id] = resultant
17546
17547 var _id2 = resultant[this._idProp];
17548 result[_id2] = resultant;
17549 }
17550
17551 return result;
17552 } else {
17553 if (id != null) {
17554 // a single item
17555 return item;
17556 } else {
17557 // just return our array
17558 return items;
17559 }
17560 }
17561 }
17562 /** @inheritdoc */
17563
17564 }, {
17565 key: "getIds",
17566 value: function getIds(options) {
17567 var data = this._data;
17568 var filter = options && options.filter;
17569 var order = options && options.order;
17570 var type = options && options.type || this._options.type;
17571 var itemIds = Object.keys(data);
17572 var ids = [];
17573 var item;
17574 var items;
17575
17576 if (filter) {
17577 // get filtered items
17578 if (order) {
17579 // create ordered list
17580 items = [];
17581
17582 for (var i = 0, len = itemIds.length; i < len; i++) {
17583 var id = itemIds[i];
17584 item = this._getItem(id, type);
17585
17586 if (filter(item)) {
17587 items.push(item);
17588 }
17589 }
17590
17591 this._sort(items, order);
17592
17593 for (var _i4 = 0, _len4 = items.length; _i4 < _len4; _i4++) {
17594 ids.push(items[_i4][this._idProp]);
17595 }
17596 } else {
17597 // create unordered list
17598 for (var _i5 = 0, _len5 = itemIds.length; _i5 < _len5; _i5++) {
17599 var _id3 = itemIds[_i5];
17600 item = this._getItem(_id3, type);
17601
17602 if (filter(item)) {
17603 ids.push(item[this._idProp]);
17604 }
17605 }
17606 }
17607 } else {
17608 // get all items
17609 if (order) {
17610 // create an ordered list
17611 items = [];
17612
17613 for (var _i6 = 0, _len6 = itemIds.length; _i6 < _len6; _i6++) {
17614 var _id4 = itemIds[_i6];
17615 items.push(data[_id4]);
17616 }
17617
17618 this._sort(items, order);
17619
17620 for (var _i7 = 0, _len7 = items.length; _i7 < _len7; _i7++) {
17621 ids.push(items[_i7][this._idProp]);
17622 }
17623 } else {
17624 // create unordered list
17625 for (var _i8 = 0, _len8 = itemIds.length; _i8 < _len8; _i8++) {
17626 var _id5 = itemIds[_i8];
17627 item = data[_id5];
17628 ids.push(item[this._idProp]);
17629 }
17630 }
17631 }
17632
17633 return ids;
17634 }
17635 /** @inheritdoc */
17636
17637 }, {
17638 key: "getDataSet",
17639 value: function getDataSet() {
17640 return this;
17641 }
17642 /** @inheritdoc */
17643
17644 }, {
17645 key: "forEach",
17646 value: function forEach(callback, options) {
17647 var filter = options && options.filter;
17648 var type = options && options.type || this._options.type;
17649 var data = this._data;
17650 var itemIds = Object.keys(data);
17651
17652 if (options && options.order) {
17653 // execute forEach on ordered list
17654 var items = this.get(options);
17655
17656 for (var i = 0, len = items.length; i < len; i++) {
17657 var item = items[i];
17658 var id = item[this._idProp];
17659 callback(item, id);
17660 }
17661 } else {
17662 // unordered
17663 for (var _i9 = 0, _len9 = itemIds.length; _i9 < _len9; _i9++) {
17664 var _id6 = itemIds[_i9];
17665
17666 var _item = this._getItem(_id6, type);
17667
17668 if (!filter || filter(_item)) {
17669 callback(_item, _id6);
17670 }
17671 }
17672 }
17673 }
17674 /** @inheritdoc */
17675
17676 }, {
17677 key: "map",
17678 value: function map(callback, options) {
17679 var filter = options && options.filter;
17680 var type = options && options.type || this._options.type;
17681 var mappedItems = [];
17682 var data = this._data;
17683 var itemIds = Object.keys(data); // convert and filter items
17684
17685 for (var i = 0, len = itemIds.length; i < len; i++) {
17686 var id = itemIds[i];
17687
17688 var item = this._getItem(id, type);
17689
17690 if (!filter || filter(item)) {
17691 mappedItems.push(callback(item, id));
17692 }
17693 } // order items
17694
17695
17696 if (options && options.order) {
17697 this._sort(mappedItems, options.order);
17698 }
17699
17700 return mappedItems;
17701 }
17702 /**
17703 * Filter the fields of an item.
17704 *
17705 * @param item - The item whose fields should be filtered.
17706 * @param fields - The names of the fields that will be kept.
17707 *
17708 * @typeParam K - Field name type.
17709 *
17710 * @returns The item without any additional fields.
17711 */
17712
17713 }, {
17714 key: "_filterFields",
17715 value: function _filterFields(item, fields) {
17716 if (!item) {
17717 // item is null
17718 return item;
17719 }
17720
17721 return (Array.isArray(fields) ? // Use the supplied array
17722 fields : // Use the keys of the supplied object
17723 Object.keys(fields)).reduce(function (filteredItem, field) {
17724 filteredItem[field] = item[field];
17725 return filteredItem;
17726 }, {});
17727 }
17728 /**
17729 * Sort the provided array with items.
17730 *
17731 * @param items - Items to be sorted in place.
17732 * @param order - A field name or custom sort function.
17733 *
17734 * @typeParam T - The type of the items in the items array.
17735 */
17736
17737 }, {
17738 key: "_sort",
17739 value: function _sort(items, order) {
17740 if (typeof order === 'string') {
17741 // order by provided field name
17742 var name = order; // field name
17743
17744 items.sort(function (a, b) {
17745 // @TODO: How to treat missing properties?
17746 var av = a[name];
17747 var bv = b[name];
17748 return av > bv ? 1 : av < bv ? -1 : 0;
17749 });
17750 } else if (typeof order === 'function') {
17751 // order by sort function
17752 items.sort(order);
17753 } else {
17754 // TODO: extend order by an Object {field:string, direction:string}
17755 // where direction can be 'asc' or 'desc'
17756 throw new TypeError('Order must be a function or a string');
17757 }
17758 }
17759 /**
17760 * Remove an item or multiple items by “reference” (only the id is used) or by id.
17761 *
17762 * 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.
17763 *
17764 * 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.
17765 *
17766 * ## Example
17767 * ```javascript
17768 * // create a DataSet
17769 * const data = new vis.DataSet([
17770 * { id: 1, text: 'item 1' },
17771 * { id: 2, text: 'item 2' },
17772 * { id: 3, text: 'item 3' }
17773 * ])
17774 *
17775 * // remove items
17776 * const ids = data.remove([2, { id: 3 }, 4])
17777 *
17778 * console.log(ids) // [2, 3]
17779 * ```
17780 *
17781 * @param id - One or more items or ids of items to be removed.
17782 * @param senderId - Sender id.
17783 *
17784 * @returns The ids of the removed items.
17785 */
17786
17787 }, {
17788 key: "remove",
17789 value: function remove(id, senderId) {
17790 var removedIds = [];
17791 var removedItems = []; // force everything to be an array for simplicity
17792
17793 var ids = Array.isArray(id) ? id : [id];
17794
17795 for (var i = 0, len = ids.length; i < len; i++) {
17796 var item = this._remove(ids[i]);
17797
17798 if (item) {
17799 var itemId = item[this._idProp];
17800
17801 if (itemId != null) {
17802 removedIds.push(itemId);
17803 removedItems.push(item);
17804 }
17805 }
17806 }
17807
17808 if (removedIds.length) {
17809 this._trigger('remove', {
17810 items: removedIds,
17811 oldData: removedItems
17812 }, senderId);
17813 }
17814
17815 return removedIds;
17816 }
17817 /**
17818 * Remove an item by its id or reference.
17819 *
17820 * @param id - Id of an item or the item itself.
17821 *
17822 * @returns The removed item if removed, null otherwise.
17823 */
17824
17825 }, {
17826 key: "_remove",
17827 value: function _remove(id) {
17828 // @TODO: It origianlly returned the item although the docs say id.
17829 // The code expects the item, so probably an error in the docs.
17830 var ident; // confirm the id to use based on the args type
17831
17832 if (isId(id)) {
17833 ident = id;
17834 } else if (id && _typeof_1$1(id) === 'object') {
17835 ident = id[this._idProp]; // look for the identifier field using ._idProp
17836 } // do the removing if the item is found
17837
17838
17839 if (ident != null && this._data[ident]) {
17840 var item = this._data[ident];
17841 delete this._data[ident];
17842 --this.length;
17843 return item;
17844 }
17845
17846 return null;
17847 }
17848 /**
17849 * Clear the entire data set.
17850 *
17851 * 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.
17852 *
17853 * @param senderId - Sender id.
17854 *
17855 * @returns removedIds - The ids of all removed items.
17856 */
17857
17858 }, {
17859 key: "clear",
17860 value: function clear(senderId) {
17861 var ids = Object.keys(this._data);
17862 var items = [];
17863
17864 for (var i = 0, len = ids.length; i < len; i++) {
17865 items.push(this._data[ids[i]]);
17866 }
17867
17868 this._data = {};
17869 this.length = 0;
17870
17871 this._trigger('remove', {
17872 items: ids,
17873 oldData: items
17874 }, senderId);
17875
17876 return ids;
17877 }
17878 /**
17879 * Find the item with maximum value of a specified field.
17880 *
17881 * @param field - Name of the property that should be searched for max value.
17882 *
17883 * @returns Item containing max value, or null if no items.
17884 */
17885
17886 }, {
17887 key: "max",
17888 value: function max(field) {
17889 var data = this._data;
17890 var itemIds = Object.keys(data);
17891 var max = null;
17892 var maxField = null;
17893
17894 for (var i = 0, len = itemIds.length; i < len; i++) {
17895 var id = itemIds[i];
17896 var item = data[id];
17897 var itemField = item[field];
17898
17899 if (itemField != null && (maxField == null || itemField > maxField)) {
17900 max = item;
17901 maxField = itemField;
17902 }
17903 }
17904
17905 return max;
17906 }
17907 /**
17908 * Find the item with minimum value of a specified field.
17909 *
17910 * @param field - Name of the property that should be searched for min value.
17911 *
17912 * @returns Item containing min value, or null if no items.
17913 */
17914
17915 }, {
17916 key: "min",
17917 value: function min(field) {
17918 var data = this._data;
17919 var itemIds = Object.keys(data);
17920 var min = null;
17921 var minField = null;
17922
17923 for (var i = 0, len = itemIds.length; i < len; i++) {
17924 var id = itemIds[i];
17925 var item = data[id];
17926 var itemField = item[field];
17927
17928 if (itemField != null && (minField == null || itemField < minField)) {
17929 min = item;
17930 minField = itemField;
17931 }
17932 }
17933
17934 return min;
17935 }
17936 /**
17937 * Find all distinct values of a specified field
17938 *
17939 * @param prop - The property name whose distinct values should be returned.
17940 *
17941 * @returns Unordered array containing all distinct values. Items without specified property are ignored.
17942 */
17943
17944 }, {
17945 key: "distinct",
17946 value: function distinct(prop) {
17947 var data = this._data;
17948 var itemIds = Object.keys(data);
17949 var values = [];
17950 var fieldType = this._options.type && this._options.type[prop] || null;
17951 var count = 0;
17952
17953 for (var i = 0, len = itemIds.length; i < len; i++) {
17954 var id = itemIds[i];
17955 var item = data[id];
17956 var value = item[prop];
17957 var exists = false;
17958
17959 for (var j = 0; j < count; j++) {
17960 if (values[j] == value) {
17961 exists = true;
17962 break;
17963 }
17964 }
17965
17966 if (!exists && value !== undefined) {
17967 values[count] = value;
17968 count++;
17969 }
17970 }
17971
17972 if (fieldType) {
17973 for (var _i10 = 0, _len10 = values.length; _i10 < _len10; _i10++) {
17974 values[_i10] = convert$1(values[_i10], fieldType);
17975 }
17976 }
17977
17978 return values;
17979 }
17980 /**
17981 * Add a single item. Will fail when an item with the same id already exists.
17982 *
17983 * @param item - A new item to be added.
17984 *
17985 * @returns Added item's id. An id is generated when it is not present in the item.
17986 */
17987
17988 }, {
17989 key: "_addItem",
17990 value: function _addItem(item) {
17991 var id = item[this._idProp];
17992
17993 if (id != null) {
17994 // check whether this id is already taken
17995 if (this._data[id]) {
17996 // item already exists
17997 throw new Error('Cannot add item: item with id ' + id + ' already exists');
17998 }
17999 } else {
18000 // generate an id
18001 id = uuid4$1();
18002 item[this._idProp] = id;
18003 }
18004
18005 var d = {};
18006 var fields = Object.keys(item);
18007
18008 for (var i = 0, len = fields.length; i < len; i++) {
18009 var field = fields[i];
18010 var fieldType = this._type[field]; // type may be undefined
18011
18012 d[field] = convert$1(item[field], fieldType);
18013 }
18014
18015 this._data[id] = d;
18016 this.length++;
18017 return id;
18018 }
18019 /**
18020 * Get an item. Fields can be converted to a specific type
18021 *
18022 * @param id - Id of the requested item.
18023 * @param types - Property name to type name object map of type converstions.
18024 *
18025 * @returns The item, optionally after type conversion.
18026 */
18027
18028 }, {
18029 key: "_getItem",
18030 value: function _getItem(id, types) {
18031 // @TODO: I have no idea how to type this.
18032 // get the item from the dataset
18033 var raw = this._data[id];
18034
18035 if (!raw) {
18036 return null;
18037 } // convert the items field types
18038
18039
18040 var converted;
18041 var fields = Object.keys(raw);
18042
18043 if (types) {
18044 converted = {};
18045
18046 for (var i = 0, len = fields.length; i < len; i++) {
18047 var field = fields[i];
18048 var value = raw[field];
18049 converted[field] = convert$1(value, types[field]);
18050 }
18051 } else {
18052 // no field types specified, no converting needed
18053 converted = _objectSpread$1({}, raw);
18054 }
18055
18056 if (converted[this._idProp] == null) {
18057 converted[this._idProp] = raw.id;
18058 }
18059
18060 return converted;
18061 }
18062 /**
18063 * Update a single item: merge with existing item.
18064 * Will fail when the item has no id, or when there does not exist an item with the same id.
18065 *
18066 * @param item - The new item
18067 *
18068 * @returns The id of the updated item.
18069 */
18070
18071 }, {
18072 key: "_updateItem",
18073 value: function _updateItem(item) {
18074 var id = item[this._idProp];
18075
18076 if (id == null) {
18077 throw new Error('Cannot update item: item has no id (item: ' + JSON.stringify(item) + ')');
18078 }
18079
18080 var d = this._data[id];
18081
18082 if (!d) {
18083 // item doesn't exist
18084 throw new Error('Cannot update item: no item with id ' + id + ' found');
18085 } // merge with current item
18086
18087
18088 var fields = Object.keys(item);
18089
18090 for (var i = 0, len = fields.length; i < len; i++) {
18091 var field = fields[i];
18092 var fieldType = this._type[field] // type may be undefined
18093 ;
18094 d[field] = convert$1(item[field], fieldType);
18095 }
18096
18097 return id;
18098 }
18099 }]);
18100 return DataSet;
18101}(DataSetPart);
18102/**
18103 * DataView
18104 *
18105 * 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.
18106 *
18107 * ## Example
18108 * ```javascript
18109 * // create a DataSet
18110 * var data = new vis.DataSet();
18111 * data.add([
18112 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
18113 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
18114 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
18115 * {id: 4, text: 'item 4'}
18116 * ]);
18117 *
18118 * // create a DataView
18119 * // the view will only contain items having a property group with value 1,
18120 * // and will only output fields id, text, and date.
18121 * var view = new vis.DataView(data, {
18122 * filter: function (item) {
18123 * return (item.group == 1);
18124 * },
18125 * fields: ['id', 'text', 'date']
18126 * });
18127 *
18128 * // subscribe to any change in the DataView
18129 * view.on('*', function (event, properties, senderId) {
18130 * console.log('event', event, properties);
18131 * });
18132 *
18133 * // update an item in the data set
18134 * data.update({id: 2, group: 1});
18135 *
18136 * // get all ids in the view
18137 * var ids = view.getIds();
18138 * console.log('ids', ids); // will output [1, 2]
18139 *
18140 * // get all items in the view
18141 * var items = view.get();
18142 * ```
18143 *
18144 * @typeParam Item - Item type that may or may not have an id.
18145 * @typeParam IdProp - Name of the property that contains the id.
18146 */
18147
18148
18149var DataView$2 =
18150/*#__PURE__*/
18151function (_DataSetPart) {
18152 inherits(DataView, _DataSetPart);
18153 /**
18154 * Create a DataView.
18155 *
18156 * @param data - The instance containing data (directly or indirectly).
18157 * @param options - Options to configure this data view.
18158 */
18159
18160 function DataView(data, options) {
18161 var _this;
18162
18163 classCallCheck(this, DataView);
18164 _this = possibleConstructorReturn(this, getPrototypeOf(DataView).call(this));
18165 /** @inheritdoc */
18166
18167 _this.length = 0;
18168 _this._ids = {}; // ids of the items currently in memory (just contains a boolean true)
18169
18170 _this._options = options || {};
18171 _this.listener = _this._onEvent.bind(assertThisInitialized(_this));
18172
18173 _this.setData(data);
18174
18175 return _this;
18176 } // TODO: implement a function .config() to dynamically update things like configured filter
18177 // and trigger changes accordingly
18178
18179 /**
18180 * Set a data source for the view.
18181 *
18182 * @param data - The instance containing data (directly or indirectly).
18183 */
18184
18185
18186 createClass(DataView, [{
18187 key: "setData",
18188 value: function setData(data) {
18189 if (this._data) {
18190 // unsubscribe from current dataset
18191 if (this._data.off) {
18192 this._data.off('*', this.listener);
18193 } // trigger a remove of all items in memory
18194
18195
18196 var ids = this._data.getIds({
18197 filter: this._options.filter
18198 });
18199
18200 var items = this._data.get(ids);
18201
18202 this._ids = {};
18203 this.length = 0;
18204
18205 this._trigger('remove', {
18206 items: ids,
18207 oldData: items
18208 });
18209 }
18210
18211 if (data != null) {
18212 this._data = data; // trigger an add of all added items
18213
18214 var _ids = this._data.getIds({
18215 filter: this._options.filter
18216 });
18217
18218 for (var i = 0, len = _ids.length; i < len; i++) {
18219 var id = _ids[i];
18220 this._ids[id] = true;
18221 }
18222
18223 this.length = _ids.length;
18224
18225 this._trigger('add', {
18226 items: _ids
18227 });
18228 } else {
18229 this._data = new DataSet();
18230 } // subscribe to new dataset
18231
18232
18233 if (this._data.on) {
18234 this._data.on('*', this.listener);
18235 }
18236 }
18237 /**
18238 * Refresh the DataView.
18239 * Useful when the DataView has a filter function containing a variable parameter.
18240 */
18241
18242 }, {
18243 key: "refresh",
18244 value: function refresh() {
18245 var ids = this._data.getIds({
18246 filter: this._options.filter
18247 });
18248
18249 var oldIds = Object.keys(this._ids);
18250 var newIds = {};
18251 var addedIds = [];
18252 var removedIds = [];
18253 var removedItems = []; // check for additions
18254
18255 for (var i = 0, len = ids.length; i < len; i++) {
18256 var id = ids[i];
18257 newIds[id] = true;
18258
18259 if (!this._ids[id]) {
18260 addedIds.push(id);
18261 this._ids[id] = true;
18262 }
18263 } // check for removals
18264
18265
18266 for (var _i = 0, _len = oldIds.length; _i < _len; _i++) {
18267 var _id = oldIds[_i];
18268
18269 var item = this._data.get(_id);
18270
18271 if (item == null) {
18272 // @TODO: Investigate.
18273 // Doesn't happen during tests or examples.
18274 // Is it really impossible or could it eventually happen?
18275 // How to handle it if it does? The types guarantee non-nullable items.
18276 console.error('If you see this, report it please.');
18277 } else if (!newIds[_id]) {
18278 removedIds.push(_id);
18279 removedItems.push(item);
18280 delete this._ids[_id];
18281 }
18282 }
18283
18284 this.length += addedIds.length - removedIds.length; // trigger events
18285
18286 if (addedIds.length) {
18287 this._trigger('add', {
18288 items: addedIds
18289 });
18290 }
18291
18292 if (removedIds.length) {
18293 this._trigger('remove', {
18294 items: removedIds,
18295 oldData: removedItems
18296 });
18297 }
18298 }
18299 /** @inheritdoc */
18300
18301 }, {
18302 key: "get",
18303 value: function get(first, second) {
18304 if (this._data == null) {
18305 return null;
18306 } // parse the arguments
18307
18308
18309 var ids = null;
18310 var options;
18311
18312 if (isId(first) || Array.isArray(first)) {
18313 ids = first;
18314 options = second;
18315 } else {
18316 options = first;
18317 } // extend the options with the default options and provided options
18318
18319
18320 var viewOptions = Object.assign({}, this._options, options); // create a combined filter method when needed
18321
18322 var thisFilter = this._options.filter;
18323 var optionsFilter = options && options.filter;
18324
18325 if (thisFilter && optionsFilter) {
18326 viewOptions.filter = function (item) {
18327 return thisFilter(item) && optionsFilter(item);
18328 };
18329 }
18330
18331 if (ids == null) {
18332 return this._data.get(viewOptions);
18333 } else {
18334 return this._data.get(ids, viewOptions);
18335 }
18336 }
18337 /** @inheritdoc */
18338
18339 }, {
18340 key: "getIds",
18341 value: function getIds(options) {
18342 if (this._data.length) {
18343 var defaultFilter = this._options.filter;
18344 var optionsFilter = options != null ? options.filter : null;
18345 var filter;
18346
18347 if (optionsFilter) {
18348 if (defaultFilter) {
18349 filter = function filter(item) {
18350 return defaultFilter(item) && optionsFilter(item);
18351 };
18352 } else {
18353 filter = optionsFilter;
18354 }
18355 } else {
18356 filter = defaultFilter;
18357 }
18358
18359 return this._data.getIds({
18360 filter: filter,
18361 order: options && options.order
18362 });
18363 } else {
18364 return [];
18365 }
18366 }
18367 /** @inheritdoc */
18368
18369 }, {
18370 key: "forEach",
18371 value: function forEach(callback, options) {
18372 if (this._data) {
18373 var defaultFilter = this._options.filter;
18374 var optionsFilter = options && options.filter;
18375 var filter;
18376
18377 if (optionsFilter) {
18378 if (defaultFilter) {
18379 filter = function filter(item) {
18380 return defaultFilter(item) && optionsFilter(item);
18381 };
18382 } else {
18383 filter = optionsFilter;
18384 }
18385 } else {
18386 filter = defaultFilter;
18387 }
18388
18389 this._data.forEach(callback, {
18390 filter: filter,
18391 order: options && options.order
18392 });
18393 }
18394 }
18395 /** @inheritdoc */
18396
18397 }, {
18398 key: "map",
18399 value: function map(callback, options) {
18400 if (this._data) {
18401 var defaultFilter = this._options.filter;
18402 var optionsFilter = options && options.filter;
18403 var filter;
18404
18405 if (optionsFilter) {
18406 if (defaultFilter) {
18407 filter = function filter(item) {
18408 return defaultFilter(item) && optionsFilter(item);
18409 };
18410 } else {
18411 filter = optionsFilter;
18412 }
18413 } else {
18414 filter = defaultFilter;
18415 }
18416
18417 return this._data.map(callback, {
18418 filter: filter,
18419 order: options && options.order
18420 });
18421 } else {
18422 return [];
18423 }
18424 }
18425 /** @inheritdoc */
18426
18427 }, {
18428 key: "getDataSet",
18429 value: function getDataSet() {
18430 return this._data.getDataSet();
18431 }
18432 /**
18433 * 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.
18434 *
18435 * @param event - The name of the event.
18436 * @param params - Parameters of the event.
18437 * @param senderId - Id supplied by the sender.
18438 */
18439
18440 }, {
18441 key: "_onEvent",
18442 value: function _onEvent(event, params, senderId) {
18443 if (!params || !params.items || !this._data) {
18444 return;
18445 }
18446
18447 var ids = params.items;
18448 var addedIds = [];
18449 var updatedIds = [];
18450 var removedIds = [];
18451 var oldItems = [];
18452 var updatedItems = [];
18453 var removedItems = [];
18454
18455 switch (event) {
18456 case 'add':
18457 // filter the ids of the added items
18458 for (var i = 0, len = ids.length; i < len; i++) {
18459 var id = ids[i];
18460 var item = this.get(id);
18461
18462 if (item) {
18463 this._ids[id] = true;
18464 addedIds.push(id);
18465 }
18466 }
18467
18468 break;
18469
18470 case 'update':
18471 // determine the event from the views viewpoint: an updated
18472 // item can be added, updated, or removed from this view.
18473 for (var _i2 = 0, _len2 = ids.length; _i2 < _len2; _i2++) {
18474 var _id2 = ids[_i2];
18475
18476 var _item = this.get(_id2);
18477
18478 if (_item) {
18479 if (this._ids[_id2]) {
18480 updatedIds.push(_id2);
18481 updatedItems.push(params.data[_i2]);
18482 oldItems.push(params.oldData[_i2]);
18483 } else {
18484 this._ids[_id2] = true;
18485 addedIds.push(_id2);
18486 }
18487 } else {
18488 if (this._ids[_id2]) {
18489 delete this._ids[_id2];
18490 removedIds.push(_id2);
18491 removedItems.push(params.oldData[_i2]);
18492 }
18493 }
18494 }
18495
18496 break;
18497
18498 case 'remove':
18499 // filter the ids of the removed items
18500 for (var _i3 = 0, _len3 = ids.length; _i3 < _len3; _i3++) {
18501 var _id3 = ids[_i3];
18502
18503 if (this._ids[_id3]) {
18504 delete this._ids[_id3];
18505 removedIds.push(_id3);
18506 removedItems.push(params.oldData[_i3]);
18507 }
18508 }
18509
18510 break;
18511 }
18512
18513 this.length += addedIds.length - removedIds.length;
18514
18515 if (addedIds.length) {
18516 this._trigger('add', {
18517 items: addedIds
18518 }, senderId);
18519 }
18520
18521 if (updatedIds.length) {
18522 this._trigger('update', {
18523 items: updatedIds,
18524 oldData: oldItems,
18525 data: updatedItems
18526 }, senderId);
18527 }
18528
18529 if (removedIds.length) {
18530 this._trigger('remove', {
18531 items: removedIds,
18532 oldData: removedItems
18533 }, senderId);
18534 }
18535 }
18536 }]);
18537 return DataView;
18538}(DataSetPart);
18539
18540var moment$2 = createCommonjsModule(function (module, exports) {
18541
18542 (function (global, factory) {
18543 module.exports = factory() ;
18544 })(commonjsGlobal, function () {
18545
18546 var hookCallback;
18547
18548 function hooks() {
18549 return hookCallback.apply(null, arguments);
18550 } // This is done to register the method called with moment()
18551 // without creating circular dependencies.
18552
18553
18554 function setHookCallback(callback) {
18555 hookCallback = callback;
18556 }
18557
18558 function isArray(input) {
18559 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
18560 }
18561
18562 function isObject(input) {
18563 // IE8 will treat undefined and null as object if it wasn't for
18564 // input != null
18565 return input != null && Object.prototype.toString.call(input) === '[object Object]';
18566 }
18567
18568 function isObjectEmpty(obj) {
18569 if (Object.getOwnPropertyNames) {
18570 return Object.getOwnPropertyNames(obj).length === 0;
18571 } else {
18572 var k;
18573
18574 for (k in obj) {
18575 if (obj.hasOwnProperty(k)) {
18576 return false;
18577 }
18578 }
18579
18580 return true;
18581 }
18582 }
18583
18584 function isUndefined(input) {
18585 return input === void 0;
18586 }
18587
18588 function isNumber(input) {
18589 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
18590 }
18591
18592 function isDate(input) {
18593 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
18594 }
18595
18596 function map(arr, fn) {
18597 var res = [],
18598 i;
18599
18600 for (i = 0; i < arr.length; ++i) {
18601 res.push(fn(arr[i], i));
18602 }
18603
18604 return res;
18605 }
18606
18607 function hasOwnProp(a, b) {
18608 return Object.prototype.hasOwnProperty.call(a, b);
18609 }
18610
18611 function extend(a, b) {
18612 for (var i in b) {
18613 if (hasOwnProp(b, i)) {
18614 a[i] = b[i];
18615 }
18616 }
18617
18618 if (hasOwnProp(b, 'toString')) {
18619 a.toString = b.toString;
18620 }
18621
18622 if (hasOwnProp(b, 'valueOf')) {
18623 a.valueOf = b.valueOf;
18624 }
18625
18626 return a;
18627 }
18628
18629 function createUTC(input, format, locale, strict) {
18630 return createLocalOrUTC(input, format, locale, strict, true).utc();
18631 }
18632
18633 function defaultParsingFlags() {
18634 // We need to deep clone this object.
18635 return {
18636 empty: false,
18637 unusedTokens: [],
18638 unusedInput: [],
18639 overflow: -2,
18640 charsLeftOver: 0,
18641 nullInput: false,
18642 invalidMonth: null,
18643 invalidFormat: false,
18644 userInvalidated: false,
18645 iso: false,
18646 parsedDateParts: [],
18647 meridiem: null,
18648 rfc2822: false,
18649 weekdayMismatch: false
18650 };
18651 }
18652
18653 function getParsingFlags(m) {
18654 if (m._pf == null) {
18655 m._pf = defaultParsingFlags();
18656 }
18657
18658 return m._pf;
18659 }
18660
18661 var some;
18662
18663 if (Array.prototype.some) {
18664 some = Array.prototype.some;
18665 } else {
18666 some = function some(fun) {
18667 var t = Object(this);
18668 var len = t.length >>> 0;
18669
18670 for (var i = 0; i < len; i++) {
18671 if (i in t && fun.call(this, t[i], i, t)) {
18672 return true;
18673 }
18674 }
18675
18676 return false;
18677 };
18678 }
18679
18680 function isValid(m) {
18681 if (m._isValid == null) {
18682 var flags = getParsingFlags(m);
18683 var parsedParts = some.call(flags.parsedDateParts, function (i) {
18684 return i != null;
18685 });
18686 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);
18687
18688 if (m._strict) {
18689 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
18690 }
18691
18692 if (Object.isFrozen == null || !Object.isFrozen(m)) {
18693 m._isValid = isNowValid;
18694 } else {
18695 return isNowValid;
18696 }
18697 }
18698
18699 return m._isValid;
18700 }
18701
18702 function createInvalid(flags) {
18703 var m = createUTC(NaN);
18704
18705 if (flags != null) {
18706 extend(getParsingFlags(m), flags);
18707 } else {
18708 getParsingFlags(m).userInvalidated = true;
18709 }
18710
18711 return m;
18712 } // Plugins that add properties should also add the key here (null value),
18713 // so we can properly clone ourselves.
18714
18715
18716 var momentProperties = hooks.momentProperties = [];
18717
18718 function copyConfig(to, from) {
18719 var i, prop, val;
18720
18721 if (!isUndefined(from._isAMomentObject)) {
18722 to._isAMomentObject = from._isAMomentObject;
18723 }
18724
18725 if (!isUndefined(from._i)) {
18726 to._i = from._i;
18727 }
18728
18729 if (!isUndefined(from._f)) {
18730 to._f = from._f;
18731 }
18732
18733 if (!isUndefined(from._l)) {
18734 to._l = from._l;
18735 }
18736
18737 if (!isUndefined(from._strict)) {
18738 to._strict = from._strict;
18739 }
18740
18741 if (!isUndefined(from._tzm)) {
18742 to._tzm = from._tzm;
18743 }
18744
18745 if (!isUndefined(from._isUTC)) {
18746 to._isUTC = from._isUTC;
18747 }
18748
18749 if (!isUndefined(from._offset)) {
18750 to._offset = from._offset;
18751 }
18752
18753 if (!isUndefined(from._pf)) {
18754 to._pf = getParsingFlags(from);
18755 }
18756
18757 if (!isUndefined(from._locale)) {
18758 to._locale = from._locale;
18759 }
18760
18761 if (momentProperties.length > 0) {
18762 for (i = 0; i < momentProperties.length; i++) {
18763 prop = momentProperties[i];
18764 val = from[prop];
18765
18766 if (!isUndefined(val)) {
18767 to[prop] = val;
18768 }
18769 }
18770 }
18771
18772 return to;
18773 }
18774
18775 var updateInProgress = false; // Moment prototype object
18776
18777 function Moment(config) {
18778 copyConfig(this, config);
18779 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
18780
18781 if (!this.isValid()) {
18782 this._d = new Date(NaN);
18783 } // Prevent infinite loop in case updateOffset creates new moment
18784 // objects.
18785
18786
18787 if (updateInProgress === false) {
18788 updateInProgress = true;
18789 hooks.updateOffset(this);
18790 updateInProgress = false;
18791 }
18792 }
18793
18794 function isMoment(obj) {
18795 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
18796 }
18797
18798 function absFloor(number) {
18799 if (number < 0) {
18800 // -0 -> 0
18801 return Math.ceil(number) || 0;
18802 } else {
18803 return Math.floor(number);
18804 }
18805 }
18806
18807 function toInt(argumentForCoercion) {
18808 var coercedNumber = +argumentForCoercion,
18809 value = 0;
18810
18811 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
18812 value = absFloor(coercedNumber);
18813 }
18814
18815 return value;
18816 } // compare two arrays, return the number of differences
18817
18818
18819 function compareArrays(array1, array2, dontConvert) {
18820 var len = Math.min(array1.length, array2.length),
18821 lengthDiff = Math.abs(array1.length - array2.length),
18822 diffs = 0,
18823 i;
18824
18825 for (i = 0; i < len; i++) {
18826 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
18827 diffs++;
18828 }
18829 }
18830
18831 return diffs + lengthDiff;
18832 }
18833
18834 function warn(msg) {
18835 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
18836 console.warn('Deprecation warning: ' + msg);
18837 }
18838 }
18839
18840 function deprecate(msg, fn) {
18841 var firstTime = true;
18842 return extend(function () {
18843 if (hooks.deprecationHandler != null) {
18844 hooks.deprecationHandler(null, msg);
18845 }
18846
18847 if (firstTime) {
18848 var args = [];
18849 var arg;
18850
18851 for (var i = 0; i < arguments.length; i++) {
18852 arg = '';
18853
18854 if (_typeof(arguments[i]) === 'object') {
18855 arg += '\n[' + i + '] ';
18856
18857 for (var key in arguments[0]) {
18858 arg += key + ': ' + arguments[0][key] + ', ';
18859 }
18860
18861 arg = arg.slice(0, -2); // Remove trailing comma and space
18862 } else {
18863 arg = arguments[i];
18864 }
18865
18866 args.push(arg);
18867 }
18868
18869 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
18870 firstTime = false;
18871 }
18872
18873 return fn.apply(this, arguments);
18874 }, fn);
18875 }
18876
18877 var deprecations = {};
18878
18879 function deprecateSimple(name, msg) {
18880 if (hooks.deprecationHandler != null) {
18881 hooks.deprecationHandler(name, msg);
18882 }
18883
18884 if (!deprecations[name]) {
18885 warn(msg);
18886 deprecations[name] = true;
18887 }
18888 }
18889
18890 hooks.suppressDeprecationWarnings = false;
18891 hooks.deprecationHandler = null;
18892
18893 function isFunction(input) {
18894 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
18895 }
18896
18897 function set(config) {
18898 var prop, i;
18899
18900 for (i in config) {
18901 prop = config[i];
18902
18903 if (isFunction(prop)) {
18904 this[i] = prop;
18905 } else {
18906 this['_' + i] = prop;
18907 }
18908 }
18909
18910 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
18911 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
18912 // TODO: Remove "ordinalParse" fallback in next major release.
18913
18914 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
18915 }
18916
18917 function mergeConfigs(parentConfig, childConfig) {
18918 var res = extend({}, parentConfig),
18919 prop;
18920
18921 for (prop in childConfig) {
18922 if (hasOwnProp(childConfig, prop)) {
18923 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
18924 res[prop] = {};
18925 extend(res[prop], parentConfig[prop]);
18926 extend(res[prop], childConfig[prop]);
18927 } else if (childConfig[prop] != null) {
18928 res[prop] = childConfig[prop];
18929 } else {
18930 delete res[prop];
18931 }
18932 }
18933 }
18934
18935 for (prop in parentConfig) {
18936 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
18937 // make sure changes to properties don't modify parent config
18938 res[prop] = extend({}, res[prop]);
18939 }
18940 }
18941
18942 return res;
18943 }
18944
18945 function Locale(config) {
18946 if (config != null) {
18947 this.set(config);
18948 }
18949 }
18950
18951 var keys;
18952
18953 if (Object.keys) {
18954 keys = Object.keys;
18955 } else {
18956 keys = function keys(obj) {
18957 var i,
18958 res = [];
18959
18960 for (i in obj) {
18961 if (hasOwnProp(obj, i)) {
18962 res.push(i);
18963 }
18964 }
18965
18966 return res;
18967 };
18968 }
18969
18970 var defaultCalendar = {
18971 sameDay: '[Today at] LT',
18972 nextDay: '[Tomorrow at] LT',
18973 nextWeek: 'dddd [at] LT',
18974 lastDay: '[Yesterday at] LT',
18975 lastWeek: '[Last] dddd [at] LT',
18976 sameElse: 'L'
18977 };
18978
18979 function calendar(key, mom, now) {
18980 var output = this._calendar[key] || this._calendar['sameElse'];
18981 return isFunction(output) ? output.call(mom, now) : output;
18982 }
18983
18984 var defaultLongDateFormat = {
18985 LTS: 'h:mm:ss A',
18986 LT: 'h:mm A',
18987 L: 'MM/DD/YYYY',
18988 LL: 'MMMM D, YYYY',
18989 LLL: 'MMMM D, YYYY h:mm A',
18990 LLLL: 'dddd, MMMM D, YYYY h:mm A'
18991 };
18992
18993 function longDateFormat(key) {
18994 var format = this._longDateFormat[key],
18995 formatUpper = this._longDateFormat[key.toUpperCase()];
18996
18997 if (format || !formatUpper) {
18998 return format;
18999 }
19000
19001 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
19002 return val.slice(1);
19003 });
19004 return this._longDateFormat[key];
19005 }
19006
19007 var defaultInvalidDate = 'Invalid date';
19008
19009 function invalidDate() {
19010 return this._invalidDate;
19011 }
19012
19013 var defaultOrdinal = '%d';
19014 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
19015
19016 function ordinal(number) {
19017 return this._ordinal.replace('%d', number);
19018 }
19019
19020 var defaultRelativeTime = {
19021 future: 'in %s',
19022 past: '%s ago',
19023 s: 'a few seconds',
19024 ss: '%d seconds',
19025 m: 'a minute',
19026 mm: '%d minutes',
19027 h: 'an hour',
19028 hh: '%d hours',
19029 d: 'a day',
19030 dd: '%d days',
19031 M: 'a month',
19032 MM: '%d months',
19033 y: 'a year',
19034 yy: '%d years'
19035 };
19036
19037 function relativeTime(number, withoutSuffix, string, isFuture) {
19038 var output = this._relativeTime[string];
19039 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
19040 }
19041
19042 function pastFuture(diff, output) {
19043 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
19044 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
19045 }
19046
19047 var aliases = {};
19048
19049 function addUnitAlias(unit, shorthand) {
19050 var lowerCase = unit.toLowerCase();
19051 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
19052 }
19053
19054 function normalizeUnits(units) {
19055 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
19056 }
19057
19058 function normalizeObjectUnits(inputObject) {
19059 var normalizedInput = {},
19060 normalizedProp,
19061 prop;
19062
19063 for (prop in inputObject) {
19064 if (hasOwnProp(inputObject, prop)) {
19065 normalizedProp = normalizeUnits(prop);
19066
19067 if (normalizedProp) {
19068 normalizedInput[normalizedProp] = inputObject[prop];
19069 }
19070 }
19071 }
19072
19073 return normalizedInput;
19074 }
19075
19076 var priorities = {};
19077
19078 function addUnitPriority(unit, priority) {
19079 priorities[unit] = priority;
19080 }
19081
19082 function getPrioritizedUnits(unitsObj) {
19083 var units = [];
19084
19085 for (var u in unitsObj) {
19086 units.push({
19087 unit: u,
19088 priority: priorities[u]
19089 });
19090 }
19091
19092 units.sort(function (a, b) {
19093 return a.priority - b.priority;
19094 });
19095 return units;
19096 }
19097
19098 function zeroFill(number, targetLength, forceSign) {
19099 var absNumber = '' + Math.abs(number),
19100 zerosToFill = targetLength - absNumber.length,
19101 sign = number >= 0;
19102 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
19103 }
19104
19105 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;
19106 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
19107 var formatFunctions = {};
19108 var formatTokenFunctions = {}; // token: 'M'
19109 // padded: ['MM', 2]
19110 // ordinal: 'Mo'
19111 // callback: function () { this.month() + 1 }
19112
19113 function addFormatToken(token, padded, ordinal, callback) {
19114 var func = callback;
19115
19116 if (typeof callback === 'string') {
19117 func = function func() {
19118 return this[callback]();
19119 };
19120 }
19121
19122 if (token) {
19123 formatTokenFunctions[token] = func;
19124 }
19125
19126 if (padded) {
19127 formatTokenFunctions[padded[0]] = function () {
19128 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
19129 };
19130 }
19131
19132 if (ordinal) {
19133 formatTokenFunctions[ordinal] = function () {
19134 return this.localeData().ordinal(func.apply(this, arguments), token);
19135 };
19136 }
19137 }
19138
19139 function removeFormattingTokens(input) {
19140 if (input.match(/\[[\s\S]/)) {
19141 return input.replace(/^\[|\]$/g, '');
19142 }
19143
19144 return input.replace(/\\/g, '');
19145 }
19146
19147 function makeFormatFunction(format) {
19148 var array = format.match(formattingTokens),
19149 i,
19150 length;
19151
19152 for (i = 0, length = array.length; i < length; i++) {
19153 if (formatTokenFunctions[array[i]]) {
19154 array[i] = formatTokenFunctions[array[i]];
19155 } else {
19156 array[i] = removeFormattingTokens(array[i]);
19157 }
19158 }
19159
19160 return function (mom) {
19161 var output = '',
19162 i;
19163
19164 for (i = 0; i < length; i++) {
19165 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
19166 }
19167
19168 return output;
19169 };
19170 } // format date using native date object
19171
19172
19173 function formatMoment(m, format) {
19174 if (!m.isValid()) {
19175 return m.localeData().invalidDate();
19176 }
19177
19178 format = expandFormat(format, m.localeData());
19179 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
19180 return formatFunctions[format](m);
19181 }
19182
19183 function expandFormat(format, locale) {
19184 var i = 5;
19185
19186 function replaceLongDateFormatTokens(input) {
19187 return locale.longDateFormat(input) || input;
19188 }
19189
19190 localFormattingTokens.lastIndex = 0;
19191
19192 while (i >= 0 && localFormattingTokens.test(format)) {
19193 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
19194 localFormattingTokens.lastIndex = 0;
19195 i -= 1;
19196 }
19197
19198 return format;
19199 }
19200
19201 var match1 = /\d/; // 0 - 9
19202
19203 var match2 = /\d\d/; // 00 - 99
19204
19205 var match3 = /\d{3}/; // 000 - 999
19206
19207 var match4 = /\d{4}/; // 0000 - 9999
19208
19209 var match6 = /[+-]?\d{6}/; // -999999 - 999999
19210
19211 var match1to2 = /\d\d?/; // 0 - 99
19212
19213 var match3to4 = /\d\d\d\d?/; // 999 - 9999
19214
19215 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
19216
19217 var match1to3 = /\d{1,3}/; // 0 - 999
19218
19219 var match1to4 = /\d{1,4}/; // 0 - 9999
19220
19221 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
19222
19223 var matchUnsigned = /\d+/; // 0 - inf
19224
19225 var matchSigned = /[+-]?\d+/; // -inf - inf
19226
19227 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
19228
19229 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
19230
19231 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
19232 // any word (or two) characters or numbers including two/three word month in arabic.
19233 // includes scottish gaelic two word and hyphenated months
19234
19235 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;
19236 var regexes = {};
19237
19238 function addRegexToken(token, regex, strictRegex) {
19239 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
19240 return isStrict && strictRegex ? strictRegex : regex;
19241 };
19242 }
19243
19244 function getParseRegexForToken(token, config) {
19245 if (!hasOwnProp(regexes, token)) {
19246 return new RegExp(unescapeFormat(token));
19247 }
19248
19249 return regexes[token](config._strict, config._locale);
19250 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
19251
19252
19253 function unescapeFormat(s) {
19254 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
19255 return p1 || p2 || p3 || p4;
19256 }));
19257 }
19258
19259 function regexEscape(s) {
19260 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
19261 }
19262
19263 var tokens = {};
19264
19265 function addParseToken(token, callback) {
19266 var i,
19267 func = callback;
19268
19269 if (typeof token === 'string') {
19270 token = [token];
19271 }
19272
19273 if (isNumber(callback)) {
19274 func = function func(input, array) {
19275 array[callback] = toInt(input);
19276 };
19277 }
19278
19279 for (i = 0; i < token.length; i++) {
19280 tokens[token[i]] = func;
19281 }
19282 }
19283
19284 function addWeekParseToken(token, callback) {
19285 addParseToken(token, function (input, array, config, token) {
19286 config._w = config._w || {};
19287 callback(input, config._w, config, token);
19288 });
19289 }
19290
19291 function addTimeToArrayFromToken(token, input, config) {
19292 if (input != null && hasOwnProp(tokens, token)) {
19293 tokens[token](input, config._a, config, token);
19294 }
19295 }
19296
19297 var YEAR = 0;
19298 var MONTH = 1;
19299 var DATE = 2;
19300 var HOUR = 3;
19301 var MINUTE = 4;
19302 var SECOND = 5;
19303 var MILLISECOND = 6;
19304 var WEEK = 7;
19305 var WEEKDAY = 8; // FORMATTING
19306
19307 addFormatToken('Y', 0, 0, function () {
19308 var y = this.year();
19309 return y <= 9999 ? '' + y : '+' + y;
19310 });
19311 addFormatToken(0, ['YY', 2], 0, function () {
19312 return this.year() % 100;
19313 });
19314 addFormatToken(0, ['YYYY', 4], 0, 'year');
19315 addFormatToken(0, ['YYYYY', 5], 0, 'year');
19316 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
19317
19318 addUnitAlias('year', 'y'); // PRIORITIES
19319
19320 addUnitPriority('year', 1); // PARSING
19321
19322 addRegexToken('Y', matchSigned);
19323 addRegexToken('YY', match1to2, match2);
19324 addRegexToken('YYYY', match1to4, match4);
19325 addRegexToken('YYYYY', match1to6, match6);
19326 addRegexToken('YYYYYY', match1to6, match6);
19327 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
19328 addParseToken('YYYY', function (input, array) {
19329 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
19330 });
19331 addParseToken('YY', function (input, array) {
19332 array[YEAR] = hooks.parseTwoDigitYear(input);
19333 });
19334 addParseToken('Y', function (input, array) {
19335 array[YEAR] = parseInt(input, 10);
19336 }); // HELPERS
19337
19338 function daysInYear(year) {
19339 return isLeapYear(year) ? 366 : 365;
19340 }
19341
19342 function isLeapYear(year) {
19343 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
19344 } // HOOKS
19345
19346
19347 hooks.parseTwoDigitYear = function (input) {
19348 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
19349 }; // MOMENTS
19350
19351
19352 var getSetYear = makeGetSet('FullYear', true);
19353
19354 function getIsLeapYear() {
19355 return isLeapYear(this.year());
19356 }
19357
19358 function makeGetSet(unit, keepTime) {
19359 return function (value) {
19360 if (value != null) {
19361 set$1(this, unit, value);
19362 hooks.updateOffset(this, keepTime);
19363 return this;
19364 } else {
19365 return get(this, unit);
19366 }
19367 };
19368 }
19369
19370 function get(mom, unit) {
19371 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
19372 }
19373
19374 function set$1(mom, unit, value) {
19375 if (mom.isValid() && !isNaN(value)) {
19376 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
19377 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
19378 } else {
19379 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
19380 }
19381 }
19382 } // MOMENTS
19383
19384
19385 function stringGet(units) {
19386 units = normalizeUnits(units);
19387
19388 if (isFunction(this[units])) {
19389 return this[units]();
19390 }
19391
19392 return this;
19393 }
19394
19395 function stringSet(units, value) {
19396 if (_typeof(units) === 'object') {
19397 units = normalizeObjectUnits(units);
19398 var prioritized = getPrioritizedUnits(units);
19399
19400 for (var i = 0; i < prioritized.length; i++) {
19401 this[prioritized[i].unit](units[prioritized[i].unit]);
19402 }
19403 } else {
19404 units = normalizeUnits(units);
19405
19406 if (isFunction(this[units])) {
19407 return this[units](value);
19408 }
19409 }
19410
19411 return this;
19412 }
19413
19414 function mod(n, x) {
19415 return (n % x + x) % x;
19416 }
19417
19418 var indexOf;
19419
19420 if (Array.prototype.indexOf) {
19421 indexOf = Array.prototype.indexOf;
19422 } else {
19423 indexOf = function indexOf(o) {
19424 // I know
19425 var i;
19426
19427 for (i = 0; i < this.length; ++i) {
19428 if (this[i] === o) {
19429 return i;
19430 }
19431 }
19432
19433 return -1;
19434 };
19435 }
19436
19437 function daysInMonth(year, month) {
19438 if (isNaN(year) || isNaN(month)) {
19439 return NaN;
19440 }
19441
19442 var modMonth = mod(month, 12);
19443 year += (month - modMonth) / 12;
19444 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
19445 } // FORMATTING
19446
19447
19448 addFormatToken('M', ['MM', 2], 'Mo', function () {
19449 return this.month() + 1;
19450 });
19451 addFormatToken('MMM', 0, 0, function (format) {
19452 return this.localeData().monthsShort(this, format);
19453 });
19454 addFormatToken('MMMM', 0, 0, function (format) {
19455 return this.localeData().months(this, format);
19456 }); // ALIASES
19457
19458 addUnitAlias('month', 'M'); // PRIORITY
19459
19460 addUnitPriority('month', 8); // PARSING
19461
19462 addRegexToken('M', match1to2);
19463 addRegexToken('MM', match1to2, match2);
19464 addRegexToken('MMM', function (isStrict, locale) {
19465 return locale.monthsShortRegex(isStrict);
19466 });
19467 addRegexToken('MMMM', function (isStrict, locale) {
19468 return locale.monthsRegex(isStrict);
19469 });
19470 addParseToken(['M', 'MM'], function (input, array) {
19471 array[MONTH] = toInt(input) - 1;
19472 });
19473 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
19474 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
19475
19476
19477 if (month != null) {
19478 array[MONTH] = month;
19479 } else {
19480 getParsingFlags(config).invalidMonth = input;
19481 }
19482 }); // LOCALES
19483
19484 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
19485 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
19486
19487 function localeMonths(m, format) {
19488 if (!m) {
19489 return isArray(this._months) ? this._months : this._months['standalone'];
19490 }
19491
19492 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
19493 }
19494
19495 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
19496
19497 function localeMonthsShort(m, format) {
19498 if (!m) {
19499 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
19500 }
19501
19502 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
19503 }
19504
19505 function handleStrictParse(monthName, format, strict) {
19506 var i,
19507 ii,
19508 mom,
19509 llc = monthName.toLocaleLowerCase();
19510
19511 if (!this._monthsParse) {
19512 // this is not used
19513 this._monthsParse = [];
19514 this._longMonthsParse = [];
19515 this._shortMonthsParse = [];
19516
19517 for (i = 0; i < 12; ++i) {
19518 mom = createUTC([2000, i]);
19519 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
19520 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
19521 }
19522 }
19523
19524 if (strict) {
19525 if (format === 'MMM') {
19526 ii = indexOf.call(this._shortMonthsParse, llc);
19527 return ii !== -1 ? ii : null;
19528 } else {
19529 ii = indexOf.call(this._longMonthsParse, llc);
19530 return ii !== -1 ? ii : null;
19531 }
19532 } else {
19533 if (format === 'MMM') {
19534 ii = indexOf.call(this._shortMonthsParse, llc);
19535
19536 if (ii !== -1) {
19537 return ii;
19538 }
19539
19540 ii = indexOf.call(this._longMonthsParse, llc);
19541 return ii !== -1 ? ii : null;
19542 } else {
19543 ii = indexOf.call(this._longMonthsParse, llc);
19544
19545 if (ii !== -1) {
19546 return ii;
19547 }
19548
19549 ii = indexOf.call(this._shortMonthsParse, llc);
19550 return ii !== -1 ? ii : null;
19551 }
19552 }
19553 }
19554
19555 function localeMonthsParse(monthName, format, strict) {
19556 var i, mom, regex;
19557
19558 if (this._monthsParseExact) {
19559 return handleStrictParse.call(this, monthName, format, strict);
19560 }
19561
19562 if (!this._monthsParse) {
19563 this._monthsParse = [];
19564 this._longMonthsParse = [];
19565 this._shortMonthsParse = [];
19566 } // TODO: add sorting
19567 // Sorting makes sure if one month (or abbr) is a prefix of another
19568 // see sorting in computeMonthsParse
19569
19570
19571 for (i = 0; i < 12; i++) {
19572 // make the regex if we don't have it already
19573 mom = createUTC([2000, i]);
19574
19575 if (strict && !this._longMonthsParse[i]) {
19576 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
19577 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
19578 }
19579
19580 if (!strict && !this._monthsParse[i]) {
19581 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
19582 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
19583 } // test the regex
19584
19585
19586 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
19587 return i;
19588 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
19589 return i;
19590 } else if (!strict && this._monthsParse[i].test(monthName)) {
19591 return i;
19592 }
19593 }
19594 } // MOMENTS
19595
19596
19597 function setMonth(mom, value) {
19598 var dayOfMonth;
19599
19600 if (!mom.isValid()) {
19601 // No op
19602 return mom;
19603 }
19604
19605 if (typeof value === 'string') {
19606 if (/^\d+$/.test(value)) {
19607 value = toInt(value);
19608 } else {
19609 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
19610
19611 if (!isNumber(value)) {
19612 return mom;
19613 }
19614 }
19615 }
19616
19617 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
19618
19619 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
19620
19621 return mom;
19622 }
19623
19624 function getSetMonth(value) {
19625 if (value != null) {
19626 setMonth(this, value);
19627 hooks.updateOffset(this, true);
19628 return this;
19629 } else {
19630 return get(this, 'Month');
19631 }
19632 }
19633
19634 function getDaysInMonth() {
19635 return daysInMonth(this.year(), this.month());
19636 }
19637
19638 var defaultMonthsShortRegex = matchWord;
19639
19640 function monthsShortRegex(isStrict) {
19641 if (this._monthsParseExact) {
19642 if (!hasOwnProp(this, '_monthsRegex')) {
19643 computeMonthsParse.call(this);
19644 }
19645
19646 if (isStrict) {
19647 return this._monthsShortStrictRegex;
19648 } else {
19649 return this._monthsShortRegex;
19650 }
19651 } else {
19652 if (!hasOwnProp(this, '_monthsShortRegex')) {
19653 this._monthsShortRegex = defaultMonthsShortRegex;
19654 }
19655
19656 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
19657 }
19658 }
19659
19660 var defaultMonthsRegex = matchWord;
19661
19662 function monthsRegex(isStrict) {
19663 if (this._monthsParseExact) {
19664 if (!hasOwnProp(this, '_monthsRegex')) {
19665 computeMonthsParse.call(this);
19666 }
19667
19668 if (isStrict) {
19669 return this._monthsStrictRegex;
19670 } else {
19671 return this._monthsRegex;
19672 }
19673 } else {
19674 if (!hasOwnProp(this, '_monthsRegex')) {
19675 this._monthsRegex = defaultMonthsRegex;
19676 }
19677
19678 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
19679 }
19680 }
19681
19682 function computeMonthsParse() {
19683 function cmpLenRev(a, b) {
19684 return b.length - a.length;
19685 }
19686
19687 var shortPieces = [],
19688 longPieces = [],
19689 mixedPieces = [],
19690 i,
19691 mom;
19692
19693 for (i = 0; i < 12; i++) {
19694 // make the regex if we don't have it already
19695 mom = createUTC([2000, i]);
19696 shortPieces.push(this.monthsShort(mom, ''));
19697 longPieces.push(this.months(mom, ''));
19698 mixedPieces.push(this.months(mom, ''));
19699 mixedPieces.push(this.monthsShort(mom, ''));
19700 } // Sorting makes sure if one month (or abbr) is a prefix of another it
19701 // will match the longer piece.
19702
19703
19704 shortPieces.sort(cmpLenRev);
19705 longPieces.sort(cmpLenRev);
19706 mixedPieces.sort(cmpLenRev);
19707
19708 for (i = 0; i < 12; i++) {
19709 shortPieces[i] = regexEscape(shortPieces[i]);
19710 longPieces[i] = regexEscape(longPieces[i]);
19711 }
19712
19713 for (i = 0; i < 24; i++) {
19714 mixedPieces[i] = regexEscape(mixedPieces[i]);
19715 }
19716
19717 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
19718 this._monthsShortRegex = this._monthsRegex;
19719 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
19720 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
19721 }
19722
19723 function createDate(y, m, d, h, M, s, ms) {
19724 // can't just apply() to create a date:
19725 // https://stackoverflow.com/q/181348
19726 var date; // the date constructor remaps years 0-99 to 1900-1999
19727
19728 if (y < 100 && y >= 0) {
19729 // preserve leap years using a full 400 year cycle, then reset
19730 date = new Date(y + 400, m, d, h, M, s, ms);
19731
19732 if (isFinite(date.getFullYear())) {
19733 date.setFullYear(y);
19734 }
19735 } else {
19736 date = new Date(y, m, d, h, M, s, ms);
19737 }
19738
19739 return date;
19740 }
19741
19742 function createUTCDate(y) {
19743 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
19744
19745 if (y < 100 && y >= 0) {
19746 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
19747
19748 args[0] = y + 400;
19749 date = new Date(Date.UTC.apply(null, args));
19750
19751 if (isFinite(date.getUTCFullYear())) {
19752 date.setUTCFullYear(y);
19753 }
19754 } else {
19755 date = new Date(Date.UTC.apply(null, arguments));
19756 }
19757
19758 return date;
19759 } // start-of-first-week - start-of-year
19760
19761
19762 function firstWeekOffset(year, dow, doy) {
19763 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
19764 fwd = 7 + dow - doy,
19765 // first-week day local weekday -- which local weekday is fwd
19766 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
19767 return -fwdlw + fwd - 1;
19768 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
19769
19770
19771 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
19772 var localWeekday = (7 + weekday - dow) % 7,
19773 weekOffset = firstWeekOffset(year, dow, doy),
19774 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
19775 resYear,
19776 resDayOfYear;
19777
19778 if (dayOfYear <= 0) {
19779 resYear = year - 1;
19780 resDayOfYear = daysInYear(resYear) + dayOfYear;
19781 } else if (dayOfYear > daysInYear(year)) {
19782 resYear = year + 1;
19783 resDayOfYear = dayOfYear - daysInYear(year);
19784 } else {
19785 resYear = year;
19786 resDayOfYear = dayOfYear;
19787 }
19788
19789 return {
19790 year: resYear,
19791 dayOfYear: resDayOfYear
19792 };
19793 }
19794
19795 function weekOfYear(mom, dow, doy) {
19796 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
19797 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
19798 resWeek,
19799 resYear;
19800
19801 if (week < 1) {
19802 resYear = mom.year() - 1;
19803 resWeek = week + weeksInYear(resYear, dow, doy);
19804 } else if (week > weeksInYear(mom.year(), dow, doy)) {
19805 resWeek = week - weeksInYear(mom.year(), dow, doy);
19806 resYear = mom.year() + 1;
19807 } else {
19808 resYear = mom.year();
19809 resWeek = week;
19810 }
19811
19812 return {
19813 week: resWeek,
19814 year: resYear
19815 };
19816 }
19817
19818 function weeksInYear(year, dow, doy) {
19819 var weekOffset = firstWeekOffset(year, dow, doy),
19820 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
19821 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
19822 } // FORMATTING
19823
19824
19825 addFormatToken('w', ['ww', 2], 'wo', 'week');
19826 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
19827
19828 addUnitAlias('week', 'w');
19829 addUnitAlias('isoWeek', 'W'); // PRIORITIES
19830
19831 addUnitPriority('week', 5);
19832 addUnitPriority('isoWeek', 5); // PARSING
19833
19834 addRegexToken('w', match1to2);
19835 addRegexToken('ww', match1to2, match2);
19836 addRegexToken('W', match1to2);
19837 addRegexToken('WW', match1to2, match2);
19838 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
19839 week[token.substr(0, 1)] = toInt(input);
19840 }); // HELPERS
19841 // LOCALES
19842
19843 function localeWeek(mom) {
19844 return weekOfYear(mom, this._week.dow, this._week.doy).week;
19845 }
19846
19847 var defaultLocaleWeek = {
19848 dow: 0,
19849 // Sunday is the first day of the week.
19850 doy: 6 // The week that contains Jan 6th is the first week of the year.
19851
19852 };
19853
19854 function localeFirstDayOfWeek() {
19855 return this._week.dow;
19856 }
19857
19858 function localeFirstDayOfYear() {
19859 return this._week.doy;
19860 } // MOMENTS
19861
19862
19863 function getSetWeek(input) {
19864 var week = this.localeData().week(this);
19865 return input == null ? week : this.add((input - week) * 7, 'd');
19866 }
19867
19868 function getSetISOWeek(input) {
19869 var week = weekOfYear(this, 1, 4).week;
19870 return input == null ? week : this.add((input - week) * 7, 'd');
19871 } // FORMATTING
19872
19873
19874 addFormatToken('d', 0, 'do', 'day');
19875 addFormatToken('dd', 0, 0, function (format) {
19876 return this.localeData().weekdaysMin(this, format);
19877 });
19878 addFormatToken('ddd', 0, 0, function (format) {
19879 return this.localeData().weekdaysShort(this, format);
19880 });
19881 addFormatToken('dddd', 0, 0, function (format) {
19882 return this.localeData().weekdays(this, format);
19883 });
19884 addFormatToken('e', 0, 0, 'weekday');
19885 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
19886
19887 addUnitAlias('day', 'd');
19888 addUnitAlias('weekday', 'e');
19889 addUnitAlias('isoWeekday', 'E'); // PRIORITY
19890
19891 addUnitPriority('day', 11);
19892 addUnitPriority('weekday', 11);
19893 addUnitPriority('isoWeekday', 11); // PARSING
19894
19895 addRegexToken('d', match1to2);
19896 addRegexToken('e', match1to2);
19897 addRegexToken('E', match1to2);
19898 addRegexToken('dd', function (isStrict, locale) {
19899 return locale.weekdaysMinRegex(isStrict);
19900 });
19901 addRegexToken('ddd', function (isStrict, locale) {
19902 return locale.weekdaysShortRegex(isStrict);
19903 });
19904 addRegexToken('dddd', function (isStrict, locale) {
19905 return locale.weekdaysRegex(isStrict);
19906 });
19907 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
19908 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
19909
19910
19911 if (weekday != null) {
19912 week.d = weekday;
19913 } else {
19914 getParsingFlags(config).invalidWeekday = input;
19915 }
19916 });
19917 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
19918 week[token] = toInt(input);
19919 }); // HELPERS
19920
19921 function parseWeekday(input, locale) {
19922 if (typeof input !== 'string') {
19923 return input;
19924 }
19925
19926 if (!isNaN(input)) {
19927 return parseInt(input, 10);
19928 }
19929
19930 input = locale.weekdaysParse(input);
19931
19932 if (typeof input === 'number') {
19933 return input;
19934 }
19935
19936 return null;
19937 }
19938
19939 function parseIsoWeekday(input, locale) {
19940 if (typeof input === 'string') {
19941 return locale.weekdaysParse(input) % 7 || 7;
19942 }
19943
19944 return isNaN(input) ? null : input;
19945 } // LOCALES
19946
19947
19948 function shiftWeekdays(ws, n) {
19949 return ws.slice(n, 7).concat(ws.slice(0, n));
19950 }
19951
19952 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
19953
19954 function localeWeekdays(m, format) {
19955 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
19956 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
19957 }
19958
19959 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
19960
19961 function localeWeekdaysShort(m) {
19962 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
19963 }
19964
19965 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
19966
19967 function localeWeekdaysMin(m) {
19968 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
19969 }
19970
19971 function handleStrictParse$1(weekdayName, format, strict) {
19972 var i,
19973 ii,
19974 mom,
19975 llc = weekdayName.toLocaleLowerCase();
19976
19977 if (!this._weekdaysParse) {
19978 this._weekdaysParse = [];
19979 this._shortWeekdaysParse = [];
19980 this._minWeekdaysParse = [];
19981
19982 for (i = 0; i < 7; ++i) {
19983 mom = createUTC([2000, 1]).day(i);
19984 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
19985 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
19986 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
19987 }
19988 }
19989
19990 if (strict) {
19991 if (format === 'dddd') {
19992 ii = indexOf.call(this._weekdaysParse, llc);
19993 return ii !== -1 ? ii : null;
19994 } else if (format === 'ddd') {
19995 ii = indexOf.call(this._shortWeekdaysParse, llc);
19996 return ii !== -1 ? ii : null;
19997 } else {
19998 ii = indexOf.call(this._minWeekdaysParse, llc);
19999 return ii !== -1 ? ii : null;
20000 }
20001 } else {
20002 if (format === 'dddd') {
20003 ii = indexOf.call(this._weekdaysParse, llc);
20004
20005 if (ii !== -1) {
20006 return ii;
20007 }
20008
20009 ii = indexOf.call(this._shortWeekdaysParse, llc);
20010
20011 if (ii !== -1) {
20012 return ii;
20013 }
20014
20015 ii = indexOf.call(this._minWeekdaysParse, llc);
20016 return ii !== -1 ? ii : null;
20017 } else if (format === 'ddd') {
20018 ii = indexOf.call(this._shortWeekdaysParse, llc);
20019
20020 if (ii !== -1) {
20021 return ii;
20022 }
20023
20024 ii = indexOf.call(this._weekdaysParse, llc);
20025
20026 if (ii !== -1) {
20027 return ii;
20028 }
20029
20030 ii = indexOf.call(this._minWeekdaysParse, llc);
20031 return ii !== -1 ? ii : null;
20032 } else {
20033 ii = indexOf.call(this._minWeekdaysParse, llc);
20034
20035 if (ii !== -1) {
20036 return ii;
20037 }
20038
20039 ii = indexOf.call(this._weekdaysParse, llc);
20040
20041 if (ii !== -1) {
20042 return ii;
20043 }
20044
20045 ii = indexOf.call(this._shortWeekdaysParse, llc);
20046 return ii !== -1 ? ii : null;
20047 }
20048 }
20049 }
20050
20051 function localeWeekdaysParse(weekdayName, format, strict) {
20052 var i, mom, regex;
20053
20054 if (this._weekdaysParseExact) {
20055 return handleStrictParse$1.call(this, weekdayName, format, strict);
20056 }
20057
20058 if (!this._weekdaysParse) {
20059 this._weekdaysParse = [];
20060 this._minWeekdaysParse = [];
20061 this._shortWeekdaysParse = [];
20062 this._fullWeekdaysParse = [];
20063 }
20064
20065 for (i = 0; i < 7; i++) {
20066 // make the regex if we don't have it already
20067 mom = createUTC([2000, 1]).day(i);
20068
20069 if (strict && !this._fullWeekdaysParse[i]) {
20070 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
20071 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
20072 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
20073 }
20074
20075 if (!this._weekdaysParse[i]) {
20076 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
20077 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
20078 } // test the regex
20079
20080
20081 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
20082 return i;
20083 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
20084 return i;
20085 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
20086 return i;
20087 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
20088 return i;
20089 }
20090 }
20091 } // MOMENTS
20092
20093
20094 function getSetDayOfWeek(input) {
20095 if (!this.isValid()) {
20096 return input != null ? this : NaN;
20097 }
20098
20099 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
20100
20101 if (input != null) {
20102 input = parseWeekday(input, this.localeData());
20103 return this.add(input - day, 'd');
20104 } else {
20105 return day;
20106 }
20107 }
20108
20109 function getSetLocaleDayOfWeek(input) {
20110 if (!this.isValid()) {
20111 return input != null ? this : NaN;
20112 }
20113
20114 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
20115 return input == null ? weekday : this.add(input - weekday, 'd');
20116 }
20117
20118 function getSetISODayOfWeek(input) {
20119 if (!this.isValid()) {
20120 return input != null ? this : NaN;
20121 } // behaves the same as moment#day except
20122 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
20123 // as a setter, sunday should belong to the previous week.
20124
20125
20126 if (input != null) {
20127 var weekday = parseIsoWeekday(input, this.localeData());
20128 return this.day(this.day() % 7 ? weekday : weekday - 7);
20129 } else {
20130 return this.day() || 7;
20131 }
20132 }
20133
20134 var defaultWeekdaysRegex = matchWord;
20135
20136 function weekdaysRegex(isStrict) {
20137 if (this._weekdaysParseExact) {
20138 if (!hasOwnProp(this, '_weekdaysRegex')) {
20139 computeWeekdaysParse.call(this);
20140 }
20141
20142 if (isStrict) {
20143 return this._weekdaysStrictRegex;
20144 } else {
20145 return this._weekdaysRegex;
20146 }
20147 } else {
20148 if (!hasOwnProp(this, '_weekdaysRegex')) {
20149 this._weekdaysRegex = defaultWeekdaysRegex;
20150 }
20151
20152 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
20153 }
20154 }
20155
20156 var defaultWeekdaysShortRegex = matchWord;
20157
20158 function weekdaysShortRegex(isStrict) {
20159 if (this._weekdaysParseExact) {
20160 if (!hasOwnProp(this, '_weekdaysRegex')) {
20161 computeWeekdaysParse.call(this);
20162 }
20163
20164 if (isStrict) {
20165 return this._weekdaysShortStrictRegex;
20166 } else {
20167 return this._weekdaysShortRegex;
20168 }
20169 } else {
20170 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
20171 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
20172 }
20173
20174 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
20175 }
20176 }
20177
20178 var defaultWeekdaysMinRegex = matchWord;
20179
20180 function weekdaysMinRegex(isStrict) {
20181 if (this._weekdaysParseExact) {
20182 if (!hasOwnProp(this, '_weekdaysRegex')) {
20183 computeWeekdaysParse.call(this);
20184 }
20185
20186 if (isStrict) {
20187 return this._weekdaysMinStrictRegex;
20188 } else {
20189 return this._weekdaysMinRegex;
20190 }
20191 } else {
20192 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
20193 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
20194 }
20195
20196 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
20197 }
20198 }
20199
20200 function computeWeekdaysParse() {
20201 function cmpLenRev(a, b) {
20202 return b.length - a.length;
20203 }
20204
20205 var minPieces = [],
20206 shortPieces = [],
20207 longPieces = [],
20208 mixedPieces = [],
20209 i,
20210 mom,
20211 minp,
20212 shortp,
20213 longp;
20214
20215 for (i = 0; i < 7; i++) {
20216 // make the regex if we don't have it already
20217 mom = createUTC([2000, 1]).day(i);
20218 minp = this.weekdaysMin(mom, '');
20219 shortp = this.weekdaysShort(mom, '');
20220 longp = this.weekdays(mom, '');
20221 minPieces.push(minp);
20222 shortPieces.push(shortp);
20223 longPieces.push(longp);
20224 mixedPieces.push(minp);
20225 mixedPieces.push(shortp);
20226 mixedPieces.push(longp);
20227 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
20228 // will match the longer piece.
20229
20230
20231 minPieces.sort(cmpLenRev);
20232 shortPieces.sort(cmpLenRev);
20233 longPieces.sort(cmpLenRev);
20234 mixedPieces.sort(cmpLenRev);
20235
20236 for (i = 0; i < 7; i++) {
20237 shortPieces[i] = regexEscape(shortPieces[i]);
20238 longPieces[i] = regexEscape(longPieces[i]);
20239 mixedPieces[i] = regexEscape(mixedPieces[i]);
20240 }
20241
20242 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
20243 this._weekdaysShortRegex = this._weekdaysRegex;
20244 this._weekdaysMinRegex = this._weekdaysRegex;
20245 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
20246 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
20247 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
20248 } // FORMATTING
20249
20250
20251 function hFormat() {
20252 return this.hours() % 12 || 12;
20253 }
20254
20255 function kFormat() {
20256 return this.hours() || 24;
20257 }
20258
20259 addFormatToken('H', ['HH', 2], 0, 'hour');
20260 addFormatToken('h', ['hh', 2], 0, hFormat);
20261 addFormatToken('k', ['kk', 2], 0, kFormat);
20262 addFormatToken('hmm', 0, 0, function () {
20263 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
20264 });
20265 addFormatToken('hmmss', 0, 0, function () {
20266 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
20267 });
20268 addFormatToken('Hmm', 0, 0, function () {
20269 return '' + this.hours() + zeroFill(this.minutes(), 2);
20270 });
20271 addFormatToken('Hmmss', 0, 0, function () {
20272 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
20273 });
20274
20275 function meridiem(token, lowercase) {
20276 addFormatToken(token, 0, 0, function () {
20277 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
20278 });
20279 }
20280
20281 meridiem('a', true);
20282 meridiem('A', false); // ALIASES
20283
20284 addUnitAlias('hour', 'h'); // PRIORITY
20285
20286 addUnitPriority('hour', 13); // PARSING
20287
20288 function matchMeridiem(isStrict, locale) {
20289 return locale._meridiemParse;
20290 }
20291
20292 addRegexToken('a', matchMeridiem);
20293 addRegexToken('A', matchMeridiem);
20294 addRegexToken('H', match1to2);
20295 addRegexToken('h', match1to2);
20296 addRegexToken('k', match1to2);
20297 addRegexToken('HH', match1to2, match2);
20298 addRegexToken('hh', match1to2, match2);
20299 addRegexToken('kk', match1to2, match2);
20300 addRegexToken('hmm', match3to4);
20301 addRegexToken('hmmss', match5to6);
20302 addRegexToken('Hmm', match3to4);
20303 addRegexToken('Hmmss', match5to6);
20304 addParseToken(['H', 'HH'], HOUR);
20305 addParseToken(['k', 'kk'], function (input, array, config) {
20306 var kInput = toInt(input);
20307 array[HOUR] = kInput === 24 ? 0 : kInput;
20308 });
20309 addParseToken(['a', 'A'], function (input, array, config) {
20310 config._isPm = config._locale.isPM(input);
20311 config._meridiem = input;
20312 });
20313 addParseToken(['h', 'hh'], function (input, array, config) {
20314 array[HOUR] = toInt(input);
20315 getParsingFlags(config).bigHour = true;
20316 });
20317 addParseToken('hmm', function (input, array, config) {
20318 var pos = input.length - 2;
20319 array[HOUR] = toInt(input.substr(0, pos));
20320 array[MINUTE] = toInt(input.substr(pos));
20321 getParsingFlags(config).bigHour = true;
20322 });
20323 addParseToken('hmmss', function (input, array, config) {
20324 var pos1 = input.length - 4;
20325 var pos2 = input.length - 2;
20326 array[HOUR] = toInt(input.substr(0, pos1));
20327 array[MINUTE] = toInt(input.substr(pos1, 2));
20328 array[SECOND] = toInt(input.substr(pos2));
20329 getParsingFlags(config).bigHour = true;
20330 });
20331 addParseToken('Hmm', function (input, array, config) {
20332 var pos = input.length - 2;
20333 array[HOUR] = toInt(input.substr(0, pos));
20334 array[MINUTE] = toInt(input.substr(pos));
20335 });
20336 addParseToken('Hmmss', function (input, array, config) {
20337 var pos1 = input.length - 4;
20338 var pos2 = input.length - 2;
20339 array[HOUR] = toInt(input.substr(0, pos1));
20340 array[MINUTE] = toInt(input.substr(pos1, 2));
20341 array[SECOND] = toInt(input.substr(pos2));
20342 }); // LOCALES
20343
20344 function localeIsPM(input) {
20345 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
20346 // Using charAt should be more compatible.
20347 return (input + '').toLowerCase().charAt(0) === 'p';
20348 }
20349
20350 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
20351
20352 function localeMeridiem(hours, minutes, isLower) {
20353 if (hours > 11) {
20354 return isLower ? 'pm' : 'PM';
20355 } else {
20356 return isLower ? 'am' : 'AM';
20357 }
20358 } // MOMENTS
20359 // Setting the hour should keep the time, because the user explicitly
20360 // specified which hour they want. So trying to maintain the same hour (in
20361 // a new timezone) makes sense. Adding/subtracting hours does not follow
20362 // this rule.
20363
20364
20365 var getSetHour = makeGetSet('Hours', true);
20366 var baseConfig = {
20367 calendar: defaultCalendar,
20368 longDateFormat: defaultLongDateFormat,
20369 invalidDate: defaultInvalidDate,
20370 ordinal: defaultOrdinal,
20371 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
20372 relativeTime: defaultRelativeTime,
20373 months: defaultLocaleMonths,
20374 monthsShort: defaultLocaleMonthsShort,
20375 week: defaultLocaleWeek,
20376 weekdays: defaultLocaleWeekdays,
20377 weekdaysMin: defaultLocaleWeekdaysMin,
20378 weekdaysShort: defaultLocaleWeekdaysShort,
20379 meridiemParse: defaultLocaleMeridiemParse
20380 }; // internal storage for locale config files
20381
20382 var locales = {};
20383 var localeFamilies = {};
20384 var globalLocale;
20385
20386 function normalizeLocale(key) {
20387 return key ? key.toLowerCase().replace('_', '-') : key;
20388 } // pick the locale from the array
20389 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
20390 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
20391
20392
20393 function chooseLocale(names) {
20394 var i = 0,
20395 j,
20396 next,
20397 locale,
20398 split;
20399
20400 while (i < names.length) {
20401 split = normalizeLocale(names[i]).split('-');
20402 j = split.length;
20403 next = normalizeLocale(names[i + 1]);
20404 next = next ? next.split('-') : null;
20405
20406 while (j > 0) {
20407 locale = loadLocale(split.slice(0, j).join('-'));
20408
20409 if (locale) {
20410 return locale;
20411 }
20412
20413 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
20414 //the next array item is better than a shallower substring of this one
20415 break;
20416 }
20417
20418 j--;
20419 }
20420
20421 i++;
20422 }
20423
20424 return globalLocale;
20425 }
20426
20427 function loadLocale(name) {
20428 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
20429
20430 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
20431 try {
20432 oldLocale = globalLocale._abbr;
20433 var aliasedRequire = commonjsRequire;
20434 aliasedRequire('./locale/' + name);
20435 getSetGlobalLocale(oldLocale);
20436 } catch (e) {}
20437 }
20438
20439 return locales[name];
20440 } // This function will load locale and then set the global locale. If
20441 // no arguments are passed in, it will simply return the current global
20442 // locale key.
20443
20444
20445 function getSetGlobalLocale(key, values) {
20446 var data;
20447
20448 if (key) {
20449 if (isUndefined(values)) {
20450 data = getLocale(key);
20451 } else {
20452 data = defineLocale(key, values);
20453 }
20454
20455 if (data) {
20456 // moment.duration._locale = moment._locale = data;
20457 globalLocale = data;
20458 } else {
20459 if (typeof console !== 'undefined' && console.warn) {
20460 //warn user if arguments are passed but the locale could not be set
20461 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
20462 }
20463 }
20464 }
20465
20466 return globalLocale._abbr;
20467 }
20468
20469 function defineLocale(name, config) {
20470 if (config !== null) {
20471 var locale,
20472 parentConfig = baseConfig;
20473 config.abbr = name;
20474
20475 if (locales[name] != null) {
20476 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.');
20477 parentConfig = locales[name]._config;
20478 } else if (config.parentLocale != null) {
20479 if (locales[config.parentLocale] != null) {
20480 parentConfig = locales[config.parentLocale]._config;
20481 } else {
20482 locale = loadLocale(config.parentLocale);
20483
20484 if (locale != null) {
20485 parentConfig = locale._config;
20486 } else {
20487 if (!localeFamilies[config.parentLocale]) {
20488 localeFamilies[config.parentLocale] = [];
20489 }
20490
20491 localeFamilies[config.parentLocale].push({
20492 name: name,
20493 config: config
20494 });
20495 return null;
20496 }
20497 }
20498 }
20499
20500 locales[name] = new Locale(mergeConfigs(parentConfig, config));
20501
20502 if (localeFamilies[name]) {
20503 localeFamilies[name].forEach(function (x) {
20504 defineLocale(x.name, x.config);
20505 });
20506 } // backwards compat for now: also set the locale
20507 // make sure we set the locale AFTER all child locales have been
20508 // created, so we won't end up with the child locale set.
20509
20510
20511 getSetGlobalLocale(name);
20512 return locales[name];
20513 } else {
20514 // useful for testing
20515 delete locales[name];
20516 return null;
20517 }
20518 }
20519
20520 function updateLocale(name, config) {
20521 if (config != null) {
20522 var locale,
20523 tmpLocale,
20524 parentConfig = baseConfig; // MERGE
20525
20526 tmpLocale = loadLocale(name);
20527
20528 if (tmpLocale != null) {
20529 parentConfig = tmpLocale._config;
20530 }
20531
20532 config = mergeConfigs(parentConfig, config);
20533 locale = new Locale(config);
20534 locale.parentLocale = locales[name];
20535 locales[name] = locale; // backwards compat for now: also set the locale
20536
20537 getSetGlobalLocale(name);
20538 } else {
20539 // pass null for config to unupdate, useful for tests
20540 if (locales[name] != null) {
20541 if (locales[name].parentLocale != null) {
20542 locales[name] = locales[name].parentLocale;
20543 } else if (locales[name] != null) {
20544 delete locales[name];
20545 }
20546 }
20547 }
20548
20549 return locales[name];
20550 } // returns locale data
20551
20552
20553 function getLocale(key) {
20554 var locale;
20555
20556 if (key && key._locale && key._locale._abbr) {
20557 key = key._locale._abbr;
20558 }
20559
20560 if (!key) {
20561 return globalLocale;
20562 }
20563
20564 if (!isArray(key)) {
20565 //short-circuit everything else
20566 locale = loadLocale(key);
20567
20568 if (locale) {
20569 return locale;
20570 }
20571
20572 key = [key];
20573 }
20574
20575 return chooseLocale(key);
20576 }
20577
20578 function listLocales() {
20579 return keys(locales);
20580 }
20581
20582 function checkOverflow(m) {
20583 var overflow;
20584 var a = m._a;
20585
20586 if (a && getParsingFlags(m).overflow === -2) {
20587 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;
20588
20589 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
20590 overflow = DATE;
20591 }
20592
20593 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
20594 overflow = WEEK;
20595 }
20596
20597 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
20598 overflow = WEEKDAY;
20599 }
20600
20601 getParsingFlags(m).overflow = overflow;
20602 }
20603
20604 return m;
20605 } // Pick the first defined of two or three arguments.
20606
20607
20608 function defaults(a, b, c) {
20609 if (a != null) {
20610 return a;
20611 }
20612
20613 if (b != null) {
20614 return b;
20615 }
20616
20617 return c;
20618 }
20619
20620 function currentDateArray(config) {
20621 // hooks is actually the exported moment object
20622 var nowValue = new Date(hooks.now());
20623
20624 if (config._useUTC) {
20625 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
20626 }
20627
20628 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
20629 } // convert an array to a date.
20630 // the array should mirror the parameters below
20631 // note: all values past the year are optional and will default to the lowest possible value.
20632 // [year, month, day , hour, minute, second, millisecond]
20633
20634
20635 function configFromArray(config) {
20636 var i,
20637 date,
20638 input = [],
20639 currentDate,
20640 expectedWeekday,
20641 yearToUse;
20642
20643 if (config._d) {
20644 return;
20645 }
20646
20647 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
20648
20649 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
20650 dayOfYearFromWeekInfo(config);
20651 } //if the day of the year is set, figure out what it is
20652
20653
20654 if (config._dayOfYear != null) {
20655 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
20656
20657 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
20658 getParsingFlags(config)._overflowDayOfYear = true;
20659 }
20660
20661 date = createUTCDate(yearToUse, 0, config._dayOfYear);
20662 config._a[MONTH] = date.getUTCMonth();
20663 config._a[DATE] = date.getUTCDate();
20664 } // Default to current date.
20665 // * if no year, month, day of month are given, default to today
20666 // * if day of month is given, default month and year
20667 // * if month is given, default only year
20668 // * if year is given, don't default anything
20669
20670
20671 for (i = 0; i < 3 && config._a[i] == null; ++i) {
20672 config._a[i] = input[i] = currentDate[i];
20673 } // Zero out whatever was not defaulted, including time
20674
20675
20676 for (; i < 7; i++) {
20677 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
20678 } // Check for 24:00:00.000
20679
20680
20681 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
20682 config._nextDay = true;
20683 config._a[HOUR] = 0;
20684 }
20685
20686 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
20687 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
20688 // with parseZone.
20689
20690 if (config._tzm != null) {
20691 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
20692 }
20693
20694 if (config._nextDay) {
20695 config._a[HOUR] = 24;
20696 } // check for mismatching day of week
20697
20698
20699 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
20700 getParsingFlags(config).weekdayMismatch = true;
20701 }
20702 }
20703
20704 function dayOfYearFromWeekInfo(config) {
20705 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
20706 w = config._w;
20707
20708 if (w.GG != null || w.W != null || w.E != null) {
20709 dow = 1;
20710 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
20711 // how we interpret now (local, utc, fixed offset). So create
20712 // a now version of current config (take local/utc/offset flags, and
20713 // create now).
20714
20715 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
20716 week = defaults(w.W, 1);
20717 weekday = defaults(w.E, 1);
20718
20719 if (weekday < 1 || weekday > 7) {
20720 weekdayOverflow = true;
20721 }
20722 } else {
20723 dow = config._locale._week.dow;
20724 doy = config._locale._week.doy;
20725 var curWeek = weekOfYear(createLocal(), dow, doy);
20726 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
20727
20728 week = defaults(w.w, curWeek.week);
20729
20730 if (w.d != null) {
20731 // weekday -- low day numbers are considered next week
20732 weekday = w.d;
20733
20734 if (weekday < 0 || weekday > 6) {
20735 weekdayOverflow = true;
20736 }
20737 } else if (w.e != null) {
20738 // local weekday -- counting starts from beginning of week
20739 weekday = w.e + dow;
20740
20741 if (w.e < 0 || w.e > 6) {
20742 weekdayOverflow = true;
20743 }
20744 } else {
20745 // default to beginning of week
20746 weekday = dow;
20747 }
20748 }
20749
20750 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
20751 getParsingFlags(config)._overflowWeeks = true;
20752 } else if (weekdayOverflow != null) {
20753 getParsingFlags(config)._overflowWeekday = true;
20754 } else {
20755 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
20756 config._a[YEAR] = temp.year;
20757 config._dayOfYear = temp.dayOfYear;
20758 }
20759 } // iso 8601 regex
20760 // 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)
20761
20762
20763 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)?)?$/;
20764 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)?)?$/;
20765 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
20766 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
20767 ['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
20768
20769 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/]];
20770 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
20771
20772 function configFromISO(config) {
20773 var i,
20774 l,
20775 string = config._i,
20776 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
20777 allowTime,
20778 dateFormat,
20779 timeFormat,
20780 tzFormat;
20781
20782 if (match) {
20783 getParsingFlags(config).iso = true;
20784
20785 for (i = 0, l = isoDates.length; i < l; i++) {
20786 if (isoDates[i][1].exec(match[1])) {
20787 dateFormat = isoDates[i][0];
20788 allowTime = isoDates[i][2] !== false;
20789 break;
20790 }
20791 }
20792
20793 if (dateFormat == null) {
20794 config._isValid = false;
20795 return;
20796 }
20797
20798 if (match[3]) {
20799 for (i = 0, l = isoTimes.length; i < l; i++) {
20800 if (isoTimes[i][1].exec(match[3])) {
20801 // match[2] should be 'T' or space
20802 timeFormat = (match[2] || ' ') + isoTimes[i][0];
20803 break;
20804 }
20805 }
20806
20807 if (timeFormat == null) {
20808 config._isValid = false;
20809 return;
20810 }
20811 }
20812
20813 if (!allowTime && timeFormat != null) {
20814 config._isValid = false;
20815 return;
20816 }
20817
20818 if (match[4]) {
20819 if (tzRegex.exec(match[4])) {
20820 tzFormat = 'Z';
20821 } else {
20822 config._isValid = false;
20823 return;
20824 }
20825 }
20826
20827 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
20828 configFromStringAndFormat(config);
20829 } else {
20830 config._isValid = false;
20831 }
20832 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
20833
20834
20835 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}))$/;
20836
20837 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
20838 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
20839
20840 if (secondStr) {
20841 result.push(parseInt(secondStr, 10));
20842 }
20843
20844 return result;
20845 }
20846
20847 function untruncateYear(yearStr) {
20848 var year = parseInt(yearStr, 10);
20849
20850 if (year <= 49) {
20851 return 2000 + year;
20852 } else if (year <= 999) {
20853 return 1900 + year;
20854 }
20855
20856 return year;
20857 }
20858
20859 function preprocessRFC2822(s) {
20860 // Remove comments and folding whitespace and replace multiple-spaces with a single space
20861 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
20862 }
20863
20864 function checkWeekday(weekdayStr, parsedInput, config) {
20865 if (weekdayStr) {
20866 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
20867 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
20868 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
20869
20870 if (weekdayProvided !== weekdayActual) {
20871 getParsingFlags(config).weekdayMismatch = true;
20872 config._isValid = false;
20873 return false;
20874 }
20875 }
20876
20877 return true;
20878 }
20879
20880 var obsOffsets = {
20881 UT: 0,
20882 GMT: 0,
20883 EDT: -4 * 60,
20884 EST: -5 * 60,
20885 CDT: -5 * 60,
20886 CST: -6 * 60,
20887 MDT: -6 * 60,
20888 MST: -7 * 60,
20889 PDT: -7 * 60,
20890 PST: -8 * 60
20891 };
20892
20893 function calculateOffset(obsOffset, militaryOffset, numOffset) {
20894 if (obsOffset) {
20895 return obsOffsets[obsOffset];
20896 } else if (militaryOffset) {
20897 // the only allowed military tz is Z
20898 return 0;
20899 } else {
20900 var hm = parseInt(numOffset, 10);
20901 var m = hm % 100,
20902 h = (hm - m) / 100;
20903 return h * 60 + m;
20904 }
20905 } // date and time from ref 2822 format
20906
20907
20908 function configFromRFC2822(config) {
20909 var match = rfc2822.exec(preprocessRFC2822(config._i));
20910
20911 if (match) {
20912 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
20913
20914 if (!checkWeekday(match[1], parsedArray, config)) {
20915 return;
20916 }
20917
20918 config._a = parsedArray;
20919 config._tzm = calculateOffset(match[8], match[9], match[10]);
20920 config._d = createUTCDate.apply(null, config._a);
20921
20922 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
20923
20924 getParsingFlags(config).rfc2822 = true;
20925 } else {
20926 config._isValid = false;
20927 }
20928 } // date from iso format or fallback
20929
20930
20931 function configFromString(config) {
20932 var matched = aspNetJsonRegex.exec(config._i);
20933
20934 if (matched !== null) {
20935 config._d = new Date(+matched[1]);
20936 return;
20937 }
20938
20939 configFromISO(config);
20940
20941 if (config._isValid === false) {
20942 delete config._isValid;
20943 } else {
20944 return;
20945 }
20946
20947 configFromRFC2822(config);
20948
20949 if (config._isValid === false) {
20950 delete config._isValid;
20951 } else {
20952 return;
20953 } // Final attempt, use Input Fallback
20954
20955
20956 hooks.createFromInputFallback(config);
20957 }
20958
20959 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) {
20960 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
20961 }); // constant that refers to the ISO standard
20962
20963 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
20964
20965
20966 hooks.RFC_2822 = function () {}; // date from string and format string
20967
20968
20969 function configFromStringAndFormat(config) {
20970 // TODO: Move this to another part of the creation flow to prevent circular deps
20971 if (config._f === hooks.ISO_8601) {
20972 configFromISO(config);
20973 return;
20974 }
20975
20976 if (config._f === hooks.RFC_2822) {
20977 configFromRFC2822(config);
20978 return;
20979 }
20980
20981 config._a = [];
20982 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
20983
20984 var string = '' + config._i,
20985 i,
20986 parsedInput,
20987 tokens,
20988 token,
20989 skipped,
20990 stringLength = string.length,
20991 totalParsedInputLength = 0;
20992 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
20993
20994 for (i = 0; i < tokens.length; i++) {
20995 token = tokens[i];
20996 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
20997 // 'regex', getParseRegexForToken(token, config));
20998
20999 if (parsedInput) {
21000 skipped = string.substr(0, string.indexOf(parsedInput));
21001
21002 if (skipped.length > 0) {
21003 getParsingFlags(config).unusedInput.push(skipped);
21004 }
21005
21006 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
21007 totalParsedInputLength += parsedInput.length;
21008 } // don't parse if it's not a known token
21009
21010
21011 if (formatTokenFunctions[token]) {
21012 if (parsedInput) {
21013 getParsingFlags(config).empty = false;
21014 } else {
21015 getParsingFlags(config).unusedTokens.push(token);
21016 }
21017
21018 addTimeToArrayFromToken(token, parsedInput, config);
21019 } else if (config._strict && !parsedInput) {
21020 getParsingFlags(config).unusedTokens.push(token);
21021 }
21022 } // add remaining unparsed input length to the string
21023
21024
21025 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
21026
21027 if (string.length > 0) {
21028 getParsingFlags(config).unusedInput.push(string);
21029 } // clear _12h flag if hour is <= 12
21030
21031
21032 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
21033 getParsingFlags(config).bigHour = undefined;
21034 }
21035
21036 getParsingFlags(config).parsedDateParts = config._a.slice(0);
21037 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
21038
21039 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
21040 configFromArray(config);
21041 checkOverflow(config);
21042 }
21043
21044 function meridiemFixWrap(locale, hour, meridiem) {
21045 var isPm;
21046
21047 if (meridiem == null) {
21048 // nothing to do
21049 return hour;
21050 }
21051
21052 if (locale.meridiemHour != null) {
21053 return locale.meridiemHour(hour, meridiem);
21054 } else if (locale.isPM != null) {
21055 // Fallback
21056 isPm = locale.isPM(meridiem);
21057
21058 if (isPm && hour < 12) {
21059 hour += 12;
21060 }
21061
21062 if (!isPm && hour === 12) {
21063 hour = 0;
21064 }
21065
21066 return hour;
21067 } else {
21068 // this is not supposed to happen
21069 return hour;
21070 }
21071 } // date from string and array of format strings
21072
21073
21074 function configFromStringAndArray(config) {
21075 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
21076
21077 if (config._f.length === 0) {
21078 getParsingFlags(config).invalidFormat = true;
21079 config._d = new Date(NaN);
21080 return;
21081 }
21082
21083 for (i = 0; i < config._f.length; i++) {
21084 currentScore = 0;
21085 tempConfig = copyConfig({}, config);
21086
21087 if (config._useUTC != null) {
21088 tempConfig._useUTC = config._useUTC;
21089 }
21090
21091 tempConfig._f = config._f[i];
21092 configFromStringAndFormat(tempConfig);
21093
21094 if (!isValid(tempConfig)) {
21095 continue;
21096 } // if there is any input that was not parsed add a penalty for that format
21097
21098
21099 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
21100
21101 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
21102 getParsingFlags(tempConfig).score = currentScore;
21103
21104 if (scoreToBeat == null || currentScore < scoreToBeat) {
21105 scoreToBeat = currentScore;
21106 bestMoment = tempConfig;
21107 }
21108 }
21109
21110 extend(config, bestMoment || tempConfig);
21111 }
21112
21113 function configFromObject(config) {
21114 if (config._d) {
21115 return;
21116 }
21117
21118 var i = normalizeObjectUnits(config._i);
21119 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
21120 return obj && parseInt(obj, 10);
21121 });
21122 configFromArray(config);
21123 }
21124
21125 function createFromConfig(config) {
21126 var res = new Moment(checkOverflow(prepareConfig(config)));
21127
21128 if (res._nextDay) {
21129 // Adding is smart enough around DST
21130 res.add(1, 'd');
21131 res._nextDay = undefined;
21132 }
21133
21134 return res;
21135 }
21136
21137 function prepareConfig(config) {
21138 var input = config._i,
21139 format = config._f;
21140 config._locale = config._locale || getLocale(config._l);
21141
21142 if (input === null || format === undefined && input === '') {
21143 return createInvalid({
21144 nullInput: true
21145 });
21146 }
21147
21148 if (typeof input === 'string') {
21149 config._i = input = config._locale.preparse(input);
21150 }
21151
21152 if (isMoment(input)) {
21153 return new Moment(checkOverflow(input));
21154 } else if (isDate(input)) {
21155 config._d = input;
21156 } else if (isArray(format)) {
21157 configFromStringAndArray(config);
21158 } else if (format) {
21159 configFromStringAndFormat(config);
21160 } else {
21161 configFromInput(config);
21162 }
21163
21164 if (!isValid(config)) {
21165 config._d = null;
21166 }
21167
21168 return config;
21169 }
21170
21171 function configFromInput(config) {
21172 var input = config._i;
21173
21174 if (isUndefined(input)) {
21175 config._d = new Date(hooks.now());
21176 } else if (isDate(input)) {
21177 config._d = new Date(input.valueOf());
21178 } else if (typeof input === 'string') {
21179 configFromString(config);
21180 } else if (isArray(input)) {
21181 config._a = map(input.slice(0), function (obj) {
21182 return parseInt(obj, 10);
21183 });
21184 configFromArray(config);
21185 } else if (isObject(input)) {
21186 configFromObject(config);
21187 } else if (isNumber(input)) {
21188 // from milliseconds
21189 config._d = new Date(input);
21190 } else {
21191 hooks.createFromInputFallback(config);
21192 }
21193 }
21194
21195 function createLocalOrUTC(input, format, locale, strict, isUTC) {
21196 var c = {};
21197
21198 if (locale === true || locale === false) {
21199 strict = locale;
21200 locale = undefined;
21201 }
21202
21203 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
21204 input = undefined;
21205 } // object construction must be done this way.
21206 // https://github.com/moment/moment/issues/1423
21207
21208
21209 c._isAMomentObject = true;
21210 c._useUTC = c._isUTC = isUTC;
21211 c._l = locale;
21212 c._i = input;
21213 c._f = format;
21214 c._strict = strict;
21215 return createFromConfig(c);
21216 }
21217
21218 function createLocal(input, format, locale, strict) {
21219 return createLocalOrUTC(input, format, locale, strict, false);
21220 }
21221
21222 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
21223 var other = createLocal.apply(null, arguments);
21224
21225 if (this.isValid() && other.isValid()) {
21226 return other < this ? this : other;
21227 } else {
21228 return createInvalid();
21229 }
21230 });
21231 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
21232 var other = createLocal.apply(null, arguments);
21233
21234 if (this.isValid() && other.isValid()) {
21235 return other > this ? this : other;
21236 } else {
21237 return createInvalid();
21238 }
21239 }); // Pick a moment m from moments so that m[fn](other) is true for all
21240 // other. This relies on the function fn to be transitive.
21241 //
21242 // moments should either be an array of moment objects or an array, whose
21243 // first element is an array of moment objects.
21244
21245 function pickBy(fn, moments) {
21246 var res, i;
21247
21248 if (moments.length === 1 && isArray(moments[0])) {
21249 moments = moments[0];
21250 }
21251
21252 if (!moments.length) {
21253 return createLocal();
21254 }
21255
21256 res = moments[0];
21257
21258 for (i = 1; i < moments.length; ++i) {
21259 if (!moments[i].isValid() || moments[i][fn](res)) {
21260 res = moments[i];
21261 }
21262 }
21263
21264 return res;
21265 } // TODO: Use [].sort instead?
21266
21267
21268 function min() {
21269 var args = [].slice.call(arguments, 0);
21270 return pickBy('isBefore', args);
21271 }
21272
21273 function max() {
21274 var args = [].slice.call(arguments, 0);
21275 return pickBy('isAfter', args);
21276 }
21277
21278 var now = function now() {
21279 return Date.now ? Date.now() : +new Date();
21280 };
21281
21282 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
21283
21284 function isDurationValid(m) {
21285 for (var key in m) {
21286 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
21287 return false;
21288 }
21289 }
21290
21291 var unitHasDecimal = false;
21292
21293 for (var i = 0; i < ordering.length; ++i) {
21294 if (m[ordering[i]]) {
21295 if (unitHasDecimal) {
21296 return false; // only allow non-integers for smallest unit
21297 }
21298
21299 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
21300 unitHasDecimal = true;
21301 }
21302 }
21303 }
21304
21305 return true;
21306 }
21307
21308 function isValid$1() {
21309 return this._isValid;
21310 }
21311
21312 function createInvalid$1() {
21313 return createDuration(NaN);
21314 }
21315
21316 function Duration(duration) {
21317 var normalizedInput = normalizeObjectUnits(duration),
21318 years = normalizedInput.year || 0,
21319 quarters = normalizedInput.quarter || 0,
21320 months = normalizedInput.month || 0,
21321 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
21322 days = normalizedInput.day || 0,
21323 hours = normalizedInput.hour || 0,
21324 minutes = normalizedInput.minute || 0,
21325 seconds = normalizedInput.second || 0,
21326 milliseconds = normalizedInput.millisecond || 0;
21327 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
21328
21329 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
21330 minutes * 6e4 + // 1000 * 60
21331 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
21332 // Because of dateAddRemove treats 24 hours as different from a
21333 // day when working around DST, we need to store them separately
21334
21335 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
21336 // which months you are are talking about, so we have to store
21337 // it separately.
21338
21339 this._months = +months + quarters * 3 + years * 12;
21340 this._data = {};
21341 this._locale = getLocale();
21342
21343 this._bubble();
21344 }
21345
21346 function isDuration(obj) {
21347 return obj instanceof Duration;
21348 }
21349
21350 function absRound(number) {
21351 if (number < 0) {
21352 return Math.round(-1 * number) * -1;
21353 } else {
21354 return Math.round(number);
21355 }
21356 } // FORMATTING
21357
21358
21359 function offset(token, separator) {
21360 addFormatToken(token, 0, 0, function () {
21361 var offset = this.utcOffset();
21362 var sign = '+';
21363
21364 if (offset < 0) {
21365 offset = -offset;
21366 sign = '-';
21367 }
21368
21369 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
21370 });
21371 }
21372
21373 offset('Z', ':');
21374 offset('ZZ', ''); // PARSING
21375
21376 addRegexToken('Z', matchShortOffset);
21377 addRegexToken('ZZ', matchShortOffset);
21378 addParseToken(['Z', 'ZZ'], function (input, array, config) {
21379 config._useUTC = true;
21380 config._tzm = offsetFromString(matchShortOffset, input);
21381 }); // HELPERS
21382 // timezone chunker
21383 // '+10:00' > ['10', '00']
21384 // '-1530' > ['-15', '30']
21385
21386 var chunkOffset = /([\+\-]|\d\d)/gi;
21387
21388 function offsetFromString(matcher, string) {
21389 var matches = (string || '').match(matcher);
21390
21391 if (matches === null) {
21392 return null;
21393 }
21394
21395 var chunk = matches[matches.length - 1] || [];
21396 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
21397 var minutes = +(parts[1] * 60) + toInt(parts[2]);
21398 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
21399 } // Return a moment from input, that is local/utc/zone equivalent to model.
21400
21401
21402 function cloneWithOffset(input, model) {
21403 var res, diff;
21404
21405 if (model._isUTC) {
21406 res = model.clone();
21407 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
21408
21409 res._d.setTime(res._d.valueOf() + diff);
21410
21411 hooks.updateOffset(res, false);
21412 return res;
21413 } else {
21414 return createLocal(input).local();
21415 }
21416 }
21417
21418 function getDateOffset(m) {
21419 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
21420 // https://github.com/moment/moment/pull/1871
21421 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
21422 } // HOOKS
21423 // This function will be called whenever a moment is mutated.
21424 // It is intended to keep the offset in sync with the timezone.
21425
21426
21427 hooks.updateOffset = function () {}; // MOMENTS
21428 // keepLocalTime = true means only change the timezone, without
21429 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
21430 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
21431 // +0200, so we adjust the time as needed, to be valid.
21432 //
21433 // Keeping the time actually adds/subtracts (one hour)
21434 // from the actual represented time. That is why we call updateOffset
21435 // a second time. In case it wants us to change the offset again
21436 // _changeInProgress == true case, then we have to adjust, because
21437 // there is no such time in the given timezone.
21438
21439
21440 function getSetOffset(input, keepLocalTime, keepMinutes) {
21441 var offset = this._offset || 0,
21442 localAdjust;
21443
21444 if (!this.isValid()) {
21445 return input != null ? this : NaN;
21446 }
21447
21448 if (input != null) {
21449 if (typeof input === 'string') {
21450 input = offsetFromString(matchShortOffset, input);
21451
21452 if (input === null) {
21453 return this;
21454 }
21455 } else if (Math.abs(input) < 16 && !keepMinutes) {
21456 input = input * 60;
21457 }
21458
21459 if (!this._isUTC && keepLocalTime) {
21460 localAdjust = getDateOffset(this);
21461 }
21462
21463 this._offset = input;
21464 this._isUTC = true;
21465
21466 if (localAdjust != null) {
21467 this.add(localAdjust, 'm');
21468 }
21469
21470 if (offset !== input) {
21471 if (!keepLocalTime || this._changeInProgress) {
21472 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
21473 } else if (!this._changeInProgress) {
21474 this._changeInProgress = true;
21475 hooks.updateOffset(this, true);
21476 this._changeInProgress = null;
21477 }
21478 }
21479
21480 return this;
21481 } else {
21482 return this._isUTC ? offset : getDateOffset(this);
21483 }
21484 }
21485
21486 function getSetZone(input, keepLocalTime) {
21487 if (input != null) {
21488 if (typeof input !== 'string') {
21489 input = -input;
21490 }
21491
21492 this.utcOffset(input, keepLocalTime);
21493 return this;
21494 } else {
21495 return -this.utcOffset();
21496 }
21497 }
21498
21499 function setOffsetToUTC(keepLocalTime) {
21500 return this.utcOffset(0, keepLocalTime);
21501 }
21502
21503 function setOffsetToLocal(keepLocalTime) {
21504 if (this._isUTC) {
21505 this.utcOffset(0, keepLocalTime);
21506 this._isUTC = false;
21507
21508 if (keepLocalTime) {
21509 this.subtract(getDateOffset(this), 'm');
21510 }
21511 }
21512
21513 return this;
21514 }
21515
21516 function setOffsetToParsedOffset() {
21517 if (this._tzm != null) {
21518 this.utcOffset(this._tzm, false, true);
21519 } else if (typeof this._i === 'string') {
21520 var tZone = offsetFromString(matchOffset, this._i);
21521
21522 if (tZone != null) {
21523 this.utcOffset(tZone);
21524 } else {
21525 this.utcOffset(0, true);
21526 }
21527 }
21528
21529 return this;
21530 }
21531
21532 function hasAlignedHourOffset(input) {
21533 if (!this.isValid()) {
21534 return false;
21535 }
21536
21537 input = input ? createLocal(input).utcOffset() : 0;
21538 return (this.utcOffset() - input) % 60 === 0;
21539 }
21540
21541 function isDaylightSavingTime() {
21542 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
21543 }
21544
21545 function isDaylightSavingTimeShifted() {
21546 if (!isUndefined(this._isDSTShifted)) {
21547 return this._isDSTShifted;
21548 }
21549
21550 var c = {};
21551 copyConfig(c, this);
21552 c = prepareConfig(c);
21553
21554 if (c._a) {
21555 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
21556 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
21557 } else {
21558 this._isDSTShifted = false;
21559 }
21560
21561 return this._isDSTShifted;
21562 }
21563
21564 function isLocal() {
21565 return this.isValid() ? !this._isUTC : false;
21566 }
21567
21568 function isUtcOffset() {
21569 return this.isValid() ? this._isUTC : false;
21570 }
21571
21572 function isUtc() {
21573 return this.isValid() ? this._isUTC && this._offset === 0 : false;
21574 } // ASP.NET json date format regex
21575
21576
21577 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
21578 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
21579 // and further modified to allow for strings containing both week and day
21580
21581 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)?)?$/;
21582
21583 function createDuration(input, key) {
21584 var duration = input,
21585 // matching against regexp is expensive, do it on demand
21586 match = null,
21587 sign,
21588 ret,
21589 diffRes;
21590
21591 if (isDuration(input)) {
21592 duration = {
21593 ms: input._milliseconds,
21594 d: input._days,
21595 M: input._months
21596 };
21597 } else if (isNumber(input)) {
21598 duration = {};
21599
21600 if (key) {
21601 duration[key] = input;
21602 } else {
21603 duration.milliseconds = input;
21604 }
21605 } else if (!!(match = aspNetRegex.exec(input))) {
21606 sign = match[1] === '-' ? -1 : 1;
21607 duration = {
21608 y: 0,
21609 d: toInt(match[DATE]) * sign,
21610 h: toInt(match[HOUR]) * sign,
21611 m: toInt(match[MINUTE]) * sign,
21612 s: toInt(match[SECOND]) * sign,
21613 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
21614
21615 };
21616 } else if (!!(match = isoRegex.exec(input))) {
21617 sign = match[1] === '-' ? -1 : 1;
21618 duration = {
21619 y: parseIso(match[2], sign),
21620 M: parseIso(match[3], sign),
21621 w: parseIso(match[4], sign),
21622 d: parseIso(match[5], sign),
21623 h: parseIso(match[6], sign),
21624 m: parseIso(match[7], sign),
21625 s: parseIso(match[8], sign)
21626 };
21627 } else if (duration == null) {
21628 // checks for null or undefined
21629 duration = {};
21630 } else if (_typeof(duration) === 'object' && ('from' in duration || 'to' in duration)) {
21631 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
21632 duration = {};
21633 duration.ms = diffRes.milliseconds;
21634 duration.M = diffRes.months;
21635 }
21636
21637 ret = new Duration(duration);
21638
21639 if (isDuration(input) && hasOwnProp(input, '_locale')) {
21640 ret._locale = input._locale;
21641 }
21642
21643 return ret;
21644 }
21645
21646 createDuration.fn = Duration.prototype;
21647 createDuration.invalid = createInvalid$1;
21648
21649 function parseIso(inp, sign) {
21650 // We'd normally use ~~inp for this, but unfortunately it also
21651 // converts floats to ints.
21652 // inp may be undefined, so careful calling replace on it.
21653 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
21654
21655 return (isNaN(res) ? 0 : res) * sign;
21656 }
21657
21658 function positiveMomentsDifference(base, other) {
21659 var res = {};
21660 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
21661
21662 if (base.clone().add(res.months, 'M').isAfter(other)) {
21663 --res.months;
21664 }
21665
21666 res.milliseconds = +other - +base.clone().add(res.months, 'M');
21667 return res;
21668 }
21669
21670 function momentsDifference(base, other) {
21671 var res;
21672
21673 if (!(base.isValid() && other.isValid())) {
21674 return {
21675 milliseconds: 0,
21676 months: 0
21677 };
21678 }
21679
21680 other = cloneWithOffset(other, base);
21681
21682 if (base.isBefore(other)) {
21683 res = positiveMomentsDifference(base, other);
21684 } else {
21685 res = positiveMomentsDifference(other, base);
21686 res.milliseconds = -res.milliseconds;
21687 res.months = -res.months;
21688 }
21689
21690 return res;
21691 } // TODO: remove 'name' arg after deprecation is removed
21692
21693
21694 function createAdder(direction, name) {
21695 return function (val, period) {
21696 var dur, tmp; //invert the arguments, but complain about it
21697
21698 if (period !== null && !isNaN(+period)) {
21699 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.');
21700 tmp = val;
21701 val = period;
21702 period = tmp;
21703 }
21704
21705 val = typeof val === 'string' ? +val : val;
21706 dur = createDuration(val, period);
21707 addSubtract(this, dur, direction);
21708 return this;
21709 };
21710 }
21711
21712 function addSubtract(mom, duration, isAdding, updateOffset) {
21713 var milliseconds = duration._milliseconds,
21714 days = absRound(duration._days),
21715 months = absRound(duration._months);
21716
21717 if (!mom.isValid()) {
21718 // No op
21719 return;
21720 }
21721
21722 updateOffset = updateOffset == null ? true : updateOffset;
21723
21724 if (months) {
21725 setMonth(mom, get(mom, 'Month') + months * isAdding);
21726 }
21727
21728 if (days) {
21729 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
21730 }
21731
21732 if (milliseconds) {
21733 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
21734 }
21735
21736 if (updateOffset) {
21737 hooks.updateOffset(mom, days || months);
21738 }
21739 }
21740
21741 var add = createAdder(1, 'add');
21742 var subtract = createAdder(-1, 'subtract');
21743
21744 function getCalendarFormat(myMoment, now) {
21745 var diff = myMoment.diff(now, 'days', true);
21746 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
21747 }
21748
21749 function calendar$1(time, formats) {
21750 // We want to compare the start of today, vs this.
21751 // Getting start-of-today depends on whether we're local/utc/offset or not.
21752 var now = time || createLocal(),
21753 sod = cloneWithOffset(now, this).startOf('day'),
21754 format = hooks.calendarFormat(this, sod) || 'sameElse';
21755 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
21756 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
21757 }
21758
21759 function clone() {
21760 return new Moment(this);
21761 }
21762
21763 function isAfter(input, units) {
21764 var localInput = isMoment(input) ? input : createLocal(input);
21765
21766 if (!(this.isValid() && localInput.isValid())) {
21767 return false;
21768 }
21769
21770 units = normalizeUnits(units) || 'millisecond';
21771
21772 if (units === 'millisecond') {
21773 return this.valueOf() > localInput.valueOf();
21774 } else {
21775 return localInput.valueOf() < this.clone().startOf(units).valueOf();
21776 }
21777 }
21778
21779 function isBefore(input, units) {
21780 var localInput = isMoment(input) ? input : createLocal(input);
21781
21782 if (!(this.isValid() && localInput.isValid())) {
21783 return false;
21784 }
21785
21786 units = normalizeUnits(units) || 'millisecond';
21787
21788 if (units === 'millisecond') {
21789 return this.valueOf() < localInput.valueOf();
21790 } else {
21791 return this.clone().endOf(units).valueOf() < localInput.valueOf();
21792 }
21793 }
21794
21795 function isBetween(from, to, units, inclusivity) {
21796 var localFrom = isMoment(from) ? from : createLocal(from),
21797 localTo = isMoment(to) ? to : createLocal(to);
21798
21799 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
21800 return false;
21801 }
21802
21803 inclusivity = inclusivity || '()';
21804 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
21805 }
21806
21807 function isSame(input, units) {
21808 var localInput = isMoment(input) ? input : createLocal(input),
21809 inputMs;
21810
21811 if (!(this.isValid() && localInput.isValid())) {
21812 return false;
21813 }
21814
21815 units = normalizeUnits(units) || 'millisecond';
21816
21817 if (units === 'millisecond') {
21818 return this.valueOf() === localInput.valueOf();
21819 } else {
21820 inputMs = localInput.valueOf();
21821 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
21822 }
21823 }
21824
21825 function isSameOrAfter(input, units) {
21826 return this.isSame(input, units) || this.isAfter(input, units);
21827 }
21828
21829 function isSameOrBefore(input, units) {
21830 return this.isSame(input, units) || this.isBefore(input, units);
21831 }
21832
21833 function diff(input, units, asFloat) {
21834 var that, zoneDelta, output;
21835
21836 if (!this.isValid()) {
21837 return NaN;
21838 }
21839
21840 that = cloneWithOffset(input, this);
21841
21842 if (!that.isValid()) {
21843 return NaN;
21844 }
21845
21846 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
21847 units = normalizeUnits(units);
21848
21849 switch (units) {
21850 case 'year':
21851 output = monthDiff(this, that) / 12;
21852 break;
21853
21854 case 'month':
21855 output = monthDiff(this, that);
21856 break;
21857
21858 case 'quarter':
21859 output = monthDiff(this, that) / 3;
21860 break;
21861
21862 case 'second':
21863 output = (this - that) / 1e3;
21864 break;
21865 // 1000
21866
21867 case 'minute':
21868 output = (this - that) / 6e4;
21869 break;
21870 // 1000 * 60
21871
21872 case 'hour':
21873 output = (this - that) / 36e5;
21874 break;
21875 // 1000 * 60 * 60
21876
21877 case 'day':
21878 output = (this - that - zoneDelta) / 864e5;
21879 break;
21880 // 1000 * 60 * 60 * 24, negate dst
21881
21882 case 'week':
21883 output = (this - that - zoneDelta) / 6048e5;
21884 break;
21885 // 1000 * 60 * 60 * 24 * 7, negate dst
21886
21887 default:
21888 output = this - that;
21889 }
21890
21891 return asFloat ? output : absFloor(output);
21892 }
21893
21894 function monthDiff(a, b) {
21895 // difference in months
21896 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
21897 // b is in (anchor - 1 month, anchor + 1 month)
21898 anchor = a.clone().add(wholeMonthDiff, 'months'),
21899 anchor2,
21900 adjust;
21901
21902 if (b - anchor < 0) {
21903 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
21904
21905 adjust = (b - anchor) / (anchor - anchor2);
21906 } else {
21907 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
21908
21909 adjust = (b - anchor) / (anchor2 - anchor);
21910 } //check for negative zero, return zero if negative zero
21911
21912
21913 return -(wholeMonthDiff + adjust) || 0;
21914 }
21915
21916 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
21917 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
21918
21919 function toString() {
21920 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
21921 }
21922
21923 function toISOString(keepOffset) {
21924 if (!this.isValid()) {
21925 return null;
21926 }
21927
21928 var utc = keepOffset !== true;
21929 var m = utc ? this.clone().utc() : this;
21930
21931 if (m.year() < 0 || m.year() > 9999) {
21932 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
21933 }
21934
21935 if (isFunction(Date.prototype.toISOString)) {
21936 // native implementation is ~50x faster, use it when we can
21937 if (utc) {
21938 return this.toDate().toISOString();
21939 } else {
21940 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
21941 }
21942 }
21943
21944 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
21945 }
21946 /**
21947 * Return a human readable representation of a moment that can
21948 * also be evaluated to get a new moment which is the same
21949 *
21950 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
21951 */
21952
21953
21954 function inspect() {
21955 if (!this.isValid()) {
21956 return 'moment.invalid(/* ' + this._i + ' */)';
21957 }
21958
21959 var func = 'moment';
21960 var zone = '';
21961
21962 if (!this.isLocal()) {
21963 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
21964 zone = 'Z';
21965 }
21966
21967 var prefix = '[' + func + '("]';
21968 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
21969 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
21970 var suffix = zone + '[")]';
21971 return this.format(prefix + year + datetime + suffix);
21972 }
21973
21974 function format(inputString) {
21975 if (!inputString) {
21976 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
21977 }
21978
21979 var output = formatMoment(this, inputString);
21980 return this.localeData().postformat(output);
21981 }
21982
21983 function from(time, withoutSuffix) {
21984 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
21985 return createDuration({
21986 to: this,
21987 from: time
21988 }).locale(this.locale()).humanize(!withoutSuffix);
21989 } else {
21990 return this.localeData().invalidDate();
21991 }
21992 }
21993
21994 function fromNow(withoutSuffix) {
21995 return this.from(createLocal(), withoutSuffix);
21996 }
21997
21998 function to(time, withoutSuffix) {
21999 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
22000 return createDuration({
22001 from: this,
22002 to: time
22003 }).locale(this.locale()).humanize(!withoutSuffix);
22004 } else {
22005 return this.localeData().invalidDate();
22006 }
22007 }
22008
22009 function toNow(withoutSuffix) {
22010 return this.to(createLocal(), withoutSuffix);
22011 } // If passed a locale key, it will set the locale for this
22012 // instance. Otherwise, it will return the locale configuration
22013 // variables for this instance.
22014
22015
22016 function locale(key) {
22017 var newLocaleData;
22018
22019 if (key === undefined) {
22020 return this._locale._abbr;
22021 } else {
22022 newLocaleData = getLocale(key);
22023
22024 if (newLocaleData != null) {
22025 this._locale = newLocaleData;
22026 }
22027
22028 return this;
22029 }
22030 }
22031
22032 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
22033 if (key === undefined) {
22034 return this.localeData();
22035 } else {
22036 return this.locale(key);
22037 }
22038 });
22039
22040 function localeData() {
22041 return this._locale;
22042 }
22043
22044 var MS_PER_SECOND = 1000;
22045 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
22046 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
22047 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
22048
22049 function mod$1(dividend, divisor) {
22050 return (dividend % divisor + divisor) % divisor;
22051 }
22052
22053 function localStartOfDate(y, m, d) {
22054 // the date constructor remaps years 0-99 to 1900-1999
22055 if (y < 100 && y >= 0) {
22056 // preserve leap years using a full 400 year cycle, then reset
22057 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
22058 } else {
22059 return new Date(y, m, d).valueOf();
22060 }
22061 }
22062
22063 function utcStartOfDate(y, m, d) {
22064 // Date.UTC remaps years 0-99 to 1900-1999
22065 if (y < 100 && y >= 0) {
22066 // preserve leap years using a full 400 year cycle, then reset
22067 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
22068 } else {
22069 return Date.UTC(y, m, d);
22070 }
22071 }
22072
22073 function startOf(units) {
22074 var time;
22075 units = normalizeUnits(units);
22076
22077 if (units === undefined || units === 'millisecond' || !this.isValid()) {
22078 return this;
22079 }
22080
22081 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
22082
22083 switch (units) {
22084 case 'year':
22085 time = startOfDate(this.year(), 0, 1);
22086 break;
22087
22088 case 'quarter':
22089 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
22090 break;
22091
22092 case 'month':
22093 time = startOfDate(this.year(), this.month(), 1);
22094 break;
22095
22096 case 'week':
22097 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
22098 break;
22099
22100 case 'isoWeek':
22101 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
22102 break;
22103
22104 case 'day':
22105 case 'date':
22106 time = startOfDate(this.year(), this.month(), this.date());
22107 break;
22108
22109 case 'hour':
22110 time = this._d.valueOf();
22111 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
22112 break;
22113
22114 case 'minute':
22115 time = this._d.valueOf();
22116 time -= mod$1(time, MS_PER_MINUTE);
22117 break;
22118
22119 case 'second':
22120 time = this._d.valueOf();
22121 time -= mod$1(time, MS_PER_SECOND);
22122 break;
22123 }
22124
22125 this._d.setTime(time);
22126
22127 hooks.updateOffset(this, true);
22128 return this;
22129 }
22130
22131 function endOf(units) {
22132 var time;
22133 units = normalizeUnits(units);
22134
22135 if (units === undefined || units === 'millisecond' || !this.isValid()) {
22136 return this;
22137 }
22138
22139 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
22140
22141 switch (units) {
22142 case 'year':
22143 time = startOfDate(this.year() + 1, 0, 1) - 1;
22144 break;
22145
22146 case 'quarter':
22147 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
22148 break;
22149
22150 case 'month':
22151 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
22152 break;
22153
22154 case 'week':
22155 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
22156 break;
22157
22158 case 'isoWeek':
22159 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
22160 break;
22161
22162 case 'day':
22163 case 'date':
22164 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
22165 break;
22166
22167 case 'hour':
22168 time = this._d.valueOf();
22169 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
22170 break;
22171
22172 case 'minute':
22173 time = this._d.valueOf();
22174 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
22175 break;
22176
22177 case 'second':
22178 time = this._d.valueOf();
22179 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
22180 break;
22181 }
22182
22183 this._d.setTime(time);
22184
22185 hooks.updateOffset(this, true);
22186 return this;
22187 }
22188
22189 function valueOf() {
22190 return this._d.valueOf() - (this._offset || 0) * 60000;
22191 }
22192
22193 function unix() {
22194 return Math.floor(this.valueOf() / 1000);
22195 }
22196
22197 function toDate() {
22198 return new Date(this.valueOf());
22199 }
22200
22201 function toArray() {
22202 var m = this;
22203 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
22204 }
22205
22206 function toObject() {
22207 var m = this;
22208 return {
22209 years: m.year(),
22210 months: m.month(),
22211 date: m.date(),
22212 hours: m.hours(),
22213 minutes: m.minutes(),
22214 seconds: m.seconds(),
22215 milliseconds: m.milliseconds()
22216 };
22217 }
22218
22219 function toJSON() {
22220 // new Date(NaN).toJSON() === null
22221 return this.isValid() ? this.toISOString() : null;
22222 }
22223
22224 function isValid$2() {
22225 return isValid(this);
22226 }
22227
22228 function parsingFlags() {
22229 return extend({}, getParsingFlags(this));
22230 }
22231
22232 function invalidAt() {
22233 return getParsingFlags(this).overflow;
22234 }
22235
22236 function creationData() {
22237 return {
22238 input: this._i,
22239 format: this._f,
22240 locale: this._locale,
22241 isUTC: this._isUTC,
22242 strict: this._strict
22243 };
22244 } // FORMATTING
22245
22246
22247 addFormatToken(0, ['gg', 2], 0, function () {
22248 return this.weekYear() % 100;
22249 });
22250 addFormatToken(0, ['GG', 2], 0, function () {
22251 return this.isoWeekYear() % 100;
22252 });
22253
22254 function addWeekYearFormatToken(token, getter) {
22255 addFormatToken(0, [token, token.length], 0, getter);
22256 }
22257
22258 addWeekYearFormatToken('gggg', 'weekYear');
22259 addWeekYearFormatToken('ggggg', 'weekYear');
22260 addWeekYearFormatToken('GGGG', 'isoWeekYear');
22261 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
22262
22263 addUnitAlias('weekYear', 'gg');
22264 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
22265
22266 addUnitPriority('weekYear', 1);
22267 addUnitPriority('isoWeekYear', 1); // PARSING
22268
22269 addRegexToken('G', matchSigned);
22270 addRegexToken('g', matchSigned);
22271 addRegexToken('GG', match1to2, match2);
22272 addRegexToken('gg', match1to2, match2);
22273 addRegexToken('GGGG', match1to4, match4);
22274 addRegexToken('gggg', match1to4, match4);
22275 addRegexToken('GGGGG', match1to6, match6);
22276 addRegexToken('ggggg', match1to6, match6);
22277 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
22278 week[token.substr(0, 2)] = toInt(input);
22279 });
22280 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
22281 week[token] = hooks.parseTwoDigitYear(input);
22282 }); // MOMENTS
22283
22284 function getSetWeekYear(input) {
22285 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
22286 }
22287
22288 function getSetISOWeekYear(input) {
22289 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
22290 }
22291
22292 function getISOWeeksInYear() {
22293 return weeksInYear(this.year(), 1, 4);
22294 }
22295
22296 function getWeeksInYear() {
22297 var weekInfo = this.localeData()._week;
22298
22299 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
22300 }
22301
22302 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
22303 var weeksTarget;
22304
22305 if (input == null) {
22306 return weekOfYear(this, dow, doy).year;
22307 } else {
22308 weeksTarget = weeksInYear(input, dow, doy);
22309
22310 if (week > weeksTarget) {
22311 week = weeksTarget;
22312 }
22313
22314 return setWeekAll.call(this, input, week, weekday, dow, doy);
22315 }
22316 }
22317
22318 function setWeekAll(weekYear, week, weekday, dow, doy) {
22319 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
22320 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
22321 this.year(date.getUTCFullYear());
22322 this.month(date.getUTCMonth());
22323 this.date(date.getUTCDate());
22324 return this;
22325 } // FORMATTING
22326
22327
22328 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
22329
22330 addUnitAlias('quarter', 'Q'); // PRIORITY
22331
22332 addUnitPriority('quarter', 7); // PARSING
22333
22334 addRegexToken('Q', match1);
22335 addParseToken('Q', function (input, array) {
22336 array[MONTH] = (toInt(input) - 1) * 3;
22337 }); // MOMENTS
22338
22339 function getSetQuarter(input) {
22340 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
22341 } // FORMATTING
22342
22343
22344 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
22345
22346 addUnitAlias('date', 'D'); // PRIORITY
22347
22348 addUnitPriority('date', 9); // PARSING
22349
22350 addRegexToken('D', match1to2);
22351 addRegexToken('DD', match1to2, match2);
22352 addRegexToken('Do', function (isStrict, locale) {
22353 // TODO: Remove "ordinalParse" fallback in next major release.
22354 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
22355 });
22356 addParseToken(['D', 'DD'], DATE);
22357 addParseToken('Do', function (input, array) {
22358 array[DATE] = toInt(input.match(match1to2)[0]);
22359 }); // MOMENTS
22360
22361 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
22362
22363 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
22364
22365 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
22366
22367 addUnitPriority('dayOfYear', 4); // PARSING
22368
22369 addRegexToken('DDD', match1to3);
22370 addRegexToken('DDDD', match3);
22371 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
22372 config._dayOfYear = toInt(input);
22373 }); // HELPERS
22374 // MOMENTS
22375
22376 function getSetDayOfYear(input) {
22377 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
22378 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
22379 } // FORMATTING
22380
22381
22382 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
22383
22384 addUnitAlias('minute', 'm'); // PRIORITY
22385
22386 addUnitPriority('minute', 14); // PARSING
22387
22388 addRegexToken('m', match1to2);
22389 addRegexToken('mm', match1to2, match2);
22390 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
22391
22392 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
22393
22394 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
22395
22396 addUnitAlias('second', 's'); // PRIORITY
22397
22398 addUnitPriority('second', 15); // PARSING
22399
22400 addRegexToken('s', match1to2);
22401 addRegexToken('ss', match1to2, match2);
22402 addParseToken(['s', 'ss'], SECOND); // MOMENTS
22403
22404 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
22405
22406 addFormatToken('S', 0, 0, function () {
22407 return ~~(this.millisecond() / 100);
22408 });
22409 addFormatToken(0, ['SS', 2], 0, function () {
22410 return ~~(this.millisecond() / 10);
22411 });
22412 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
22413 addFormatToken(0, ['SSSS', 4], 0, function () {
22414 return this.millisecond() * 10;
22415 });
22416 addFormatToken(0, ['SSSSS', 5], 0, function () {
22417 return this.millisecond() * 100;
22418 });
22419 addFormatToken(0, ['SSSSSS', 6], 0, function () {
22420 return this.millisecond() * 1000;
22421 });
22422 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
22423 return this.millisecond() * 10000;
22424 });
22425 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
22426 return this.millisecond() * 100000;
22427 });
22428 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
22429 return this.millisecond() * 1000000;
22430 }); // ALIASES
22431
22432 addUnitAlias('millisecond', 'ms'); // PRIORITY
22433
22434 addUnitPriority('millisecond', 16); // PARSING
22435
22436 addRegexToken('S', match1to3, match1);
22437 addRegexToken('SS', match1to3, match2);
22438 addRegexToken('SSS', match1to3, match3);
22439 var token;
22440
22441 for (token = 'SSSS'; token.length <= 9; token += 'S') {
22442 addRegexToken(token, matchUnsigned);
22443 }
22444
22445 function parseMs(input, array) {
22446 array[MILLISECOND] = toInt(('0.' + input) * 1000);
22447 }
22448
22449 for (token = 'S'; token.length <= 9; token += 'S') {
22450 addParseToken(token, parseMs);
22451 } // MOMENTS
22452
22453
22454 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
22455
22456 addFormatToken('z', 0, 0, 'zoneAbbr');
22457 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
22458
22459 function getZoneAbbr() {
22460 return this._isUTC ? 'UTC' : '';
22461 }
22462
22463 function getZoneName() {
22464 return this._isUTC ? 'Coordinated Universal Time' : '';
22465 }
22466
22467 var proto = Moment.prototype;
22468 proto.add = add;
22469 proto.calendar = calendar$1;
22470 proto.clone = clone;
22471 proto.diff = diff;
22472 proto.endOf = endOf;
22473 proto.format = format;
22474 proto.from = from;
22475 proto.fromNow = fromNow;
22476 proto.to = to;
22477 proto.toNow = toNow;
22478 proto.get = stringGet;
22479 proto.invalidAt = invalidAt;
22480 proto.isAfter = isAfter;
22481 proto.isBefore = isBefore;
22482 proto.isBetween = isBetween;
22483 proto.isSame = isSame;
22484 proto.isSameOrAfter = isSameOrAfter;
22485 proto.isSameOrBefore = isSameOrBefore;
22486 proto.isValid = isValid$2;
22487 proto.lang = lang;
22488 proto.locale = locale;
22489 proto.localeData = localeData;
22490 proto.max = prototypeMax;
22491 proto.min = prototypeMin;
22492 proto.parsingFlags = parsingFlags;
22493 proto.set = stringSet;
22494 proto.startOf = startOf;
22495 proto.subtract = subtract;
22496 proto.toArray = toArray;
22497 proto.toObject = toObject;
22498 proto.toDate = toDate;
22499 proto.toISOString = toISOString;
22500 proto.inspect = inspect;
22501 proto.toJSON = toJSON;
22502 proto.toString = toString;
22503 proto.unix = unix;
22504 proto.valueOf = valueOf;
22505 proto.creationData = creationData;
22506 proto.year = getSetYear;
22507 proto.isLeapYear = getIsLeapYear;
22508 proto.weekYear = getSetWeekYear;
22509 proto.isoWeekYear = getSetISOWeekYear;
22510 proto.quarter = proto.quarters = getSetQuarter;
22511 proto.month = getSetMonth;
22512 proto.daysInMonth = getDaysInMonth;
22513 proto.week = proto.weeks = getSetWeek;
22514 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
22515 proto.weeksInYear = getWeeksInYear;
22516 proto.isoWeeksInYear = getISOWeeksInYear;
22517 proto.date = getSetDayOfMonth;
22518 proto.day = proto.days = getSetDayOfWeek;
22519 proto.weekday = getSetLocaleDayOfWeek;
22520 proto.isoWeekday = getSetISODayOfWeek;
22521 proto.dayOfYear = getSetDayOfYear;
22522 proto.hour = proto.hours = getSetHour;
22523 proto.minute = proto.minutes = getSetMinute;
22524 proto.second = proto.seconds = getSetSecond;
22525 proto.millisecond = proto.milliseconds = getSetMillisecond;
22526 proto.utcOffset = getSetOffset;
22527 proto.utc = setOffsetToUTC;
22528 proto.local = setOffsetToLocal;
22529 proto.parseZone = setOffsetToParsedOffset;
22530 proto.hasAlignedHourOffset = hasAlignedHourOffset;
22531 proto.isDST = isDaylightSavingTime;
22532 proto.isLocal = isLocal;
22533 proto.isUtcOffset = isUtcOffset;
22534 proto.isUtc = isUtc;
22535 proto.isUTC = isUtc;
22536 proto.zoneAbbr = getZoneAbbr;
22537 proto.zoneName = getZoneName;
22538 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
22539 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
22540 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
22541 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
22542 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
22543
22544 function createUnix(input) {
22545 return createLocal(input * 1000);
22546 }
22547
22548 function createInZone() {
22549 return createLocal.apply(null, arguments).parseZone();
22550 }
22551
22552 function preParsePostFormat(string) {
22553 return string;
22554 }
22555
22556 var proto$1 = Locale.prototype;
22557 proto$1.calendar = calendar;
22558 proto$1.longDateFormat = longDateFormat;
22559 proto$1.invalidDate = invalidDate;
22560 proto$1.ordinal = ordinal;
22561 proto$1.preparse = preParsePostFormat;
22562 proto$1.postformat = preParsePostFormat;
22563 proto$1.relativeTime = relativeTime;
22564 proto$1.pastFuture = pastFuture;
22565 proto$1.set = set;
22566 proto$1.months = localeMonths;
22567 proto$1.monthsShort = localeMonthsShort;
22568 proto$1.monthsParse = localeMonthsParse;
22569 proto$1.monthsRegex = monthsRegex;
22570 proto$1.monthsShortRegex = monthsShortRegex;
22571 proto$1.week = localeWeek;
22572 proto$1.firstDayOfYear = localeFirstDayOfYear;
22573 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
22574 proto$1.weekdays = localeWeekdays;
22575 proto$1.weekdaysMin = localeWeekdaysMin;
22576 proto$1.weekdaysShort = localeWeekdaysShort;
22577 proto$1.weekdaysParse = localeWeekdaysParse;
22578 proto$1.weekdaysRegex = weekdaysRegex;
22579 proto$1.weekdaysShortRegex = weekdaysShortRegex;
22580 proto$1.weekdaysMinRegex = weekdaysMinRegex;
22581 proto$1.isPM = localeIsPM;
22582 proto$1.meridiem = localeMeridiem;
22583
22584 function get$1(format, index, field, setter) {
22585 var locale = getLocale();
22586 var utc = createUTC().set(setter, index);
22587 return locale[field](utc, format);
22588 }
22589
22590 function listMonthsImpl(format, index, field) {
22591 if (isNumber(format)) {
22592 index = format;
22593 format = undefined;
22594 }
22595
22596 format = format || '';
22597
22598 if (index != null) {
22599 return get$1(format, index, field, 'month');
22600 }
22601
22602 var i;
22603 var out = [];
22604
22605 for (i = 0; i < 12; i++) {
22606 out[i] = get$1(format, i, field, 'month');
22607 }
22608
22609 return out;
22610 } // ()
22611 // (5)
22612 // (fmt, 5)
22613 // (fmt)
22614 // (true)
22615 // (true, 5)
22616 // (true, fmt, 5)
22617 // (true, fmt)
22618
22619
22620 function listWeekdaysImpl(localeSorted, format, index, field) {
22621 if (typeof localeSorted === 'boolean') {
22622 if (isNumber(format)) {
22623 index = format;
22624 format = undefined;
22625 }
22626
22627 format = format || '';
22628 } else {
22629 format = localeSorted;
22630 index = format;
22631 localeSorted = false;
22632
22633 if (isNumber(format)) {
22634 index = format;
22635 format = undefined;
22636 }
22637
22638 format = format || '';
22639 }
22640
22641 var locale = getLocale(),
22642 shift = localeSorted ? locale._week.dow : 0;
22643
22644 if (index != null) {
22645 return get$1(format, (index + shift) % 7, field, 'day');
22646 }
22647
22648 var i;
22649 var out = [];
22650
22651 for (i = 0; i < 7; i++) {
22652 out[i] = get$1(format, (i + shift) % 7, field, 'day');
22653 }
22654
22655 return out;
22656 }
22657
22658 function listMonths(format, index) {
22659 return listMonthsImpl(format, index, 'months');
22660 }
22661
22662 function listMonthsShort(format, index) {
22663 return listMonthsImpl(format, index, 'monthsShort');
22664 }
22665
22666 function listWeekdays(localeSorted, format, index) {
22667 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
22668 }
22669
22670 function listWeekdaysShort(localeSorted, format, index) {
22671 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
22672 }
22673
22674 function listWeekdaysMin(localeSorted, format, index) {
22675 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
22676 }
22677
22678 getSetGlobalLocale('en', {
22679 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
22680 ordinal: function ordinal(number) {
22681 var b = number % 10,
22682 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
22683 return number + output;
22684 }
22685 }); // Side effect imports
22686
22687 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
22688 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
22689 var mathAbs = Math.abs;
22690
22691 function abs() {
22692 var data = this._data;
22693 this._milliseconds = mathAbs(this._milliseconds);
22694 this._days = mathAbs(this._days);
22695 this._months = mathAbs(this._months);
22696 data.milliseconds = mathAbs(data.milliseconds);
22697 data.seconds = mathAbs(data.seconds);
22698 data.minutes = mathAbs(data.minutes);
22699 data.hours = mathAbs(data.hours);
22700 data.months = mathAbs(data.months);
22701 data.years = mathAbs(data.years);
22702 return this;
22703 }
22704
22705 function addSubtract$1(duration, input, value, direction) {
22706 var other = createDuration(input, value);
22707 duration._milliseconds += direction * other._milliseconds;
22708 duration._days += direction * other._days;
22709 duration._months += direction * other._months;
22710 return duration._bubble();
22711 } // supports only 2.0-style add(1, 's') or add(duration)
22712
22713
22714 function add$1(input, value) {
22715 return addSubtract$1(this, input, value, 1);
22716 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
22717
22718
22719 function subtract$1(input, value) {
22720 return addSubtract$1(this, input, value, -1);
22721 }
22722
22723 function absCeil(number) {
22724 if (number < 0) {
22725 return Math.floor(number);
22726 } else {
22727 return Math.ceil(number);
22728 }
22729 }
22730
22731 function bubble() {
22732 var milliseconds = this._milliseconds;
22733 var days = this._days;
22734 var months = this._months;
22735 var data = this._data;
22736 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
22737 // check: https://github.com/moment/moment/issues/2166
22738
22739 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
22740 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
22741 days = 0;
22742 months = 0;
22743 } // The following code bubbles up values, see the tests for
22744 // examples of what that means.
22745
22746
22747 data.milliseconds = milliseconds % 1000;
22748 seconds = absFloor(milliseconds / 1000);
22749 data.seconds = seconds % 60;
22750 minutes = absFloor(seconds / 60);
22751 data.minutes = minutes % 60;
22752 hours = absFloor(minutes / 60);
22753 data.hours = hours % 24;
22754 days += absFloor(hours / 24); // convert days to months
22755
22756 monthsFromDays = absFloor(daysToMonths(days));
22757 months += monthsFromDays;
22758 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
22759
22760 years = absFloor(months / 12);
22761 months %= 12;
22762 data.days = days;
22763 data.months = months;
22764 data.years = years;
22765 return this;
22766 }
22767
22768 function daysToMonths(days) {
22769 // 400 years have 146097 days (taking into account leap year rules)
22770 // 400 years have 12 months === 4800
22771 return days * 4800 / 146097;
22772 }
22773
22774 function monthsToDays(months) {
22775 // the reverse of daysToMonths
22776 return months * 146097 / 4800;
22777 }
22778
22779 function as(units) {
22780 if (!this.isValid()) {
22781 return NaN;
22782 }
22783
22784 var days;
22785 var months;
22786 var milliseconds = this._milliseconds;
22787 units = normalizeUnits(units);
22788
22789 if (units === 'month' || units === 'quarter' || units === 'year') {
22790 days = this._days + milliseconds / 864e5;
22791 months = this._months + daysToMonths(days);
22792
22793 switch (units) {
22794 case 'month':
22795 return months;
22796
22797 case 'quarter':
22798 return months / 3;
22799
22800 case 'year':
22801 return months / 12;
22802 }
22803 } else {
22804 // handle milliseconds separately because of floating point math errors (issue #1867)
22805 days = this._days + Math.round(monthsToDays(this._months));
22806
22807 switch (units) {
22808 case 'week':
22809 return days / 7 + milliseconds / 6048e5;
22810
22811 case 'day':
22812 return days + milliseconds / 864e5;
22813
22814 case 'hour':
22815 return days * 24 + milliseconds / 36e5;
22816
22817 case 'minute':
22818 return days * 1440 + milliseconds / 6e4;
22819
22820 case 'second':
22821 return days * 86400 + milliseconds / 1000;
22822 // Math.floor prevents floating point math errors here
22823
22824 case 'millisecond':
22825 return Math.floor(days * 864e5) + milliseconds;
22826
22827 default:
22828 throw new Error('Unknown unit ' + units);
22829 }
22830 }
22831 } // TODO: Use this.as('ms')?
22832
22833
22834 function valueOf$1() {
22835 if (!this.isValid()) {
22836 return NaN;
22837 }
22838
22839 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
22840 }
22841
22842 function makeAs(alias) {
22843 return function () {
22844 return this.as(alias);
22845 };
22846 }
22847
22848 var asMilliseconds = makeAs('ms');
22849 var asSeconds = makeAs('s');
22850 var asMinutes = makeAs('m');
22851 var asHours = makeAs('h');
22852 var asDays = makeAs('d');
22853 var asWeeks = makeAs('w');
22854 var asMonths = makeAs('M');
22855 var asQuarters = makeAs('Q');
22856 var asYears = makeAs('y');
22857
22858 function clone$1() {
22859 return createDuration(this);
22860 }
22861
22862 function get$2(units) {
22863 units = normalizeUnits(units);
22864 return this.isValid() ? this[units + 's']() : NaN;
22865 }
22866
22867 function makeGetter(name) {
22868 return function () {
22869 return this.isValid() ? this._data[name] : NaN;
22870 };
22871 }
22872
22873 var milliseconds = makeGetter('milliseconds');
22874 var seconds = makeGetter('seconds');
22875 var minutes = makeGetter('minutes');
22876 var hours = makeGetter('hours');
22877 var days = makeGetter('days');
22878 var months = makeGetter('months');
22879 var years = makeGetter('years');
22880
22881 function weeks() {
22882 return absFloor(this.days() / 7);
22883 }
22884
22885 var round = Math.round;
22886 var thresholds = {
22887 ss: 44,
22888 // a few seconds to seconds
22889 s: 45,
22890 // seconds to minute
22891 m: 45,
22892 // minutes to hour
22893 h: 22,
22894 // hours to day
22895 d: 26,
22896 // days to month
22897 M: 11 // months to year
22898
22899 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
22900
22901 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
22902 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
22903 }
22904
22905 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
22906 var duration = createDuration(posNegDuration).abs();
22907 var seconds = round(duration.as('s'));
22908 var minutes = round(duration.as('m'));
22909 var hours = round(duration.as('h'));
22910 var days = round(duration.as('d'));
22911 var months = round(duration.as('M'));
22912 var years = round(duration.as('y'));
22913 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];
22914 a[2] = withoutSuffix;
22915 a[3] = +posNegDuration > 0;
22916 a[4] = locale;
22917 return substituteTimeAgo.apply(null, a);
22918 } // This function allows you to set the rounding function for relative time strings
22919
22920
22921 function getSetRelativeTimeRounding(roundingFunction) {
22922 if (roundingFunction === undefined) {
22923 return round;
22924 }
22925
22926 if (typeof roundingFunction === 'function') {
22927 round = roundingFunction;
22928 return true;
22929 }
22930
22931 return false;
22932 } // This function allows you to set a threshold for relative time strings
22933
22934
22935 function getSetRelativeTimeThreshold(threshold, limit) {
22936 if (thresholds[threshold] === undefined) {
22937 return false;
22938 }
22939
22940 if (limit === undefined) {
22941 return thresholds[threshold];
22942 }
22943
22944 thresholds[threshold] = limit;
22945
22946 if (threshold === 's') {
22947 thresholds.ss = limit - 1;
22948 }
22949
22950 return true;
22951 }
22952
22953 function humanize(withSuffix) {
22954 if (!this.isValid()) {
22955 return this.localeData().invalidDate();
22956 }
22957
22958 var locale = this.localeData();
22959 var output = relativeTime$1(this, !withSuffix, locale);
22960
22961 if (withSuffix) {
22962 output = locale.pastFuture(+this, output);
22963 }
22964
22965 return locale.postformat(output);
22966 }
22967
22968 var abs$1 = Math.abs;
22969
22970 function sign(x) {
22971 return (x > 0) - (x < 0) || +x;
22972 }
22973
22974 function toISOString$1() {
22975 // for ISO strings we do not use the normal bubbling rules:
22976 // * milliseconds bubble up until they become hours
22977 // * days do not bubble at all
22978 // * months bubble up until they become years
22979 // This is because there is no context-free conversion between hours and days
22980 // (think of clock changes)
22981 // and also not between days and months (28-31 days per month)
22982 if (!this.isValid()) {
22983 return this.localeData().invalidDate();
22984 }
22985
22986 var seconds = abs$1(this._milliseconds) / 1000;
22987 var days = abs$1(this._days);
22988 var months = abs$1(this._months);
22989 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
22990
22991 minutes = absFloor(seconds / 60);
22992 hours = absFloor(minutes / 60);
22993 seconds %= 60;
22994 minutes %= 60; // 12 months -> 1 year
22995
22996 years = absFloor(months / 12);
22997 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
22998
22999 var Y = years;
23000 var M = months;
23001 var D = days;
23002 var h = hours;
23003 var m = minutes;
23004 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
23005 var total = this.asSeconds();
23006
23007 if (!total) {
23008 // this is the same as C#'s (Noda) and python (isodate)...
23009 // but not other JS (goog.date)
23010 return 'P0D';
23011 }
23012
23013 var totalSign = total < 0 ? '-' : '';
23014 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
23015 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
23016 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
23017 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' : '');
23018 }
23019
23020 var proto$2 = Duration.prototype;
23021 proto$2.isValid = isValid$1;
23022 proto$2.abs = abs;
23023 proto$2.add = add$1;
23024 proto$2.subtract = subtract$1;
23025 proto$2.as = as;
23026 proto$2.asMilliseconds = asMilliseconds;
23027 proto$2.asSeconds = asSeconds;
23028 proto$2.asMinutes = asMinutes;
23029 proto$2.asHours = asHours;
23030 proto$2.asDays = asDays;
23031 proto$2.asWeeks = asWeeks;
23032 proto$2.asMonths = asMonths;
23033 proto$2.asQuarters = asQuarters;
23034 proto$2.asYears = asYears;
23035 proto$2.valueOf = valueOf$1;
23036 proto$2._bubble = bubble;
23037 proto$2.clone = clone$1;
23038 proto$2.get = get$2;
23039 proto$2.milliseconds = milliseconds;
23040 proto$2.seconds = seconds;
23041 proto$2.minutes = minutes;
23042 proto$2.hours = hours;
23043 proto$2.days = days;
23044 proto$2.weeks = weeks;
23045 proto$2.months = months;
23046 proto$2.years = years;
23047 proto$2.humanize = humanize;
23048 proto$2.toISOString = toISOString$1;
23049 proto$2.toString = toISOString$1;
23050 proto$2.toJSON = toISOString$1;
23051 proto$2.locale = locale;
23052 proto$2.localeData = localeData;
23053 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
23054 proto$2.lang = lang; // Side effect imports
23055 // FORMATTING
23056
23057 addFormatToken('X', 0, 0, 'unix');
23058 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
23059
23060 addRegexToken('x', matchSigned);
23061 addRegexToken('X', matchTimestamp);
23062 addParseToken('X', function (input, array, config) {
23063 config._d = new Date(parseFloat(input, 10) * 1000);
23064 });
23065 addParseToken('x', function (input, array, config) {
23066 config._d = new Date(toInt(input));
23067 }); // Side effect imports
23068
23069 hooks.version = '2.24.0';
23070 setHookCallback(createLocal);
23071 hooks.fn = proto;
23072 hooks.min = min;
23073 hooks.max = max;
23074 hooks.now = now;
23075 hooks.utc = createUTC;
23076 hooks.unix = createUnix;
23077 hooks.months = listMonths;
23078 hooks.isDate = isDate;
23079 hooks.locale = getSetGlobalLocale;
23080 hooks.invalid = createInvalid;
23081 hooks.duration = createDuration;
23082 hooks.isMoment = isMoment;
23083 hooks.weekdays = listWeekdays;
23084 hooks.parseZone = createInZone;
23085 hooks.localeData = getLocale;
23086 hooks.isDuration = isDuration;
23087 hooks.monthsShort = listMonthsShort;
23088 hooks.weekdaysMin = listWeekdaysMin;
23089 hooks.defineLocale = defineLocale;
23090 hooks.updateLocale = updateLocale;
23091 hooks.locales = listLocales;
23092 hooks.weekdaysShort = listWeekdaysShort;
23093 hooks.normalizeUnits = normalizeUnits;
23094 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
23095 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
23096 hooks.calendarFormat = getCalendarFormat;
23097 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
23098
23099 hooks.HTML5_FMT = {
23100 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
23101 // <input type="datetime-local" />
23102 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
23103 // <input type="datetime-local" step="1" />
23104 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
23105 // <input type="datetime-local" step="0.001" />
23106 DATE: 'YYYY-MM-DD',
23107 // <input type="date" />
23108 TIME: 'HH:mm',
23109 // <input type="time" />
23110 TIME_SECONDS: 'HH:mm:ss',
23111 // <input type="time" step="1" />
23112 TIME_MS: 'HH:mm:ss.SSS',
23113 // <input type="time" step="0.001" />
23114 WEEK: 'GGGG-[W]WW',
23115 // <input type="week" />
23116 MONTH: 'YYYY-MM' // <input type="month" />
23117
23118 };
23119 return hooks;
23120 });
23121});
23122
23123// use this instance. Else, load via commonjs.
23124
23125var moment$3 = typeof window !== 'undefined' && window['moment'] || moment$2;
23126
23127/** Prototype for visual components */
23128
23129var Component =
23130/*#__PURE__*/
23131function () {
23132 /**
23133 * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} [body]
23134 * @param {Object} [options]
23135 */
23136 function Component(body, options) {
23137 _classCallCheck(this, Component);
23138
23139 // eslint-disable-line no-unused-vars
23140 this.options = null;
23141 this.props = null;
23142 }
23143 /**
23144 * Set options for the component. The new options will be merged into the
23145 * current options.
23146 * @param {Object} options
23147 */
23148
23149
23150 _createClass(Component, [{
23151 key: "setOptions",
23152 value: function setOptions(options) {
23153 if (options) {
23154 util.extend(this.options, options);
23155 }
23156 }
23157 /**
23158 * Repaint the component
23159 * @return {boolean} Returns true if the component is resized
23160 */
23161
23162 }, {
23163 key: "redraw",
23164 value: function redraw() {
23165 // should be implemented by the component
23166 return false;
23167 }
23168 /**
23169 * Destroy the component. Cleanup DOM and event listeners
23170 */
23171
23172 }, {
23173 key: "destroy",
23174 value: function destroy() {} // should be implemented by the component
23175
23176 /**
23177 * Test whether the component is resized since the last time _isResized() was
23178 * called.
23179 * @return {Boolean} Returns true if the component is resized
23180 * @protected
23181 */
23182
23183 }, {
23184 key: "_isResized",
23185 value: function _isResized() {
23186 var resized = this.props._previousWidth !== this.props.width || this.props._previousHeight !== this.props.height;
23187 this.props._previousWidth = this.props.width;
23188 this.props._previousHeight = this.props.height;
23189 return resized;
23190 }
23191 }]);
23192
23193 return Component;
23194}();
23195
23196// `String.prototype.repeat` method
23197// https://tc39.github.io/ecma262/#sec-string.prototype.repeat
23198_export({ target: 'String', proto: true }, {
23199 repeat: stringRepeat
23200});
23201
23202/**
23203 * used in Core to convert the options into a volatile variable
23204 *
23205 * @param {function} moment
23206 * @param {Object} body
23207 * @param {Array | Object} hiddenDates
23208 * @returns {number}
23209 */
23210function convertHiddenOptions(moment, body, hiddenDates) {
23211 if (hiddenDates && !Array.isArray(hiddenDates)) {
23212 return convertHiddenOptions(moment, body, [hiddenDates]);
23213 }
23214
23215 body.hiddenDates = [];
23216
23217 if (hiddenDates) {
23218 if (Array.isArray(hiddenDates) == true) {
23219 for (var i = 0; i < hiddenDates.length; i++) {
23220 if (hiddenDates[i].repeat === undefined) {
23221 var dateItem = {};
23222 dateItem.start = moment(hiddenDates[i].start).toDate().valueOf();
23223 dateItem.end = moment(hiddenDates[i].end).toDate().valueOf();
23224 body.hiddenDates.push(dateItem);
23225 }
23226 }
23227
23228 body.hiddenDates.sort(function (a, b) {
23229 return a.start - b.start;
23230 }); // sort by start time
23231 }
23232 }
23233}
23234/**
23235 * create new entrees for the repeating hidden dates
23236 *
23237 * @param {function} moment
23238 * @param {Object} body
23239 * @param {Array | Object} hiddenDates
23240 * @returns {null}
23241 */
23242
23243function updateHiddenDates(moment, body, hiddenDates) {
23244 if (hiddenDates && !Array.isArray(hiddenDates)) {
23245 return updateHiddenDates(moment, body, [hiddenDates]);
23246 }
23247
23248 if (hiddenDates && body.domProps.centerContainer.width !== undefined) {
23249 convertHiddenOptions(moment, body, hiddenDates);
23250 var start = moment(body.range.start);
23251 var end = moment(body.range.end);
23252 var totalRange = body.range.end - body.range.start;
23253 var pixelTime = totalRange / body.domProps.centerContainer.width;
23254
23255 for (var i = 0; i < hiddenDates.length; i++) {
23256 if (hiddenDates[i].repeat !== undefined) {
23257 var startDate = moment(hiddenDates[i].start);
23258 var endDate = moment(hiddenDates[i].end);
23259
23260 if (startDate._d == "Invalid Date") {
23261 throw new Error("Supplied start date is not valid: ".concat(hiddenDates[i].start));
23262 }
23263
23264 if (endDate._d == "Invalid Date") {
23265 throw new Error("Supplied end date is not valid: ".concat(hiddenDates[i].end));
23266 }
23267
23268 var duration = endDate - startDate;
23269
23270 if (duration >= 4 * pixelTime) {
23271 var offset = 0;
23272 var runUntil = end.clone();
23273
23274 switch (hiddenDates[i].repeat) {
23275 case "daily":
23276 // case of time
23277 if (startDate.day() != endDate.day()) {
23278 offset = 1;
23279 }
23280
23281 startDate.dayOfYear(start.dayOfYear());
23282 startDate.year(start.year());
23283 startDate.subtract(7, 'days');
23284 endDate.dayOfYear(start.dayOfYear());
23285 endDate.year(start.year());
23286 endDate.subtract(7 - offset, 'days');
23287 runUntil.add(1, 'weeks');
23288 break;
23289
23290 case "weekly":
23291 {
23292 var dayOffset = endDate.diff(startDate, 'days');
23293 var day = startDate.day(); // set the start date to the range.start
23294
23295 startDate.date(start.date());
23296 startDate.month(start.month());
23297 startDate.year(start.year());
23298 endDate = startDate.clone(); // force
23299
23300 startDate.day(day);
23301 endDate.day(day);
23302 endDate.add(dayOffset, 'days');
23303 startDate.subtract(1, 'weeks');
23304 endDate.subtract(1, 'weeks');
23305 runUntil.add(1, 'weeks');
23306 break;
23307 }
23308
23309 case "monthly":
23310 if (startDate.month() != endDate.month()) {
23311 offset = 1;
23312 }
23313
23314 startDate.month(start.month());
23315 startDate.year(start.year());
23316 startDate.subtract(1, 'months');
23317 endDate.month(start.month());
23318 endDate.year(start.year());
23319 endDate.subtract(1, 'months');
23320 endDate.add(offset, 'months');
23321 runUntil.add(1, 'months');
23322 break;
23323
23324 case "yearly":
23325 if (startDate.year() != endDate.year()) {
23326 offset = 1;
23327 }
23328
23329 startDate.year(start.year());
23330 startDate.subtract(1, 'years');
23331 endDate.year(start.year());
23332 endDate.subtract(1, 'years');
23333 endDate.add(offset, 'years');
23334 runUntil.add(1, 'years');
23335 break;
23336
23337 default:
23338 console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:", hiddenDates[i].repeat);
23339 return;
23340 }
23341
23342 while (startDate < runUntil) {
23343 body.hiddenDates.push({
23344 start: startDate.valueOf(),
23345 end: endDate.valueOf()
23346 });
23347
23348 switch (hiddenDates[i].repeat) {
23349 case "daily":
23350 startDate.add(1, 'days');
23351 endDate.add(1, 'days');
23352 break;
23353
23354 case "weekly":
23355 startDate.add(1, 'weeks');
23356 endDate.add(1, 'weeks');
23357 break;
23358
23359 case "monthly":
23360 startDate.add(1, 'months');
23361 endDate.add(1, 'months');
23362 break;
23363
23364 case "yearly":
23365 startDate.add(1, 'y');
23366 endDate.add(1, 'y');
23367 break;
23368
23369 default:
23370 console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:", hiddenDates[i].repeat);
23371 return;
23372 }
23373 }
23374
23375 body.hiddenDates.push({
23376 start: startDate.valueOf(),
23377 end: endDate.valueOf()
23378 });
23379 }
23380 }
23381 } // remove duplicates, merge where possible
23382
23383
23384 removeDuplicates(body); // ensure the new positions are not on hidden dates
23385
23386 var startHidden = getIsHidden(body.range.start, body.hiddenDates);
23387 var endHidden = getIsHidden(body.range.end, body.hiddenDates);
23388 var rangeStart = body.range.start;
23389 var rangeEnd = body.range.end;
23390
23391 if (startHidden.hidden == true) {
23392 rangeStart = body.range.startToFront == true ? startHidden.startDate - 1 : startHidden.endDate + 1;
23393 }
23394
23395 if (endHidden.hidden == true) {
23396 rangeEnd = body.range.endToFront == true ? endHidden.startDate - 1 : endHidden.endDate + 1;
23397 }
23398
23399 if (startHidden.hidden == true || endHidden.hidden == true) {
23400 body.range._applyRange(rangeStart, rangeEnd);
23401 }
23402 }
23403}
23404/**
23405 * remove duplicates from the hidden dates list. Duplicates are evil. They mess everything up.
23406 * Scales with N^2
23407 *
23408 * @param {Object} body
23409 */
23410
23411function removeDuplicates(body) {
23412 var hiddenDates = body.hiddenDates;
23413 var safeDates = [];
23414
23415 for (var i = 0; i < hiddenDates.length; i++) {
23416 for (var j = 0; j < hiddenDates.length; j++) {
23417 if (i != j && hiddenDates[j].remove != true && hiddenDates[i].remove != true) {
23418 // j inside i
23419 if (hiddenDates[j].start >= hiddenDates[i].start && hiddenDates[j].end <= hiddenDates[i].end) {
23420 hiddenDates[j].remove = true;
23421 } // j start inside i
23422 else if (hiddenDates[j].start >= hiddenDates[i].start && hiddenDates[j].start <= hiddenDates[i].end) {
23423 hiddenDates[i].end = hiddenDates[j].end;
23424 hiddenDates[j].remove = true;
23425 } // j end inside i
23426 else if (hiddenDates[j].end >= hiddenDates[i].start && hiddenDates[j].end <= hiddenDates[i].end) {
23427 hiddenDates[i].start = hiddenDates[j].start;
23428 hiddenDates[j].remove = true;
23429 }
23430 }
23431 }
23432 }
23433
23434 for (i = 0; i < hiddenDates.length; i++) {
23435 if (hiddenDates[i].remove !== true) {
23436 safeDates.push(hiddenDates[i]);
23437 }
23438 }
23439
23440 body.hiddenDates = safeDates;
23441 body.hiddenDates.sort(function (a, b) {
23442 return a.start - b.start;
23443 }); // sort by start time
23444}
23445/**
23446 * Prints dates to console
23447 * @param {array} dates
23448 */
23449
23450function printDates(dates) {
23451 for (var i = 0; i < dates.length; i++) {
23452 console.log(i, new Date(dates[i].start), new Date(dates[i].end), dates[i].start, dates[i].end, dates[i].remove);
23453 }
23454}
23455/**
23456 * Used in TimeStep to avoid the hidden times.
23457 * @param {function} moment
23458 * @param {TimeStep} timeStep
23459 * @param {Date} previousTime
23460 */
23461
23462function stepOverHiddenDates(moment, timeStep, previousTime) {
23463 var stepInHidden = false;
23464 var currentValue = timeStep.current.valueOf();
23465
23466 for (var i = 0; i < timeStep.hiddenDates.length; i++) {
23467 var startDate = timeStep.hiddenDates[i].start;
23468 var endDate = timeStep.hiddenDates[i].end;
23469
23470 if (currentValue >= startDate && currentValue < endDate) {
23471 stepInHidden = true;
23472 break;
23473 }
23474 }
23475
23476 if (stepInHidden == true && currentValue < timeStep._end.valueOf() && currentValue != previousTime) {
23477 var prevValue = moment(previousTime);
23478 var newValue = moment(endDate); //check if the next step should be major
23479
23480 if (prevValue.year() != newValue.year()) {
23481 timeStep.switchedYear = true;
23482 } else if (prevValue.month() != newValue.month()) {
23483 timeStep.switchedMonth = true;
23484 } else if (prevValue.dayOfYear() != newValue.dayOfYear()) {
23485 timeStep.switchedDay = true;
23486 }
23487
23488 timeStep.current = newValue;
23489 }
23490} ///**
23491// * Used in TimeStep to avoid the hidden times.
23492// * @param timeStep
23493// * @param previousTime
23494// */
23495//checkFirstStep = function(timeStep) {
23496// var stepInHidden = false;
23497// var currentValue = timeStep.current.valueOf();
23498// for (var i = 0; i < timeStep.hiddenDates.length; i++) {
23499// var startDate = timeStep.hiddenDates[i].start;
23500// var endDate = timeStep.hiddenDates[i].end;
23501// if (currentValue >= startDate && currentValue < endDate) {
23502// stepInHidden = true;
23503// break;
23504// }
23505// }
23506//
23507// if (stepInHidden == true && currentValue <= timeStep._end.valueOf()) {
23508// var newValue = moment(endDate);
23509// timeStep.current = newValue.toDate();
23510// }
23511//};
23512
23513/**
23514 * replaces the Core toScreen methods
23515 *
23516 * @param {timeline.Core} Core
23517 * @param {Date} time
23518 * @param {number} width
23519 * @returns {number}
23520 */
23521
23522function toScreen(Core, time, width) {
23523 var conversion;
23524
23525 if (Core.body.hiddenDates.length == 0) {
23526 conversion = Core.range.conversion(width);
23527 return (time.valueOf() - conversion.offset) * conversion.scale;
23528 } else {
23529 var hidden = getIsHidden(time, Core.body.hiddenDates);
23530
23531 if (hidden.hidden == true) {
23532 time = hidden.startDate;
23533 }
23534
23535 var duration = getHiddenDurationBetween(Core.body.hiddenDates, Core.range.start, Core.range.end);
23536
23537 if (time < Core.range.start) {
23538 conversion = Core.range.conversion(width, duration);
23539 var hiddenBeforeStart = getHiddenDurationBeforeStart(Core.body.hiddenDates, time, conversion.offset);
23540 time = Core.options.moment(time).toDate().valueOf();
23541 time = time + hiddenBeforeStart;
23542 return -(conversion.offset - time.valueOf()) * conversion.scale;
23543 } else if (time > Core.range.end) {
23544 var rangeAfterEnd = {
23545 start: Core.range.start,
23546 end: time
23547 };
23548 time = correctTimeForHidden(Core.options.moment, Core.body.hiddenDates, rangeAfterEnd, time);
23549 conversion = Core.range.conversion(width, duration);
23550 return (time.valueOf() - conversion.offset) * conversion.scale;
23551 } else {
23552 time = correctTimeForHidden(Core.options.moment, Core.body.hiddenDates, Core.range, time);
23553 conversion = Core.range.conversion(width, duration);
23554 return (time.valueOf() - conversion.offset) * conversion.scale;
23555 }
23556 }
23557}
23558/**
23559 * Replaces the core toTime methods
23560 *
23561 * @param {timeline.Core} Core
23562 * @param {number} x
23563 * @param {number} width
23564 * @returns {Date}
23565 */
23566
23567function toTime(Core, x, width) {
23568 if (Core.body.hiddenDates.length == 0) {
23569 var conversion = Core.range.conversion(width);
23570 return new Date(x / conversion.scale + conversion.offset);
23571 } else {
23572 var hiddenDuration = getHiddenDurationBetween(Core.body.hiddenDates, Core.range.start, Core.range.end);
23573 var totalDuration = Core.range.end - Core.range.start - hiddenDuration;
23574 var partialDuration = totalDuration * x / width;
23575 var accumulatedHiddenDuration = getAccumulatedHiddenDuration(Core.body.hiddenDates, Core.range, partialDuration);
23576 return new Date(accumulatedHiddenDuration + partialDuration + Core.range.start);
23577 }
23578}
23579/**
23580 * Support function
23581 *
23582 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23583 * @param {number} start
23584 * @param {number} end
23585 * @returns {number}
23586 */
23587
23588function getHiddenDurationBetween(hiddenDates, start, end) {
23589 var duration = 0;
23590
23591 for (var i = 0; i < hiddenDates.length; i++) {
23592 var startDate = hiddenDates[i].start;
23593 var endDate = hiddenDates[i].end; // if time after the cutout, and the
23594
23595 if (startDate >= start && endDate < end) {
23596 duration += endDate - startDate;
23597 }
23598 }
23599
23600 return duration;
23601}
23602/**
23603 * Support function
23604 *
23605 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23606 * @param {number} start
23607 * @param {number} end
23608 * @returns {number}
23609 */
23610
23611function getHiddenDurationBeforeStart(hiddenDates, start, end) {
23612 var duration = 0;
23613
23614 for (var i = 0; i < hiddenDates.length; i++) {
23615 var startDate = hiddenDates[i].start;
23616 var endDate = hiddenDates[i].end;
23617
23618 if (startDate >= start && endDate <= end) {
23619 duration += endDate - startDate;
23620 }
23621 }
23622
23623 return duration;
23624}
23625/**
23626 * Support function
23627 * @param {function} moment
23628 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23629 * @param {{start: number, end: number}} range
23630 * @param {Date} time
23631 * @returns {number}
23632 */
23633
23634function correctTimeForHidden(moment, hiddenDates, range, time) {
23635 time = moment(time).toDate().valueOf();
23636 time -= getHiddenDurationBefore(moment, hiddenDates, range, time);
23637 return time;
23638}
23639/**
23640 * Support function
23641 * @param {function} moment
23642 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23643 * @param {{start: number, end: number}} range
23644 * @param {Date} time
23645 * @returns {number}
23646 */
23647
23648function getHiddenDurationBefore(moment, hiddenDates, range, time) {
23649 var timeOffset = 0;
23650 time = moment(time).toDate().valueOf();
23651
23652 for (var i = 0; i < hiddenDates.length; i++) {
23653 var startDate = hiddenDates[i].start;
23654 var endDate = hiddenDates[i].end; // if time after the cutout, and the
23655
23656 if (startDate >= range.start && endDate < range.end) {
23657 if (time >= endDate) {
23658 timeOffset += endDate - startDate;
23659 }
23660 }
23661 }
23662
23663 return timeOffset;
23664}
23665/**
23666 * sum the duration from start to finish, including the hidden duration,
23667 * until the required amount has been reached, return the accumulated hidden duration
23668 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23669 * @param {{start: number, end: number}} range
23670 * @param {number} [requiredDuration=0]
23671 * @returns {number}
23672 */
23673
23674function getAccumulatedHiddenDuration(hiddenDates, range, requiredDuration) {
23675 var hiddenDuration = 0;
23676 var duration = 0;
23677 var previousPoint = range.start; //printDates(hiddenDates)
23678
23679 for (var i = 0; i < hiddenDates.length; i++) {
23680 var startDate = hiddenDates[i].start;
23681 var endDate = hiddenDates[i].end; // if time after the cutout, and the
23682
23683 if (startDate >= range.start && endDate < range.end) {
23684 duration += startDate - previousPoint;
23685 previousPoint = endDate;
23686
23687 if (duration >= requiredDuration) {
23688 break;
23689 } else {
23690 hiddenDuration += endDate - startDate;
23691 }
23692 }
23693 }
23694
23695 return hiddenDuration;
23696}
23697/**
23698 * used to step over to either side of a hidden block. Correction is disabled on tablets, might be set to true
23699 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23700 * @param {Date} time
23701 * @param {number} direction
23702 * @param {boolean} correctionEnabled
23703 * @returns {Date|number}
23704 */
23705
23706function snapAwayFromHidden(hiddenDates, time, direction, correctionEnabled) {
23707 var isHidden = getIsHidden(time, hiddenDates);
23708
23709 if (isHidden.hidden == true) {
23710 if (direction < 0) {
23711 if (correctionEnabled == true) {
23712 return isHidden.startDate - (isHidden.endDate - time) - 1;
23713 } else {
23714 return isHidden.startDate - 1;
23715 }
23716 } else {
23717 if (correctionEnabled == true) {
23718 return isHidden.endDate + (time - isHidden.startDate) + 1;
23719 } else {
23720 return isHidden.endDate + 1;
23721 }
23722 }
23723 } else {
23724 return time;
23725 }
23726}
23727/**
23728 * Check if a time is hidden
23729 *
23730 * @param {Date} time
23731 * @param {Array.<{start: Window.start, end: *}>} hiddenDates
23732 * @returns {{hidden: boolean, startDate: Window.start, endDate: *}}
23733 */
23734
23735function getIsHidden(time, hiddenDates) {
23736 for (var i = 0; i < hiddenDates.length; i++) {
23737 var startDate = hiddenDates[i].start;
23738 var endDate = hiddenDates[i].end;
23739
23740 if (time >= startDate && time < endDate) {
23741 // if the start is entering a hidden zone
23742 return {
23743 hidden: true,
23744 startDate: startDate,
23745 endDate: endDate
23746 };
23747 }
23748 }
23749
23750 return {
23751 hidden: false,
23752 startDate: startDate,
23753 endDate: endDate
23754 };
23755}
23756
23757var DateUtil = /*#__PURE__*/Object.freeze({
23758 convertHiddenOptions: convertHiddenOptions,
23759 updateHiddenDates: updateHiddenDates,
23760 removeDuplicates: removeDuplicates,
23761 printDates: printDates,
23762 stepOverHiddenDates: stepOverHiddenDates,
23763 toScreen: toScreen,
23764 toTime: toTime,
23765 getHiddenDurationBetween: getHiddenDurationBetween,
23766 getHiddenDurationBeforeStart: getHiddenDurationBeforeStart,
23767 correctTimeForHidden: correctTimeForHidden,
23768 getHiddenDurationBefore: getHiddenDurationBefore,
23769 getAccumulatedHiddenDuration: getAccumulatedHiddenDuration,
23770 snapAwayFromHidden: snapAwayFromHidden,
23771 getIsHidden: getIsHidden
23772});
23773
23774/**
23775 * A Range controls a numeric range with a start and end value.
23776 * The Range adjusts the range based on mouse events or programmatic changes,
23777 * and triggers events when the range is changing or has been changed.
23778 */
23779
23780var Range =
23781/*#__PURE__*/
23782function (_Component) {
23783 _inherits(Range, _Component);
23784
23785 /**
23786 * @param {{dom: Object, domProps: Object, emitter: Emitter}} body
23787 * @param {Object} [options] See description at Range.setOptions
23788 * @constructor Range
23789 * @extends Component
23790 */
23791 function Range(body, options) {
23792 var _this;
23793
23794 _classCallCheck(this, Range);
23795
23796 _this = _possibleConstructorReturn(this, _getPrototypeOf(Range).call(this));
23797 var now = moment$3().hours(0).minutes(0).seconds(0).milliseconds(0);
23798 var start = now.clone().add(-3, 'days').valueOf();
23799 var end = now.clone().add(3, 'days').valueOf();
23800 _this.millisecondsPerPixelCache = undefined;
23801
23802 if (options === undefined) {
23803 _this.start = start;
23804 _this.end = end;
23805 } else {
23806 _this.start = options.start || start;
23807 _this.end = options.end || end;
23808 }
23809
23810 _this.rolling = false;
23811 _this.body = body;
23812 _this.deltaDifference = 0;
23813 _this.scaleOffset = 0;
23814 _this.startToFront = false;
23815 _this.endToFront = true; // default options
23816
23817 _this.defaultOptions = {
23818 rtl: false,
23819 start: null,
23820 end: null,
23821 moment: moment$3,
23822 direction: 'horizontal',
23823 // 'horizontal' or 'vertical'
23824 moveable: true,
23825 zoomable: true,
23826 min: null,
23827 max: null,
23828 zoomMin: 10,
23829 // milliseconds
23830 zoomMax: 1000 * 60 * 60 * 24 * 365 * 10000,
23831 // milliseconds
23832 rollingMode: {
23833 follow: false,
23834 offset: 0.5
23835 }
23836 };
23837 _this.options = util.extend({}, _this.defaultOptions);
23838 _this.props = {
23839 touch: {}
23840 };
23841 _this.animationTimer = null; // drag listeners for dragging
23842
23843 _this.body.emitter.on('panstart', _this._onDragStart.bind(_assertThisInitialized(_this)));
23844
23845 _this.body.emitter.on('panmove', _this._onDrag.bind(_assertThisInitialized(_this)));
23846
23847 _this.body.emitter.on('panend', _this._onDragEnd.bind(_assertThisInitialized(_this))); // mouse wheel for zooming
23848
23849
23850 _this.body.emitter.on('mousewheel', _this._onMouseWheel.bind(_assertThisInitialized(_this))); // pinch to zoom
23851
23852
23853 _this.body.emitter.on('touch', _this._onTouch.bind(_assertThisInitialized(_this)));
23854
23855 _this.body.emitter.on('pinch', _this._onPinch.bind(_assertThisInitialized(_this))); // on click of rolling mode button
23856
23857
23858 _this.body.dom.rollingModeBtn.addEventListener('click', _this.startRolling.bind(_assertThisInitialized(_this)));
23859
23860 _this.setOptions(options);
23861
23862 return _this;
23863 }
23864 /**
23865 * Set options for the range controller
23866 * @param {Object} options Available options:
23867 * {number | Date | String} start Start date for the range
23868 * {number | Date | String} end End date for the range
23869 * {number} min Minimum value for start
23870 * {number} max Maximum value for end
23871 * {number} zoomMin Set a minimum value for
23872 * (end - start).
23873 * {number} zoomMax Set a maximum value for
23874 * (end - start).
23875 * {boolean} moveable Enable moving of the range
23876 * by dragging. True by default
23877 * {boolean} zoomable Enable zooming of the range
23878 * by pinching/scrolling. True by default
23879 */
23880
23881
23882 _createClass(Range, [{
23883 key: "setOptions",
23884 value: function setOptions(options) {
23885 if (options) {
23886 // copy the options that we know
23887 var fields = ['animation', 'direction', 'min', 'max', 'zoomMin', 'zoomMax', 'moveable', 'zoomable', 'moment', 'activate', 'hiddenDates', 'zoomKey', 'zoomFriction', 'rtl', 'showCurrentTime', 'rollingMode', 'horizontalScroll'];
23888 util.selectiveExtend(fields, this.options, options);
23889
23890 if (options.rollingMode && options.rollingMode.follow) {
23891 this.startRolling();
23892 }
23893
23894 if ('start' in options || 'end' in options) {
23895 // apply a new range. both start and end are optional
23896 this.setRange(options.start, options.end);
23897 }
23898 }
23899 }
23900 /**
23901 * Start auto refreshing the current time bar
23902 */
23903
23904 }, {
23905 key: "startRolling",
23906 value: function startRolling() {
23907 var me = this;
23908 /**
23909 * Updates the current time.
23910 */
23911
23912 function update() {
23913 me.stopRolling();
23914 me.rolling = true;
23915 var interval = me.end - me.start;
23916 var t = util.convert(new Date(), 'Date').valueOf();
23917 var rollingModeOffset = me.options.rollingMode && me.options.rollingMode.offset || 0.5;
23918 var start = t - interval * rollingModeOffset;
23919 var end = t + interval * (1 - rollingModeOffset);
23920 var options = {
23921 animation: false
23922 };
23923 me.setRange(start, end, options); // determine interval to refresh
23924
23925 var scale = me.conversion(me.body.domProps.center.width).scale;
23926 interval = 1 / scale / 10;
23927 if (interval < 30) interval = 30;
23928 if (interval > 1000) interval = 1000;
23929 me.body.dom.rollingModeBtn.style.visibility = "hidden"; // start a renderTimer to adjust for the new time
23930
23931 me.currentTimeTimer = setTimeout(update, interval);
23932 }
23933
23934 update();
23935 }
23936 /**
23937 * Stop auto refreshing the current time bar
23938 */
23939
23940 }, {
23941 key: "stopRolling",
23942 value: function stopRolling() {
23943 if (this.currentTimeTimer !== undefined) {
23944 clearTimeout(this.currentTimeTimer);
23945 this.rolling = false;
23946 this.body.dom.rollingModeBtn.style.visibility = "visible";
23947 }
23948 }
23949 /**
23950 * Set a new start and end range
23951 * @param {Date | number | string} start
23952 * @param {Date | number | string} end
23953 * @param {Object} options Available options:
23954 * {boolean | {duration: number, easingFunction: string}} [animation=false]
23955 * If true, the range is animated
23956 * smoothly to the new window. An object can be
23957 * provided to specify duration and easing function.
23958 * Default duration is 500 ms, and default easing
23959 * function is 'easeInOutQuad'.
23960 * {boolean} [byUser=false]
23961 * {Event} event Mouse event
23962 * @param {Function} callback a callback function to be executed at the end of this function
23963 * @param {Function} frameCallback a callback function executed each frame of the range animation.
23964 * The callback will be passed three parameters:
23965 * {number} easeCoefficient an easing coefficent
23966 * {boolean} willDraw If true the caller will redraw after the callback completes
23967 * {boolean} done If true then animation is ending after the current frame
23968 * @return {void}
23969 */
23970
23971 }, {
23972 key: "setRange",
23973 value: function setRange(start, end, options, callback, frameCallback) {
23974 if (!options) {
23975 options = {};
23976 }
23977
23978 if (options.byUser !== true) {
23979 options.byUser = false;
23980 }
23981
23982 var me = this;
23983 var finalStart = start != undefined ? util.convert(start, 'Date').valueOf() : null;
23984 var finalEnd = end != undefined ? util.convert(end, 'Date').valueOf() : null;
23985
23986 this._cancelAnimation();
23987
23988 this.millisecondsPerPixelCache = undefined;
23989
23990 if (options.animation) {
23991 // true or an Object
23992 var initStart = this.start;
23993 var initEnd = this.end;
23994 var duration = _typeof(options.animation) === 'object' && 'duration' in options.animation ? options.animation.duration : 500;
23995 var easingName = _typeof(options.animation) === 'object' && 'easingFunction' in options.animation ? options.animation.easingFunction : 'easeInOutQuad';
23996 var easingFunction = util.easingFunctions[easingName];
23997
23998 if (!easingFunction) {
23999 throw new Error("Unknown easing function ".concat(JSON.stringify(easingName), ". Choose from: ").concat(Object.keys(util.easingFunctions).join(', ')));
24000 }
24001
24002 var initTime = Date.now();
24003 var anyChanged = false;
24004
24005 var next = function next() {
24006 if (!me.props.touch.dragging) {
24007 var now = Date.now();
24008 var time = now - initTime;
24009 var ease = easingFunction(time / duration);
24010 var done = time > duration;
24011 var s = done || finalStart === null ? finalStart : initStart + (finalStart - initStart) * ease;
24012 var e = done || finalEnd === null ? finalEnd : initEnd + (finalEnd - initEnd) * ease;
24013 changed = me._applyRange(s, e);
24014 updateHiddenDates(me.options.moment, me.body, me.options.hiddenDates);
24015 anyChanged = anyChanged || changed;
24016 var params = {
24017 start: new Date(me.start),
24018 end: new Date(me.end),
24019 byUser: options.byUser,
24020 event: options.event
24021 };
24022
24023 if (frameCallback) {
24024 frameCallback(ease, changed, done);
24025 }
24026
24027 if (changed) {
24028 me.body.emitter.emit('rangechange', params);
24029 }
24030
24031 if (done) {
24032 if (anyChanged) {
24033 me.body.emitter.emit('rangechanged', params);
24034
24035 if (callback) {
24036 return callback();
24037 }
24038 }
24039 } else {
24040 // animate with as high as possible frame rate, leave 20 ms in between
24041 // each to prevent the browser from blocking
24042 me.animationTimer = setTimeout(next, 20);
24043 }
24044 }
24045 };
24046
24047 return next();
24048 } else {
24049 var changed = this._applyRange(finalStart, finalEnd);
24050
24051 updateHiddenDates(this.options.moment, this.body, this.options.hiddenDates);
24052
24053 if (changed) {
24054 var params = {
24055 start: new Date(this.start),
24056 end: new Date(this.end),
24057 byUser: options.byUser,
24058 event: options.event
24059 };
24060 this.body.emitter.emit('rangechange', params);
24061 clearTimeout(me.timeoutID);
24062 me.timeoutID = setTimeout(function () {
24063 me.body.emitter.emit('rangechanged', params);
24064 }, 200);
24065
24066 if (callback) {
24067 return callback();
24068 }
24069 }
24070 }
24071 }
24072 /**
24073 * Get the number of milliseconds per pixel.
24074 *
24075 * @returns {undefined|number}
24076 */
24077
24078 }, {
24079 key: "getMillisecondsPerPixel",
24080 value: function getMillisecondsPerPixel() {
24081 if (this.millisecondsPerPixelCache === undefined) {
24082 this.millisecondsPerPixelCache = (this.end - this.start) / this.body.dom.center.clientWidth;
24083 }
24084
24085 return this.millisecondsPerPixelCache;
24086 }
24087 /**
24088 * Stop an animation
24089 * @private
24090 */
24091
24092 }, {
24093 key: "_cancelAnimation",
24094 value: function _cancelAnimation() {
24095 if (this.animationTimer) {
24096 clearTimeout(this.animationTimer);
24097 this.animationTimer = null;
24098 }
24099 }
24100 /**
24101 * Set a new start and end range. This method is the same as setRange, but
24102 * does not trigger a range change and range changed event, and it returns
24103 * true when the range is changed
24104 * @param {number} [start]
24105 * @param {number} [end]
24106 * @return {boolean} changed
24107 * @private
24108 */
24109
24110 }, {
24111 key: "_applyRange",
24112 value: function _applyRange(start, end) {
24113 var newStart = start != null ? util.convert(start, 'Date').valueOf() : this.start;
24114 var newEnd = end != null ? util.convert(end, 'Date').valueOf() : this.end;
24115 var max = this.options.max != null ? util.convert(this.options.max, 'Date').valueOf() : null;
24116 var min = this.options.min != null ? util.convert(this.options.min, 'Date').valueOf() : null;
24117 var diff; // check for valid number
24118
24119 if (isNaN(newStart) || newStart === null) {
24120 throw new Error("Invalid start \"".concat(start, "\""));
24121 }
24122
24123 if (isNaN(newEnd) || newEnd === null) {
24124 throw new Error("Invalid end \"".concat(end, "\""));
24125 } // prevent end < start
24126
24127
24128 if (newEnd < newStart) {
24129 newEnd = newStart;
24130 } // prevent start < min
24131
24132
24133 if (min !== null) {
24134 if (newStart < min) {
24135 diff = min - newStart;
24136 newStart += diff;
24137 newEnd += diff; // prevent end > max
24138
24139 if (max != null) {
24140 if (newEnd > max) {
24141 newEnd = max;
24142 }
24143 }
24144 }
24145 } // prevent end > max
24146
24147
24148 if (max !== null) {
24149 if (newEnd > max) {
24150 diff = newEnd - max;
24151 newStart -= diff;
24152 newEnd -= diff; // prevent start < min
24153
24154 if (min != null) {
24155 if (newStart < min) {
24156 newStart = min;
24157 }
24158 }
24159 }
24160 } // prevent (end-start) < zoomMin
24161
24162
24163 if (this.options.zoomMin !== null) {
24164 var zoomMin = parseFloat(this.options.zoomMin);
24165
24166 if (zoomMin < 0) {
24167 zoomMin = 0;
24168 }
24169
24170 if (newEnd - newStart < zoomMin) {
24171 // compensate for a scale of 0.5 ms
24172 var compensation = 0.5;
24173
24174 if (this.end - this.start === zoomMin && newStart >= this.start - compensation && newEnd <= this.end) {
24175 // ignore this action, we are already zoomed to the minimum
24176 newStart = this.start;
24177 newEnd = this.end;
24178 } else {
24179 // zoom to the minimum
24180 diff = zoomMin - (newEnd - newStart);
24181 newStart -= diff / 2;
24182 newEnd += diff / 2;
24183 }
24184 }
24185 } // prevent (end-start) > zoomMax
24186
24187
24188 if (this.options.zoomMax !== null) {
24189 var zoomMax = parseFloat(this.options.zoomMax);
24190
24191 if (zoomMax < 0) {
24192 zoomMax = 0;
24193 }
24194
24195 if (newEnd - newStart > zoomMax) {
24196 if (this.end - this.start === zoomMax && newStart < this.start && newEnd > this.end) {
24197 // ignore this action, we are already zoomed to the maximum
24198 newStart = this.start;
24199 newEnd = this.end;
24200 } else {
24201 // zoom to the maximum
24202 diff = newEnd - newStart - zoomMax;
24203 newStart += diff / 2;
24204 newEnd -= diff / 2;
24205 }
24206 }
24207 }
24208
24209 var changed = this.start != newStart || this.end != newEnd; // if the new range does NOT overlap with the old range, emit checkRangedItems to avoid not showing ranged items (ranged meaning has end time, not necessarily of type Range)
24210
24211 if (!(newStart >= this.start && newStart <= this.end || newEnd >= this.start && newEnd <= this.end) && !(this.start >= newStart && this.start <= newEnd || this.end >= newStart && this.end <= newEnd)) {
24212 this.body.emitter.emit('checkRangedItems');
24213 }
24214
24215 this.start = newStart;
24216 this.end = newEnd;
24217 return changed;
24218 }
24219 /**
24220 * Retrieve the current range.
24221 * @return {Object} An object with start and end properties
24222 */
24223
24224 }, {
24225 key: "getRange",
24226 value: function getRange() {
24227 return {
24228 start: this.start,
24229 end: this.end
24230 };
24231 }
24232 /**
24233 * Calculate the conversion offset and scale for current range, based on
24234 * the provided width
24235 * @param {number} width
24236 * @param {number} [totalHidden=0]
24237 * @returns {{offset: number, scale: number}} conversion
24238 */
24239
24240 }, {
24241 key: "conversion",
24242 value: function conversion(width, totalHidden) {
24243 return Range.conversion(this.start, this.end, width, totalHidden);
24244 }
24245 /**
24246 * Static method to calculate the conversion offset and scale for a range,
24247 * based on the provided start, end, and width
24248 * @param {number} start
24249 * @param {number} end
24250 * @param {number} width
24251 * @param {number} [totalHidden=0]
24252 * @returns {{offset: number, scale: number}} conversion
24253 */
24254
24255 }, {
24256 key: "_onDragStart",
24257
24258 /**
24259 * Start dragging horizontally or vertically
24260 * @param {Event} event
24261 * @private
24262 */
24263 value: function _onDragStart(event) {
24264 this.deltaDifference = 0;
24265 this.previousDelta = 0; // only allow dragging when configured as movable
24266
24267 if (!this.options.moveable) return; // only start dragging when the mouse is inside the current range
24268
24269 if (!this._isInsideRange(event)) return; // refuse to drag when we where pinching to prevent the timeline make a jump
24270 // when releasing the fingers in opposite order from the touch screen
24271
24272 if (!this.props.touch.allowDragging) return;
24273 this.stopRolling();
24274 this.props.touch.start = this.start;
24275 this.props.touch.end = this.end;
24276 this.props.touch.dragging = true;
24277
24278 if (this.body.dom.root) {
24279 this.body.dom.root.style.cursor = 'move';
24280 }
24281 }
24282 /**
24283 * Perform dragging operation
24284 * @param {Event} event
24285 * @private
24286 */
24287
24288 }, {
24289 key: "_onDrag",
24290 value: function _onDrag(event) {
24291 if (!event) return;
24292 if (!this.props.touch.dragging) return; // only allow dragging when configured as movable
24293
24294 if (!this.options.moveable) return; // TODO: this may be redundant in hammerjs2
24295 // refuse to drag when we where pinching to prevent the timeline make a jump
24296 // when releasing the fingers in opposite order from the touch screen
24297
24298 if (!this.props.touch.allowDragging) return;
24299 var direction = this.options.direction;
24300 validateDirection(direction);
24301 var delta = direction == 'horizontal' ? event.deltaX : event.deltaY;
24302 delta -= this.deltaDifference;
24303 var interval = this.props.touch.end - this.props.touch.start; // normalize dragging speed if cutout is in between.
24304
24305 var duration = getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end);
24306 interval -= duration;
24307 var width = direction == 'horizontal' ? this.body.domProps.center.width : this.body.domProps.center.height;
24308 var diffRange;
24309
24310 if (this.options.rtl) {
24311 diffRange = delta / width * interval;
24312 } else {
24313 diffRange = -delta / width * interval;
24314 }
24315
24316 var newStart = this.props.touch.start + diffRange;
24317 var newEnd = this.props.touch.end + diffRange; // snapping times away from hidden zones
24318
24319 var safeStart = snapAwayFromHidden(this.body.hiddenDates, newStart, this.previousDelta - delta, true);
24320 var safeEnd = snapAwayFromHidden(this.body.hiddenDates, newEnd, this.previousDelta - delta, true);
24321
24322 if (safeStart != newStart || safeEnd != newEnd) {
24323 this.deltaDifference += delta;
24324 this.props.touch.start = safeStart;
24325 this.props.touch.end = safeEnd;
24326
24327 this._onDrag(event);
24328
24329 return;
24330 }
24331
24332 this.previousDelta = delta;
24333
24334 this._applyRange(newStart, newEnd);
24335
24336 var startDate = new Date(this.start);
24337 var endDate = new Date(this.end); // fire a rangechange event
24338
24339 this.body.emitter.emit('rangechange', {
24340 start: startDate,
24341 end: endDate,
24342 byUser: true,
24343 event: event
24344 }); // fire a panmove event
24345
24346 this.body.emitter.emit('panmove');
24347 }
24348 /**
24349 * Stop dragging operation
24350 * @param {event} event
24351 * @private
24352 */
24353
24354 }, {
24355 key: "_onDragEnd",
24356 value: function _onDragEnd(event) {
24357 if (!this.props.touch.dragging) return; // only allow dragging when configured as movable
24358
24359 if (!this.options.moveable) return; // TODO: this may be redundant in hammerjs2
24360 // refuse to drag when we where pinching to prevent the timeline make a jump
24361 // when releasing the fingers in opposite order from the touch screen
24362
24363 if (!this.props.touch.allowDragging) return;
24364 this.props.touch.dragging = false;
24365
24366 if (this.body.dom.root) {
24367 this.body.dom.root.style.cursor = 'auto';
24368 } // fire a rangechanged event
24369
24370
24371 this.body.emitter.emit('rangechanged', {
24372 start: new Date(this.start),
24373 end: new Date(this.end),
24374 byUser: true,
24375 event: event
24376 });
24377 }
24378 /**
24379 * Event handler for mouse wheel event, used to zoom
24380 * Code from http://adomas.org/javascript-mouse-wheel/
24381 * @param {Event} event
24382 * @private
24383 */
24384
24385 }, {
24386 key: "_onMouseWheel",
24387 value: function _onMouseWheel(event) {
24388 // retrieve delta
24389 var delta = 0;
24390
24391 if (event.wheelDelta) {
24392 /* IE/Opera. */
24393 delta = event.wheelDelta / 120;
24394 } else if (event.detail) {
24395 /* Mozilla case. */
24396 // In Mozilla, sign of delta is different than in IE.
24397 // Also, delta is multiple of 3.
24398 delta = -event.detail / 3;
24399 } else if (event.deltaY) {
24400 delta = -event.deltaY / 3;
24401 } // don't allow zoom when the according key is pressed and the zoomKey option or not zoomable but movable
24402
24403
24404 if (this.options.zoomKey && !event[this.options.zoomKey] && this.options.zoomable || !this.options.zoomable && this.options.moveable) {
24405 return;
24406 } // only allow zooming when configured as zoomable and moveable
24407
24408
24409 if (!(this.options.zoomable && this.options.moveable)) return; // only zoom when the mouse is inside the current range
24410
24411 if (!this._isInsideRange(event)) return; // If delta is nonzero, handle it.
24412 // Basically, delta is now positive if wheel was scrolled up,
24413 // and negative, if wheel was scrolled down.
24414
24415 if (delta) {
24416 // perform the zoom action. Delta is normally 1 or -1
24417 // adjust a negative delta such that zooming in with delta 0.1
24418 // equals zooming out with a delta -0.1
24419 var zoomFriction = this.options.zoomFriction || 5;
24420 var scale;
24421
24422 if (delta < 0) {
24423 scale = 1 - delta / zoomFriction;
24424 } else {
24425 scale = 1 / (1 + delta / zoomFriction);
24426 } // calculate center, the date to zoom around
24427
24428
24429 var pointerDate;
24430
24431 if (this.rolling) {
24432 var rollingModeOffset = this.options.rollingMode && this.options.rollingMode.offset || 0.5;
24433 pointerDate = this.start + (this.end - this.start) * rollingModeOffset;
24434 } else {
24435 var pointer = this.getPointer({
24436 x: event.clientX,
24437 y: event.clientY
24438 }, this.body.dom.center);
24439 pointerDate = this._pointerToDate(pointer);
24440 }
24441
24442 this.zoom(scale, pointerDate, delta, event); // Prevent default actions caused by mouse wheel
24443 // (else the page and timeline both scroll)
24444
24445 event.preventDefault();
24446 }
24447 }
24448 /**
24449 * Start of a touch gesture
24450 * @param {Event} event
24451 * @private
24452 */
24453
24454 }, {
24455 key: "_onTouch",
24456 value: function _onTouch(event) {
24457 // eslint-disable-line no-unused-vars
24458 this.props.touch.start = this.start;
24459 this.props.touch.end = this.end;
24460 this.props.touch.allowDragging = true;
24461 this.props.touch.center = null;
24462 this.scaleOffset = 0;
24463 this.deltaDifference = 0; // Disable the browser default handling of this event.
24464
24465 util.preventDefault(event);
24466 }
24467 /**
24468 * Handle pinch event
24469 * @param {Event} event
24470 * @private
24471 */
24472
24473 }, {
24474 key: "_onPinch",
24475 value: function _onPinch(event) {
24476 // only allow zooming when configured as zoomable and moveable
24477 if (!(this.options.zoomable && this.options.moveable)) return; // Disable the browser default handling of this event.
24478
24479 util.preventDefault(event);
24480 this.props.touch.allowDragging = false;
24481
24482 if (!this.props.touch.center) {
24483 this.props.touch.center = this.getPointer(event.center, this.body.dom.center);
24484 }
24485
24486 this.stopRolling();
24487 var scale = 1 / (event.scale + this.scaleOffset);
24488
24489 var centerDate = this._pointerToDate(this.props.touch.center);
24490
24491 var hiddenDuration = getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end);
24492 var hiddenDurationBefore = getHiddenDurationBefore(this.options.moment, this.body.hiddenDates, this, centerDate);
24493 var hiddenDurationAfter = hiddenDuration - hiddenDurationBefore; // calculate new start and end
24494
24495 var newStart = centerDate - hiddenDurationBefore + (this.props.touch.start - (centerDate - hiddenDurationBefore)) * scale;
24496 var newEnd = centerDate + hiddenDurationAfter + (this.props.touch.end - (centerDate + hiddenDurationAfter)) * scale; // snapping times away from hidden zones
24497
24498 this.startToFront = 1 - scale <= 0; // used to do the right auto correction with periodic hidden times
24499
24500 this.endToFront = scale - 1 <= 0; // used to do the right auto correction with periodic hidden times
24501
24502 var safeStart = snapAwayFromHidden(this.body.hiddenDates, newStart, 1 - scale, true);
24503 var safeEnd = snapAwayFromHidden(this.body.hiddenDates, newEnd, scale - 1, true);
24504
24505 if (safeStart != newStart || safeEnd != newEnd) {
24506 this.props.touch.start = safeStart;
24507 this.props.touch.end = safeEnd;
24508 this.scaleOffset = 1 - event.scale;
24509 newStart = safeStart;
24510 newEnd = safeEnd;
24511 }
24512
24513 var options = {
24514 animation: false,
24515 byUser: true,
24516 event: event
24517 };
24518 this.setRange(newStart, newEnd, options);
24519 this.startToFront = false; // revert to default
24520
24521 this.endToFront = true; // revert to default
24522 }
24523 /**
24524 * Test whether the mouse from a mouse event is inside the visible window,
24525 * between the current start and end date
24526 * @param {Object} event
24527 * @return {boolean} Returns true when inside the visible window
24528 * @private
24529 */
24530
24531 }, {
24532 key: "_isInsideRange",
24533 value: function _isInsideRange(event) {
24534 // calculate the time where the mouse is, check whether inside
24535 // and no scroll action should happen.
24536 var clientX = event.center ? event.center.x : event.clientX;
24537 var centerContainerRect = this.body.dom.centerContainer.getBoundingClientRect();
24538 var x = this.options.rtl ? clientX - centerContainerRect.left : centerContainerRect.right - clientX;
24539 var time = this.body.util.toTime(x);
24540 return time >= this.start && time <= this.end;
24541 }
24542 /**
24543 * Helper function to calculate the center date for zooming
24544 * @param {{x: number, y: number}} pointer
24545 * @return {number} date
24546 * @private
24547 */
24548
24549 }, {
24550 key: "_pointerToDate",
24551 value: function _pointerToDate(pointer) {
24552 var conversion;
24553 var direction = this.options.direction;
24554 validateDirection(direction);
24555
24556 if (direction == 'horizontal') {
24557 return this.body.util.toTime(pointer.x).valueOf();
24558 } else {
24559 var height = this.body.domProps.center.height;
24560 conversion = this.conversion(height);
24561 return pointer.y / conversion.scale + conversion.offset;
24562 }
24563 }
24564 /**
24565 * Get the pointer location relative to the location of the dom element
24566 * @param {{x: number, y: number}} touch
24567 * @param {Element} element HTML DOM element
24568 * @return {{x: number, y: number}} pointer
24569 * @private
24570 */
24571
24572 }, {
24573 key: "getPointer",
24574 value: function getPointer(touch, element) {
24575 var elementRect = element.getBoundingClientRect();
24576
24577 if (this.options.rtl) {
24578 return {
24579 x: elementRect.right - touch.x,
24580 y: touch.y - elementRect.top
24581 };
24582 } else {
24583 return {
24584 x: touch.x - elementRect.left,
24585 y: touch.y - elementRect.top
24586 };
24587 }
24588 }
24589 /**
24590 * Zoom the range the given scale in or out. Start and end date will
24591 * be adjusted, and the timeline will be redrawn. You can optionally give a
24592 * date around which to zoom.
24593 * For example, try scale = 0.9 or 1.1
24594 * @param {number} scale Scaling factor. Values above 1 will zoom out,
24595 * values below 1 will zoom in.
24596 * @param {number} [center] Value representing a date around which will
24597 * be zoomed.
24598 * @param {number} delta
24599 * @param {Event} event
24600 */
24601
24602 }, {
24603 key: "zoom",
24604 value: function zoom(scale, center, delta, event) {
24605 // if centerDate is not provided, take it half between start Date and end Date
24606 if (center == null) {
24607 center = (this.start + this.end) / 2;
24608 }
24609
24610 var hiddenDuration = getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end);
24611 var hiddenDurationBefore = getHiddenDurationBefore(this.options.moment, this.body.hiddenDates, this, center);
24612 var hiddenDurationAfter = hiddenDuration - hiddenDurationBefore; // calculate new start and end
24613
24614 var newStart = center - hiddenDurationBefore + (this.start - (center - hiddenDurationBefore)) * scale;
24615 var newEnd = center + hiddenDurationAfter + (this.end - (center + hiddenDurationAfter)) * scale; // snapping times away from hidden zones
24616
24617 this.startToFront = delta > 0 ? false : true; // used to do the right autocorrection with periodic hidden times
24618
24619 this.endToFront = -delta > 0 ? false : true; // used to do the right autocorrection with periodic hidden times
24620
24621 var safeStart = snapAwayFromHidden(this.body.hiddenDates, newStart, delta, true);
24622 var safeEnd = snapAwayFromHidden(this.body.hiddenDates, newEnd, -delta, true);
24623
24624 if (safeStart != newStart || safeEnd != newEnd) {
24625 newStart = safeStart;
24626 newEnd = safeEnd;
24627 }
24628
24629 var options = {
24630 animation: false,
24631 byUser: true,
24632 event: event
24633 };
24634 this.setRange(newStart, newEnd, options);
24635 this.startToFront = false; // revert to default
24636
24637 this.endToFront = true; // revert to default
24638 }
24639 /**
24640 * Move the range with a given delta to the left or right. Start and end
24641 * value will be adjusted. For example, try delta = 0.1 or -0.1
24642 * @param {number} delta Moving amount. Positive value will move right,
24643 * negative value will move left
24644 */
24645
24646 }, {
24647 key: "move",
24648 value: function move(delta) {
24649 // zoom start Date and end Date relative to the centerDate
24650 var diff = this.end - this.start; // apply new values
24651
24652 var newStart = this.start + diff * delta;
24653 var newEnd = this.end + diff * delta; // TODO: reckon with min and max range
24654
24655 this.start = newStart;
24656 this.end = newEnd;
24657 }
24658 /**
24659 * Move the range to a new center point
24660 * @param {number} moveTo New center point of the range
24661 */
24662
24663 }, {
24664 key: "moveTo",
24665 value: function moveTo(_moveTo) {
24666 var center = (this.start + this.end) / 2;
24667 var diff = center - _moveTo; // calculate new start and end
24668
24669 var newStart = this.start - diff;
24670 var newEnd = this.end - diff;
24671 var options = {
24672 animation: false,
24673 byUser: true,
24674 event: null
24675 };
24676 this.setRange(newStart, newEnd, options);
24677 }
24678 }], [{
24679 key: "conversion",
24680 value: function conversion(start, end, width, totalHidden) {
24681 if (totalHidden === undefined) {
24682 totalHidden = 0;
24683 }
24684
24685 if (width != 0 && end - start != 0) {
24686 return {
24687 offset: start,
24688 scale: width / (end - start - totalHidden)
24689 };
24690 } else {
24691 return {
24692 offset: 0,
24693 scale: 1
24694 };
24695 }
24696 }
24697 }]);
24698
24699 return Range;
24700}(Component);
24701
24702function validateDirection(direction) {
24703 if (direction != 'horizontal' && direction != 'vertical') {
24704 throw new TypeError("Unknown direction \"".concat(direction, "\". Choose \"horizontal\" or \"vertical\"."));
24705 }
24706}
24707
24708/**
24709 * Expose `Emitter`.
24710 */
24711var emitterComponent = Emitter;
24712/**
24713 * Initialize a new `Emitter`.
24714 *
24715 * @api public
24716 */
24717
24718function Emitter(obj) {
24719 if (obj) return mixin(obj);
24720}
24721/**
24722 * Mixin the emitter properties.
24723 *
24724 * @param {Object} obj
24725 * @return {Object}
24726 * @api private
24727 */
24728
24729function mixin(obj) {
24730 for (var key in Emitter.prototype) {
24731 obj[key] = Emitter.prototype[key];
24732 }
24733
24734 return obj;
24735}
24736/**
24737 * Listen on the given `event` with `fn`.
24738 *
24739 * @param {String} event
24740 * @param {Function} fn
24741 * @return {Emitter}
24742 * @api public
24743 */
24744
24745
24746Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
24747 this._callbacks = this._callbacks || {};
24748 (this._callbacks[event] = this._callbacks[event] || []).push(fn);
24749 return this;
24750};
24751/**
24752 * Adds an `event` listener that will be invoked a single
24753 * time then automatically removed.
24754 *
24755 * @param {String} event
24756 * @param {Function} fn
24757 * @return {Emitter}
24758 * @api public
24759 */
24760
24761
24762Emitter.prototype.once = function (event, fn) {
24763 var self = this;
24764 this._callbacks = this._callbacks || {};
24765
24766 function on() {
24767 self.off(event, on);
24768 fn.apply(this, arguments);
24769 }
24770
24771 on.fn = fn;
24772 this.on(event, on);
24773 return this;
24774};
24775/**
24776 * Remove the given callback for `event` or all
24777 * registered callbacks.
24778 *
24779 * @param {String} event
24780 * @param {Function} fn
24781 * @return {Emitter}
24782 * @api public
24783 */
24784
24785
24786Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
24787 this._callbacks = this._callbacks || {}; // all
24788
24789 if (0 == arguments.length) {
24790 this._callbacks = {};
24791 return this;
24792 } // specific event
24793
24794
24795 var callbacks = this._callbacks[event];
24796 if (!callbacks) return this; // remove all handlers
24797
24798 if (1 == arguments.length) {
24799 delete this._callbacks[event];
24800 return this;
24801 } // remove specific handler
24802
24803
24804 var cb;
24805
24806 for (var i = 0; i < callbacks.length; i++) {
24807 cb = callbacks[i];
24808
24809 if (cb === fn || cb.fn === fn) {
24810 callbacks.splice(i, 1);
24811 break;
24812 }
24813 }
24814
24815 return this;
24816};
24817/**
24818 * Emit `event` with the given args.
24819 *
24820 * @param {String} event
24821 * @param {Mixed} ...
24822 * @return {Emitter}
24823 */
24824
24825
24826Emitter.prototype.emit = function (event) {
24827 this._callbacks = this._callbacks || {};
24828 var args = [].slice.call(arguments, 1),
24829 callbacks = this._callbacks[event];
24830
24831 if (callbacks) {
24832 callbacks = callbacks.slice(0);
24833
24834 for (var i = 0, len = callbacks.length; i < len; ++i) {
24835 callbacks[i].apply(this, args);
24836 }
24837 }
24838
24839 return this;
24840};
24841/**
24842 * Return array of callbacks for `event`.
24843 *
24844 * @param {String} event
24845 * @return {Array}
24846 * @api public
24847 */
24848
24849
24850Emitter.prototype.listeners = function (event) {
24851 this._callbacks = this._callbacks || {};
24852 return this._callbacks[event] || [];
24853};
24854/**
24855 * Check if this emitter has `event` handlers.
24856 *
24857 * @param {String} event
24858 * @return {Boolean}
24859 * @api public
24860 */
24861
24862
24863Emitter.prototype.hasListeners = function (event) {
24864 return !!this.listeners(event).length;
24865};
24866
24867var propagating = createCommonjsModule(function (module, exports) {
24868
24869 (function (factory) {
24870 {
24871 // Node. Does not work with strict CommonJS, but
24872 // only CommonJS-like environments that support module.exports,
24873 // like Node.
24874 module.exports = factory();
24875 }
24876 })(function () {
24877 var _firstTarget = null; // singleton, will contain the target element where the touch event started
24878
24879 /**
24880 * Extend an Hammer.js instance with event propagation.
24881 *
24882 * Features:
24883 * - Events emitted by hammer will propagate in order from child to parent
24884 * elements.
24885 * - Events are extended with a function `event.stopPropagation()` to stop
24886 * propagation to parent elements.
24887 * - An option `preventDefault` to stop all default browser behavior.
24888 *
24889 * Usage:
24890 * var hammer = propagatingHammer(new Hammer(element));
24891 * var hammer = propagatingHammer(new Hammer(element), {preventDefault: true});
24892 *
24893 * @param {Hammer.Manager} hammer An hammer instance.
24894 * @param {Object} [options] Available options:
24895 * - `preventDefault: true | false | 'mouse' | 'touch' | 'pen'`.
24896 * Enforce preventing the default browser behavior.
24897 * Cannot be set to `false`.
24898 * @return {Hammer.Manager} Returns the same hammer instance with extended
24899 * functionality
24900 */
24901
24902 return function propagating(hammer, options) {
24903 var _options = options || {
24904 preventDefault: false
24905 };
24906
24907 if (hammer.Manager) {
24908 // This looks like the Hammer constructor.
24909 // Overload the constructors with our own.
24910 var Hammer = hammer;
24911
24912 var PropagatingHammer = function PropagatingHammer(element, options) {
24913 var o = Object.create(_options);
24914 if (options) Hammer.assign(o, options);
24915 return propagating(new Hammer(element, o), o);
24916 };
24917
24918 Hammer.assign(PropagatingHammer, Hammer);
24919
24920 PropagatingHammer.Manager = function (element, options) {
24921 var o = Object.create(_options);
24922 if (options) Hammer.assign(o, options);
24923 return propagating(new Hammer.Manager(element, o), o);
24924 };
24925
24926 return PropagatingHammer;
24927 } // create a wrapper object which will override the functions
24928 // `on`, `off`, `destroy`, and `emit` of the hammer instance
24929
24930
24931 var wrapper = Object.create(hammer); // attach to DOM element
24932
24933 var element = hammer.element;
24934 if (!element.hammer) element.hammer = [];
24935 element.hammer.push(wrapper); // register an event to catch the start of a gesture and store the
24936 // target in a singleton
24937
24938 hammer.on('hammer.input', function (event) {
24939 if (_options.preventDefault === true || _options.preventDefault === event.pointerType) {
24940 event.preventDefault();
24941 }
24942
24943 if (event.isFirst) {
24944 _firstTarget = event.target;
24945 }
24946 });
24947 /** @type {Object.<String, Array.<function>>} */
24948
24949 wrapper._handlers = {};
24950 /**
24951 * Register a handler for one or multiple events
24952 * @param {String} events A space separated string with events
24953 * @param {function} handler A callback function, called as handler(event)
24954 * @returns {Hammer.Manager} Returns the hammer instance
24955 */
24956
24957 wrapper.on = function (events, handler) {
24958 // register the handler
24959 split(events).forEach(function (event) {
24960 var _handlers = wrapper._handlers[event];
24961
24962 if (!_handlers) {
24963 wrapper._handlers[event] = _handlers = []; // register the static, propagated handler
24964
24965 hammer.on(event, propagatedHandler);
24966 }
24967
24968 _handlers.push(handler);
24969 });
24970 return wrapper;
24971 };
24972 /**
24973 * Unregister a handler for one or multiple events
24974 * @param {String} events A space separated string with events
24975 * @param {function} [handler] Optional. The registered handler. If not
24976 * provided, all handlers for given events
24977 * are removed.
24978 * @returns {Hammer.Manager} Returns the hammer instance
24979 */
24980
24981
24982 wrapper.off = function (events, handler) {
24983 // unregister the handler
24984 split(events).forEach(function (event) {
24985 var _handlers = wrapper._handlers[event];
24986
24987 if (_handlers) {
24988 _handlers = handler ? _handlers.filter(function (h) {
24989 return h !== handler;
24990 }) : [];
24991
24992 if (_handlers.length > 0) {
24993 wrapper._handlers[event] = _handlers;
24994 } else {
24995 // remove static, propagated handler
24996 hammer.off(event, propagatedHandler);
24997 delete wrapper._handlers[event];
24998 }
24999 }
25000 });
25001 return wrapper;
25002 };
25003 /**
25004 * Emit to the event listeners
25005 * @param {string} eventType
25006 * @param {Event} event
25007 */
25008
25009
25010 wrapper.emit = function (eventType, event) {
25011 _firstTarget = event.target;
25012 hammer.emit(eventType, event);
25013 };
25014
25015 wrapper.destroy = function () {
25016 // Detach from DOM element
25017 var hammers = hammer.element.hammer;
25018 var idx = hammers.indexOf(wrapper);
25019 if (idx !== -1) hammers.splice(idx, 1);
25020 if (!hammers.length) delete hammer.element.hammer; // clear all handlers
25021
25022 wrapper._handlers = {}; // call original hammer destroy
25023
25024 hammer.destroy();
25025 }; // split a string with space separated words
25026
25027
25028 function split(events) {
25029 return events.match(/[^ ]+/g);
25030 }
25031 /**
25032 * A static event handler, applying event propagation.
25033 * @param {Object} event
25034 */
25035
25036
25037 function propagatedHandler(event) {
25038 // let only a single hammer instance handle this event
25039 if (event.type !== 'hammer.input') {
25040 // it is possible that the same srcEvent is used with multiple hammer events,
25041 // we keep track on which events are handled in an object _handled
25042 if (!event.srcEvent._handled) {
25043 event.srcEvent._handled = {};
25044 }
25045
25046 if (event.srcEvent._handled[event.type]) {
25047 return;
25048 } else {
25049 event.srcEvent._handled[event.type] = true;
25050 }
25051 } // attach a stopPropagation function to the event
25052
25053
25054 var stopped = false;
25055
25056 event.stopPropagation = function () {
25057 stopped = true;
25058 }; //wrap the srcEvent's stopPropagation to also stop hammer propagation:
25059
25060
25061 var srcStop = event.srcEvent.stopPropagation.bind(event.srcEvent);
25062
25063 if (typeof srcStop == "function") {
25064 event.srcEvent.stopPropagation = function () {
25065 srcStop();
25066 event.stopPropagation();
25067 };
25068 } // attach firstTarget property to the event
25069
25070
25071 event.firstTarget = _firstTarget; // propagate over all elements (until stopped)
25072
25073 var elem = _firstTarget;
25074
25075 while (elem && !stopped) {
25076 var elemHammer = elem.hammer;
25077
25078 if (elemHammer) {
25079 var _handlers;
25080
25081 for (var k = 0; k < elemHammer.length; k++) {
25082 _handlers = elemHammer[k]._handlers[event.type];
25083 if (_handlers) for (var i = 0; i < _handlers.length && !stopped; i++) {
25084 _handlers[i](event);
25085 }
25086 }
25087 }
25088
25089 elem = elem.parentNode;
25090 }
25091 }
25092
25093 return wrapper;
25094 };
25095 });
25096});
25097
25098/*! Hammer.JS - v2.0.15 - 2019-04-04
25099 * http://naver.github.io/egjs
25100 *
25101 * Forked By Naver egjs
25102 * Copyright (c) hammerjs
25103 * Licensed under the MIT license */
25104function _extends() {
25105 _extends = Object.assign || function (target) {
25106 for (var i = 1; i < arguments.length; i++) {
25107 var source = arguments[i];
25108
25109 for (var key in source) {
25110 if (Object.prototype.hasOwnProperty.call(source, key)) {
25111 target[key] = source[key];
25112 }
25113 }
25114 }
25115
25116 return target;
25117 };
25118
25119 return _extends.apply(this, arguments);
25120}
25121
25122function _inheritsLoose(subClass, superClass) {
25123 subClass.prototype = Object.create(superClass.prototype);
25124 subClass.prototype.constructor = subClass;
25125 subClass.__proto__ = superClass;
25126}
25127
25128function _assertThisInitialized$2(self) {
25129 if (self === void 0) {
25130 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
25131 }
25132
25133 return self;
25134}
25135/**
25136 * @private
25137 * extend object.
25138 * means that properties in dest will be overwritten by the ones in src.
25139 * @param {Object} target
25140 * @param {...Object} objects_to_assign
25141 * @returns {Object} target
25142 */
25143
25144
25145var assign;
25146
25147if (typeof Object.assign !== 'function') {
25148 assign = function assign(target) {
25149 if (target === undefined || target === null) {
25150 throw new TypeError('Cannot convert undefined or null to object');
25151 }
25152
25153 var output = Object(target);
25154
25155 for (var index = 1; index < arguments.length; index++) {
25156 var source = arguments[index];
25157
25158 if (source !== undefined && source !== null) {
25159 for (var nextKey in source) {
25160 if (source.hasOwnProperty(nextKey)) {
25161 output[nextKey] = source[nextKey];
25162 }
25163 }
25164 }
25165 }
25166
25167 return output;
25168 };
25169} else {
25170 assign = Object.assign;
25171}
25172
25173var assign$1 = assign;
25174var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
25175var TEST_ELEMENT = typeof document === "undefined" ? {
25176 style: {}
25177} : document.createElement('div');
25178var TYPE_FUNCTION = 'function';
25179var round = Math.round,
25180 abs$1 = Math.abs;
25181var now = Date.now;
25182/**
25183 * @private
25184 * get the prefixed property
25185 * @param {Object} obj
25186 * @param {String} property
25187 * @returns {String|Undefined} prefixed
25188 */
25189
25190function prefixed(obj, property) {
25191 var prefix;
25192 var prop;
25193 var camelProp = property[0].toUpperCase() + property.slice(1);
25194 var i = 0;
25195
25196 while (i < VENDOR_PREFIXES.length) {
25197 prefix = VENDOR_PREFIXES[i];
25198 prop = prefix ? prefix + camelProp : property;
25199
25200 if (prop in obj) {
25201 return prop;
25202 }
25203
25204 i++;
25205 }
25206
25207 return undefined;
25208}
25209/* eslint-disable no-new-func, no-nested-ternary */
25210
25211
25212var win;
25213
25214if (typeof window === "undefined") {
25215 // window is undefined in node.js
25216 win = {};
25217} else {
25218 win = window;
25219}
25220
25221var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
25222var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
25223
25224function getTouchActionProps() {
25225 if (!NATIVE_TOUCH_ACTION) {
25226 return false;
25227 }
25228
25229 var touchMap = {};
25230 var cssSupports = win.CSS && win.CSS.supports;
25231 ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
25232 // If css.supports is not supported but there is native touch-action assume it supports
25233 // all values. This is the case for IE 10 and 11.
25234 return touchMap[val] = cssSupports ? win.CSS.supports('touch-action', val) : true;
25235 });
25236 return touchMap;
25237}
25238
25239var TOUCH_ACTION_COMPUTE = 'compute';
25240var TOUCH_ACTION_AUTO = 'auto';
25241var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
25242
25243var TOUCH_ACTION_NONE = 'none';
25244var TOUCH_ACTION_PAN_X = 'pan-x';
25245var TOUCH_ACTION_PAN_Y = 'pan-y';
25246var TOUCH_ACTION_MAP = getTouchActionProps();
25247var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
25248var SUPPORT_TOUCH = 'ontouchstart' in win;
25249var SUPPORT_POINTER_EVENTS = prefixed(win, 'PointerEvent') !== undefined;
25250var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
25251var INPUT_TYPE_TOUCH = 'touch';
25252var INPUT_TYPE_PEN = 'pen';
25253var INPUT_TYPE_MOUSE = 'mouse';
25254var INPUT_TYPE_KINECT = 'kinect';
25255var COMPUTE_INTERVAL = 25;
25256var INPUT_START = 1;
25257var INPUT_MOVE = 2;
25258var INPUT_END = 4;
25259var INPUT_CANCEL = 8;
25260var DIRECTION_NONE = 1;
25261var DIRECTION_LEFT = 2;
25262var DIRECTION_RIGHT = 4;
25263var DIRECTION_UP = 8;
25264var DIRECTION_DOWN = 16;
25265var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
25266var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
25267var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
25268var PROPS_XY = ['x', 'y'];
25269var PROPS_CLIENT_XY = ['clientX', 'clientY'];
25270/**
25271 * @private
25272 * walk objects and arrays
25273 * @param {Object} obj
25274 * @param {Function} iterator
25275 * @param {Object} context
25276 */
25277
25278function each(obj, iterator, context) {
25279 var i;
25280
25281 if (!obj) {
25282 return;
25283 }
25284
25285 if (obj.forEach) {
25286 obj.forEach(iterator, context);
25287 } else if (obj.length !== undefined) {
25288 i = 0;
25289
25290 while (i < obj.length) {
25291 iterator.call(context, obj[i], i, obj);
25292 i++;
25293 }
25294 } else {
25295 for (i in obj) {
25296 obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
25297 }
25298 }
25299}
25300/**
25301 * @private
25302 * let a boolean value also be a function that must return a boolean
25303 * this first item in args will be used as the context
25304 * @param {Boolean|Function} val
25305 * @param {Array} [args]
25306 * @returns {Boolean}
25307 */
25308
25309
25310function boolOrFn(val, args) {
25311 if (_typeof(val) === TYPE_FUNCTION) {
25312 return val.apply(args ? args[0] || undefined : undefined, args);
25313 }
25314
25315 return val;
25316}
25317/**
25318 * @private
25319 * small indexOf wrapper
25320 * @param {String} str
25321 * @param {String} find
25322 * @returns {Boolean} found
25323 */
25324
25325
25326function inStr(str, find) {
25327 return str.indexOf(find) > -1;
25328}
25329/**
25330 * @private
25331 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
25332 * @param {String} actions
25333 * @returns {*}
25334 */
25335
25336
25337function cleanTouchActions(actions) {
25338 // none
25339 if (inStr(actions, TOUCH_ACTION_NONE)) {
25340 return TOUCH_ACTION_NONE;
25341 }
25342
25343 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
25344 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
25345 // for different directions, e.g. horizontal pan but vertical swipe?)
25346 // we need none (as otherwise with pan-x pan-y combined none of these
25347 // recognizers will work, since the browser would handle all panning
25348
25349 if (hasPanX && hasPanY) {
25350 return TOUCH_ACTION_NONE;
25351 } // pan-x OR pan-y
25352
25353
25354 if (hasPanX || hasPanY) {
25355 return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
25356 } // manipulation
25357
25358
25359 if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
25360 return TOUCH_ACTION_MANIPULATION;
25361 }
25362
25363 return TOUCH_ACTION_AUTO;
25364}
25365/**
25366 * @private
25367 * Touch Action
25368 * sets the touchAction property or uses the js alternative
25369 * @param {Manager} manager
25370 * @param {String} value
25371 * @constructor
25372 */
25373
25374
25375var TouchAction =
25376/*#__PURE__*/
25377function () {
25378 function TouchAction(manager, value) {
25379 this.manager = manager;
25380 this.set(value);
25381 }
25382 /**
25383 * @private
25384 * set the touchAction value on the element or enable the polyfill
25385 * @param {String} value
25386 */
25387
25388
25389 var _proto = TouchAction.prototype;
25390
25391 _proto.set = function set(value) {
25392 // find out the touch-action by the event handlers
25393 if (value === TOUCH_ACTION_COMPUTE) {
25394 value = this.compute();
25395 }
25396
25397 if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
25398 this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
25399 }
25400
25401 this.actions = value.toLowerCase().trim();
25402 };
25403 /**
25404 * @private
25405 * just re-set the touchAction value
25406 */
25407
25408
25409 _proto.update = function update() {
25410 this.set(this.manager.options.touchAction);
25411 };
25412 /**
25413 * @private
25414 * compute the value for the touchAction property based on the recognizer's settings
25415 * @returns {String} value
25416 */
25417
25418
25419 _proto.compute = function compute() {
25420 var actions = [];
25421 each(this.manager.recognizers, function (recognizer) {
25422 if (boolOrFn(recognizer.options.enable, [recognizer])) {
25423 actions = actions.concat(recognizer.getTouchAction());
25424 }
25425 });
25426 return cleanTouchActions(actions.join(' '));
25427 };
25428 /**
25429 * @private
25430 * this method is called on each input cycle and provides the preventing of the browser behavior
25431 * @param {Object} input
25432 */
25433
25434
25435 _proto.preventDefaults = function preventDefaults(input) {
25436 var srcEvent = input.srcEvent;
25437 var direction = input.offsetDirection; // if the touch action did prevented once this session
25438
25439 if (this.manager.session.prevented) {
25440 srcEvent.preventDefault();
25441 return;
25442 }
25443
25444 var actions = this.actions;
25445 var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
25446 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
25447 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
25448
25449 if (hasNone) {
25450 // do not prevent defaults if this is a tap gesture
25451 var isTapPointer = input.pointers.length === 1;
25452 var isTapMovement = input.distance < 2;
25453 var isTapTouchTime = input.deltaTime < 250;
25454
25455 if (isTapPointer && isTapMovement && isTapTouchTime) {
25456 return;
25457 }
25458 }
25459
25460 if (hasPanX && hasPanY) {
25461 // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
25462 return;
25463 }
25464
25465 if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
25466 return this.preventSrc(srcEvent);
25467 }
25468 };
25469 /**
25470 * @private
25471 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
25472 * @param {Object} srcEvent
25473 */
25474
25475
25476 _proto.preventSrc = function preventSrc(srcEvent) {
25477 this.manager.session.prevented = true;
25478 srcEvent.preventDefault();
25479 };
25480
25481 return TouchAction;
25482}();
25483/**
25484 * @private
25485 * find if a node is in the given parent
25486 * @method hasParent
25487 * @param {HTMLElement} node
25488 * @param {HTMLElement} parent
25489 * @return {Boolean} found
25490 */
25491
25492
25493function hasParent$1(node, parent) {
25494 while (node) {
25495 if (node === parent) {
25496 return true;
25497 }
25498
25499 node = node.parentNode;
25500 }
25501
25502 return false;
25503}
25504/**
25505 * @private
25506 * get the center of all the pointers
25507 * @param {Array} pointers
25508 * @return {Object} center contains `x` and `y` properties
25509 */
25510
25511
25512function getCenter(pointers) {
25513 var pointersLength = pointers.length; // no need to loop when only one touch
25514
25515 if (pointersLength === 1) {
25516 return {
25517 x: round(pointers[0].clientX),
25518 y: round(pointers[0].clientY)
25519 };
25520 }
25521
25522 var x = 0;
25523 var y = 0;
25524 var i = 0;
25525
25526 while (i < pointersLength) {
25527 x += pointers[i].clientX;
25528 y += pointers[i].clientY;
25529 i++;
25530 }
25531
25532 return {
25533 x: round(x / pointersLength),
25534 y: round(y / pointersLength)
25535 };
25536}
25537/**
25538 * @private
25539 * create a simple clone from the input used for storage of firstInput and firstMultiple
25540 * @param {Object} input
25541 * @returns {Object} clonedInputData
25542 */
25543
25544
25545function simpleCloneInputData(input) {
25546 // make a simple copy of the pointers because we will get a reference if we don't
25547 // we only need clientXY for the calculations
25548 var pointers = [];
25549 var i = 0;
25550
25551 while (i < input.pointers.length) {
25552 pointers[i] = {
25553 clientX: round(input.pointers[i].clientX),
25554 clientY: round(input.pointers[i].clientY)
25555 };
25556 i++;
25557 }
25558
25559 return {
25560 timeStamp: now(),
25561 pointers: pointers,
25562 center: getCenter(pointers),
25563 deltaX: input.deltaX,
25564 deltaY: input.deltaY
25565 };
25566}
25567/**
25568 * @private
25569 * calculate the absolute distance between two points
25570 * @param {Object} p1 {x, y}
25571 * @param {Object} p2 {x, y}
25572 * @param {Array} [props] containing x and y keys
25573 * @return {Number} distance
25574 */
25575
25576
25577function getDistance(p1, p2, props) {
25578 if (!props) {
25579 props = PROPS_XY;
25580 }
25581
25582 var x = p2[props[0]] - p1[props[0]];
25583 var y = p2[props[1]] - p1[props[1]];
25584 return Math.sqrt(x * x + y * y);
25585}
25586/**
25587 * @private
25588 * calculate the angle between two coordinates
25589 * @param {Object} p1
25590 * @param {Object} p2
25591 * @param {Array} [props] containing x and y keys
25592 * @return {Number} angle
25593 */
25594
25595
25596function getAngle(p1, p2, props) {
25597 if (!props) {
25598 props = PROPS_XY;
25599 }
25600
25601 var x = p2[props[0]] - p1[props[0]];
25602 var y = p2[props[1]] - p1[props[1]];
25603 return Math.atan2(y, x) * 180 / Math.PI;
25604}
25605/**
25606 * @private
25607 * get the direction between two points
25608 * @param {Number} x
25609 * @param {Number} y
25610 * @return {Number} direction
25611 */
25612
25613
25614function getDirection(x, y) {
25615 if (x === y) {
25616 return DIRECTION_NONE;
25617 }
25618
25619 if (abs$1(x) >= abs$1(y)) {
25620 return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
25621 }
25622
25623 return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
25624}
25625
25626function computeDeltaXY(session, input) {
25627 var center = input.center; // let { offsetDelta:offset = {}, prevDelta = {}, prevInput = {} } = session;
25628 // jscs throwing error on defalut destructured values and without defaults tests fail
25629
25630 var offset = session.offsetDelta || {};
25631 var prevDelta = session.prevDelta || {};
25632 var prevInput = session.prevInput || {};
25633
25634 if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
25635 prevDelta = session.prevDelta = {
25636 x: prevInput.deltaX || 0,
25637 y: prevInput.deltaY || 0
25638 };
25639 offset = session.offsetDelta = {
25640 x: center.x,
25641 y: center.y
25642 };
25643 }
25644
25645 input.deltaX = prevDelta.x + (center.x - offset.x);
25646 input.deltaY = prevDelta.y + (center.y - offset.y);
25647}
25648/**
25649 * @private
25650 * calculate the velocity between two points. unit is in px per ms.
25651 * @param {Number} deltaTime
25652 * @param {Number} x
25653 * @param {Number} y
25654 * @return {Object} velocity `x` and `y`
25655 */
25656
25657
25658function getVelocity(deltaTime, x, y) {
25659 return {
25660 x: x / deltaTime || 0,
25661 y: y / deltaTime || 0
25662 };
25663}
25664/**
25665 * @private
25666 * calculate the scale factor between two pointersets
25667 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
25668 * @param {Array} start array of pointers
25669 * @param {Array} end array of pointers
25670 * @return {Number} scale
25671 */
25672
25673
25674function getScale(start, end) {
25675 return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
25676}
25677/**
25678 * @private
25679 * calculate the rotation degrees between two pointersets
25680 * @param {Array} start array of pointers
25681 * @param {Array} end array of pointers
25682 * @return {Number} rotation
25683 */
25684
25685
25686function getRotation(start, end) {
25687 return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
25688}
25689/**
25690 * @private
25691 * velocity is calculated every x ms
25692 * @param {Object} session
25693 * @param {Object} input
25694 */
25695
25696
25697function computeIntervalInputData(session, input) {
25698 var last = session.lastInterval || input;
25699 var deltaTime = input.timeStamp - last.timeStamp;
25700 var velocity;
25701 var velocityX;
25702 var velocityY;
25703 var direction;
25704
25705 if (input.eventType !== INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
25706 var deltaX = input.deltaX - last.deltaX;
25707 var deltaY = input.deltaY - last.deltaY;
25708 var v = getVelocity(deltaTime, deltaX, deltaY);
25709 velocityX = v.x;
25710 velocityY = v.y;
25711 velocity = abs$1(v.x) > abs$1(v.y) ? v.x : v.y;
25712 direction = getDirection(deltaX, deltaY);
25713 session.lastInterval = input;
25714 } else {
25715 // use latest velocity info if it doesn't overtake a minimum period
25716 velocity = last.velocity;
25717 velocityX = last.velocityX;
25718 velocityY = last.velocityY;
25719 direction = last.direction;
25720 }
25721
25722 input.velocity = velocity;
25723 input.velocityX = velocityX;
25724 input.velocityY = velocityY;
25725 input.direction = direction;
25726}
25727/**
25728* @private
25729 * extend the data with some usable properties like scale, rotate, velocity etc
25730 * @param {Object} manager
25731 * @param {Object} input
25732 */
25733
25734
25735function computeInputData(manager, input) {
25736 var session = manager.session;
25737 var pointers = input.pointers;
25738 var pointersLength = pointers.length; // store the first input to calculate the distance and direction
25739
25740 if (!session.firstInput) {
25741 session.firstInput = simpleCloneInputData(input);
25742 } // to compute scale and rotation we need to store the multiple touches
25743
25744
25745 if (pointersLength > 1 && !session.firstMultiple) {
25746 session.firstMultiple = simpleCloneInputData(input);
25747 } else if (pointersLength === 1) {
25748 session.firstMultiple = false;
25749 }
25750
25751 var firstInput = session.firstInput,
25752 firstMultiple = session.firstMultiple;
25753 var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
25754 var center = input.center = getCenter(pointers);
25755 input.timeStamp = now();
25756 input.deltaTime = input.timeStamp - firstInput.timeStamp;
25757 input.angle = getAngle(offsetCenter, center);
25758 input.distance = getDistance(offsetCenter, center);
25759 computeDeltaXY(session, input);
25760 input.offsetDirection = getDirection(input.deltaX, input.deltaY);
25761 var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
25762 input.overallVelocityX = overallVelocity.x;
25763 input.overallVelocityY = overallVelocity.y;
25764 input.overallVelocity = abs$1(overallVelocity.x) > abs$1(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
25765 input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
25766 input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
25767 input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
25768 computeIntervalInputData(session, input); // find the correct target
25769
25770 var target = manager.element;
25771
25772 if (hasParent$1(input.srcEvent.target, target)) {
25773 target = input.srcEvent.target;
25774 }
25775
25776 input.target = target;
25777}
25778/**
25779 * @private
25780 * handle input events
25781 * @param {Manager} manager
25782 * @param {String} eventType
25783 * @param {Object} input
25784 */
25785
25786
25787function inputHandler(manager, eventType, input) {
25788 var pointersLen = input.pointers.length;
25789 var changedPointersLen = input.changedPointers.length;
25790 var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
25791 var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
25792 input.isFirst = !!isFirst;
25793 input.isFinal = !!isFinal;
25794
25795 if (isFirst) {
25796 manager.session = {};
25797 } // source event is the normalized value of the domEvents
25798 // like 'touchstart, mouseup, pointerdown'
25799
25800
25801 input.eventType = eventType; // compute scale, rotation etc
25802
25803 computeInputData(manager, input); // emit secret event
25804
25805 manager.emit('hammer.input', input);
25806 manager.recognize(input);
25807 manager.session.prevInput = input;
25808}
25809/**
25810 * @private
25811 * split string on whitespace
25812 * @param {String} str
25813 * @returns {Array} words
25814 */
25815
25816
25817function splitStr(str) {
25818 return str.trim().split(/\s+/g);
25819}
25820/**
25821 * @private
25822 * addEventListener with multiple events at once
25823 * @param {EventTarget} target
25824 * @param {String} types
25825 * @param {Function} handler
25826 */
25827
25828
25829function addEventListeners(target, types, handler) {
25830 each(splitStr(types), function (type) {
25831 target.addEventListener(type, handler, false);
25832 });
25833}
25834/**
25835 * @private
25836 * removeEventListener with multiple events at once
25837 * @param {EventTarget} target
25838 * @param {String} types
25839 * @param {Function} handler
25840 */
25841
25842
25843function removeEventListeners(target, types, handler) {
25844 each(splitStr(types), function (type) {
25845 target.removeEventListener(type, handler, false);
25846 });
25847}
25848/**
25849 * @private
25850 * get the window object of an element
25851 * @param {HTMLElement} element
25852 * @returns {DocumentView|Window}
25853 */
25854
25855
25856function getWindowForElement(element) {
25857 var doc = element.ownerDocument || element;
25858 return doc.defaultView || doc.parentWindow || window;
25859}
25860/**
25861 * @private
25862 * create new input type manager
25863 * @param {Manager} manager
25864 * @param {Function} callback
25865 * @returns {Input}
25866 * @constructor
25867 */
25868
25869
25870var Input =
25871/*#__PURE__*/
25872function () {
25873 function Input(manager, callback) {
25874 var self = this;
25875 this.manager = manager;
25876 this.callback = callback;
25877 this.element = manager.element;
25878 this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager,
25879 // so when disabled the input events are completely bypassed.
25880
25881 this.domHandler = function (ev) {
25882 if (boolOrFn(manager.options.enable, [manager])) {
25883 self.handler(ev);
25884 }
25885 };
25886
25887 this.init();
25888 }
25889 /**
25890 * @private
25891 * should handle the inputEvent data and trigger the callback
25892 * @virtual
25893 */
25894
25895
25896 var _proto = Input.prototype;
25897
25898 _proto.handler = function handler() {};
25899 /**
25900 * @private
25901 * bind the events
25902 */
25903
25904
25905 _proto.init = function init() {
25906 this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
25907 this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
25908 this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
25909 };
25910 /**
25911 * @private
25912 * unbind the events
25913 */
25914
25915
25916 _proto.destroy = function destroy() {
25917 this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
25918 this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
25919 this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
25920 };
25921
25922 return Input;
25923}();
25924/**
25925 * @private
25926 * find if a array contains the object using indexOf or a simple polyFill
25927 * @param {Array} src
25928 * @param {String} find
25929 * @param {String} [findByKey]
25930 * @return {Boolean|Number} false when not found, or the index
25931 */
25932
25933
25934function inArray(src, find, findByKey) {
25935 if (src.indexOf && !findByKey) {
25936 return src.indexOf(find);
25937 } else {
25938 var i = 0;
25939
25940 while (i < src.length) {
25941 if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
25942 // do not use === here, test fails
25943 return i;
25944 }
25945
25946 i++;
25947 }
25948
25949 return -1;
25950 }
25951}
25952
25953var POINTER_INPUT_MAP = {
25954 pointerdown: INPUT_START,
25955 pointermove: INPUT_MOVE,
25956 pointerup: INPUT_END,
25957 pointercancel: INPUT_CANCEL,
25958 pointerout: INPUT_CANCEL
25959}; // in IE10 the pointer types is defined as an enum
25960
25961var IE10_POINTER_TYPE_ENUM = {
25962 2: INPUT_TYPE_TOUCH,
25963 3: INPUT_TYPE_PEN,
25964 4: INPUT_TYPE_MOUSE,
25965 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
25966
25967};
25968var POINTER_ELEMENT_EVENTS = 'pointerdown';
25969var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive
25970
25971if (win.MSPointerEvent && !win.PointerEvent) {
25972 POINTER_ELEMENT_EVENTS = 'MSPointerDown';
25973 POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
25974}
25975/**
25976 * @private
25977 * Pointer events input
25978 * @constructor
25979 * @extends Input
25980 */
25981
25982
25983var PointerEventInput =
25984/*#__PURE__*/
25985function (_Input) {
25986 _inheritsLoose(PointerEventInput, _Input);
25987
25988 function PointerEventInput() {
25989 var _this;
25990
25991 var proto = PointerEventInput.prototype;
25992 proto.evEl = POINTER_ELEMENT_EVENTS;
25993 proto.evWin = POINTER_WINDOW_EVENTS;
25994 _this = _Input.apply(this, arguments) || this;
25995 _this.store = _this.manager.session.pointerEvents = [];
25996 return _this;
25997 }
25998 /**
25999 * @private
26000 * handle mouse events
26001 * @param {Object} ev
26002 */
26003
26004
26005 var _proto = PointerEventInput.prototype;
26006
26007 _proto.handler = function handler(ev) {
26008 var store = this.store;
26009 var removePointer = false;
26010 var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
26011 var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
26012 var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
26013 var isTouch = pointerType === INPUT_TYPE_TOUCH; // get index of the event in the store
26014
26015 var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down
26016
26017 if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
26018 if (storeIndex < 0) {
26019 store.push(ev);
26020 storeIndex = store.length - 1;
26021 }
26022 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
26023 removePointer = true;
26024 } // it not found, so the pointer hasn't been down (so it's probably a hover)
26025
26026
26027 if (storeIndex < 0) {
26028 return;
26029 } // update the event in the store
26030
26031
26032 store[storeIndex] = ev;
26033 this.callback(this.manager, eventType, {
26034 pointers: store,
26035 changedPointers: [ev],
26036 pointerType: pointerType,
26037 srcEvent: ev
26038 });
26039
26040 if (removePointer) {
26041 // remove from the store
26042 store.splice(storeIndex, 1);
26043 }
26044 };
26045
26046 return PointerEventInput;
26047}(Input);
26048/**
26049 * @private
26050 * convert array-like objects to real arrays
26051 * @param {Object} obj
26052 * @returns {Array}
26053 */
26054
26055
26056function toArray$1(obj) {
26057 return Array.prototype.slice.call(obj, 0);
26058}
26059/**
26060 * @private
26061 * unique array with objects based on a key (like 'id') or just by the array's value
26062 * @param {Array} src [{id:1},{id:2},{id:1}]
26063 * @param {String} [key]
26064 * @param {Boolean} [sort=False]
26065 * @returns {Array} [{id:1},{id:2}]
26066 */
26067
26068
26069function uniqueArray(src, key, sort) {
26070 var results = [];
26071 var values = [];
26072 var i = 0;
26073
26074 while (i < src.length) {
26075 var val = key ? src[i][key] : src[i];
26076
26077 if (inArray(values, val) < 0) {
26078 results.push(src[i]);
26079 }
26080
26081 values[i] = val;
26082 i++;
26083 }
26084
26085 if (sort) {
26086 if (!key) {
26087 results = results.sort();
26088 } else {
26089 results = results.sort(function (a, b) {
26090 return a[key] > b[key];
26091 });
26092 }
26093 }
26094
26095 return results;
26096}
26097
26098var TOUCH_INPUT_MAP = {
26099 touchstart: INPUT_START,
26100 touchmove: INPUT_MOVE,
26101 touchend: INPUT_END,
26102 touchcancel: INPUT_CANCEL
26103};
26104var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
26105/**
26106 * @private
26107 * Multi-user touch events input
26108 * @constructor
26109 * @extends Input
26110 */
26111
26112var TouchInput =
26113/*#__PURE__*/
26114function (_Input) {
26115 _inheritsLoose(TouchInput, _Input);
26116
26117 function TouchInput() {
26118 var _this;
26119
26120 TouchInput.prototype.evTarget = TOUCH_TARGET_EVENTS;
26121 _this = _Input.apply(this, arguments) || this;
26122 _this.targetIds = {}; // this.evTarget = TOUCH_TARGET_EVENTS;
26123
26124 return _this;
26125 }
26126
26127 var _proto = TouchInput.prototype;
26128
26129 _proto.handler = function handler(ev) {
26130 var type = TOUCH_INPUT_MAP[ev.type];
26131 var touches = getTouches.call(this, ev, type);
26132
26133 if (!touches) {
26134 return;
26135 }
26136
26137 this.callback(this.manager, type, {
26138 pointers: touches[0],
26139 changedPointers: touches[1],
26140 pointerType: INPUT_TYPE_TOUCH,
26141 srcEvent: ev
26142 });
26143 };
26144
26145 return TouchInput;
26146}(Input);
26147
26148function getTouches(ev, type) {
26149 var allTouches = toArray$1(ev.touches);
26150 var targetIds = this.targetIds; // when there is only one touch, the process can be simplified
26151
26152 if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
26153 targetIds[allTouches[0].identifier] = true;
26154 return [allTouches, allTouches];
26155 }
26156
26157 var i;
26158 var targetTouches;
26159 var changedTouches = toArray$1(ev.changedTouches);
26160 var changedTargetTouches = [];
26161 var target = this.target; // get target touches from touches
26162
26163 targetTouches = allTouches.filter(function (touch) {
26164 return hasParent$1(touch.target, target);
26165 }); // collect touches
26166
26167 if (type === INPUT_START) {
26168 i = 0;
26169
26170 while (i < targetTouches.length) {
26171 targetIds[targetTouches[i].identifier] = true;
26172 i++;
26173 }
26174 } // filter changed touches to only contain touches that exist in the collected target ids
26175
26176
26177 i = 0;
26178
26179 while (i < changedTouches.length) {
26180 if (targetIds[changedTouches[i].identifier]) {
26181 changedTargetTouches.push(changedTouches[i]);
26182 } // cleanup removed touches
26183
26184
26185 if (type & (INPUT_END | INPUT_CANCEL)) {
26186 delete targetIds[changedTouches[i].identifier];
26187 }
26188
26189 i++;
26190 }
26191
26192 if (!changedTargetTouches.length) {
26193 return;
26194 }
26195
26196 return [// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
26197 uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches];
26198}
26199
26200var MOUSE_INPUT_MAP = {
26201 mousedown: INPUT_START,
26202 mousemove: INPUT_MOVE,
26203 mouseup: INPUT_END
26204};
26205var MOUSE_ELEMENT_EVENTS = 'mousedown';
26206var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
26207/**
26208 * @private
26209 * Mouse events input
26210 * @constructor
26211 * @extends Input
26212 */
26213
26214var MouseInput =
26215/*#__PURE__*/
26216function (_Input) {
26217 _inheritsLoose(MouseInput, _Input);
26218
26219 function MouseInput() {
26220 var _this;
26221
26222 var proto = MouseInput.prototype;
26223 proto.evEl = MOUSE_ELEMENT_EVENTS;
26224 proto.evWin = MOUSE_WINDOW_EVENTS;
26225 _this = _Input.apply(this, arguments) || this;
26226 _this.pressed = false; // mousedown state
26227
26228 return _this;
26229 }
26230 /**
26231 * @private
26232 * handle mouse events
26233 * @param {Object} ev
26234 */
26235
26236
26237 var _proto = MouseInput.prototype;
26238
26239 _proto.handler = function handler(ev) {
26240 var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down
26241
26242 if (eventType & INPUT_START && ev.button === 0) {
26243 this.pressed = true;
26244 }
26245
26246 if (eventType & INPUT_MOVE && ev.which !== 1) {
26247 eventType = INPUT_END;
26248 } // mouse must be down
26249
26250
26251 if (!this.pressed) {
26252 return;
26253 }
26254
26255 if (eventType & INPUT_END) {
26256 this.pressed = false;
26257 }
26258
26259 this.callback(this.manager, eventType, {
26260 pointers: [ev],
26261 changedPointers: [ev],
26262 pointerType: INPUT_TYPE_MOUSE,
26263 srcEvent: ev
26264 });
26265 };
26266
26267 return MouseInput;
26268}(Input);
26269/**
26270 * @private
26271 * Combined touch and mouse input
26272 *
26273 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
26274 * This because touch devices also emit mouse events while doing a touch.
26275 *
26276 * @constructor
26277 * @extends Input
26278 */
26279
26280
26281var DEDUP_TIMEOUT = 2500;
26282var DEDUP_DISTANCE = 25;
26283
26284function setLastTouch(eventData) {
26285 var _eventData$changedPoi = eventData.changedPointers,
26286 touch = _eventData$changedPoi[0];
26287
26288 if (touch.identifier === this.primaryTouch) {
26289 var lastTouch = {
26290 x: touch.clientX,
26291 y: touch.clientY
26292 };
26293 var lts = this.lastTouches;
26294 this.lastTouches.push(lastTouch);
26295
26296 var removeLastTouch = function removeLastTouch() {
26297 var i = lts.indexOf(lastTouch);
26298
26299 if (i > -1) {
26300 lts.splice(i, 1);
26301 }
26302 };
26303
26304 setTimeout(removeLastTouch, DEDUP_TIMEOUT);
26305 }
26306}
26307
26308function recordTouches(eventType, eventData) {
26309 if (eventType & INPUT_START) {
26310 this.primaryTouch = eventData.changedPointers[0].identifier;
26311 setLastTouch.call(this, eventData);
26312 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
26313 setLastTouch.call(this, eventData);
26314 }
26315}
26316
26317function isSyntheticEvent(eventData) {
26318 var x = eventData.srcEvent.clientX;
26319 var y = eventData.srcEvent.clientY;
26320
26321 for (var i = 0; i < this.lastTouches.length; i++) {
26322 var t = this.lastTouches[i];
26323 var dx = Math.abs(x - t.x);
26324 var dy = Math.abs(y - t.y);
26325
26326 if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
26327 return true;
26328 }
26329 }
26330
26331 return false;
26332}
26333
26334var TouchMouseInput =
26335/*#__PURE__*/
26336function () {
26337 var TouchMouseInput =
26338 /*#__PURE__*/
26339 function (_Input) {
26340 _inheritsLoose(TouchMouseInput, _Input);
26341
26342 function TouchMouseInput(_manager, callback) {
26343 var _this;
26344
26345 _this = _Input.call(this, _manager, callback) || this;
26346
26347 _this.handler = function (manager, inputEvent, inputData) {
26348 var isTouch = inputData.pointerType === INPUT_TYPE_TOUCH;
26349 var isMouse = inputData.pointerType === INPUT_TYPE_MOUSE;
26350
26351 if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
26352 return;
26353 } // when we're in a touch event, record touches to de-dupe synthetic mouse event
26354
26355
26356 if (isTouch) {
26357 recordTouches.call(_assertThisInitialized$2(_assertThisInitialized$2(_this)), inputEvent, inputData);
26358 } else if (isMouse && isSyntheticEvent.call(_assertThisInitialized$2(_assertThisInitialized$2(_this)), inputData)) {
26359 return;
26360 }
26361
26362 _this.callback(manager, inputEvent, inputData);
26363 };
26364
26365 _this.touch = new TouchInput(_this.manager, _this.handler);
26366 _this.mouse = new MouseInput(_this.manager, _this.handler);
26367 _this.primaryTouch = null;
26368 _this.lastTouches = [];
26369 return _this;
26370 }
26371 /**
26372 * @private
26373 * handle mouse and touch events
26374 * @param {Hammer} manager
26375 * @param {String} inputEvent
26376 * @param {Object} inputData
26377 */
26378
26379
26380 var _proto = TouchMouseInput.prototype;
26381 /**
26382 * @private
26383 * remove the event listeners
26384 */
26385
26386 _proto.destroy = function destroy() {
26387 this.touch.destroy();
26388 this.mouse.destroy();
26389 };
26390
26391 return TouchMouseInput;
26392 }(Input);
26393
26394 return TouchMouseInput;
26395}();
26396/**
26397 * @private
26398 * create new input type manager
26399 * called by the Manager constructor
26400 * @param {Hammer} manager
26401 * @returns {Input}
26402 */
26403
26404
26405function createInputInstance(manager) {
26406 var Type; // let inputClass = manager.options.inputClass;
26407
26408 var inputClass = manager.options.inputClass;
26409
26410 if (inputClass) {
26411 Type = inputClass;
26412 } else if (SUPPORT_POINTER_EVENTS) {
26413 Type = PointerEventInput;
26414 } else if (SUPPORT_ONLY_TOUCH) {
26415 Type = TouchInput;
26416 } else if (!SUPPORT_TOUCH) {
26417 Type = MouseInput;
26418 } else {
26419 Type = TouchMouseInput;
26420 }
26421
26422 return new Type(manager, inputHandler);
26423}
26424/**
26425 * @private
26426 * if the argument is an array, we want to execute the fn on each entry
26427 * if it aint an array we don't want to do a thing.
26428 * this is used by all the methods that accept a single and array argument.
26429 * @param {*|Array} arg
26430 * @param {String} fn
26431 * @param {Object} [context]
26432 * @returns {Boolean}
26433 */
26434
26435
26436function invokeArrayArg(arg, fn, context) {
26437 if (Array.isArray(arg)) {
26438 each(arg, context[fn], context);
26439 return true;
26440 }
26441
26442 return false;
26443}
26444
26445var STATE_POSSIBLE = 1;
26446var STATE_BEGAN = 2;
26447var STATE_CHANGED = 4;
26448var STATE_ENDED = 8;
26449var STATE_RECOGNIZED = STATE_ENDED;
26450var STATE_CANCELLED = 16;
26451var STATE_FAILED = 32;
26452/**
26453 * @private
26454 * get a unique id
26455 * @returns {number} uniqueId
26456 */
26457
26458var _uniqueId = 1;
26459
26460function uniqueId() {
26461 return _uniqueId++;
26462}
26463/**
26464 * @private
26465 * get a recognizer by name if it is bound to a manager
26466 * @param {Recognizer|String} otherRecognizer
26467 * @param {Recognizer} recognizer
26468 * @returns {Recognizer}
26469 */
26470
26471
26472function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
26473 var manager = recognizer.manager;
26474
26475 if (manager) {
26476 return manager.get(otherRecognizer);
26477 }
26478
26479 return otherRecognizer;
26480}
26481/**
26482 * @private
26483 * get a usable string, used as event postfix
26484 * @param {constant} state
26485 * @returns {String} state
26486 */
26487
26488
26489function stateStr(state) {
26490 if (state & STATE_CANCELLED) {
26491 return 'cancel';
26492 } else if (state & STATE_ENDED) {
26493 return 'end';
26494 } else if (state & STATE_CHANGED) {
26495 return 'move';
26496 } else if (state & STATE_BEGAN) {
26497 return 'start';
26498 }
26499
26500 return '';
26501}
26502/**
26503 * @private
26504 * Recognizer flow explained; *
26505 * All recognizers have the initial state of POSSIBLE when a input session starts.
26506 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
26507 * Example session for mouse-input: mousedown -> mousemove -> mouseup
26508 *
26509 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
26510 * which determines with state it should be.
26511 *
26512 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
26513 * POSSIBLE to give it another change on the next cycle.
26514 *
26515 * Possible
26516 * |
26517 * +-----+---------------+
26518 * | |
26519 * +-----+-----+ |
26520 * | | |
26521 * Failed Cancelled |
26522 * +-------+------+
26523 * | |
26524 * Recognized Began
26525 * |
26526 * Changed
26527 * |
26528 * Ended/Recognized
26529 */
26530
26531/**
26532 * @private
26533 * Recognizer
26534 * Every recognizer needs to extend from this class.
26535 * @constructor
26536 * @param {Object} options
26537 */
26538
26539
26540var Recognizer =
26541/*#__PURE__*/
26542function () {
26543 function Recognizer(options) {
26544 if (options === void 0) {
26545 options = {};
26546 }
26547
26548 this.options = _extends({
26549 enable: true
26550 }, options);
26551 this.id = uniqueId();
26552 this.manager = null; // default is enable true
26553
26554 this.state = STATE_POSSIBLE;
26555 this.simultaneous = {};
26556 this.requireFail = [];
26557 }
26558 /**
26559 * @private
26560 * set options
26561 * @param {Object} options
26562 * @return {Recognizer}
26563 */
26564
26565
26566 var _proto = Recognizer.prototype;
26567
26568 _proto.set = function set(options) {
26569 assign$1(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state
26570
26571 this.manager && this.manager.touchAction.update();
26572 return this;
26573 };
26574 /**
26575 * @private
26576 * recognize simultaneous with an other recognizer.
26577 * @param {Recognizer} otherRecognizer
26578 * @returns {Recognizer} this
26579 */
26580
26581
26582 _proto.recognizeWith = function recognizeWith(otherRecognizer) {
26583 if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
26584 return this;
26585 }
26586
26587 var simultaneous = this.simultaneous;
26588 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
26589
26590 if (!simultaneous[otherRecognizer.id]) {
26591 simultaneous[otherRecognizer.id] = otherRecognizer;
26592 otherRecognizer.recognizeWith(this);
26593 }
26594
26595 return this;
26596 };
26597 /**
26598 * @private
26599 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
26600 * @param {Recognizer} otherRecognizer
26601 * @returns {Recognizer} this
26602 */
26603
26604
26605 _proto.dropRecognizeWith = function dropRecognizeWith(otherRecognizer) {
26606 if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
26607 return this;
26608 }
26609
26610 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
26611 delete this.simultaneous[otherRecognizer.id];
26612 return this;
26613 };
26614 /**
26615 * @private
26616 * recognizer can only run when an other is failing
26617 * @param {Recognizer} otherRecognizer
26618 * @returns {Recognizer} this
26619 */
26620
26621
26622 _proto.requireFailure = function requireFailure(otherRecognizer) {
26623 if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
26624 return this;
26625 }
26626
26627 var requireFail = this.requireFail;
26628 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
26629
26630 if (inArray(requireFail, otherRecognizer) === -1) {
26631 requireFail.push(otherRecognizer);
26632 otherRecognizer.requireFailure(this);
26633 }
26634
26635 return this;
26636 };
26637 /**
26638 * @private
26639 * drop the requireFailure link. it does not remove the link on the other recognizer.
26640 * @param {Recognizer} otherRecognizer
26641 * @returns {Recognizer} this
26642 */
26643
26644
26645 _proto.dropRequireFailure = function dropRequireFailure(otherRecognizer) {
26646 if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
26647 return this;
26648 }
26649
26650 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
26651 var index = inArray(this.requireFail, otherRecognizer);
26652
26653 if (index > -1) {
26654 this.requireFail.splice(index, 1);
26655 }
26656
26657 return this;
26658 };
26659 /**
26660 * @private
26661 * has require failures boolean
26662 * @returns {boolean}
26663 */
26664
26665
26666 _proto.hasRequireFailures = function hasRequireFailures() {
26667 return this.requireFail.length > 0;
26668 };
26669 /**
26670 * @private
26671 * if the recognizer can recognize simultaneous with an other recognizer
26672 * @param {Recognizer} otherRecognizer
26673 * @returns {Boolean}
26674 */
26675
26676
26677 _proto.canRecognizeWith = function canRecognizeWith(otherRecognizer) {
26678 return !!this.simultaneous[otherRecognizer.id];
26679 };
26680 /**
26681 * @private
26682 * You should use `tryEmit` instead of `emit` directly to check
26683 * that all the needed recognizers has failed before emitting.
26684 * @param {Object} input
26685 */
26686
26687
26688 _proto.emit = function emit(input) {
26689 var self = this;
26690 var state = this.state;
26691
26692 function emit(event) {
26693 self.manager.emit(event, input);
26694 } // 'panstart' and 'panmove'
26695
26696
26697 if (state < STATE_ENDED) {
26698 emit(self.options.event + stateStr(state));
26699 }
26700
26701 emit(self.options.event); // simple 'eventName' events
26702
26703 if (input.additionalEvent) {
26704 // additional event(panleft, panright, pinchin, pinchout...)
26705 emit(input.additionalEvent);
26706 } // panend and pancancel
26707
26708
26709 if (state >= STATE_ENDED) {
26710 emit(self.options.event + stateStr(state));
26711 }
26712 };
26713 /**
26714 * @private
26715 * Check that all the require failure recognizers has failed,
26716 * if true, it emits a gesture event,
26717 * otherwise, setup the state to FAILED.
26718 * @param {Object} input
26719 */
26720
26721
26722 _proto.tryEmit = function tryEmit(input) {
26723 if (this.canEmit()) {
26724 return this.emit(input);
26725 } // it's failing anyway
26726
26727
26728 this.state = STATE_FAILED;
26729 };
26730 /**
26731 * @private
26732 * can we emit?
26733 * @returns {boolean}
26734 */
26735
26736
26737 _proto.canEmit = function canEmit() {
26738 var i = 0;
26739
26740 while (i < this.requireFail.length) {
26741 if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
26742 return false;
26743 }
26744
26745 i++;
26746 }
26747
26748 return true;
26749 };
26750 /**
26751 * @private
26752 * update the recognizer
26753 * @param {Object} inputData
26754 */
26755
26756
26757 _proto.recognize = function recognize(inputData) {
26758 // make a new copy of the inputData
26759 // so we can change the inputData without messing up the other recognizers
26760 var inputDataClone = assign$1({}, inputData); // is is enabled and allow recognizing?
26761
26762 if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
26763 this.reset();
26764 this.state = STATE_FAILED;
26765 return;
26766 } // reset when we've reached the end
26767
26768
26769 if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
26770 this.state = STATE_POSSIBLE;
26771 }
26772
26773 this.state = this.process(inputDataClone); // the recognizer has recognized a gesture
26774 // so trigger an event
26775
26776 if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
26777 this.tryEmit(inputDataClone);
26778 }
26779 };
26780 /**
26781 * @private
26782 * return the state of the recognizer
26783 * the actual recognizing happens in this method
26784 * @virtual
26785 * @param {Object} inputData
26786 * @returns {constant} STATE
26787 */
26788
26789 /* jshint ignore:start */
26790
26791
26792 _proto.process = function process(inputData) {};
26793 /* jshint ignore:end */
26794
26795 /**
26796 * @private
26797 * return the preferred touch-action
26798 * @virtual
26799 * @returns {Array}
26800 */
26801
26802
26803 _proto.getTouchAction = function getTouchAction() {};
26804 /**
26805 * @private
26806 * called when the gesture isn't allowed to recognize
26807 * like when another is being recognized or it is disabled
26808 * @virtual
26809 */
26810
26811
26812 _proto.reset = function reset() {};
26813
26814 return Recognizer;
26815}();
26816
26817var defaults = {
26818 /**
26819 * @private
26820 * set if DOM events are being triggered.
26821 * But this is slower and unused by simple implementations, so disabled by default.
26822 * @type {Boolean}
26823 * @default false
26824 */
26825 domEvents: false,
26826
26827 /**
26828 * @private
26829 * The value for the touchAction property/fallback.
26830 * When set to `compute` it will magically set the correct value based on the added recognizers.
26831 * @type {String}
26832 * @default compute
26833 */
26834 touchAction: TOUCH_ACTION_COMPUTE,
26835
26836 /**
26837 * @private
26838 * @type {Boolean}
26839 * @default true
26840 */
26841 enable: true,
26842
26843 /**
26844 * @private
26845 * EXPERIMENTAL FEATURE -- can be removed/changed
26846 * Change the parent input target element.
26847 * If Null, then it is being set the to main element.
26848 * @type {Null|EventTarget}
26849 * @default null
26850 */
26851 inputTarget: null,
26852
26853 /**
26854 * @private
26855 * force an input class
26856 * @type {Null|Function}
26857 * @default null
26858 */
26859 inputClass: null,
26860
26861 /**
26862 * @private
26863 * Default recognizer setup when calling `Hammer()`
26864 * When creating a new Manager these will be skipped.
26865 * @type {Array}
26866 */
26867 preset: [],
26868
26869 /**
26870 * @private
26871 * Some CSS properties can be used to improve the working of Hammer.
26872 * Add them to this method and they will be set when creating a new Manager.
26873 * @namespace
26874 */
26875 cssProps: {
26876 /**
26877 * @private
26878 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
26879 * @type {String}
26880 * @default 'none'
26881 */
26882 userSelect: "none",
26883
26884 /**
26885 * @private
26886 * Disable the Windows Phone grippers when pressing an element.
26887 * @type {String}
26888 * @default 'none'
26889 */
26890 touchSelect: "none",
26891
26892 /**
26893 * @private
26894 * Disables the default callout shown when you touch and hold a touch target.
26895 * On iOS, when you touch and hold a touch target such as a link, Safari displays
26896 * a callout containing information about the link. This property allows you to disable that callout.
26897 * @type {String}
26898 * @default 'none'
26899 */
26900 touchCallout: "none",
26901
26902 /**
26903 * @private
26904 * Specifies whether zooming is enabled. Used by IE10>
26905 * @type {String}
26906 * @default 'none'
26907 */
26908 contentZooming: "none",
26909
26910 /**
26911 * @private
26912 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
26913 * @type {String}
26914 * @default 'none'
26915 */
26916 userDrag: "none",
26917
26918 /**
26919 * @private
26920 * Overrides the highlight color shown when the user taps a link or a JavaScript
26921 * clickable element in iOS. This property obeys the alpha value, if specified.
26922 * @type {String}
26923 * @default 'rgba(0,0,0,0)'
26924 */
26925 tapHighlightColor: "rgba(0,0,0,0)"
26926 }
26927};
26928var STOP = 1;
26929var FORCED_STOP = 2;
26930/**
26931 * @private
26932 * add/remove the css properties as defined in manager.options.cssProps
26933 * @param {Manager} manager
26934 * @param {Boolean} add
26935 */
26936
26937function toggleCssProps(manager, add) {
26938 var element = manager.element;
26939
26940 if (!element.style) {
26941 return;
26942 }
26943
26944 var prop;
26945 each(manager.options.cssProps, function (value, name) {
26946 prop = prefixed(element.style, name);
26947
26948 if (add) {
26949 manager.oldCssProps[prop] = element.style[prop];
26950 element.style[prop] = value;
26951 } else {
26952 element.style[prop] = manager.oldCssProps[prop] || "";
26953 }
26954 });
26955
26956 if (!add) {
26957 manager.oldCssProps = {};
26958 }
26959}
26960/**
26961 * @private
26962 * trigger dom event
26963 * @param {String} event
26964 * @param {Object} data
26965 */
26966
26967
26968function triggerDomEvent(event, data) {
26969 var gestureEvent = document.createEvent("Event");
26970 gestureEvent.initEvent(event, true, true);
26971 gestureEvent.gesture = data;
26972 data.target.dispatchEvent(gestureEvent);
26973}
26974/**
26975* @private
26976 * Manager
26977 * @param {HTMLElement} element
26978 * @param {Object} [options]
26979 * @constructor
26980 */
26981
26982
26983var Manager =
26984/*#__PURE__*/
26985function () {
26986 function Manager(element, options) {
26987 var _this = this;
26988
26989 this.options = assign$1({}, defaults, options || {});
26990 this.options.inputTarget = this.options.inputTarget || element;
26991 this.handlers = {};
26992 this.session = {};
26993 this.recognizers = [];
26994 this.oldCssProps = {};
26995 this.element = element;
26996 this.input = createInputInstance(this);
26997 this.touchAction = new TouchAction(this, this.options.touchAction);
26998 toggleCssProps(this, true);
26999 each(this.options.recognizers, function (item) {
27000 var recognizer = _this.add(new item[0](item[1]));
27001
27002 item[2] && recognizer.recognizeWith(item[2]);
27003 item[3] && recognizer.requireFailure(item[3]);
27004 }, this);
27005 }
27006 /**
27007 * @private
27008 * set options
27009 * @param {Object} options
27010 * @returns {Manager}
27011 */
27012
27013
27014 var _proto = Manager.prototype;
27015
27016 _proto.set = function set(options) {
27017 assign$1(this.options, options); // Options that need a little more setup
27018
27019 if (options.touchAction) {
27020 this.touchAction.update();
27021 }
27022
27023 if (options.inputTarget) {
27024 // Clean up existing event listeners and reinitialize
27025 this.input.destroy();
27026 this.input.target = options.inputTarget;
27027 this.input.init();
27028 }
27029
27030 return this;
27031 };
27032 /**
27033 * @private
27034 * stop recognizing for this session.
27035 * This session will be discarded, when a new [input]start event is fired.
27036 * When forced, the recognizer cycle is stopped immediately.
27037 * @param {Boolean} [force]
27038 */
27039
27040
27041 _proto.stop = function stop(force) {
27042 this.session.stopped = force ? FORCED_STOP : STOP;
27043 };
27044 /**
27045 * @private
27046 * run the recognizers!
27047 * called by the inputHandler function on every movement of the pointers (touches)
27048 * it walks through all the recognizers and tries to detect the gesture that is being made
27049 * @param {Object} inputData
27050 */
27051
27052
27053 _proto.recognize = function recognize(inputData) {
27054 var session = this.session;
27055
27056 if (session.stopped) {
27057 return;
27058 } // run the touch-action polyfill
27059
27060
27061 this.touchAction.preventDefaults(inputData);
27062 var recognizer;
27063 var recognizers = this.recognizers; // this holds the recognizer that is being recognized.
27064 // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
27065 // if no recognizer is detecting a thing, it is set to `null`
27066
27067 var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized
27068 // or when we're in a new session
27069
27070 if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
27071 session.curRecognizer = null;
27072 curRecognizer = null;
27073 }
27074
27075 var i = 0;
27076
27077 while (i < recognizers.length) {
27078 recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one.
27079 // 1. allow if the session is NOT forced stopped (see the .stop() method)
27080 // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
27081 // that is being recognized.
27082 // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
27083 // this can be setup with the `recognizeWith()` method on the recognizer.
27084
27085 if (session.stopped !== FORCED_STOP && ( // 1
27086 !curRecognizer || recognizer === curRecognizer || // 2
27087 recognizer.canRecognizeWith(curRecognizer))) {
27088 // 3
27089 recognizer.recognize(inputData);
27090 } else {
27091 recognizer.reset();
27092 } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
27093 // current active recognizer. but only if we don't already have an active recognizer
27094
27095
27096 if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
27097 session.curRecognizer = recognizer;
27098 curRecognizer = recognizer;
27099 }
27100
27101 i++;
27102 }
27103 };
27104 /**
27105 * @private
27106 * get a recognizer by its event name.
27107 * @param {Recognizer|String} recognizer
27108 * @returns {Recognizer|Null}
27109 */
27110
27111
27112 _proto.get = function get(recognizer) {
27113 if (recognizer instanceof Recognizer) {
27114 return recognizer;
27115 }
27116
27117 var recognizers = this.recognizers;
27118
27119 for (var i = 0; i < recognizers.length; i++) {
27120 if (recognizers[i].options.event === recognizer) {
27121 return recognizers[i];
27122 }
27123 }
27124
27125 return null;
27126 };
27127 /**
27128 * @private add a recognizer to the manager
27129 * existing recognizers with the same event name will be removed
27130 * @param {Recognizer} recognizer
27131 * @returns {Recognizer|Manager}
27132 */
27133
27134
27135 _proto.add = function add(recognizer) {
27136 if (invokeArrayArg(recognizer, "add", this)) {
27137 return this;
27138 } // remove existing
27139
27140
27141 var existing = this.get(recognizer.options.event);
27142
27143 if (existing) {
27144 this.remove(existing);
27145 }
27146
27147 this.recognizers.push(recognizer);
27148 recognizer.manager = this;
27149 this.touchAction.update();
27150 return recognizer;
27151 };
27152 /**
27153 * @private
27154 * remove a recognizer by name or instance
27155 * @param {Recognizer|String} recognizer
27156 * @returns {Manager}
27157 */
27158
27159
27160 _proto.remove = function remove(recognizer) {
27161 if (invokeArrayArg(recognizer, "remove", this)) {
27162 return this;
27163 }
27164
27165 var targetRecognizer = this.get(recognizer); // let's make sure this recognizer exists
27166
27167 if (recognizer) {
27168 var recognizers = this.recognizers;
27169 var index = inArray(recognizers, targetRecognizer);
27170
27171 if (index !== -1) {
27172 recognizers.splice(index, 1);
27173 this.touchAction.update();
27174 }
27175 }
27176
27177 return this;
27178 };
27179 /**
27180 * @private
27181 * bind event
27182 * @param {String} events
27183 * @param {Function} handler
27184 * @returns {EventEmitter} this
27185 */
27186
27187
27188 _proto.on = function on(events, handler) {
27189 if (events === undefined || handler === undefined) {
27190 return this;
27191 }
27192
27193 var handlers = this.handlers;
27194 each(splitStr(events), function (event) {
27195 handlers[event] = handlers[event] || [];
27196 handlers[event].push(handler);
27197 });
27198 return this;
27199 };
27200 /**
27201 * @private unbind event, leave emit blank to remove all handlers
27202 * @param {String} events
27203 * @param {Function} [handler]
27204 * @returns {EventEmitter} this
27205 */
27206
27207
27208 _proto.off = function off(events, handler) {
27209 if (events === undefined) {
27210 return this;
27211 }
27212
27213 var handlers = this.handlers;
27214 each(splitStr(events), function (event) {
27215 if (!handler) {
27216 delete handlers[event];
27217 } else {
27218 handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
27219 }
27220 });
27221 return this;
27222 };
27223 /**
27224 * @private emit event to the listeners
27225 * @param {String} event
27226 * @param {Object} data
27227 */
27228
27229
27230 _proto.emit = function emit(event, data) {
27231 // we also want to trigger dom events
27232 if (this.options.domEvents) {
27233 triggerDomEvent(event, data);
27234 } // no handlers, so skip it all
27235
27236
27237 var handlers = this.handlers[event] && this.handlers[event].slice();
27238
27239 if (!handlers || !handlers.length) {
27240 return;
27241 }
27242
27243 data.type = event;
27244
27245 data.preventDefault = function () {
27246 data.srcEvent.preventDefault();
27247 };
27248
27249 var i = 0;
27250
27251 while (i < handlers.length) {
27252 handlers[i](data);
27253 i++;
27254 }
27255 };
27256 /**
27257 * @private
27258 * destroy the manager and unbinds all events
27259 * it doesn't unbind dom events, that is the user own responsibility
27260 */
27261
27262
27263 _proto.destroy = function destroy() {
27264 this.element && toggleCssProps(this, false);
27265 this.handlers = {};
27266 this.session = {};
27267 this.input.destroy();
27268 this.element = null;
27269 };
27270
27271 return Manager;
27272}();
27273
27274var SINGLE_TOUCH_INPUT_MAP = {
27275 touchstart: INPUT_START,
27276 touchmove: INPUT_MOVE,
27277 touchend: INPUT_END,
27278 touchcancel: INPUT_CANCEL
27279};
27280var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
27281var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
27282/**
27283 * @private
27284 * Touch events input
27285 * @constructor
27286 * @extends Input
27287 */
27288
27289var SingleTouchInput =
27290/*#__PURE__*/
27291function (_Input) {
27292 _inheritsLoose(SingleTouchInput, _Input);
27293
27294 function SingleTouchInput() {
27295 var _this;
27296
27297 var proto = SingleTouchInput.prototype;
27298 proto.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
27299 proto.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
27300 _this = _Input.apply(this, arguments) || this;
27301 _this.started = false;
27302 return _this;
27303 }
27304
27305 var _proto = SingleTouchInput.prototype;
27306
27307 _proto.handler = function handler(ev) {
27308 var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events?
27309
27310 if (type === INPUT_START) {
27311 this.started = true;
27312 }
27313
27314 if (!this.started) {
27315 return;
27316 }
27317
27318 var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state
27319
27320 if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
27321 this.started = false;
27322 }
27323
27324 this.callback(this.manager, type, {
27325 pointers: touches[0],
27326 changedPointers: touches[1],
27327 pointerType: INPUT_TYPE_TOUCH,
27328 srcEvent: ev
27329 });
27330 };
27331
27332 return SingleTouchInput;
27333}(Input);
27334
27335function normalizeSingleTouches(ev, type) {
27336 var all = toArray$1(ev.touches);
27337 var changed = toArray$1(ev.changedTouches);
27338
27339 if (type & (INPUT_END | INPUT_CANCEL)) {
27340 all = uniqueArray(all.concat(changed), 'identifier', true);
27341 }
27342
27343 return [all, changed];
27344}
27345/**
27346 * @private
27347 * This recognizer is just used as a base for the simple attribute recognizers.
27348 * @constructor
27349 * @extends Recognizer
27350 */
27351
27352
27353var AttrRecognizer =
27354/*#__PURE__*/
27355function (_Recognizer) {
27356 _inheritsLoose(AttrRecognizer, _Recognizer);
27357
27358 function AttrRecognizer(options) {
27359 if (options === void 0) {
27360 options = {};
27361 }
27362
27363 return _Recognizer.call(this, _extends({
27364 pointers: 1
27365 }, options)) || this;
27366 }
27367 /**
27368 * @private
27369 * Used to check if it the recognizer receives valid input, like input.distance > 10.
27370 * @memberof AttrRecognizer
27371 * @param {Object} input
27372 * @returns {Boolean} recognized
27373 */
27374
27375
27376 var _proto = AttrRecognizer.prototype;
27377
27378 _proto.attrTest = function attrTest(input) {
27379 var optionPointers = this.options.pointers;
27380 return optionPointers === 0 || input.pointers.length === optionPointers;
27381 };
27382 /**
27383 * @private
27384 * Process the input and return the state for the recognizer
27385 * @memberof AttrRecognizer
27386 * @param {Object} input
27387 * @returns {*} State
27388 */
27389
27390
27391 _proto.process = function process(input) {
27392 var state = this.state;
27393 var eventType = input.eventType;
27394 var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
27395 var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED
27396
27397 if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
27398 return state | STATE_CANCELLED;
27399 } else if (isRecognized || isValid) {
27400 if (eventType & INPUT_END) {
27401 return state | STATE_ENDED;
27402 } else if (!(state & STATE_BEGAN)) {
27403 return STATE_BEGAN;
27404 }
27405
27406 return state | STATE_CHANGED;
27407 }
27408
27409 return STATE_FAILED;
27410 };
27411
27412 return AttrRecognizer;
27413}(Recognizer);
27414/**
27415 * @private
27416 * A tap is recognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
27417 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
27418 * a single tap.
27419 *
27420 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
27421 * multi-taps being recognized.
27422 * @constructor
27423 * @extends Recognizer
27424 */
27425
27426
27427var TapRecognizer =
27428/*#__PURE__*/
27429function (_Recognizer) {
27430 _inheritsLoose(TapRecognizer, _Recognizer);
27431
27432 function TapRecognizer(options) {
27433 var _this;
27434
27435 if (options === void 0) {
27436 options = {};
27437 }
27438
27439 _this = _Recognizer.call(this, _extends({
27440 event: 'tap',
27441 pointers: 1,
27442 taps: 1,
27443 interval: 300,
27444 // max time between the multi-tap taps
27445 time: 250,
27446 // max time of the pointer to be down (like finger on the screen)
27447 threshold: 9,
27448 // a minimal movement is ok, but keep it low
27449 posThreshold: 10
27450 }, options)) || this; // previous time and center,
27451 // used for tap counting
27452
27453 _this.pTime = false;
27454 _this.pCenter = false;
27455 _this._timer = null;
27456 _this._input = null;
27457 _this.count = 0;
27458 return _this;
27459 }
27460
27461 var _proto = TapRecognizer.prototype;
27462
27463 _proto.getTouchAction = function getTouchAction() {
27464 return [TOUCH_ACTION_MANIPULATION];
27465 };
27466
27467 _proto.process = function process(input) {
27468 var _this2 = this;
27469
27470 var options = this.options;
27471 var validPointers = input.pointers.length === options.pointers;
27472 var validMovement = input.distance < options.threshold;
27473 var validTouchTime = input.deltaTime < options.time;
27474 this.reset();
27475
27476 if (input.eventType & INPUT_START && this.count === 0) {
27477 return this.failTimeout();
27478 } // we only allow little movement
27479 // and we've reached an end event, so a tap is possible
27480
27481
27482 if (validMovement && validTouchTime && validPointers) {
27483 if (input.eventType !== INPUT_END) {
27484 return this.failTimeout();
27485 }
27486
27487 var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
27488 var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
27489 this.pTime = input.timeStamp;
27490 this.pCenter = input.center;
27491
27492 if (!validMultiTap || !validInterval) {
27493 this.count = 1;
27494 } else {
27495 this.count += 1;
27496 }
27497
27498 this._input = input; // if tap count matches we have recognized it,
27499 // else it has began recognizing...
27500
27501 var tapCount = this.count % options.taps;
27502
27503 if (tapCount === 0) {
27504 // no failing requirements, immediately trigger the tap event
27505 // or wait as long as the multitap interval to trigger
27506 if (!this.hasRequireFailures()) {
27507 return STATE_RECOGNIZED;
27508 } else {
27509 this._timer = setTimeout(function () {
27510 _this2.state = STATE_RECOGNIZED;
27511
27512 _this2.tryEmit();
27513 }, options.interval);
27514 return STATE_BEGAN;
27515 }
27516 }
27517 }
27518
27519 return STATE_FAILED;
27520 };
27521
27522 _proto.failTimeout = function failTimeout() {
27523 var _this3 = this;
27524
27525 this._timer = setTimeout(function () {
27526 _this3.state = STATE_FAILED;
27527 }, this.options.interval);
27528 return STATE_FAILED;
27529 };
27530
27531 _proto.reset = function reset() {
27532 clearTimeout(this._timer);
27533 };
27534
27535 _proto.emit = function emit() {
27536 if (this.state === STATE_RECOGNIZED) {
27537 this._input.tapCount = this.count;
27538 this.manager.emit(this.options.event, this._input);
27539 }
27540 };
27541
27542 return TapRecognizer;
27543}(Recognizer);
27544/**
27545 * @private
27546 * direction cons to string
27547 * @param {constant} direction
27548 * @returns {String}
27549 */
27550
27551
27552function directionStr(direction) {
27553 if (direction === DIRECTION_DOWN) {
27554 return 'down';
27555 } else if (direction === DIRECTION_UP) {
27556 return 'up';
27557 } else if (direction === DIRECTION_LEFT) {
27558 return 'left';
27559 } else if (direction === DIRECTION_RIGHT) {
27560 return 'right';
27561 }
27562
27563 return '';
27564}
27565/**
27566 * @private
27567 * Pan
27568 * Recognized when the pointer is down and moved in the allowed direction.
27569 * @constructor
27570 * @extends AttrRecognizer
27571 */
27572
27573
27574var PanRecognizer =
27575/*#__PURE__*/
27576function (_AttrRecognizer) {
27577 _inheritsLoose(PanRecognizer, _AttrRecognizer);
27578
27579 function PanRecognizer(options) {
27580 var _this;
27581
27582 if (options === void 0) {
27583 options = {};
27584 }
27585
27586 _this = _AttrRecognizer.call(this, _extends({
27587 event: 'pan',
27588 threshold: 10,
27589 pointers: 1,
27590 direction: DIRECTION_ALL
27591 }, options)) || this;
27592 _this.pX = null;
27593 _this.pY = null;
27594 return _this;
27595 }
27596
27597 var _proto = PanRecognizer.prototype;
27598
27599 _proto.getTouchAction = function getTouchAction() {
27600 var direction = this.options.direction;
27601 var actions = [];
27602
27603 if (direction & DIRECTION_HORIZONTAL) {
27604 actions.push(TOUCH_ACTION_PAN_Y);
27605 }
27606
27607 if (direction & DIRECTION_VERTICAL) {
27608 actions.push(TOUCH_ACTION_PAN_X);
27609 }
27610
27611 return actions;
27612 };
27613
27614 _proto.directionTest = function directionTest(input) {
27615 var options = this.options;
27616 var hasMoved = true;
27617 var distance = input.distance;
27618 var direction = input.direction;
27619 var x = input.deltaX;
27620 var y = input.deltaY; // lock to axis?
27621
27622 if (!(direction & options.direction)) {
27623 if (options.direction & DIRECTION_HORIZONTAL) {
27624 direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
27625 hasMoved = x !== this.pX;
27626 distance = Math.abs(input.deltaX);
27627 } else {
27628 direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
27629 hasMoved = y !== this.pY;
27630 distance = Math.abs(input.deltaY);
27631 }
27632 }
27633
27634 input.direction = direction;
27635 return hasMoved && distance > options.threshold && direction & options.direction;
27636 };
27637
27638 _proto.attrTest = function attrTest(input) {
27639 return AttrRecognizer.prototype.attrTest.call(this, input) && ( // replace with a super call
27640 this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
27641 };
27642
27643 _proto.emit = function emit(input) {
27644 this.pX = input.deltaX;
27645 this.pY = input.deltaY;
27646 var direction = directionStr(input.direction);
27647
27648 if (direction) {
27649 input.additionalEvent = this.options.event + direction;
27650 }
27651
27652 _AttrRecognizer.prototype.emit.call(this, input);
27653 };
27654
27655 return PanRecognizer;
27656}(AttrRecognizer);
27657/**
27658 * @private
27659 * Swipe
27660 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
27661 * @constructor
27662 * @extends AttrRecognizer
27663 */
27664
27665
27666var SwipeRecognizer =
27667/*#__PURE__*/
27668function (_AttrRecognizer) {
27669 _inheritsLoose(SwipeRecognizer, _AttrRecognizer);
27670
27671 function SwipeRecognizer(options) {
27672 if (options === void 0) {
27673 options = {};
27674 }
27675
27676 return _AttrRecognizer.call(this, _extends({
27677 event: 'swipe',
27678 threshold: 10,
27679 velocity: 0.3,
27680 direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
27681 pointers: 1
27682 }, options)) || this;
27683 }
27684
27685 var _proto = SwipeRecognizer.prototype;
27686
27687 _proto.getTouchAction = function getTouchAction() {
27688 return PanRecognizer.prototype.getTouchAction.call(this);
27689 };
27690
27691 _proto.attrTest = function attrTest(input) {
27692 var direction = this.options.direction;
27693 var velocity;
27694
27695 if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
27696 velocity = input.overallVelocity;
27697 } else if (direction & DIRECTION_HORIZONTAL) {
27698 velocity = input.overallVelocityX;
27699 } else if (direction & DIRECTION_VERTICAL) {
27700 velocity = input.overallVelocityY;
27701 }
27702
27703 return _AttrRecognizer.prototype.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers === this.options.pointers && abs$1(velocity) > this.options.velocity && input.eventType & INPUT_END;
27704 };
27705
27706 _proto.emit = function emit(input) {
27707 var direction = directionStr(input.offsetDirection);
27708
27709 if (direction) {
27710 this.manager.emit(this.options.event + direction, input);
27711 }
27712
27713 this.manager.emit(this.options.event, input);
27714 };
27715
27716 return SwipeRecognizer;
27717}(AttrRecognizer);
27718/**
27719 * @private
27720 * Pinch
27721 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
27722 * @constructor
27723 * @extends AttrRecognizer
27724 */
27725
27726
27727var PinchRecognizer =
27728/*#__PURE__*/
27729function (_AttrRecognizer) {
27730 _inheritsLoose(PinchRecognizer, _AttrRecognizer);
27731
27732 function PinchRecognizer(options) {
27733 if (options === void 0) {
27734 options = {};
27735 }
27736
27737 return _AttrRecognizer.call(this, _extends({
27738 event: 'pinch',
27739 threshold: 0,
27740 pointers: 2
27741 }, options)) || this;
27742 }
27743
27744 var _proto = PinchRecognizer.prototype;
27745
27746 _proto.getTouchAction = function getTouchAction() {
27747 return [TOUCH_ACTION_NONE];
27748 };
27749
27750 _proto.attrTest = function attrTest(input) {
27751 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
27752 };
27753
27754 _proto.emit = function emit(input) {
27755 if (input.scale !== 1) {
27756 var inOut = input.scale < 1 ? 'in' : 'out';
27757 input.additionalEvent = this.options.event + inOut;
27758 }
27759
27760 _AttrRecognizer.prototype.emit.call(this, input);
27761 };
27762
27763 return PinchRecognizer;
27764}(AttrRecognizer);
27765/**
27766 * @private
27767 * Rotate
27768 * Recognized when two or more pointer are moving in a circular motion.
27769 * @constructor
27770 * @extends AttrRecognizer
27771 */
27772
27773
27774var RotateRecognizer =
27775/*#__PURE__*/
27776function (_AttrRecognizer) {
27777 _inheritsLoose(RotateRecognizer, _AttrRecognizer);
27778
27779 function RotateRecognizer(options) {
27780 if (options === void 0) {
27781 options = {};
27782 }
27783
27784 return _AttrRecognizer.call(this, _extends({
27785 event: 'rotate',
27786 threshold: 0,
27787 pointers: 2
27788 }, options)) || this;
27789 }
27790
27791 var _proto = RotateRecognizer.prototype;
27792
27793 _proto.getTouchAction = function getTouchAction() {
27794 return [TOUCH_ACTION_NONE];
27795 };
27796
27797 _proto.attrTest = function attrTest(input) {
27798 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
27799 };
27800
27801 return RotateRecognizer;
27802}(AttrRecognizer);
27803/**
27804 * @private
27805 * Press
27806 * Recognized when the pointer is down for x ms without any movement.
27807 * @constructor
27808 * @extends Recognizer
27809 */
27810
27811
27812var PressRecognizer =
27813/*#__PURE__*/
27814function (_Recognizer) {
27815 _inheritsLoose(PressRecognizer, _Recognizer);
27816
27817 function PressRecognizer(options) {
27818 var _this;
27819
27820 if (options === void 0) {
27821 options = {};
27822 }
27823
27824 _this = _Recognizer.call(this, _extends({
27825 event: 'press',
27826 pointers: 1,
27827 time: 251,
27828 // minimal time of the pointer to be pressed
27829 threshold: 9
27830 }, options)) || this;
27831 _this._timer = null;
27832 _this._input = null;
27833 return _this;
27834 }
27835
27836 var _proto = PressRecognizer.prototype;
27837
27838 _proto.getTouchAction = function getTouchAction() {
27839 return [TOUCH_ACTION_AUTO];
27840 };
27841
27842 _proto.process = function process(input) {
27843 var _this2 = this;
27844
27845 var options = this.options;
27846 var validPointers = input.pointers.length === options.pointers;
27847 var validMovement = input.distance < options.threshold;
27848 var validTime = input.deltaTime > options.time;
27849 this._input = input; // we only allow little movement
27850 // and we've reached an end event, so a tap is possible
27851
27852 if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
27853 this.reset();
27854 } else if (input.eventType & INPUT_START) {
27855 this.reset();
27856 this._timer = setTimeout(function () {
27857 _this2.state = STATE_RECOGNIZED;
27858
27859 _this2.tryEmit();
27860 }, options.time);
27861 } else if (input.eventType & INPUT_END) {
27862 return STATE_RECOGNIZED;
27863 }
27864
27865 return STATE_FAILED;
27866 };
27867
27868 _proto.reset = function reset() {
27869 clearTimeout(this._timer);
27870 };
27871
27872 _proto.emit = function emit(input) {
27873 if (this.state !== STATE_RECOGNIZED) {
27874 return;
27875 }
27876
27877 if (input && input.eventType & INPUT_END) {
27878 this.manager.emit(this.options.event + "up", input);
27879 } else {
27880 this._input.timeStamp = now();
27881 this.manager.emit(this.options.event, this._input);
27882 }
27883 };
27884
27885 return PressRecognizer;
27886}(Recognizer);
27887/**
27888 * @private
27889 * wrap a method with a deprecation warning and stack trace
27890 * @param {Function} method
27891 * @param {String} name
27892 * @param {String} message
27893 * @returns {Function} A new function wrapping the supplied method.
27894 */
27895
27896
27897function deprecate(method, name, message) {
27898 var deprecationMessage = "DEPRECATED METHOD: " + name + "\n" + message + " AT \n";
27899 return function () {
27900 var e = new Error('get-stack-trace');
27901 var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
27902 var log = window.console && (window.console.warn || window.console.log);
27903
27904 if (log) {
27905 log.call(window.console, deprecationMessage, stack);
27906 }
27907
27908 return method.apply(this, arguments);
27909 };
27910}
27911/**
27912 * @private
27913 * extend object.
27914 * means that properties in dest will be overwritten by the ones in src.
27915 * @param {Object} dest
27916 * @param {Object} src
27917 * @param {Boolean} [merge=false]
27918 * @returns {Object} dest
27919 */
27920
27921
27922var extend$1 = deprecate(function (dest, src, merge) {
27923 var keys = Object.keys(src);
27924 var i = 0;
27925
27926 while (i < keys.length) {
27927 if (!merge || merge && dest[keys[i]] === undefined) {
27928 dest[keys[i]] = src[keys[i]];
27929 }
27930
27931 i++;
27932 }
27933
27934 return dest;
27935}, 'extend', 'Use `assign`.');
27936/**
27937 * @private
27938 * merge the values from src in the dest.
27939 * means that properties that exist in dest will not be overwritten by src
27940 * @param {Object} dest
27941 * @param {Object} src
27942 * @returns {Object} dest
27943 */
27944
27945var merge = deprecate(function (dest, src) {
27946 return extend$1(dest, src, true);
27947}, 'merge', 'Use `assign`.');
27948/**
27949 * @private
27950 * simple class inheritance
27951 * @param {Function} child
27952 * @param {Function} base
27953 * @param {Object} [properties]
27954 */
27955
27956function inherit(child, base, properties) {
27957 var baseP = base.prototype;
27958 var childP;
27959 childP = child.prototype = Object.create(baseP);
27960 childP.constructor = child;
27961 childP._super = baseP;
27962
27963 if (properties) {
27964 assign$1(childP, properties);
27965 }
27966}
27967/**
27968 * @private
27969 * simple function bind
27970 * @param {Function} fn
27971 * @param {Object} context
27972 * @returns {Function}
27973 */
27974
27975
27976function bindFn(fn, context) {
27977 return function boundFn() {
27978 return fn.apply(context, arguments);
27979 };
27980}
27981/**
27982 * @private
27983 * Simple way to create a manager with a default set of recognizers.
27984 * @param {HTMLElement} element
27985 * @param {Object} [options]
27986 * @constructor
27987 */
27988
27989
27990var Hammer =
27991/*#__PURE__*/
27992function () {
27993 var Hammer =
27994 /**
27995 * @private
27996 * @const {string}
27997 */
27998 function Hammer(element, options) {
27999 if (options === void 0) {
28000 options = {};
28001 }
28002
28003 return new Manager(element, _extends({
28004 recognizers: [// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
28005 [RotateRecognizer, {
28006 enable: false
28007 }], [PinchRecognizer, {
28008 enable: false
28009 }, ['rotate']], [SwipeRecognizer, {
28010 direction: DIRECTION_HORIZONTAL
28011 }], [PanRecognizer, {
28012 direction: DIRECTION_HORIZONTAL
28013 }, ['swipe']], [TapRecognizer], [TapRecognizer, {
28014 event: 'doubletap',
28015 taps: 2
28016 }, ['tap']], [PressRecognizer]]
28017 }, options));
28018 };
28019
28020 Hammer.VERSION = "2.0.15";
28021 Hammer.DIRECTION_ALL = DIRECTION_ALL;
28022 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
28023 Hammer.DIRECTION_LEFT = DIRECTION_LEFT;
28024 Hammer.DIRECTION_RIGHT = DIRECTION_RIGHT;
28025 Hammer.DIRECTION_UP = DIRECTION_UP;
28026 Hammer.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL;
28027 Hammer.DIRECTION_VERTICAL = DIRECTION_VERTICAL;
28028 Hammer.DIRECTION_NONE = DIRECTION_NONE;
28029 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
28030 Hammer.INPUT_START = INPUT_START;
28031 Hammer.INPUT_MOVE = INPUT_MOVE;
28032 Hammer.INPUT_END = INPUT_END;
28033 Hammer.INPUT_CANCEL = INPUT_CANCEL;
28034 Hammer.STATE_POSSIBLE = STATE_POSSIBLE;
28035 Hammer.STATE_BEGAN = STATE_BEGAN;
28036 Hammer.STATE_CHANGED = STATE_CHANGED;
28037 Hammer.STATE_ENDED = STATE_ENDED;
28038 Hammer.STATE_RECOGNIZED = STATE_RECOGNIZED;
28039 Hammer.STATE_CANCELLED = STATE_CANCELLED;
28040 Hammer.STATE_FAILED = STATE_FAILED;
28041 Hammer.Manager = Manager;
28042 Hammer.Input = Input;
28043 Hammer.TouchAction = TouchAction;
28044 Hammer.TouchInput = TouchInput;
28045 Hammer.MouseInput = MouseInput;
28046 Hammer.PointerEventInput = PointerEventInput;
28047 Hammer.TouchMouseInput = TouchMouseInput;
28048 Hammer.SingleTouchInput = SingleTouchInput;
28049 Hammer.Recognizer = Recognizer;
28050 Hammer.AttrRecognizer = AttrRecognizer;
28051 Hammer.Tap = TapRecognizer;
28052 Hammer.Pan = PanRecognizer;
28053 Hammer.Swipe = SwipeRecognizer;
28054 Hammer.Pinch = PinchRecognizer;
28055 Hammer.Rotate = RotateRecognizer;
28056 Hammer.Press = PressRecognizer;
28057 Hammer.on = addEventListeners;
28058 Hammer.off = removeEventListeners;
28059 Hammer.each = each;
28060 Hammer.merge = merge;
28061 Hammer.extend = extend$1;
28062 Hammer.bindFn = bindFn;
28063 Hammer.assign = assign$1;
28064 Hammer.inherit = inherit;
28065 Hammer.bindFn = bindFn;
28066 Hammer.prefixed = prefixed;
28067 Hammer.toArray = toArray$1;
28068 Hammer.inArray = inArray;
28069 Hammer.uniqueArray = uniqueArray;
28070 Hammer.splitStr = splitStr;
28071 Hammer.boolOrFn = boolOrFn;
28072 Hammer.hasParent = hasParent$1;
28073 Hammer.addEventListeners = addEventListeners;
28074 Hammer.removeEventListeners = removeEventListeners;
28075 Hammer.defaults = defaults;
28076 return Hammer;
28077}();
28078
28079/**
28080 * Setup a mock hammer.js object, for unit testing.
28081 *
28082 * Inspiration: https://github.com/uber/deck.gl/pull/658
28083 *
28084 * @returns {{on: noop, off: noop, destroy: noop, emit: noop, get: get}}
28085 */
28086
28087function hammerMock() {
28088 var noop = function noop() {};
28089
28090 return {
28091 on: noop,
28092 off: noop,
28093 destroy: noop,
28094 emit: noop,
28095 get: function get(m) {
28096 //eslint-disable-line no-unused-vars
28097 return {
28098 set: noop
28099 };
28100 }
28101 };
28102}
28103
28104var modifiedHammer;
28105
28106if (typeof window !== 'undefined') {
28107 var OurHammer = window['Hammer'] || Hammer;
28108 modifiedHammer = propagating(OurHammer, {
28109 preventDefault: 'mouse'
28110 });
28111} else {
28112 modifiedHammer = function modifiedHammer() {
28113 return (// hammer.js is only available in a browser, not in node.js. Replacing it with a mock object.
28114 hammerMock()
28115 );
28116 };
28117}
28118
28119var Hammer$1 = modifiedHammer;
28120
28121/**
28122 * Register a touch event, taking place before a gesture
28123 * @param {Hammer} hammer A hammer instance
28124 * @param {function} callback Callback, called as callback(event)
28125 */
28126function onTouch(hammer, callback) {
28127 callback.inputHandler = function (event) {
28128 if (event.isFirst) {
28129 callback(event);
28130 }
28131 };
28132
28133 hammer.on('hammer.input', callback.inputHandler);
28134}
28135/**
28136 * Register a release event, taking place after a gesture
28137 * @param {Hammer} hammer A hammer instance
28138 * @param {function} callback Callback, called as callback(event)
28139 * @returns {*}
28140 */
28141
28142function onRelease(hammer, callback) {
28143 callback.inputHandler = function (event) {
28144 if (event.isFinal) {
28145 callback(event);
28146 }
28147 };
28148
28149 return hammer.on('hammer.input', callback.inputHandler);
28150}
28151/**
28152 * Hack the PinchRecognizer such that it doesn't prevent default behavior
28153 * for vertical panning.
28154 *
28155 * Yeah ... this is quite a hack ... see https://github.com/hammerjs/hammer.js/issues/932
28156 *
28157 * @param {Hammer.Pinch} pinchRecognizer
28158 * @return {Hammer.Pinch} returns the pinchRecognizer
28159 */
28160
28161function disablePreventDefaultVertically(pinchRecognizer) {
28162 var TOUCH_ACTION_PAN_Y = 'pan-y';
28163
28164 pinchRecognizer.getTouchAction = function () {
28165 // default method returns [TOUCH_ACTION_NONE]
28166 return [TOUCH_ACTION_PAN_Y];
28167 };
28168
28169 return pinchRecognizer;
28170}
28171
28172/**
28173 * The class TimeStep is an iterator for dates. You provide a start date and an
28174 * end date. The class itself determines the best scale (step size) based on the
28175 * provided start Date, end Date, and minimumStep.
28176 *
28177 * If minimumStep is provided, the step size is chosen as close as possible
28178 * to the minimumStep but larger than minimumStep. If minimumStep is not
28179 * provided, the scale is set to 1 DAY.
28180 * The minimumStep should correspond with the onscreen size of about 6 characters
28181 *
28182 * Alternatively, you can set a scale by hand.
28183 * After creation, you can initialize the class by executing first(). Then you
28184 * can iterate from the start date to the end date via next(). You can check if
28185 * the end date is reached with the function hasNext(). After each step, you can
28186 * retrieve the current date via getCurrent().
28187 * The TimeStep has scales ranging from milliseconds, seconds, minutes, hours,
28188 * days, to years.
28189 *
28190 * Version: 1.2
28191 *
28192 */
28193
28194var TimeStep =
28195/*#__PURE__*/
28196function () {
28197 /**
28198 * @param {Date} [start] The start date, for example new Date(2010, 9, 21)
28199 * or new Date(2010, 9, 21, 23, 45, 00)
28200 * @param {Date} [end] The end date
28201 * @param {number} [minimumStep] Optional. Minimum step size in milliseconds
28202 * @param {Date|Array.<Date>} [hiddenDates] Optional.
28203 * @param {{showMajorLabels: boolean}} [options] Optional.
28204 * @constructor TimeStep
28205 */
28206 function TimeStep(start, end, minimumStep, hiddenDates, options) {
28207 _classCallCheck(this, TimeStep);
28208
28209 this.moment = moment$3; // variables
28210
28211 this.current = this.moment();
28212 this._start = this.moment();
28213 this._end = this.moment();
28214 this.autoScale = true;
28215 this.scale = 'day';
28216 this.step = 1; // initialize the range
28217
28218 this.setRange(start, end, minimumStep); // hidden Dates options
28219
28220 this.switchedDay = false;
28221 this.switchedMonth = false;
28222 this.switchedYear = false;
28223
28224 if (Array.isArray(hiddenDates)) {
28225 this.hiddenDates = hiddenDates;
28226 } else if (hiddenDates != undefined) {
28227 this.hiddenDates = [hiddenDates];
28228 } else {
28229 this.hiddenDates = [];
28230 }
28231
28232 this.format = TimeStep.FORMAT; // default formatting
28233
28234 this.options = options ? options : {};
28235 }
28236 /**
28237 * Set custom constructor function for moment. Can be used to set dates
28238 * to UTC or to set a utcOffset.
28239 * @param {function} moment
28240 */
28241
28242
28243 _createClass(TimeStep, [{
28244 key: "setMoment",
28245 value: function setMoment(moment) {
28246 this.moment = moment; // update the date properties, can have a new utcOffset
28247
28248 this.current = this.moment(this.current.valueOf());
28249 this._start = this.moment(this._start.valueOf());
28250 this._end = this.moment(this._end.valueOf());
28251 }
28252 /**
28253 * Set custom formatting for the minor an major labels of the TimeStep.
28254 * Both `minorLabels` and `majorLabels` are an Object with properties:
28255 * 'millisecond', 'second', 'minute', 'hour', 'weekday', 'day', 'week', 'month', 'year'.
28256 * @param {{minorLabels: Object, majorLabels: Object}} format
28257 */
28258
28259 }, {
28260 key: "setFormat",
28261 value: function setFormat(format) {
28262 var defaultFormat = util.deepExtend({}, TimeStep.FORMAT);
28263 this.format = util.deepExtend(defaultFormat, format);
28264 }
28265 /**
28266 * Set a new range
28267 * If minimumStep is provided, the step size is chosen as close as possible
28268 * to the minimumStep but larger than minimumStep. If minimumStep is not
28269 * provided, the scale is set to 1 DAY.
28270 * The minimumStep should correspond with the onscreen size of about 6 characters
28271 * @param {Date} [start] The start date and time.
28272 * @param {Date} [end] The end date and time.
28273 * @param {int} [minimumStep] Optional. Minimum step size in milliseconds
28274 */
28275
28276 }, {
28277 key: "setRange",
28278 value: function setRange(start, end, minimumStep) {
28279 if (!(start instanceof Date) || !(end instanceof Date)) {
28280 throw "No legal start or end date in method setRange";
28281 }
28282
28283 this._start = start != undefined ? this.moment(start.valueOf()) : Date.now();
28284 this._end = end != undefined ? this.moment(end.valueOf()) : Date.now();
28285
28286 if (this.autoScale) {
28287 this.setMinimumStep(minimumStep);
28288 }
28289 }
28290 /**
28291 * Set the range iterator to the start date.
28292 */
28293
28294 }, {
28295 key: "start",
28296 value: function start() {
28297 this.current = this._start.clone();
28298 this.roundToMinor();
28299 }
28300 /**
28301 * Round the current date to the first minor date value
28302 * This must be executed once when the current date is set to start Date
28303 */
28304
28305 }, {
28306 key: "roundToMinor",
28307 value: function roundToMinor() {
28308 // round to floor
28309 // to prevent year & month scales rounding down to the first day of week we perform this separately
28310 if (this.scale == 'week') {
28311 this.current.weekday(0);
28312 } // IMPORTANT: we have no breaks in this switch! (this is no bug)
28313 // noinspection FallThroughInSwitchStatementJS
28314
28315
28316 switch (this.scale) {
28317 case 'year':
28318 this.current.year(this.step * Math.floor(this.current.year() / this.step));
28319 this.current.month(0);
28320
28321 case 'month':
28322 this.current.date(1);
28323 // eslint-disable-line no-fallthrough
28324
28325 case 'week': // eslint-disable-line no-fallthrough
28326
28327 case 'day': // eslint-disable-line no-fallthrough
28328
28329 case 'weekday':
28330 this.current.hours(0);
28331 // eslint-disable-line no-fallthrough
28332
28333 case 'hour':
28334 this.current.minutes(0);
28335 // eslint-disable-line no-fallthrough
28336
28337 case 'minute':
28338 this.current.seconds(0);
28339 // eslint-disable-line no-fallthrough
28340
28341 case 'second':
28342 this.current.milliseconds(0);
28343 // eslint-disable-line no-fallthrough
28344 //case 'millisecond': // nothing to do for milliseconds
28345 }
28346
28347 if (this.step != 1) {
28348 // round down to the first minor value that is a multiple of the current step size
28349 var priorCurrent = this.current.clone();
28350
28351 switch (this.scale) {
28352 case 'millisecond':
28353 this.current.subtract(this.current.milliseconds() % this.step, 'milliseconds');
28354 break;
28355
28356 case 'second':
28357 this.current.subtract(this.current.seconds() % this.step, 'seconds');
28358 break;
28359
28360 case 'minute':
28361 this.current.subtract(this.current.minutes() % this.step, 'minutes');
28362 break;
28363
28364 case 'hour':
28365 this.current.subtract(this.current.hours() % this.step, 'hours');
28366 break;
28367
28368 case 'weekday': // intentional fall through
28369
28370 case 'day':
28371 this.current.subtract((this.current.date() - 1) % this.step, 'day');
28372 break;
28373
28374 case 'week':
28375 this.current.subtract(this.current.week() % this.step, 'week');
28376 break;
28377
28378 case 'month':
28379 this.current.subtract(this.current.month() % this.step, 'month');
28380 break;
28381
28382 case 'year':
28383 this.current.subtract(this.current.year() % this.step, 'year');
28384 break;
28385
28386 default:
28387 break;
28388 }
28389
28390 if (!priorCurrent.isSame(this.current)) {
28391 this.current = moment$3(snapAwayFromHidden(this.hiddenDates, this.current.valueOf(), -1, true));
28392 }
28393 }
28394 }
28395 /**
28396 * Check if the there is a next step
28397 * @return {boolean} true if the current date has not passed the end date
28398 */
28399
28400 }, {
28401 key: "hasNext",
28402 value: function hasNext() {
28403 return this.current.valueOf() <= this._end.valueOf();
28404 }
28405 /**
28406 * Do the next step
28407 */
28408
28409 }, {
28410 key: "next",
28411 value: function next() {
28412 var prev = this.current.valueOf(); // Two cases, needed to prevent issues with switching daylight savings
28413 // (end of March and end of October)
28414
28415 switch (this.scale) {
28416 case 'millisecond':
28417 this.current.add(this.step, 'millisecond');
28418 break;
28419
28420 case 'second':
28421 this.current.add(this.step, 'second');
28422 break;
28423
28424 case 'minute':
28425 this.current.add(this.step, 'minute');
28426 break;
28427
28428 case 'hour':
28429 this.current.add(this.step, 'hour');
28430
28431 if (this.current.month() < 6) {
28432 this.current.subtract(this.current.hours() % this.step, 'hour');
28433 } else {
28434 if (this.current.hours() % this.step !== 0) {
28435 this.current.add(this.step - this.current.hours() % this.step, 'hour');
28436 }
28437 }
28438
28439 break;
28440
28441 case 'weekday': // intentional fall through
28442
28443 case 'day':
28444 this.current.add(this.step, 'day');
28445 break;
28446
28447 case 'week':
28448 if (this.current.weekday() !== 0) {
28449 // we had a month break not correlating with a week's start before
28450 this.current.weekday(0); // switch back to week cycles
28451
28452 this.current.add(this.step, 'week');
28453 } else if (this.options.showMajorLabels === false) {
28454 this.current.add(this.step, 'week'); // the default case
28455 } else {
28456 // first day of the week
28457 var nextWeek = this.current.clone();
28458 nextWeek.add(1, 'week');
28459
28460 if (nextWeek.isSame(this.current, 'month')) {
28461 // is the first day of the next week in the same month?
28462 this.current.add(this.step, 'week'); // the default case
28463 } else {
28464 // inject a step at each first day of the month
28465 this.current.add(this.step, 'week');
28466 this.current.date(1);
28467 }
28468 }
28469
28470 break;
28471
28472 case 'month':
28473 this.current.add(this.step, 'month');
28474 break;
28475
28476 case 'year':
28477 this.current.add(this.step, 'year');
28478 break;
28479
28480 default:
28481 break;
28482 }
28483
28484 if (this.step != 1) {
28485 // round down to the correct major value
28486 switch (this.scale) {
28487 case 'millisecond':
28488 if (this.current.milliseconds() > 0 && this.current.milliseconds() < this.step) this.current.milliseconds(0);
28489 break;
28490
28491 case 'second':
28492 if (this.current.seconds() > 0 && this.current.seconds() < this.step) this.current.seconds(0);
28493 break;
28494
28495 case 'minute':
28496 if (this.current.minutes() > 0 && this.current.minutes() < this.step) this.current.minutes(0);
28497 break;
28498
28499 case 'hour':
28500 if (this.current.hours() > 0 && this.current.hours() < this.step) this.current.hours(0);
28501 break;
28502
28503 case 'weekday': // intentional fall through
28504
28505 case 'day':
28506 if (this.current.date() < this.step + 1) this.current.date(1);
28507 break;
28508
28509 case 'week':
28510 if (this.current.week() < this.step) this.current.week(1);
28511 break;
28512 // week numbering starts at 1, not 0
28513
28514 case 'month':
28515 if (this.current.month() < this.step) this.current.month(0);
28516 break;
28517
28518 case 'year':
28519 break;
28520 // nothing to do for year
28521
28522 default:
28523 break;
28524 }
28525 } // safety mechanism: if current time is still unchanged, move to the end
28526
28527
28528 if (this.current.valueOf() == prev) {
28529 this.current = this._end.clone();
28530 } // Reset switches for year, month and day. Will get set to true where appropriate in DateUtil.stepOverHiddenDates
28531
28532
28533 this.switchedDay = false;
28534 this.switchedMonth = false;
28535 this.switchedYear = false;
28536 stepOverHiddenDates(this.moment, this, prev);
28537 }
28538 /**
28539 * Get the current datetime
28540 * @return {Moment} current The current date
28541 */
28542
28543 }, {
28544 key: "getCurrent",
28545 value: function getCurrent() {
28546 return this.current.clone();
28547 }
28548 /**
28549 * Set a custom scale. Autoscaling will be disabled.
28550 * For example setScale('minute', 5) will result
28551 * in minor steps of 5 minutes, and major steps of an hour.
28552 *
28553 * @param {{scale: string, step: number}} params
28554 * An object containing two properties:
28555 * - A string 'scale'. Choose from 'millisecond', 'second',
28556 * 'minute', 'hour', 'weekday', 'day', 'week', 'month', 'year'.
28557 * - A number 'step'. A step size, by default 1.
28558 * Choose for example 1, 2, 5, or 10.
28559 */
28560
28561 }, {
28562 key: "setScale",
28563 value: function setScale(params) {
28564 if (params && typeof params.scale == 'string') {
28565 this.scale = params.scale;
28566 this.step = params.step > 0 ? params.step : 1;
28567 this.autoScale = false;
28568 }
28569 }
28570 /**
28571 * Enable or disable autoscaling
28572 * @param {boolean} enable If true, autoascaling is set true
28573 */
28574
28575 }, {
28576 key: "setAutoScale",
28577 value: function setAutoScale(enable) {
28578 this.autoScale = enable;
28579 }
28580 /**
28581 * Automatically determine the scale that bests fits the provided minimum step
28582 * @param {number} [minimumStep] The minimum step size in milliseconds
28583 */
28584
28585 }, {
28586 key: "setMinimumStep",
28587 value: function setMinimumStep(minimumStep) {
28588 if (minimumStep == undefined) {
28589 return;
28590 } //var b = asc + ds;
28591
28592
28593 var stepYear = 1000 * 60 * 60 * 24 * 30 * 12;
28594 var stepMonth = 1000 * 60 * 60 * 24 * 30;
28595 var stepDay = 1000 * 60 * 60 * 24;
28596 var stepHour = 1000 * 60 * 60;
28597 var stepMinute = 1000 * 60;
28598 var stepSecond = 1000;
28599 var stepMillisecond = 1; // find the smallest step that is larger than the provided minimumStep
28600
28601 if (stepYear * 1000 > minimumStep) {
28602 this.scale = 'year';
28603 this.step = 1000;
28604 }
28605
28606 if (stepYear * 500 > minimumStep) {
28607 this.scale = 'year';
28608 this.step = 500;
28609 }
28610
28611 if (stepYear * 100 > minimumStep) {
28612 this.scale = 'year';
28613 this.step = 100;
28614 }
28615
28616 if (stepYear * 50 > minimumStep) {
28617 this.scale = 'year';
28618 this.step = 50;
28619 }
28620
28621 if (stepYear * 10 > minimumStep) {
28622 this.scale = 'year';
28623 this.step = 10;
28624 }
28625
28626 if (stepYear * 5 > minimumStep) {
28627 this.scale = 'year';
28628 this.step = 5;
28629 }
28630
28631 if (stepYear > minimumStep) {
28632 this.scale = 'year';
28633 this.step = 1;
28634 }
28635
28636 if (stepMonth * 3 > minimumStep) {
28637 this.scale = 'month';
28638 this.step = 3;
28639 }
28640
28641 if (stepMonth > minimumStep) {
28642 this.scale = 'month';
28643 this.step = 1;
28644 }
28645
28646 if (stepDay * 7 > minimumStep) {
28647 this.scale = 'week';
28648 this.step = 1;
28649 }
28650
28651 if (stepDay * 2 > minimumStep) {
28652 this.scale = 'day';
28653 this.step = 2;
28654 }
28655
28656 if (stepDay > minimumStep) {
28657 this.scale = 'day';
28658 this.step = 1;
28659 }
28660
28661 if (stepDay / 2 > minimumStep) {
28662 this.scale = 'weekday';
28663 this.step = 1;
28664 }
28665
28666 if (stepHour * 4 > minimumStep) {
28667 this.scale = 'hour';
28668 this.step = 4;
28669 }
28670
28671 if (stepHour > minimumStep) {
28672 this.scale = 'hour';
28673 this.step = 1;
28674 }
28675
28676 if (stepMinute * 15 > minimumStep) {
28677 this.scale = 'minute';
28678 this.step = 15;
28679 }
28680
28681 if (stepMinute * 10 > minimumStep) {
28682 this.scale = 'minute';
28683 this.step = 10;
28684 }
28685
28686 if (stepMinute * 5 > minimumStep) {
28687 this.scale = 'minute';
28688 this.step = 5;
28689 }
28690
28691 if (stepMinute > minimumStep) {
28692 this.scale = 'minute';
28693 this.step = 1;
28694 }
28695
28696 if (stepSecond * 15 > minimumStep) {
28697 this.scale = 'second';
28698 this.step = 15;
28699 }
28700
28701 if (stepSecond * 10 > minimumStep) {
28702 this.scale = 'second';
28703 this.step = 10;
28704 }
28705
28706 if (stepSecond * 5 > minimumStep) {
28707 this.scale = 'second';
28708 this.step = 5;
28709 }
28710
28711 if (stepSecond > minimumStep) {
28712 this.scale = 'second';
28713 this.step = 1;
28714 }
28715
28716 if (stepMillisecond * 200 > minimumStep) {
28717 this.scale = 'millisecond';
28718 this.step = 200;
28719 }
28720
28721 if (stepMillisecond * 100 > minimumStep) {
28722 this.scale = 'millisecond';
28723 this.step = 100;
28724 }
28725
28726 if (stepMillisecond * 50 > minimumStep) {
28727 this.scale = 'millisecond';
28728 this.step = 50;
28729 }
28730
28731 if (stepMillisecond * 10 > minimumStep) {
28732 this.scale = 'millisecond';
28733 this.step = 10;
28734 }
28735
28736 if (stepMillisecond * 5 > minimumStep) {
28737 this.scale = 'millisecond';
28738 this.step = 5;
28739 }
28740
28741 if (stepMillisecond > minimumStep) {
28742 this.scale = 'millisecond';
28743 this.step = 1;
28744 }
28745 }
28746 /**
28747 * Snap a date to a rounded value.
28748 * The snap intervals are dependent on the current scale and step.
28749 * Static function
28750 * @param {Date} date the date to be snapped.
28751 * @param {string} scale Current scale, can be 'millisecond', 'second',
28752 * 'minute', 'hour', 'weekday, 'day', 'week', 'month', 'year'.
28753 * @param {number} step Current step (1, 2, 4, 5, ...
28754 * @return {Date} snappedDate
28755 */
28756
28757 }, {
28758 key: "isMajor",
28759
28760 /**
28761 * Check if the current value is a major value (for example when the step
28762 * is DAY, a major value is each first day of the MONTH)
28763 * @return {boolean} true if current date is major, else false.
28764 */
28765 value: function isMajor() {
28766 if (this.switchedYear == true) {
28767 switch (this.scale) {
28768 case 'year':
28769 case 'month':
28770 case 'week':
28771 case 'weekday':
28772 case 'day':
28773 case 'hour':
28774 case 'minute':
28775 case 'second':
28776 case 'millisecond':
28777 return true;
28778
28779 default:
28780 return false;
28781 }
28782 } else if (this.switchedMonth == true) {
28783 switch (this.scale) {
28784 case 'week':
28785 case 'weekday':
28786 case 'day':
28787 case 'hour':
28788 case 'minute':
28789 case 'second':
28790 case 'millisecond':
28791 return true;
28792
28793 default:
28794 return false;
28795 }
28796 } else if (this.switchedDay == true) {
28797 switch (this.scale) {
28798 case 'millisecond':
28799 case 'second':
28800 case 'minute':
28801 case 'hour':
28802 return true;
28803
28804 default:
28805 return false;
28806 }
28807 }
28808
28809 var date = this.moment(this.current);
28810
28811 switch (this.scale) {
28812 case 'millisecond':
28813 return date.milliseconds() == 0;
28814
28815 case 'second':
28816 return date.seconds() == 0;
28817
28818 case 'minute':
28819 return date.hours() == 0 && date.minutes() == 0;
28820
28821 case 'hour':
28822 return date.hours() == 0;
28823
28824 case 'weekday': // intentional fall through
28825
28826 case 'day':
28827 return date.date() == 1;
28828
28829 case 'week':
28830 return date.date() == 1;
28831
28832 case 'month':
28833 return date.month() == 0;
28834
28835 case 'year':
28836 return false;
28837
28838 default:
28839 return false;
28840 }
28841 }
28842 /**
28843 * Returns formatted text for the minor axislabel, depending on the current
28844 * date and the scale. For example when scale is MINUTE, the current time is
28845 * formatted as "hh:mm".
28846 * @param {Date} [date=this.current] custom date. if not provided, current date is taken
28847 * @returns {String}
28848 */
28849
28850 }, {
28851 key: "getLabelMinor",
28852 value: function getLabelMinor(date) {
28853 if (date == undefined) {
28854 date = this.current;
28855 }
28856
28857 if (date instanceof Date) {
28858 date = this.moment(date);
28859 }
28860
28861 if (typeof this.format.minorLabels === "function") {
28862 return this.format.minorLabels(date, this.scale, this.step);
28863 }
28864
28865 var format = this.format.minorLabels[this.scale]; // noinspection FallThroughInSwitchStatementJS
28866
28867 switch (this.scale) {
28868 case 'week':
28869 // Don't draw the minor label if this date is the first day of a month AND if it's NOT the start of the week.
28870 // The 'date' variable may actually be the 'next' step when called from TimeAxis' _repaintLabels.
28871 if (date.date() === 1 && date.weekday() !== 0) {
28872 return "";
28873 }
28874
28875 default:
28876 // eslint-disable-line no-fallthrough
28877 return format && format.length > 0 ? this.moment(date).format(format) : '';
28878 }
28879 }
28880 /**
28881 * Returns formatted text for the major axis label, depending on the current
28882 * date and the scale. For example when scale is MINUTE, the major scale is
28883 * hours, and the hour will be formatted as "hh".
28884 * @param {Date} [date=this.current] custom date. if not provided, current date is taken
28885 * @returns {String}
28886 */
28887
28888 }, {
28889 key: "getLabelMajor",
28890 value: function getLabelMajor(date) {
28891 if (date == undefined) {
28892 date = this.current;
28893 }
28894
28895 if (date instanceof Date) {
28896 date = this.moment(date);
28897 }
28898
28899 if (typeof this.format.majorLabels === "function") {
28900 return this.format.majorLabels(date, this.scale, this.step);
28901 }
28902
28903 var format = this.format.majorLabels[this.scale];
28904 return format && format.length > 0 ? this.moment(date).format(format) : '';
28905 }
28906 /**
28907 * get class name
28908 * @return {string} class name
28909 */
28910
28911 }, {
28912 key: "getClassName",
28913 value: function getClassName() {
28914 var _moment = this.moment;
28915 var m = this.moment(this.current);
28916 var current = m.locale ? m.locale('en') : m.lang('en'); // old versions of moment have .lang() function
28917
28918 var step = this.step;
28919 var classNames = [];
28920 /**
28921 *
28922 * @param {number} value
28923 * @returns {String}
28924 */
28925
28926 function even(value) {
28927 return value / step % 2 == 0 ? ' vis-even' : ' vis-odd';
28928 }
28929 /**
28930 *
28931 * @param {Date} date
28932 * @returns {String}
28933 */
28934
28935
28936 function today(date) {
28937 if (date.isSame(Date.now(), 'day')) {
28938 return ' vis-today';
28939 }
28940
28941 if (date.isSame(_moment().add(1, 'day'), 'day')) {
28942 return ' vis-tomorrow';
28943 }
28944
28945 if (date.isSame(_moment().add(-1, 'day'), 'day')) {
28946 return ' vis-yesterday';
28947 }
28948
28949 return '';
28950 }
28951 /**
28952 *
28953 * @param {Date} date
28954 * @returns {String}
28955 */
28956
28957
28958 function currentWeek(date) {
28959 return date.isSame(Date.now(), 'week') ? ' vis-current-week' : '';
28960 }
28961 /**
28962 *
28963 * @param {Date} date
28964 * @returns {String}
28965 */
28966
28967
28968 function currentMonth(date) {
28969 return date.isSame(Date.now(), 'month') ? ' vis-current-month' : '';
28970 }
28971 /**
28972 *
28973 * @param {Date} date
28974 * @returns {String}
28975 */
28976
28977
28978 function currentYear(date) {
28979 return date.isSame(Date.now(), 'year') ? ' vis-current-year' : '';
28980 }
28981
28982 switch (this.scale) {
28983 case 'millisecond':
28984 classNames.push(today(current));
28985 classNames.push(even(current.milliseconds()));
28986 break;
28987
28988 case 'second':
28989 classNames.push(today(current));
28990 classNames.push(even(current.seconds()));
28991 break;
28992
28993 case 'minute':
28994 classNames.push(today(current));
28995 classNames.push(even(current.minutes()));
28996 break;
28997
28998 case 'hour':
28999 classNames.push("vis-h".concat(current.hours()).concat(this.step == 4 ? '-h' + (current.hours() + 4) : ''));
29000 classNames.push(today(current));
29001 classNames.push(even(current.hours()));
29002 break;
29003
29004 case 'weekday':
29005 classNames.push("vis-".concat(current.format('dddd').toLowerCase()));
29006 classNames.push(today(current));
29007 classNames.push(currentWeek(current));
29008 classNames.push(even(current.date()));
29009 break;
29010
29011 case 'day':
29012 classNames.push("vis-day".concat(current.date()));
29013 classNames.push("vis-".concat(current.format('MMMM').toLowerCase()));
29014 classNames.push(today(current));
29015 classNames.push(currentMonth(current));
29016 classNames.push(this.step <= 2 ? today(current) : '');
29017 classNames.push(this.step <= 2 ? "vis-".concat(current.format('dddd').toLowerCase()) : '');
29018 classNames.push(even(current.date() - 1));
29019 break;
29020
29021 case 'week':
29022 classNames.push("vis-week".concat(current.format('w')));
29023 classNames.push(currentWeek(current));
29024 classNames.push(even(current.week()));
29025 break;
29026
29027 case 'month':
29028 classNames.push("vis-".concat(current.format('MMMM').toLowerCase()));
29029 classNames.push(currentMonth(current));
29030 classNames.push(even(current.month()));
29031 break;
29032
29033 case 'year':
29034 classNames.push("vis-year".concat(current.year()));
29035 classNames.push(currentYear(current));
29036 classNames.push(even(current.year()));
29037 break;
29038 }
29039
29040 return classNames.filter(String).join(" ");
29041 }
29042 }], [{
29043 key: "snap",
29044 value: function snap(date, scale, step) {
29045 var clone = moment$3(date);
29046
29047 if (scale == 'year') {
29048 var year = clone.year() + Math.round(clone.month() / 12);
29049 clone.year(Math.round(year / step) * step);
29050 clone.month(0);
29051 clone.date(0);
29052 clone.hours(0);
29053 clone.minutes(0);
29054 clone.seconds(0);
29055 clone.milliseconds(0);
29056 } else if (scale == 'month') {
29057 if (clone.date() > 15) {
29058 clone.date(1);
29059 clone.add(1, 'month'); // important: first set Date to 1, after that change the month.
29060 } else {
29061 clone.date(1);
29062 }
29063
29064 clone.hours(0);
29065 clone.minutes(0);
29066 clone.seconds(0);
29067 clone.milliseconds(0);
29068 } else if (scale == 'week') {
29069 if (clone.weekday() > 2) {
29070 // doing it the momentjs locale aware way
29071 clone.weekday(0);
29072 clone.add(1, 'week');
29073 } else {
29074 clone.weekday(0);
29075 }
29076
29077 clone.hours(0);
29078 clone.minutes(0);
29079 clone.seconds(0);
29080 clone.milliseconds(0);
29081 } else if (scale == 'day') {
29082 //noinspection FallthroughInSwitchStatementJS
29083 switch (step) {
29084 case 5:
29085 case 2:
29086 clone.hours(Math.round(clone.hours() / 24) * 24);
29087 break;
29088
29089 default:
29090 clone.hours(Math.round(clone.hours() / 12) * 12);
29091 break;
29092 }
29093
29094 clone.minutes(0);
29095 clone.seconds(0);
29096 clone.milliseconds(0);
29097 } else if (scale == 'weekday') {
29098 //noinspection FallthroughInSwitchStatementJS
29099 switch (step) {
29100 case 5:
29101 case 2:
29102 clone.hours(Math.round(clone.hours() / 12) * 12);
29103 break;
29104
29105 default:
29106 clone.hours(Math.round(clone.hours() / 6) * 6);
29107 break;
29108 }
29109
29110 clone.minutes(0);
29111 clone.seconds(0);
29112 clone.milliseconds(0);
29113 } else if (scale == 'hour') {
29114 switch (step) {
29115 case 4:
29116 clone.minutes(Math.round(clone.minutes() / 60) * 60);
29117 break;
29118
29119 default:
29120 clone.minutes(Math.round(clone.minutes() / 30) * 30);
29121 break;
29122 }
29123
29124 clone.seconds(0);
29125 clone.milliseconds(0);
29126 } else if (scale == 'minute') {
29127 //noinspection FallthroughInSwitchStatementJS
29128 switch (step) {
29129 case 15:
29130 case 10:
29131 clone.minutes(Math.round(clone.minutes() / 5) * 5);
29132 clone.seconds(0);
29133 break;
29134
29135 case 5:
29136 clone.seconds(Math.round(clone.seconds() / 60) * 60);
29137 break;
29138
29139 default:
29140 clone.seconds(Math.round(clone.seconds() / 30) * 30);
29141 break;
29142 }
29143
29144 clone.milliseconds(0);
29145 } else if (scale == 'second') {
29146 //noinspection FallthroughInSwitchStatementJS
29147 switch (step) {
29148 case 15:
29149 case 10:
29150 clone.seconds(Math.round(clone.seconds() / 5) * 5);
29151 clone.milliseconds(0);
29152 break;
29153
29154 case 5:
29155 clone.milliseconds(Math.round(clone.milliseconds() / 1000) * 1000);
29156 break;
29157
29158 default:
29159 clone.milliseconds(Math.round(clone.milliseconds() / 500) * 500);
29160 break;
29161 }
29162 } else if (scale == 'millisecond') {
29163 var _step = step > 5 ? step / 2 : 1;
29164
29165 clone.milliseconds(Math.round(clone.milliseconds() / _step) * _step);
29166 }
29167
29168 return clone;
29169 }
29170 }]);
29171
29172 return TimeStep;
29173}(); // Time formatting
29174
29175
29176TimeStep.FORMAT = {
29177 minorLabels: {
29178 millisecond: 'SSS',
29179 second: 's',
29180 minute: 'HH:mm',
29181 hour: 'HH:mm',
29182 weekday: 'ddd D',
29183 day: 'D',
29184 week: 'w',
29185 month: 'MMM',
29186 year: 'YYYY'
29187 },
29188 majorLabels: {
29189 millisecond: 'HH:mm:ss',
29190 second: 'D MMMM HH:mm',
29191 minute: 'ddd D MMMM',
29192 hour: 'ddd D MMMM',
29193 weekday: 'MMMM YYYY',
29194 day: 'MMMM YYYY',
29195 week: 'MMMM YYYY',
29196 month: 'YYYY',
29197 year: ''
29198 }
29199};
29200
29201/** A horizontal time axis */
29202
29203var TimeAxis =
29204/*#__PURE__*/
29205function (_Component) {
29206 _inherits(TimeAxis, _Component);
29207
29208 /**
29209 * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} body
29210 * @param {Object} [options] See TimeAxis.setOptions for the available
29211 * options.
29212 * @constructor TimeAxis
29213 * @extends Component
29214 */
29215 function TimeAxis(body, options) {
29216 var _this;
29217
29218 _classCallCheck(this, TimeAxis);
29219
29220 _this = _possibleConstructorReturn(this, _getPrototypeOf(TimeAxis).call(this));
29221 _this.dom = {
29222 foreground: null,
29223 lines: [],
29224 majorTexts: [],
29225 minorTexts: [],
29226 redundant: {
29227 lines: [],
29228 majorTexts: [],
29229 minorTexts: []
29230 }
29231 };
29232 _this.props = {
29233 range: {
29234 start: 0,
29235 end: 0,
29236 minimumStep: 0
29237 },
29238 lineTop: 0
29239 };
29240 _this.defaultOptions = {
29241 orientation: {
29242 axis: 'bottom'
29243 },
29244 // axis orientation: 'top' or 'bottom'
29245 showMinorLabels: true,
29246 showMajorLabels: true,
29247 maxMinorChars: 7,
29248 format: TimeStep.FORMAT,
29249 moment: moment$3,
29250 timeAxis: null
29251 };
29252 _this.options = util.extend({}, _this.defaultOptions);
29253 _this.body = body; // create the HTML DOM
29254
29255 _this._create();
29256
29257 _this.setOptions(options);
29258
29259 return _this;
29260 }
29261 /**
29262 * Set options for the TimeAxis.
29263 * Parameters will be merged in current options.
29264 * @param {Object} options Available options:
29265 * {string} [orientation.axis]
29266 * {boolean} [showMinorLabels]
29267 * {boolean} [showMajorLabels]
29268 */
29269
29270
29271 _createClass(TimeAxis, [{
29272 key: "setOptions",
29273 value: function setOptions(options) {
29274 if (options) {
29275 // copy all options that we know
29276 util.selectiveExtend(['showMinorLabels', 'showMajorLabels', 'maxMinorChars', 'hiddenDates', 'timeAxis', 'moment', 'rtl'], this.options, options); // deep copy the format options
29277
29278 util.selectiveDeepExtend(['format'], this.options, options);
29279
29280 if ('orientation' in options) {
29281 if (typeof options.orientation === 'string') {
29282 this.options.orientation.axis = options.orientation;
29283 } else if (_typeof(options.orientation) === 'object' && 'axis' in options.orientation) {
29284 this.options.orientation.axis = options.orientation.axis;
29285 }
29286 } // apply locale to moment.js
29287 // TODO: not so nice, this is applied globally to moment.js
29288
29289
29290 if ('locale' in options) {
29291 if (typeof moment$3.locale === 'function') {
29292 // moment.js 2.8.1+
29293 moment$3.locale(options.locale);
29294 } else {
29295 moment$3.lang(options.locale);
29296 }
29297 }
29298 }
29299 }
29300 /**
29301 * Create the HTML DOM for the TimeAxis
29302 */
29303
29304 }, {
29305 key: "_create",
29306 value: function _create() {
29307 this.dom.foreground = document.createElement('div');
29308 this.dom.background = document.createElement('div');
29309 this.dom.foreground.className = 'vis-time-axis vis-foreground';
29310 this.dom.background.className = 'vis-time-axis vis-background';
29311 }
29312 /**
29313 * Destroy the TimeAxis
29314 */
29315
29316 }, {
29317 key: "destroy",
29318 value: function destroy() {
29319 // remove from DOM
29320 if (this.dom.foreground.parentNode) {
29321 this.dom.foreground.parentNode.removeChild(this.dom.foreground);
29322 }
29323
29324 if (this.dom.background.parentNode) {
29325 this.dom.background.parentNode.removeChild(this.dom.background);
29326 }
29327
29328 this.body = null;
29329 }
29330 /**
29331 * Repaint the component
29332 * @return {boolean} Returns true if the component is resized
29333 */
29334
29335 }, {
29336 key: "redraw",
29337 value: function redraw() {
29338 var props = this.props;
29339 var foreground = this.dom.foreground;
29340 var background = this.dom.background; // determine the correct parent DOM element (depending on option orientation)
29341
29342 var parent = this.options.orientation.axis == 'top' ? this.body.dom.top : this.body.dom.bottom;
29343 var parentChanged = foreground.parentNode !== parent; // calculate character width and height
29344
29345 this._calculateCharSize(); // TODO: recalculate sizes only needed when parent is resized or options is changed
29346
29347
29348 var showMinorLabels = this.options.showMinorLabels && this.options.orientation.axis !== 'none';
29349 var showMajorLabels = this.options.showMajorLabels && this.options.orientation.axis !== 'none'; // determine the width and height of the elemens for the axis
29350
29351 props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0;
29352 props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0;
29353 props.height = props.minorLabelHeight + props.majorLabelHeight;
29354 props.width = foreground.offsetWidth;
29355 props.minorLineHeight = this.body.domProps.root.height - props.majorLabelHeight - (this.options.orientation.axis == 'top' ? this.body.domProps.bottom.height : this.body.domProps.top.height);
29356 props.minorLineWidth = 1; // TODO: really calculate width
29357
29358 props.majorLineHeight = props.minorLineHeight + props.majorLabelHeight;
29359 props.majorLineWidth = 1; // TODO: really calculate width
29360 // take foreground and background offline while updating (is almost twice as fast)
29361
29362 var foregroundNextSibling = foreground.nextSibling;
29363 var backgroundNextSibling = background.nextSibling;
29364 foreground.parentNode && foreground.parentNode.removeChild(foreground);
29365 background.parentNode && background.parentNode.removeChild(background);
29366 foreground.style.height = "".concat(this.props.height, "px");
29367
29368 this._repaintLabels(); // put DOM online again (at the same place)
29369
29370
29371 if (foregroundNextSibling) {
29372 parent.insertBefore(foreground, foregroundNextSibling);
29373 } else {
29374 parent.appendChild(foreground);
29375 }
29376
29377 if (backgroundNextSibling) {
29378 this.body.dom.backgroundVertical.insertBefore(background, backgroundNextSibling);
29379 } else {
29380 this.body.dom.backgroundVertical.appendChild(background);
29381 }
29382
29383 return this._isResized() || parentChanged;
29384 }
29385 /**
29386 * Repaint major and minor text labels and vertical grid lines
29387 * @private
29388 */
29389
29390 }, {
29391 key: "_repaintLabels",
29392 value: function _repaintLabels() {
29393 var orientation = this.options.orientation.axis; // calculate range and step (step such that we have space for 7 characters per label)
29394
29395 var start = util.convert(this.body.range.start, 'Number');
29396 var end = util.convert(this.body.range.end, 'Number');
29397 var timeLabelsize = this.body.util.toTime((this.props.minorCharWidth || 10) * this.options.maxMinorChars).valueOf();
29398 var minimumStep = timeLabelsize - getHiddenDurationBefore(this.options.moment, this.body.hiddenDates, this.body.range, timeLabelsize);
29399 minimumStep -= this.body.util.toTime(0).valueOf();
29400 var step = new TimeStep(new Date(start), new Date(end), minimumStep, this.body.hiddenDates, this.options);
29401 step.setMoment(this.options.moment);
29402
29403 if (this.options.format) {
29404 step.setFormat(this.options.format);
29405 }
29406
29407 if (this.options.timeAxis) {
29408 step.setScale(this.options.timeAxis);
29409 }
29410
29411 this.step = step; // Move all DOM elements to a "redundant" list, where they
29412 // can be picked for re-use, and clear the lists with lines and texts.
29413 // At the end of the function _repaintLabels, left over elements will be cleaned up
29414
29415 var dom = this.dom;
29416 dom.redundant.lines = dom.lines;
29417 dom.redundant.majorTexts = dom.majorTexts;
29418 dom.redundant.minorTexts = dom.minorTexts;
29419 dom.lines = [];
29420 dom.majorTexts = [];
29421 dom.minorTexts = [];
29422 var current;
29423 var next;
29424 var x;
29425 var xNext;
29426 var isMajor;
29427 var showMinorGrid;
29428 var width = 0;
29429 var prevWidth;
29430 var line;
29431 var xFirstMajorLabel = undefined;
29432 var count = 0;
29433 var MAX = 1000;
29434 var className;
29435 step.start();
29436 next = step.getCurrent();
29437 xNext = this.body.util.toScreen(next);
29438
29439 while (step.hasNext() && count < MAX) {
29440 count++;
29441 isMajor = step.isMajor();
29442 className = step.getClassName();
29443 current = next;
29444 x = xNext;
29445 step.next();
29446 next = step.getCurrent();
29447 xNext = this.body.util.toScreen(next);
29448 prevWidth = width;
29449 width = xNext - x;
29450
29451 switch (step.scale) {
29452 case 'week':
29453 showMinorGrid = true;
29454 break;
29455
29456 default:
29457 showMinorGrid = width >= prevWidth * 0.4;
29458 break;
29459 // prevent displaying of the 31th of the month on a scale of 5 days
29460 }
29461
29462 if (this.options.showMinorLabels && showMinorGrid) {
29463 var label = this._repaintMinorText(x, step.getLabelMinor(current), orientation, className);
29464
29465 label.style.width = "".concat(width, "px"); // set width to prevent overflow
29466 }
29467
29468 if (isMajor && this.options.showMajorLabels) {
29469 if (x > 0) {
29470 if (xFirstMajorLabel == undefined) {
29471 xFirstMajorLabel = x;
29472 }
29473
29474 label = this._repaintMajorText(x, step.getLabelMajor(current), orientation, className);
29475 }
29476
29477 line = this._repaintMajorLine(x, width, orientation, className);
29478 } else {
29479 // minor line
29480 if (showMinorGrid) {
29481 line = this._repaintMinorLine(x, width, orientation, className);
29482 } else {
29483 if (line) {
29484 // adjust the width of the previous grid
29485 line.style.width = "".concat(parseInt(line.style.width) + width, "px");
29486 }
29487 }
29488 }
29489 }
29490
29491 if (count === MAX && !warnedForOverflow) {
29492 console.warn("Something is wrong with the Timeline scale. Limited drawing of grid lines to ".concat(MAX, " lines."));
29493 warnedForOverflow = true;
29494 } // create a major label on the left when needed
29495
29496
29497 if (this.options.showMajorLabels) {
29498 var leftTime = this.body.util.toTime(0); // upper bound estimation
29499
29500 var leftText = step.getLabelMajor(leftTime);
29501 var widthText = leftText.length * (this.props.majorCharWidth || 10) + 10;
29502
29503 if (xFirstMajorLabel == undefined || widthText < xFirstMajorLabel) {
29504 this._repaintMajorText(0, leftText, orientation, className);
29505 }
29506 } // Cleanup leftover DOM elements from the redundant list
29507
29508
29509 util.forEach(this.dom.redundant, function (arr) {
29510 while (arr.length) {
29511 var elem = arr.pop();
29512
29513 if (elem && elem.parentNode) {
29514 elem.parentNode.removeChild(elem);
29515 }
29516 }
29517 });
29518 }
29519 /**
29520 * Create a minor label for the axis at position x
29521 * @param {number} x
29522 * @param {string} text
29523 * @param {string} orientation "top" or "bottom" (default)
29524 * @param {string} className
29525 * @return {Element} Returns the HTML element of the created label
29526 * @private
29527 */
29528
29529 }, {
29530 key: "_repaintMinorText",
29531 value: function _repaintMinorText(x, text, orientation, className) {
29532 // reuse redundant label
29533 var label = this.dom.redundant.minorTexts.shift();
29534
29535 if (!label) {
29536 // create new label
29537 var content = document.createTextNode('');
29538 label = document.createElement('div');
29539 label.appendChild(content);
29540 this.dom.foreground.appendChild(label);
29541 }
29542
29543 this.dom.minorTexts.push(label);
29544 label.innerHTML = text;
29545 var y = orientation == 'top' ? this.props.majorLabelHeight : 0;
29546
29547 this._setXY(label, x, y);
29548
29549 label.className = "vis-text vis-minor ".concat(className); //label.title = title; // TODO: this is a heavy operation
29550
29551 return label;
29552 }
29553 /**
29554 * Create a Major label for the axis at position x
29555 * @param {number} x
29556 * @param {string} text
29557 * @param {string} orientation "top" or "bottom" (default)
29558 * @param {string} className
29559 * @return {Element} Returns the HTML element of the created label
29560 * @private
29561 */
29562
29563 }, {
29564 key: "_repaintMajorText",
29565 value: function _repaintMajorText(x, text, orientation, className) {
29566 // reuse redundant label
29567 var label = this.dom.redundant.majorTexts.shift();
29568
29569 if (!label) {
29570 // create label
29571 var content = document.createElement('div');
29572 label = document.createElement('div');
29573 label.appendChild(content);
29574 this.dom.foreground.appendChild(label);
29575 }
29576
29577 label.childNodes[0].innerHTML = text;
29578 label.className = "vis-text vis-major ".concat(className); //label.title = title; // TODO: this is a heavy operation
29579
29580 var y = orientation == 'top' ? 0 : this.props.minorLabelHeight;
29581
29582 this._setXY(label, x, y);
29583
29584 this.dom.majorTexts.push(label);
29585 return label;
29586 }
29587 /**
29588 * sets xy
29589 * @param {string} label
29590 * @param {number} x
29591 * @param {number} y
29592 * @private
29593 */
29594
29595 }, {
29596 key: "_setXY",
29597 value: function _setXY(label, x, y) {
29598 // If rtl is true, inverse x.
29599 var directionX = this.options.rtl ? x * -1 : x;
29600 label.style.transform = "translate(".concat(directionX, "px, ").concat(y, "px)");
29601 }
29602 /**
29603 * Create a minor line for the axis at position x
29604 * @param {number} left
29605 * @param {number} width
29606 * @param {string} orientation "top" or "bottom" (default)
29607 * @param {string} className
29608 * @return {Element} Returns the created line
29609 * @private
29610 */
29611
29612 }, {
29613 key: "_repaintMinorLine",
29614 value: function _repaintMinorLine(left, width, orientation, className) {
29615 // reuse redundant line
29616 var line = this.dom.redundant.lines.shift();
29617
29618 if (!line) {
29619 // create vertical line
29620 line = document.createElement('div');
29621 this.dom.background.appendChild(line);
29622 }
29623
29624 this.dom.lines.push(line);
29625 var props = this.props;
29626 line.style.width = "".concat(width, "px");
29627 line.style.height = "".concat(props.minorLineHeight, "px");
29628 var y = orientation == 'top' ? props.majorLabelHeight : this.body.domProps.top.height;
29629 var x = left - props.minorLineWidth / 2;
29630
29631 this._setXY(line, x, y);
29632
29633 line.className = "vis-grid ".concat(this.options.rtl ? 'vis-vertical-rtl' : 'vis-vertical', " vis-minor ").concat(className);
29634 return line;
29635 }
29636 /**
29637 * Create a Major line for the axis at position x
29638 * @param {number} left
29639 * @param {number} width
29640 * @param {string} orientation "top" or "bottom" (default)
29641 * @param {string} className
29642 * @return {Element} Returns the created line
29643 * @private
29644 */
29645
29646 }, {
29647 key: "_repaintMajorLine",
29648 value: function _repaintMajorLine(left, width, orientation, className) {
29649 // reuse redundant line
29650 var line = this.dom.redundant.lines.shift();
29651
29652 if (!line) {
29653 // create vertical line
29654 line = document.createElement('div');
29655 this.dom.background.appendChild(line);
29656 }
29657
29658 this.dom.lines.push(line);
29659 var props = this.props;
29660 line.style.width = "".concat(width, "px");
29661 line.style.height = "".concat(props.majorLineHeight, "px");
29662 var y = orientation == 'top' ? 0 : this.body.domProps.top.height;
29663 var x = left - props.majorLineWidth / 2;
29664
29665 this._setXY(line, x, y);
29666
29667 line.className = "vis-grid ".concat(this.options.rtl ? 'vis-vertical-rtl' : 'vis-vertical', " vis-major ").concat(className);
29668 return line;
29669 }
29670 /**
29671 * Determine the size of text on the axis (both major and minor axis).
29672 * The size is calculated only once and then cached in this.props.
29673 * @private
29674 */
29675
29676 }, {
29677 key: "_calculateCharSize",
29678 value: function _calculateCharSize() {
29679 // Note: We calculate char size with every redraw. Size may change, for
29680 // example when any of the timelines parents had display:none for example.
29681 // determine the char width and height on the minor axis
29682 if (!this.dom.measureCharMinor) {
29683 this.dom.measureCharMinor = document.createElement('DIV');
29684 this.dom.measureCharMinor.className = 'vis-text vis-minor vis-measure';
29685 this.dom.measureCharMinor.style.position = 'absolute';
29686 this.dom.measureCharMinor.appendChild(document.createTextNode('0'));
29687 this.dom.foreground.appendChild(this.dom.measureCharMinor);
29688 }
29689
29690 this.props.minorCharHeight = this.dom.measureCharMinor.clientHeight;
29691 this.props.minorCharWidth = this.dom.measureCharMinor.clientWidth; // determine the char width and height on the major axis
29692
29693 if (!this.dom.measureCharMajor) {
29694 this.dom.measureCharMajor = document.createElement('DIV');
29695 this.dom.measureCharMajor.className = 'vis-text vis-major vis-measure';
29696 this.dom.measureCharMajor.style.position = 'absolute';
29697 this.dom.measureCharMajor.appendChild(document.createTextNode('0'));
29698 this.dom.foreground.appendChild(this.dom.measureCharMajor);
29699 }
29700
29701 this.props.majorCharHeight = this.dom.measureCharMajor.clientHeight;
29702 this.props.majorCharWidth = this.dom.measureCharMajor.clientWidth;
29703 }
29704 }]);
29705
29706 return TimeAxis;
29707}(Component);
29708
29709var warnedForOverflow = false;
29710
29711var keycharm = createCommonjsModule(function (module, exports) {
29712 /**
29713 * Created by Alex on 11/6/2014.
29714 */
29715 // https://github.com/umdjs/umd/blob/master/returnExports.js#L40-L60
29716 // if the module has no dependencies, the above pattern can be simplified to
29717
29718 (function (root, factory) {
29719 {
29720 // Node. Does not work with strict CommonJS, but
29721 // only CommonJS-like environments that support module.exports,
29722 // like Node.
29723 module.exports = factory();
29724 }
29725 })(commonjsGlobal, function () {
29726 function keycharm(options) {
29727 var preventDefault = options && options.preventDefault || false;
29728 var container = options && options.container || window;
29729 var _exportFunctions = {};
29730 var _bound = {
29731 keydown: {},
29732 keyup: {}
29733 };
29734 var _keys = {};
29735 var i; // a - z
29736
29737 for (i = 97; i <= 122; i++) {
29738 _keys[String.fromCharCode(i)] = {
29739 code: 65 + (i - 97),
29740 shift: false
29741 };
29742 } // A - Z
29743
29744
29745 for (i = 65; i <= 90; i++) {
29746 _keys[String.fromCharCode(i)] = {
29747 code: i,
29748 shift: true
29749 };
29750 } // 0 - 9
29751
29752
29753 for (i = 0; i <= 9; i++) {
29754 _keys['' + i] = {
29755 code: 48 + i,
29756 shift: false
29757 };
29758 } // F1 - F12
29759
29760
29761 for (i = 1; i <= 12; i++) {
29762 _keys['F' + i] = {
29763 code: 111 + i,
29764 shift: false
29765 };
29766 } // num0 - num9
29767
29768
29769 for (i = 0; i <= 9; i++) {
29770 _keys['num' + i] = {
29771 code: 96 + i,
29772 shift: false
29773 };
29774 } // numpad misc
29775
29776
29777 _keys['num*'] = {
29778 code: 106,
29779 shift: false
29780 };
29781 _keys['num+'] = {
29782 code: 107,
29783 shift: false
29784 };
29785 _keys['num-'] = {
29786 code: 109,
29787 shift: false
29788 };
29789 _keys['num/'] = {
29790 code: 111,
29791 shift: false
29792 };
29793 _keys['num.'] = {
29794 code: 110,
29795 shift: false
29796 }; // arrows
29797
29798 _keys['left'] = {
29799 code: 37,
29800 shift: false
29801 };
29802 _keys['up'] = {
29803 code: 38,
29804 shift: false
29805 };
29806 _keys['right'] = {
29807 code: 39,
29808 shift: false
29809 };
29810 _keys['down'] = {
29811 code: 40,
29812 shift: false
29813 }; // extra keys
29814
29815 _keys['space'] = {
29816 code: 32,
29817 shift: false
29818 };
29819 _keys['enter'] = {
29820 code: 13,
29821 shift: false
29822 };
29823 _keys['shift'] = {
29824 code: 16,
29825 shift: undefined
29826 };
29827 _keys['esc'] = {
29828 code: 27,
29829 shift: false
29830 };
29831 _keys['backspace'] = {
29832 code: 8,
29833 shift: false
29834 };
29835 _keys['tab'] = {
29836 code: 9,
29837 shift: false
29838 };
29839 _keys['ctrl'] = {
29840 code: 17,
29841 shift: false
29842 };
29843 _keys['alt'] = {
29844 code: 18,
29845 shift: false
29846 };
29847 _keys['delete'] = {
29848 code: 46,
29849 shift: false
29850 };
29851 _keys['pageup'] = {
29852 code: 33,
29853 shift: false
29854 };
29855 _keys['pagedown'] = {
29856 code: 34,
29857 shift: false
29858 }; // symbols
29859
29860 _keys['='] = {
29861 code: 187,
29862 shift: false
29863 };
29864 _keys['-'] = {
29865 code: 189,
29866 shift: false
29867 };
29868 _keys[']'] = {
29869 code: 221,
29870 shift: false
29871 };
29872 _keys['['] = {
29873 code: 219,
29874 shift: false
29875 };
29876
29877 var down = function down(event) {
29878 handleEvent(event, 'keydown');
29879 };
29880
29881 var up = function up(event) {
29882 handleEvent(event, 'keyup');
29883 }; // handle the actualy bound key with the event
29884
29885
29886 var handleEvent = function handleEvent(event, type) {
29887 if (_bound[type][event.keyCode] !== undefined) {
29888 var bound = _bound[type][event.keyCode];
29889
29890 for (var i = 0; i < bound.length; i++) {
29891 if (bound[i].shift === undefined) {
29892 bound[i].fn(event);
29893 } else if (bound[i].shift == true && event.shiftKey == true) {
29894 bound[i].fn(event);
29895 } else if (bound[i].shift == false && event.shiftKey == false) {
29896 bound[i].fn(event);
29897 }
29898 }
29899
29900 if (preventDefault == true) {
29901 event.preventDefault();
29902 }
29903 }
29904 }; // bind a key to a callback
29905
29906
29907 _exportFunctions.bind = function (key, callback, type) {
29908 if (type === undefined) {
29909 type = 'keydown';
29910 }
29911
29912 if (_keys[key] === undefined) {
29913 throw new Error("unsupported key: " + key);
29914 }
29915
29916 if (_bound[type][_keys[key].code] === undefined) {
29917 _bound[type][_keys[key].code] = [];
29918 }
29919
29920 _bound[type][_keys[key].code].push({
29921 fn: callback,
29922 shift: _keys[key].shift
29923 });
29924 }; // bind all keys to a call back (demo purposes)
29925
29926
29927 _exportFunctions.bindAll = function (callback, type) {
29928 if (type === undefined) {
29929 type = 'keydown';
29930 }
29931
29932 for (var key in _keys) {
29933 if (_keys.hasOwnProperty(key)) {
29934 _exportFunctions.bind(key, callback, type);
29935 }
29936 }
29937 }; // get the key label from an event
29938
29939
29940 _exportFunctions.getKey = function (event) {
29941 for (var key in _keys) {
29942 if (_keys.hasOwnProperty(key)) {
29943 if (event.shiftKey == true && _keys[key].shift == true && event.keyCode == _keys[key].code) {
29944 return key;
29945 } else if (event.shiftKey == false && _keys[key].shift == false && event.keyCode == _keys[key].code) {
29946 return key;
29947 } else if (event.keyCode == _keys[key].code && key == 'shift') {
29948 return key;
29949 }
29950 }
29951 }
29952
29953 return "unknown key, currently not supported";
29954 }; // unbind either a specific callback from a key or all of them (by leaving callback undefined)
29955
29956
29957 _exportFunctions.unbind = function (key, callback, type) {
29958 if (type === undefined) {
29959 type = 'keydown';
29960 }
29961
29962 if (_keys[key] === undefined) {
29963 throw new Error("unsupported key: " + key);
29964 }
29965
29966 if (callback !== undefined) {
29967 var newBindings = [];
29968 var bound = _bound[type][_keys[key].code];
29969
29970 if (bound !== undefined) {
29971 for (var i = 0; i < bound.length; i++) {
29972 if (!(bound[i].fn == callback && bound[i].shift == _keys[key].shift)) {
29973 newBindings.push(_bound[type][_keys[key].code][i]);
29974 }
29975 }
29976 }
29977
29978 _bound[type][_keys[key].code] = newBindings;
29979 } else {
29980 _bound[type][_keys[key].code] = [];
29981 }
29982 }; // reset all bound variables.
29983
29984
29985 _exportFunctions.reset = function () {
29986 _bound = {
29987 keydown: {},
29988 keyup: {}
29989 };
29990 }; // unbind all listeners and reset all variables.
29991
29992
29993 _exportFunctions.destroy = function () {
29994 _bound = {
29995 keydown: {},
29996 keyup: {}
29997 };
29998 container.removeEventListener('keydown', down, true);
29999 container.removeEventListener('keyup', up, true);
30000 }; // create listeners.
30001
30002
30003 container.addEventListener('keydown', down, true);
30004 container.addEventListener('keyup', up, true); // return the public functions.
30005
30006 return _exportFunctions;
30007 }
30008
30009 return keycharm;
30010 });
30011});
30012
30013/**
30014 * Turn an element into an clickToUse element.
30015 * When not active, the element has a transparent overlay. When the overlay is
30016 * clicked, the mode is changed to active.
30017 * When active, the element is displayed with a blue border around it, and
30018 * the interactive contents of the element can be used. When clicked outside
30019 * the element, the elements mode is changed to inactive.
30020 * @param {Element} container
30021 * @constructor Activator
30022 */
30023
30024function Activator(container) {
30025 this.active = false;
30026 this.dom = {
30027 container: container
30028 };
30029 this.dom.overlay = document.createElement('div');
30030 this.dom.overlay.className = 'vis-overlay';
30031 this.dom.container.appendChild(this.dom.overlay);
30032 this.hammer = Hammer$1(this.dom.overlay);
30033 this.hammer.on('tap', this._onTapOverlay.bind(this)); // block all touch events (except tap)
30034
30035 var me = this;
30036 var events = ['tap', 'doubletap', 'press', 'pinch', 'pan', 'panstart', 'panmove', 'panend'];
30037 events.forEach(function (event) {
30038 me.hammer.on(event, function (event) {
30039 event.stopPropagation();
30040 });
30041 }); // attach a click event to the window, in order to deactivate when clicking outside the timeline
30042
30043 if (document && document.body) {
30044 this.onClick = function (event) {
30045 if (!_hasParent(event.target, container)) {
30046 me.deactivate();
30047 }
30048 };
30049
30050 document.body.addEventListener('click', this.onClick);
30051 }
30052
30053 if (this.keycharm !== undefined) {
30054 this.keycharm.destroy();
30055 }
30056
30057 this.keycharm = keycharm(); // keycharm listener only bounded when active)
30058
30059 this.escListener = this.deactivate.bind(this);
30060} // turn into an event emitter
30061
30062
30063emitterComponent(Activator.prototype); // The currently active activator
30064
30065Activator.current = null;
30066/**
30067 * Destroy the activator. Cleans up all created DOM and event listeners
30068 */
30069
30070Activator.prototype.destroy = function () {
30071 this.deactivate(); // remove dom
30072
30073 this.dom.overlay.parentNode.removeChild(this.dom.overlay); // remove global event listener
30074
30075 if (this.onClick) {
30076 document.body.removeEventListener('click', this.onClick);
30077 } // remove keycharm
30078
30079
30080 if (this.keycharm !== undefined) {
30081 this.keycharm.destroy();
30082 }
30083
30084 this.keycharm = null; // cleanup hammer instances
30085
30086 this.hammer.destroy();
30087 this.hammer = null; // FIXME: cleaning up hammer instances doesn't work (Timeline not removed from memory)
30088};
30089/**
30090 * Activate the element
30091 * Overlay is hidden, element is decorated with a blue shadow border
30092 */
30093
30094
30095Activator.prototype.activate = function () {
30096 // we allow only one active activator at a time
30097 if (Activator.current) {
30098 Activator.current.deactivate();
30099 }
30100
30101 Activator.current = this;
30102 this.active = true;
30103 this.dom.overlay.style.display = 'none';
30104 util.addClassName(this.dom.container, 'vis-active');
30105 this.emit('change');
30106 this.emit('activate'); // ugly hack: bind ESC after emitting the events, as the Network rebinds all
30107 // keyboard events on a 'change' event
30108
30109 this.keycharm.bind('esc', this.escListener);
30110};
30111/**
30112 * Deactivate the element
30113 * Overlay is displayed on top of the element
30114 */
30115
30116
30117Activator.prototype.deactivate = function () {
30118 this.active = false;
30119 this.dom.overlay.style.display = '';
30120 util.removeClassName(this.dom.container, 'vis-active');
30121 this.keycharm.unbind('esc', this.escListener);
30122 this.emit('change');
30123 this.emit('deactivate');
30124};
30125/**
30126 * Handle a tap event: activate the container
30127 * @param {Event} event The event
30128 * @private
30129 */
30130
30131
30132Activator.prototype._onTapOverlay = function (event) {
30133 // activate the container
30134 this.activate();
30135 event.stopPropagation();
30136};
30137/**
30138 * Test whether the element has the requested parent element somewhere in
30139 * its chain of parent nodes.
30140 * @param {HTMLElement} element
30141 * @param {HTMLElement} parent
30142 * @returns {boolean} Returns true when the parent is found somewhere in the
30143 * chain of parent nodes.
30144 * @private
30145 */
30146
30147
30148function _hasParent(element, parent) {
30149 while (element) {
30150 if (element === parent) {
30151 return true;
30152 }
30153
30154 element = element.parentNode;
30155 }
30156
30157 return false;
30158}
30159
30160var it = createCommonjsModule(function (module, exports) {
30161
30162 (function (global, factory) {
30163 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30164 })(commonjsGlobal, function (moment) {
30165
30166 var it = moment.defineLocale('it', {
30167 months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),
30168 monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
30169 weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),
30170 weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
30171 weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'),
30172 longDateFormat: {
30173 LT: 'HH:mm',
30174 LTS: 'HH:mm:ss',
30175 L: 'DD/MM/YYYY',
30176 LL: 'D MMMM YYYY',
30177 LLL: 'D MMMM YYYY HH:mm',
30178 LLLL: 'dddd D MMMM YYYY HH:mm'
30179 },
30180 calendar: {
30181 sameDay: '[Oggi alle] LT',
30182 nextDay: '[Domani alle] LT',
30183 nextWeek: 'dddd [alle] LT',
30184 lastDay: '[Ieri alle] LT',
30185 lastWeek: function lastWeek() {
30186 switch (this.day()) {
30187 case 0:
30188 return '[la scorsa] dddd [alle] LT';
30189
30190 default:
30191 return '[lo scorso] dddd [alle] LT';
30192 }
30193 },
30194 sameElse: 'L'
30195 },
30196 relativeTime: {
30197 future: function future(s) {
30198 return (/^[0-9].+$/.test(s) ? 'tra' : 'in') + ' ' + s;
30199 },
30200 past: '%s fa',
30201 s: 'alcuni secondi',
30202 ss: '%d secondi',
30203 m: 'un minuto',
30204 mm: '%d minuti',
30205 h: 'un\'ora',
30206 hh: '%d ore',
30207 d: 'un giorno',
30208 dd: '%d giorni',
30209 M: 'un mese',
30210 MM: '%d mesi',
30211 y: 'un anno',
30212 yy: '%d anni'
30213 },
30214 dayOfMonthOrdinalParse: /\d{1,2}º/,
30215 ordinal: '%dº',
30216 week: {
30217 dow: 1,
30218 // Monday is the first day of the week.
30219 doy: 4 // The week that contains Jan 4th is the first week of the year.
30220
30221 }
30222 });
30223 return it;
30224 });
30225});
30226
30227var nl = createCommonjsModule(function (module, exports) {
30228
30229 (function (global, factory) {
30230 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30231 })(commonjsGlobal, function (moment) {
30232
30233 var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),
30234 monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
30235 var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
30236 var monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
30237 var nl = moment.defineLocale('nl', {
30238 months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
30239 monthsShort: function monthsShort(m, format) {
30240 if (!m) {
30241 return monthsShortWithDots;
30242 } else if (/-MMM-/.test(format)) {
30243 return monthsShortWithoutDots[m.month()];
30244 } else {
30245 return monthsShortWithDots[m.month()];
30246 }
30247 },
30248 monthsRegex: monthsRegex,
30249 monthsShortRegex: monthsRegex,
30250 monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,
30251 monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
30252 monthsParse: monthsParse,
30253 longMonthsParse: monthsParse,
30254 shortMonthsParse: monthsParse,
30255 weekdays: 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
30256 weekdaysShort: 'zo._ma._di._wo._do._vr._za.'.split('_'),
30257 weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'),
30258 weekdaysParseExact: true,
30259 longDateFormat: {
30260 LT: 'HH:mm',
30261 LTS: 'HH:mm:ss',
30262 L: 'DD-MM-YYYY',
30263 LL: 'D MMMM YYYY',
30264 LLL: 'D MMMM YYYY HH:mm',
30265 LLLL: 'dddd D MMMM YYYY HH:mm'
30266 },
30267 calendar: {
30268 sameDay: '[vandaag om] LT',
30269 nextDay: '[morgen om] LT',
30270 nextWeek: 'dddd [om] LT',
30271 lastDay: '[gisteren om] LT',
30272 lastWeek: '[afgelopen] dddd [om] LT',
30273 sameElse: 'L'
30274 },
30275 relativeTime: {
30276 future: 'over %s',
30277 past: '%s geleden',
30278 s: 'een paar seconden',
30279 ss: '%d seconden',
30280 m: 'één minuut',
30281 mm: '%d minuten',
30282 h: 'één uur',
30283 hh: '%d uur',
30284 d: 'één dag',
30285 dd: '%d dagen',
30286 M: 'één maand',
30287 MM: '%d maanden',
30288 y: 'één jaar',
30289 yy: '%d jaar'
30290 },
30291 dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
30292 ordinal: function ordinal(number) {
30293 return number + (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de');
30294 },
30295 week: {
30296 dow: 1,
30297 // Monday is the first day of the week.
30298 doy: 4 // The week that contains Jan 4th is the first week of the year.
30299
30300 }
30301 });
30302 return nl;
30303 });
30304});
30305
30306var de = createCommonjsModule(function (module, exports) {
30307
30308 (function (global, factory) {
30309 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30310 })(commonjsGlobal, function (moment) {
30311
30312 function processRelativeTime(number, withoutSuffix, key, isFuture) {
30313 var format = {
30314 'm': ['eine Minute', 'einer Minute'],
30315 'h': ['eine Stunde', 'einer Stunde'],
30316 'd': ['ein Tag', 'einem Tag'],
30317 'dd': [number + ' Tage', number + ' Tagen'],
30318 'M': ['ein Monat', 'einem Monat'],
30319 'MM': [number + ' Monate', number + ' Monaten'],
30320 'y': ['ein Jahr', 'einem Jahr'],
30321 'yy': [number + ' Jahre', number + ' Jahren']
30322 };
30323 return withoutSuffix ? format[key][0] : format[key][1];
30324 }
30325
30326 var de = moment.defineLocale('de', {
30327 months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
30328 monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'),
30329 monthsParseExact: true,
30330 weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
30331 weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
30332 weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
30333 weekdaysParseExact: true,
30334 longDateFormat: {
30335 LT: 'HH:mm',
30336 LTS: 'HH:mm:ss',
30337 L: 'DD.MM.YYYY',
30338 LL: 'D. MMMM YYYY',
30339 LLL: 'D. MMMM YYYY HH:mm',
30340 LLLL: 'dddd, D. MMMM YYYY HH:mm'
30341 },
30342 calendar: {
30343 sameDay: '[heute um] LT [Uhr]',
30344 sameElse: 'L',
30345 nextDay: '[morgen um] LT [Uhr]',
30346 nextWeek: 'dddd [um] LT [Uhr]',
30347 lastDay: '[gestern um] LT [Uhr]',
30348 lastWeek: '[letzten] dddd [um] LT [Uhr]'
30349 },
30350 relativeTime: {
30351 future: 'in %s',
30352 past: 'vor %s',
30353 s: 'ein paar Sekunden',
30354 ss: '%d Sekunden',
30355 m: processRelativeTime,
30356 mm: '%d Minuten',
30357 h: processRelativeTime,
30358 hh: '%d Stunden',
30359 d: processRelativeTime,
30360 dd: processRelativeTime,
30361 M: processRelativeTime,
30362 MM: processRelativeTime,
30363 y: processRelativeTime,
30364 yy: processRelativeTime
30365 },
30366 dayOfMonthOrdinalParse: /\d{1,2}\./,
30367 ordinal: '%d.',
30368 week: {
30369 dow: 1,
30370 // Monday is the first day of the week.
30371 doy: 4 // The week that contains Jan 4th is the first week of the year.
30372
30373 }
30374 });
30375 return de;
30376 });
30377});
30378
30379var fr = createCommonjsModule(function (module, exports) {
30380
30381 (function (global, factory) {
30382 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30383 })(commonjsGlobal, function (moment) {
30384
30385 var fr = moment.defineLocale('fr', {
30386 months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
30387 monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
30388 monthsParseExact: true,
30389 weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
30390 weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
30391 weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
30392 weekdaysParseExact: true,
30393 longDateFormat: {
30394 LT: 'HH:mm',
30395 LTS: 'HH:mm:ss',
30396 L: 'DD/MM/YYYY',
30397 LL: 'D MMMM YYYY',
30398 LLL: 'D MMMM YYYY HH:mm',
30399 LLLL: 'dddd D MMMM YYYY HH:mm'
30400 },
30401 calendar: {
30402 sameDay: '[Aujourd’hui à] LT',
30403 nextDay: '[Demain à] LT',
30404 nextWeek: 'dddd [à] LT',
30405 lastDay: '[Hier à] LT',
30406 lastWeek: 'dddd [dernier à] LT',
30407 sameElse: 'L'
30408 },
30409 relativeTime: {
30410 future: 'dans %s',
30411 past: 'il y a %s',
30412 s: 'quelques secondes',
30413 ss: '%d secondes',
30414 m: 'une minute',
30415 mm: '%d minutes',
30416 h: 'une heure',
30417 hh: '%d heures',
30418 d: 'un jour',
30419 dd: '%d jours',
30420 M: 'un mois',
30421 MM: '%d mois',
30422 y: 'un an',
30423 yy: '%d ans'
30424 },
30425 dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
30426 ordinal: function ordinal(number, period) {
30427 switch (period) {
30428 // TODO: Return 'e' when day of month > 1. Move this case inside
30429 // block for masculine words below.
30430 // See https://github.com/moment/moment/issues/3375
30431 case 'D':
30432 return number + (number === 1 ? 'er' : '');
30433 // Words with masculine grammatical gender: mois, trimestre, jour
30434
30435 default:
30436 case 'M':
30437 case 'Q':
30438 case 'DDD':
30439 case 'd':
30440 return number + (number === 1 ? 'er' : 'e');
30441 // Words with feminine grammatical gender: semaine
30442
30443 case 'w':
30444 case 'W':
30445 return number + (number === 1 ? 're' : 'e');
30446 }
30447 },
30448 week: {
30449 dow: 1,
30450 // Monday is the first day of the week.
30451 doy: 4 // The week that contains Jan 4th is the first week of the year.
30452
30453 }
30454 });
30455 return fr;
30456 });
30457});
30458
30459var es = createCommonjsModule(function (module, exports) {
30460
30461 (function (global, factory) {
30462 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30463 })(commonjsGlobal, function (moment) {
30464
30465 var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),
30466 _monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
30467
30468 var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i];
30469 var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
30470 var es = moment.defineLocale('es', {
30471 months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
30472 monthsShort: function monthsShort(m, format) {
30473 if (!m) {
30474 return monthsShortDot;
30475 } else if (/-MMM-/.test(format)) {
30476 return _monthsShort[m.month()];
30477 } else {
30478 return monthsShortDot[m.month()];
30479 }
30480 },
30481 monthsRegex: monthsRegex,
30482 monthsShortRegex: monthsRegex,
30483 monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
30484 monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
30485 monthsParse: monthsParse,
30486 longMonthsParse: monthsParse,
30487 shortMonthsParse: monthsParse,
30488 weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
30489 weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
30490 weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
30491 weekdaysParseExact: true,
30492 longDateFormat: {
30493 LT: 'H:mm',
30494 LTS: 'H:mm:ss',
30495 L: 'DD/MM/YYYY',
30496 LL: 'D [de] MMMM [de] YYYY',
30497 LLL: 'D [de] MMMM [de] YYYY H:mm',
30498 LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm'
30499 },
30500 calendar: {
30501 sameDay: function sameDay() {
30502 return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
30503 },
30504 nextDay: function nextDay() {
30505 return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
30506 },
30507 nextWeek: function nextWeek() {
30508 return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
30509 },
30510 lastDay: function lastDay() {
30511 return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
30512 },
30513 lastWeek: function lastWeek() {
30514 return '[el] dddd [pasado a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
30515 },
30516 sameElse: 'L'
30517 },
30518 relativeTime: {
30519 future: 'en %s',
30520 past: 'hace %s',
30521 s: 'unos segundos',
30522 ss: '%d segundos',
30523 m: 'un minuto',
30524 mm: '%d minutos',
30525 h: 'una hora',
30526 hh: '%d horas',
30527 d: 'un día',
30528 dd: '%d días',
30529 M: 'un mes',
30530 MM: '%d meses',
30531 y: 'un año',
30532 yy: '%d años'
30533 },
30534 dayOfMonthOrdinalParse: /\d{1,2}º/,
30535 ordinal: '%dº',
30536 week: {
30537 dow: 1,
30538 // Monday is the first day of the week.
30539 doy: 4 // The week that contains Jan 4th is the first week of the year.
30540
30541 }
30542 });
30543 return es;
30544 });
30545});
30546
30547var uk = createCommonjsModule(function (module, exports) {
30548
30549 (function (global, factory) {
30550 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30551 })(commonjsGlobal, function (moment) {
30552
30553 function plural(word, num) {
30554 var forms = word.split('_');
30555 return num % 10 === 1 && num % 100 !== 11 ? forms[0] : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2];
30556 }
30557
30558 function relativeTimeWithPlural(number, withoutSuffix, key) {
30559 var format = {
30560 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд',
30561 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
30562 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
30563 'dd': 'день_дні_днів',
30564 'MM': 'місяць_місяці_місяців',
30565 'yy': 'рік_роки_років'
30566 };
30567
30568 if (key === 'm') {
30569 return withoutSuffix ? 'хвилина' : 'хвилину';
30570 } else if (key === 'h') {
30571 return withoutSuffix ? 'година' : 'годину';
30572 } else {
30573 return number + ' ' + plural(format[key], +number);
30574 }
30575 }
30576
30577 function weekdaysCaseReplace(m, format) {
30578 var weekdays = {
30579 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
30580 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
30581 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
30582 };
30583
30584 if (m === true) {
30585 return weekdays['nominative'].slice(1, 7).concat(weekdays['nominative'].slice(0, 1));
30586 }
30587
30588 if (!m) {
30589 return weekdays['nominative'];
30590 }
30591
30592 var nounCase = /(\[[ВвУу]\]) ?dddd/.test(format) ? 'accusative' : /\[?(?:минулої|наступної)? ?\] ?dddd/.test(format) ? 'genitive' : 'nominative';
30593 return weekdays[nounCase][m.day()];
30594 }
30595
30596 function processHoursFunction(str) {
30597 return function () {
30598 return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
30599 };
30600 }
30601
30602 var uk = moment.defineLocale('uk', {
30603 months: {
30604 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),
30605 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')
30606 },
30607 monthsShort: 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),
30608 weekdays: weekdaysCaseReplace,
30609 weekdaysShort: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
30610 weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
30611 longDateFormat: {
30612 LT: 'HH:mm',
30613 LTS: 'HH:mm:ss',
30614 L: 'DD.MM.YYYY',
30615 LL: 'D MMMM YYYY р.',
30616 LLL: 'D MMMM YYYY р., HH:mm',
30617 LLLL: 'dddd, D MMMM YYYY р., HH:mm'
30618 },
30619 calendar: {
30620 sameDay: processHoursFunction('[Сьогодні '),
30621 nextDay: processHoursFunction('[Завтра '),
30622 lastDay: processHoursFunction('[Вчора '),
30623 nextWeek: processHoursFunction('[У] dddd ['),
30624 lastWeek: function lastWeek() {
30625 switch (this.day()) {
30626 case 0:
30627 case 3:
30628 case 5:
30629 case 6:
30630 return processHoursFunction('[Минулої] dddd [').call(this);
30631
30632 case 1:
30633 case 2:
30634 case 4:
30635 return processHoursFunction('[Минулого] dddd [').call(this);
30636 }
30637 },
30638 sameElse: 'L'
30639 },
30640 relativeTime: {
30641 future: 'за %s',
30642 past: '%s тому',
30643 s: 'декілька секунд',
30644 ss: relativeTimeWithPlural,
30645 m: relativeTimeWithPlural,
30646 mm: relativeTimeWithPlural,
30647 h: 'годину',
30648 hh: relativeTimeWithPlural,
30649 d: 'день',
30650 dd: relativeTimeWithPlural,
30651 M: 'місяць',
30652 MM: relativeTimeWithPlural,
30653 y: 'рік',
30654 yy: relativeTimeWithPlural
30655 },
30656 // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
30657 meridiemParse: /ночі|ранку|дня|вечора/,
30658 isPM: function isPM(input) {
30659 return /^(дня|вечора)$/.test(input);
30660 },
30661 meridiem: function meridiem(hour, minute, isLower) {
30662 if (hour < 4) {
30663 return 'ночі';
30664 } else if (hour < 12) {
30665 return 'ранку';
30666 } else if (hour < 17) {
30667 return 'дня';
30668 } else {
30669 return 'вечора';
30670 }
30671 },
30672 dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/,
30673 ordinal: function ordinal(number, period) {
30674 switch (period) {
30675 case 'M':
30676 case 'd':
30677 case 'DDD':
30678 case 'w':
30679 case 'W':
30680 return number + '-й';
30681
30682 case 'D':
30683 return number + '-го';
30684
30685 default:
30686 return number;
30687 }
30688 },
30689 week: {
30690 dow: 1,
30691 // Monday is the first day of the week.
30692 doy: 7 // The week that contains Jan 7th is the first week of the year.
30693
30694 }
30695 });
30696 return uk;
30697 });
30698});
30699
30700var ru = createCommonjsModule(function (module, exports) {
30701
30702 (function (global, factory) {
30703 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30704 })(commonjsGlobal, function (moment) {
30705
30706 function plural(word, num) {
30707 var forms = word.split('_');
30708 return num % 10 === 1 && num % 100 !== 11 ? forms[0] : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2];
30709 }
30710
30711 function relativeTimeWithPlural(number, withoutSuffix, key) {
30712 var format = {
30713 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд',
30714 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
30715 'hh': 'час_часа_часов',
30716 'dd': 'день_дня_дней',
30717 'MM': 'месяц_месяца_месяцев',
30718 'yy': 'год_года_лет'
30719 };
30720
30721 if (key === 'm') {
30722 return withoutSuffix ? 'минута' : 'минуту';
30723 } else {
30724 return number + ' ' + plural(format[key], +number);
30725 }
30726 }
30727
30728 var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; // http://new.gramota.ru/spravka/rules/139-prop : § 103
30729 // Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637
30730 // CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753
30731
30732 var ru = moment.defineLocale('ru', {
30733 months: {
30734 format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),
30735 standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')
30736 },
30737 monthsShort: {
30738 // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ?
30739 format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),
30740 standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')
30741 },
30742 weekdays: {
30743 standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
30744 format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),
30745 isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/
30746 },
30747 weekdaysShort: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
30748 weekdaysMin: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
30749 monthsParse: monthsParse,
30750 longMonthsParse: monthsParse,
30751 shortMonthsParse: monthsParse,
30752 // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки
30753 monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
30754 // копия предыдущего
30755 monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
30756 // полные названия с падежами
30757 monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,
30758 // Выражение, которое соотвествует только сокращённым формам
30759 monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,
30760 longDateFormat: {
30761 LT: 'H:mm',
30762 LTS: 'H:mm:ss',
30763 L: 'DD.MM.YYYY',
30764 LL: 'D MMMM YYYY г.',
30765 LLL: 'D MMMM YYYY г., H:mm',
30766 LLLL: 'dddd, D MMMM YYYY г., H:mm'
30767 },
30768 calendar: {
30769 sameDay: '[Сегодня, в] LT',
30770 nextDay: '[Завтра, в] LT',
30771 lastDay: '[Вчера, в] LT',
30772 nextWeek: function nextWeek(now) {
30773 if (now.week() !== this.week()) {
30774 switch (this.day()) {
30775 case 0:
30776 return '[В следующее] dddd, [в] LT';
30777
30778 case 1:
30779 case 2:
30780 case 4:
30781 return '[В следующий] dddd, [в] LT';
30782
30783 case 3:
30784 case 5:
30785 case 6:
30786 return '[В следующую] dddd, [в] LT';
30787 }
30788 } else {
30789 if (this.day() === 2) {
30790 return '[Во] dddd, [в] LT';
30791 } else {
30792 return '[В] dddd, [в] LT';
30793 }
30794 }
30795 },
30796 lastWeek: function lastWeek(now) {
30797 if (now.week() !== this.week()) {
30798 switch (this.day()) {
30799 case 0:
30800 return '[В прошлое] dddd, [в] LT';
30801
30802 case 1:
30803 case 2:
30804 case 4:
30805 return '[В прошлый] dddd, [в] LT';
30806
30807 case 3:
30808 case 5:
30809 case 6:
30810 return '[В прошлую] dddd, [в] LT';
30811 }
30812 } else {
30813 if (this.day() === 2) {
30814 return '[Во] dddd, [в] LT';
30815 } else {
30816 return '[В] dddd, [в] LT';
30817 }
30818 }
30819 },
30820 sameElse: 'L'
30821 },
30822 relativeTime: {
30823 future: 'через %s',
30824 past: '%s назад',
30825 s: 'несколько секунд',
30826 ss: relativeTimeWithPlural,
30827 m: relativeTimeWithPlural,
30828 mm: relativeTimeWithPlural,
30829 h: 'час',
30830 hh: relativeTimeWithPlural,
30831 d: 'день',
30832 dd: relativeTimeWithPlural,
30833 M: 'месяц',
30834 MM: relativeTimeWithPlural,
30835 y: 'год',
30836 yy: relativeTimeWithPlural
30837 },
30838 meridiemParse: /ночи|утра|дня|вечера/i,
30839 isPM: function isPM(input) {
30840 return /^(дня|вечера)$/.test(input);
30841 },
30842 meridiem: function meridiem(hour, minute, isLower) {
30843 if (hour < 4) {
30844 return 'ночи';
30845 } else if (hour < 12) {
30846 return 'утра';
30847 } else if (hour < 17) {
30848 return 'дня';
30849 } else {
30850 return 'вечера';
30851 }
30852 },
30853 dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/,
30854 ordinal: function ordinal(number, period) {
30855 switch (period) {
30856 case 'M':
30857 case 'd':
30858 case 'DDD':
30859 return number + '-й';
30860
30861 case 'D':
30862 return number + '-го';
30863
30864 case 'w':
30865 case 'W':
30866 return number + '-я';
30867
30868 default:
30869 return number;
30870 }
30871 },
30872 week: {
30873 dow: 1,
30874 // Monday is the first day of the week.
30875 doy: 4 // The week that contains Jan 4th is the first week of the year.
30876
30877 }
30878 });
30879 return ru;
30880 });
30881});
30882
30883var ja = createCommonjsModule(function (module, exports) {
30884
30885 (function (global, factory) {
30886 typeof commonjsRequire === 'function' ? factory(moment$2) : factory(global.moment);
30887 })(commonjsGlobal, function (moment) {
30888
30889 var ja = moment.defineLocale('ja', {
30890 months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
30891 monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
30892 weekdays: '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
30893 weekdaysShort: '日_月_火_水_木_金_土'.split('_'),
30894 weekdaysMin: '日_月_火_水_木_金_土'.split('_'),
30895 longDateFormat: {
30896 LT: 'HH:mm',
30897 LTS: 'HH:mm:ss',
30898 L: 'YYYY/MM/DD',
30899 LL: 'YYYY年M月D日',
30900 LLL: 'YYYY年M月D日 HH:mm',
30901 LLLL: 'YYYY年M月D日 dddd HH:mm',
30902 l: 'YYYY/MM/DD',
30903 ll: 'YYYY年M月D日',
30904 lll: 'YYYY年M月D日 HH:mm',
30905 llll: 'YYYY年M月D日(ddd) HH:mm'
30906 },
30907 meridiemParse: /午前|午後/i,
30908 isPM: function isPM(input) {
30909 return input === '午後';
30910 },
30911 meridiem: function meridiem(hour, minute, isLower) {
30912 if (hour < 12) {
30913 return '午前';
30914 } else {
30915 return '午後';
30916 }
30917 },
30918 calendar: {
30919 sameDay: '[今日] LT',
30920 nextDay: '[明日] LT',
30921 nextWeek: function nextWeek(now) {
30922 if (now.week() < this.week()) {
30923 return '[来週]dddd LT';
30924 } else {
30925 return 'dddd LT';
30926 }
30927 },
30928 lastDay: '[昨日] LT',
30929 lastWeek: function lastWeek(now) {
30930 if (this.week() < now.week()) {
30931 return '[先週]dddd LT';
30932 } else {
30933 return 'dddd LT';
30934 }
30935 },
30936 sameElse: 'L'
30937 },
30938 dayOfMonthOrdinalParse: /\d{1,2}日/,
30939 ordinal: function ordinal(number, period) {
30940 switch (period) {
30941 case 'd':
30942 case 'D':
30943 case 'DDD':
30944 return number + '日';
30945
30946 default:
30947 return number;
30948 }
30949 },
30950 relativeTime: {
30951 future: '%s後',
30952 past: '%s前',
30953 s: '数秒',
30954 ss: '%d秒',
30955 m: '1分',
30956 mm: '%d分',
30957 h: '1時間',
30958 hh: '%d時間',
30959 d: '1日',
30960 dd: '%d日',
30961 M: '1ヶ月',
30962 MM: '%dヶ月',
30963 y: '1年',
30964 yy: '%d年'
30965 }
30966 });
30967 return ja;
30968 });
30969});
30970
30971var locales = createCommonjsModule(function (module, exports) {
30972 // English
30973 exports['en'] = {
30974 current: 'current',
30975 time: 'time',
30976 deleteSelected: 'Delete selected'
30977 };
30978 exports['en_EN'] = exports['en'];
30979 exports['en_US'] = exports['en']; // Italiano
30980
30981 exports['it'] = {
30982 current: 'attuale',
30983 time: 'tempo',
30984 deleteSelected: 'Cancella la selezione'
30985 };
30986 exports['it_IT'] = exports['it'];
30987 exports['it_CH'] = exports['it']; // Dutch
30988
30989 exports['nl'] = {
30990 current: 'huidige',
30991 time: 'tijd',
30992 deleteSelected: 'Selectie verwijderen'
30993 };
30994 exports['nl_NL'] = exports['nl'];
30995 exports['nl_BE'] = exports['nl']; // German
30996
30997 exports['de'] = {
30998 current: 'Aktuelle',
30999 time: 'Zeit',
31000 deleteSelected: "L\xF6sche Auswahl"
31001 };
31002 exports['de_DE'] = exports['de']; // French
31003
31004 exports['fr'] = {
31005 current: 'actuel',
31006 time: 'heure',
31007 deleteSelected: 'Effacer la selection'
31008 };
31009 exports['fr_FR'] = exports['fr'];
31010 exports['fr_CA'] = exports['fr'];
31011 exports['fr_BE'] = exports['fr']; // Espanol
31012
31013 exports['es'] = {
31014 current: 'corriente',
31015 time: 'hora',
31016 deleteSelected: "Eliminar selecci\xF3n"
31017 };
31018 exports['es_ES'] = exports['es']; // Ukrainian
31019
31020 exports['uk'] = {
31021 current: 'поточний',
31022 time: 'час',
31023 deleteSelected: 'Видалити обране'
31024 };
31025 exports['uk_UA'] = exports['uk']; // Russian
31026
31027 exports['ru'] = {
31028 current: 'текущее',
31029 time: 'время',
31030 deleteSelected: 'Удалить выбранное'
31031 };
31032 exports['ru_RU'] = exports['ru']; // Japanese
31033
31034 exports['ja'] = {
31035 current: '現在',
31036 time: '時刻',
31037 deleteSelected: '選択されたものを削除'
31038 };
31039 exports['ja_JP'] = exports['ja'];
31040});
31041
31042/** A custom time bar */
31043
31044var CustomTime =
31045/*#__PURE__*/
31046function (_Component) {
31047 _inherits(CustomTime, _Component);
31048
31049 /**
31050 * @param {{range: Range, dom: Object}} body
31051 * @param {Object} [options] Available parameters:
31052 * {number | string} id
31053 * {string} locales
31054 * {string} locale
31055 * @constructor CustomTime
31056 * @extends Component
31057 */
31058 function CustomTime(body, options) {
31059 var _this;
31060
31061 _classCallCheck(this, CustomTime);
31062
31063 _this = _possibleConstructorReturn(this, _getPrototypeOf(CustomTime).call(this));
31064 _this.body = body; // default options
31065
31066 _this.defaultOptions = {
31067 moment: moment$3,
31068 locales: locales,
31069 locale: 'en',
31070 id: undefined,
31071 title: undefined
31072 };
31073 _this.options = util.extend({}, _this.defaultOptions);
31074
31075 _this.setOptions(options);
31076
31077 util.extend(_this.options.locales, locales, _this.options.locales);
31078 var defaultLocales = _this.defaultOptions.locales[_this.defaultOptions.locale];
31079 Object.keys(_this.options.locales).forEach(function (locale) {
31080 _this.options.locales[locale] = util.extend({}, defaultLocales, _this.options.locales[locale]);
31081 });
31082
31083 if (options && options.time) {
31084 _this.customTime = options.time;
31085 } else {
31086 _this.customTime = new Date();
31087 }
31088
31089 _this.eventParams = {}; // stores state parameters while dragging the bar
31090 // create the DOM
31091
31092 _this._create();
31093
31094 return _this;
31095 }
31096 /**
31097 * Set options for the component. Options will be merged in current options.
31098 * @param {Object} options Available parameters:
31099 * {number | string} id
31100 * {string} locales
31101 * {string} locale
31102 */
31103
31104
31105 _createClass(CustomTime, [{
31106 key: "setOptions",
31107 value: function setOptions(options) {
31108 if (options) {
31109 // copy all options that we know
31110 util.selectiveExtend(['moment', 'locale', 'locales', 'id', 'title', 'rtl'], this.options, options);
31111 }
31112 }
31113 /**
31114 * Create the DOM for the custom time
31115 * @private
31116 */
31117
31118 }, {
31119 key: "_create",
31120 value: function _create() {
31121 var bar = document.createElement('div');
31122 bar['custom-time'] = this;
31123 bar.className = "vis-custom-time ".concat(this.options.id || '');
31124 bar.style.position = 'absolute';
31125 bar.style.top = '0px';
31126 bar.style.height = '100%';
31127 this.bar = bar;
31128 var drag = document.createElement('div');
31129 drag.style.position = 'relative';
31130 drag.style.top = '0px';
31131
31132 if (this.options.rtl) {
31133 drag.style.right = '-10px';
31134 } else {
31135 drag.style.left = '-10px';
31136 }
31137
31138 drag.style.height = '100%';
31139 drag.style.width = '20px';
31140 /**
31141 *
31142 * @param {WheelEvent} e
31143 */
31144
31145 function onMouseWheel(e) {
31146 this.body.range._onMouseWheel(e);
31147 }
31148
31149 if (drag.addEventListener) {
31150 // IE9, Chrome, Safari, Opera
31151 drag.addEventListener("mousewheel", onMouseWheel.bind(this), false); // Firefox
31152
31153 drag.addEventListener("DOMMouseScroll", onMouseWheel.bind(this), false);
31154 } else {
31155 // IE 6/7/8
31156 drag.attachEvent("onmousewheel", onMouseWheel.bind(this));
31157 }
31158
31159 bar.appendChild(drag); // attach event listeners
31160
31161 this.hammer = new Hammer$1(drag);
31162 this.hammer.on('panstart', this._onDragStart.bind(this));
31163 this.hammer.on('panmove', this._onDrag.bind(this));
31164 this.hammer.on('panend', this._onDragEnd.bind(this));
31165 this.hammer.get('pan').set({
31166 threshold: 5,
31167 direction: Hammer$1.DIRECTION_ALL
31168 });
31169 }
31170 /**
31171 * Destroy the CustomTime bar
31172 */
31173
31174 }, {
31175 key: "destroy",
31176 value: function destroy() {
31177 this.hide();
31178 this.hammer.destroy();
31179 this.hammer = null;
31180 this.body = null;
31181 }
31182 /**
31183 * Repaint the component
31184 * @return {boolean} Returns true if the component is resized
31185 */
31186
31187 }, {
31188 key: "redraw",
31189 value: function redraw() {
31190 var parent = this.body.dom.backgroundVertical;
31191
31192 if (this.bar.parentNode != parent) {
31193 // attach to the dom
31194 if (this.bar.parentNode) {
31195 this.bar.parentNode.removeChild(this.bar);
31196 }
31197
31198 parent.appendChild(this.bar);
31199 }
31200
31201 var x = this.body.util.toScreen(this.customTime);
31202 var locale = this.options.locales[this.options.locale];
31203
31204 if (!locale) {
31205 if (!this.warned) {
31206 console.warn("WARNING: options.locales['".concat(this.options.locale, "'] not found. See https://visjs.github.io/vis-timeline/docs/timeline/#Localization"));
31207 this.warned = true;
31208 }
31209
31210 locale = this.options.locales['en']; // fall back on english when not available
31211 }
31212
31213 var title = this.options.title; // To hide the title completely use empty string ''.
31214
31215 if (title === undefined) {
31216 title = "".concat(locale.time, ": ").concat(this.options.moment(this.customTime).format('dddd, MMMM Do YYYY, H:mm:ss'));
31217 title = title.charAt(0).toUpperCase() + title.substring(1);
31218 } else if (typeof title === "function") {
31219 title = title.call(this.customTime);
31220 }
31221
31222 this.options.rtl ? this.bar.style.right = "".concat(x, "px") : this.bar.style.left = "".concat(x, "px");
31223 this.bar.title = title;
31224 return false;
31225 }
31226 /**
31227 * Remove the CustomTime from the DOM
31228 */
31229
31230 }, {
31231 key: "hide",
31232 value: function hide() {
31233 // remove the line from the DOM
31234 if (this.bar.parentNode) {
31235 this.bar.parentNode.removeChild(this.bar);
31236 }
31237 }
31238 /**
31239 * Set custom time.
31240 * @param {Date | number | string} time
31241 */
31242
31243 }, {
31244 key: "setCustomTime",
31245 value: function setCustomTime(time) {
31246 this.customTime = util.convert(time, 'Date');
31247 this.redraw();
31248 }
31249 /**
31250 * Retrieve the current custom time.
31251 * @return {Date} customTime
31252 */
31253
31254 }, {
31255 key: "getCustomTime",
31256 value: function getCustomTime() {
31257 return new Date(this.customTime.valueOf());
31258 }
31259 /**
31260 * Set custom marker.
31261 * @param {string} [title] Title of the custom marker
31262 * @param {boolean} [editable] Make the custom marker editable.
31263 */
31264
31265 }, {
31266 key: "setCustomMarker",
31267 value: function setCustomMarker(title, editable) {
31268 var marker = document.createElement('div');
31269 marker.className = "vis-custom-time-marker";
31270 marker.innerHTML = title;
31271 marker.style.position = 'absolute';
31272
31273 if (editable) {
31274 marker.setAttribute('contenteditable', 'true');
31275 marker.addEventListener('pointerdown', function () {
31276 marker.focus();
31277 });
31278 marker.addEventListener('input', this._onMarkerChange.bind(this)); // The editable div element has no change event, so here emulates the change event.
31279
31280 marker.title = title;
31281 marker.addEventListener('blur', function (event) {
31282 if (this.title != event.target.innerHTML) {
31283 this._onMarkerChanged(event);
31284
31285 this.title = event.target.innerHTML;
31286 }
31287 }.bind(this));
31288 }
31289
31290 this.bar.appendChild(marker);
31291 }
31292 /**
31293 * Set custom title.
31294 * @param {Date | number | string} title
31295 */
31296
31297 }, {
31298 key: "setCustomTitle",
31299 value: function setCustomTitle(title) {
31300 this.options.title = title;
31301 }
31302 /**
31303 * Start moving horizontally
31304 * @param {Event} event
31305 * @private
31306 */
31307
31308 }, {
31309 key: "_onDragStart",
31310 value: function _onDragStart(event) {
31311 this.eventParams.dragging = true;
31312 this.eventParams.customTime = this.customTime;
31313 event.stopPropagation();
31314 }
31315 /**
31316 * Perform moving operating.
31317 * @param {Event} event
31318 * @private
31319 */
31320
31321 }, {
31322 key: "_onDrag",
31323 value: function _onDrag(event) {
31324 if (!this.eventParams.dragging) return;
31325 var deltaX = this.options.rtl ? -1 * event.deltaX : event.deltaX;
31326 var x = this.body.util.toScreen(this.eventParams.customTime) + deltaX;
31327 var time = this.body.util.toTime(x);
31328 this.setCustomTime(time); // fire a timechange event
31329
31330 this.body.emitter.emit('timechange', {
31331 id: this.options.id,
31332 time: new Date(this.customTime.valueOf()),
31333 event: event
31334 });
31335 event.stopPropagation();
31336 }
31337 /**
31338 * Stop moving operating.
31339 * @param {Event} event
31340 * @private
31341 */
31342
31343 }, {
31344 key: "_onDragEnd",
31345 value: function _onDragEnd(event) {
31346 if (!this.eventParams.dragging) return; // fire a timechanged event
31347
31348 this.body.emitter.emit('timechanged', {
31349 id: this.options.id,
31350 time: new Date(this.customTime.valueOf()),
31351 event: event
31352 });
31353 event.stopPropagation();
31354 }
31355 /**
31356 * Perform input operating.
31357 * @param {Event} event
31358 * @private
31359 */
31360
31361 }, {
31362 key: "_onMarkerChange",
31363 value: function _onMarkerChange(event) {
31364 this.body.emitter.emit('markerchange', {
31365 id: this.options.id,
31366 title: event.target.innerHTML,
31367 event: event
31368 });
31369 event.stopPropagation();
31370 }
31371 /**
31372 * Perform change operating.
31373 * @param {Event} event
31374 * @private
31375 */
31376
31377 }, {
31378 key: "_onMarkerChanged",
31379 value: function _onMarkerChanged(event) {
31380 this.body.emitter.emit('markerchanged', {
31381 id: this.options.id,
31382 title: event.target.innerHTML,
31383 event: event
31384 });
31385 event.stopPropagation();
31386 }
31387 /**
31388 * Find a custom time from an event target:
31389 * searches for the attribute 'custom-time' in the event target's element tree
31390 * @param {Event} event
31391 * @return {CustomTime | null} customTime
31392 */
31393
31394 }], [{
31395 key: "customTimeFromTarget",
31396 value: function customTimeFromTarget(event) {
31397 var target = event.target;
31398
31399 while (target) {
31400 if (target.hasOwnProperty('custom-time')) {
31401 return target['custom-time'];
31402 }
31403
31404 target = target.parentNode;
31405 }
31406
31407 return null;
31408 }
31409 }]);
31410
31411 return CustomTime;
31412}(Component);
31413
31414/**
31415 * Create a timeline visualization
31416 * @constructor Core
31417 */
31418
31419var Core =
31420/*#__PURE__*/
31421function () {
31422 function Core() {
31423 _classCallCheck(this, Core);
31424 }
31425
31426 _createClass(Core, [{
31427 key: "_create",
31428
31429 /**
31430 * Create the main DOM for the Core: a root panel containing left, right,
31431 * top, bottom, content, and background panel.
31432 * @param {Element} container The container element where the Core will
31433 * be attached.
31434 * @protected
31435 */
31436 value: function _create(container) {
31437 var _this = this;
31438
31439 this.dom = {};
31440 this.dom.container = container;
31441 this.dom.container.style.position = 'relative';
31442 this.dom.root = document.createElement('div');
31443 this.dom.background = document.createElement('div');
31444 this.dom.backgroundVertical = document.createElement('div');
31445 this.dom.backgroundHorizontal = document.createElement('div');
31446 this.dom.centerContainer = document.createElement('div');
31447 this.dom.leftContainer = document.createElement('div');
31448 this.dom.rightContainer = document.createElement('div');
31449 this.dom.center = document.createElement('div');
31450 this.dom.left = document.createElement('div');
31451 this.dom.right = document.createElement('div');
31452 this.dom.top = document.createElement('div');
31453 this.dom.bottom = document.createElement('div');
31454 this.dom.shadowTop = document.createElement('div');
31455 this.dom.shadowBottom = document.createElement('div');
31456 this.dom.shadowTopLeft = document.createElement('div');
31457 this.dom.shadowBottomLeft = document.createElement('div');
31458 this.dom.shadowTopRight = document.createElement('div');
31459 this.dom.shadowBottomRight = document.createElement('div');
31460 this.dom.rollingModeBtn = document.createElement('div');
31461 this.dom.loadingScreen = document.createElement('div');
31462 this.dom.root.className = 'vis-timeline';
31463 this.dom.background.className = 'vis-panel vis-background';
31464 this.dom.backgroundVertical.className = 'vis-panel vis-background vis-vertical';
31465 this.dom.backgroundHorizontal.className = 'vis-panel vis-background vis-horizontal';
31466 this.dom.centerContainer.className = 'vis-panel vis-center';
31467 this.dom.leftContainer.className = 'vis-panel vis-left';
31468 this.dom.rightContainer.className = 'vis-panel vis-right';
31469 this.dom.top.className = 'vis-panel vis-top';
31470 this.dom.bottom.className = 'vis-panel vis-bottom';
31471 this.dom.left.className = 'vis-content';
31472 this.dom.center.className = 'vis-content';
31473 this.dom.right.className = 'vis-content';
31474 this.dom.shadowTop.className = 'vis-shadow vis-top';
31475 this.dom.shadowBottom.className = 'vis-shadow vis-bottom';
31476 this.dom.shadowTopLeft.className = 'vis-shadow vis-top';
31477 this.dom.shadowBottomLeft.className = 'vis-shadow vis-bottom';
31478 this.dom.shadowTopRight.className = 'vis-shadow vis-top';
31479 this.dom.shadowBottomRight.className = 'vis-shadow vis-bottom';
31480 this.dom.rollingModeBtn.className = 'vis-rolling-mode-btn';
31481 this.dom.loadingScreen.className = 'vis-loading-screen';
31482 this.dom.root.appendChild(this.dom.background);
31483 this.dom.root.appendChild(this.dom.backgroundVertical);
31484 this.dom.root.appendChild(this.dom.backgroundHorizontal);
31485 this.dom.root.appendChild(this.dom.centerContainer);
31486 this.dom.root.appendChild(this.dom.leftContainer);
31487 this.dom.root.appendChild(this.dom.rightContainer);
31488 this.dom.root.appendChild(this.dom.top);
31489 this.dom.root.appendChild(this.dom.bottom);
31490 this.dom.root.appendChild(this.dom.rollingModeBtn);
31491 this.dom.centerContainer.appendChild(this.dom.center);
31492 this.dom.leftContainer.appendChild(this.dom.left);
31493 this.dom.rightContainer.appendChild(this.dom.right);
31494 this.dom.centerContainer.appendChild(this.dom.shadowTop);
31495 this.dom.centerContainer.appendChild(this.dom.shadowBottom);
31496 this.dom.leftContainer.appendChild(this.dom.shadowTopLeft);
31497 this.dom.leftContainer.appendChild(this.dom.shadowBottomLeft);
31498 this.dom.rightContainer.appendChild(this.dom.shadowTopRight);
31499 this.dom.rightContainer.appendChild(this.dom.shadowBottomRight); // size properties of each of the panels
31500
31501 this.props = {
31502 root: {},
31503 background: {},
31504 centerContainer: {},
31505 leftContainer: {},
31506 rightContainer: {},
31507 center: {},
31508 left: {},
31509 right: {},
31510 top: {},
31511 bottom: {},
31512 border: {},
31513 scrollTop: 0,
31514 scrollTopMin: 0
31515 };
31516 this.on('rangechange', function () {
31517 if (_this.initialDrawDone === true) {
31518 _this._redraw();
31519 }
31520 });
31521 this.on('rangechanged', function () {
31522 if (!_this.initialRangeChangeDone) {
31523 _this.initialRangeChangeDone = true;
31524 }
31525 });
31526 this.on('touch', this._onTouch.bind(this));
31527 this.on('panmove', this._onDrag.bind(this));
31528 var me = this;
31529 this._origRedraw = this._redraw.bind(this);
31530 this._redraw = util.throttle(this._origRedraw);
31531 this.on('_change', function (properties) {
31532 if (me.itemSet && me.itemSet.initialItemSetDrawn && properties && properties.queue == true) {
31533 me._redraw();
31534 } else {
31535 me._origRedraw();
31536 }
31537 }); // create event listeners for all interesting events, these events will be
31538 // emitted via emitter
31539
31540 this.hammer = new Hammer$1(this.dom.root);
31541 var pinchRecognizer = this.hammer.get('pinch').set({
31542 enable: true
31543 });
31544 pinchRecognizer && disablePreventDefaultVertically(pinchRecognizer);
31545 this.hammer.get('pan').set({
31546 threshold: 5,
31547 direction: Hammer$1.DIRECTION_ALL
31548 });
31549 this.listeners = {};
31550 var events = ['tap', 'doubletap', 'press', 'pinch', 'pan', 'panstart', 'panmove', 'panend' // TODO: cleanup
31551 //'touch', 'pinch',
31552 //'tap', 'doubletap', 'hold',
31553 //'dragstart', 'drag', 'dragend',
31554 //'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox
31555 ];
31556 events.forEach(function (type) {
31557 var listener = function listener(event) {
31558 if (me.isActive()) {
31559 me.emit(type, event);
31560 }
31561 };
31562
31563 me.hammer.on(type, listener);
31564 me.listeners[type] = listener;
31565 }); // emulate a touch event (emitted before the start of a pan, pinch, tap, or press)
31566
31567 onTouch(this.hammer, function (event) {
31568 me.emit('touch', event);
31569 }); // emulate a release event (emitted after a pan, pinch, tap, or press)
31570
31571 onRelease(this.hammer, function (event) {
31572 me.emit('release', event);
31573 });
31574 /**
31575 *
31576 * @param {WheelEvent} event
31577 */
31578
31579 function onMouseWheel(event) {
31580 // Reasonable default wheel deltas
31581 var LINE_HEIGHT = 40;
31582 var PAGE_HEIGHT = 800;
31583
31584 if (this.isActive()) {
31585 this.emit('mousewheel', event);
31586 } // deltaX and deltaY normalization from jquery.mousewheel.js
31587
31588
31589 var deltaX = 0;
31590 var deltaY = 0; // Old school scrollwheel delta
31591
31592 if ('detail' in event) {
31593 deltaY = event.detail * -1;
31594 }
31595
31596 if ('wheelDelta' in event) {
31597 deltaY = event.wheelDelta;
31598 }
31599
31600 if ('wheelDeltaY' in event) {
31601 deltaY = event.wheelDeltaY;
31602 }
31603
31604 if ('wheelDeltaX' in event) {
31605 deltaX = event.wheelDeltaX * -1;
31606 } // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
31607
31608
31609 if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {
31610 deltaX = deltaY * -1;
31611 deltaY = 0;
31612 } // New school wheel delta (wheel event)
31613
31614
31615 if ('deltaY' in event) {
31616 deltaY = event.deltaY * -1;
31617 }
31618
31619 if ('deltaX' in event) {
31620 deltaX = event.deltaX;
31621 } // Normalize deltas
31622
31623
31624 if (event.deltaMode) {
31625 if (event.deltaMode === 1) {
31626 // delta in LINE units
31627 deltaX *= LINE_HEIGHT;
31628 deltaY *= LINE_HEIGHT;
31629 } else {
31630 // delta in PAGE units
31631 deltaX *= LINE_HEIGHT;
31632 deltaY *= PAGE_HEIGHT;
31633 }
31634 } // Prevent scrolling when zooming (no zoom key, or pressing zoom key)
31635
31636
31637 if (this.options.preferZoom) {
31638 if (!this.options.zoomKey || event[this.options.zoomKey]) return;
31639 } else {
31640 if (this.options.zoomKey && event[this.options.zoomKey]) return;
31641 } // Don't preventDefault if you can't scroll
31642
31643
31644 if (!this.options.verticalScroll && !this.options.horizontalScroll) return;
31645
31646 if (this.options.verticalScroll && Math.abs(deltaY) >= Math.abs(deltaX)) {
31647 var current = this.props.scrollTop;
31648 var adjusted = current + deltaY;
31649
31650 if (this.isActive()) {
31651 var newScrollTop = this._setScrollTop(adjusted);
31652
31653 if (newScrollTop !== current) {
31654 this._redraw();
31655
31656 this.emit('scroll', event); // Prevent default actions caused by mouse wheel
31657 // (else the page and timeline both scroll)
31658
31659 event.preventDefault();
31660 }
31661 }
31662 } else if (this.options.horizontalScroll) {
31663 var delta = Math.abs(deltaX) >= Math.abs(deltaY) ? deltaX : deltaY; // calculate a single scroll jump relative to the range scale
31664
31665 var diff = delta / 120 * (this.range.end - this.range.start) / 20; // calculate new start and end
31666
31667 var newStart = this.range.start + diff;
31668 var newEnd = this.range.end + diff;
31669 var options = {
31670 animation: false,
31671 byUser: true,
31672 event: event
31673 };
31674 this.range.setRange(newStart, newEnd, options);
31675 event.preventDefault();
31676 }
31677 } // Add modern wheel event listener
31678
31679
31680 var wheelType = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
31681 document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
31682 this.dom.centerContainer.addEventListener ? "DOMMouseScroll" : // Older Firefox versions use "DOMMouseScroll"
31683 "onmousewheel"; // All the use "onmousewheel"
31684
31685 this.dom.centerContainer.addEventListener(wheelType, onMouseWheel.bind(this), false);
31686 /**
31687 *
31688 * @param {scroll} event
31689 */
31690
31691 function onMouseScrollSide(event) {
31692 if (!me.options.verticalScroll) return;
31693 event.preventDefault();
31694
31695 if (me.isActive()) {
31696 var adjusted = -event.target.scrollTop;
31697
31698 me._setScrollTop(adjusted);
31699
31700 me._redraw();
31701
31702 me.emit('scrollSide', event);
31703 }
31704 }
31705
31706 this.dom.left.parentNode.addEventListener('scroll', onMouseScrollSide.bind(this));
31707 this.dom.right.parentNode.addEventListener('scroll', onMouseScrollSide.bind(this));
31708 var itemAddedToTimeline = false;
31709 /**
31710 *
31711 * @param {dragover} event
31712 * @returns {boolean}
31713 */
31714
31715 function handleDragOver(event) {
31716 if (event.preventDefault) {
31717 me.emit('dragover', me.getEventProperties(event));
31718 event.preventDefault(); // Necessary. Allows us to drop.
31719 } // make sure your target is a timeline element
31720
31721
31722 if (!(event.target.className.indexOf("timeline") > -1)) return; // make sure only one item is added every time you're over the timeline
31723
31724 if (itemAddedToTimeline) return;
31725 event.dataTransfer.dropEffect = 'move';
31726 itemAddedToTimeline = true;
31727 return false;
31728 }
31729 /**
31730 *
31731 * @param {drop} event
31732 * @returns {boolean}
31733 */
31734
31735
31736 function handleDrop(event) {
31737 // prevent redirect to blank page - Firefox
31738 if (event.preventDefault) {
31739 event.preventDefault();
31740 }
31741
31742 if (event.stopPropagation) {
31743 event.stopPropagation();
31744 } // return when dropping non-timeline items
31745
31746
31747 try {
31748 var itemData = JSON.parse(event.dataTransfer.getData("text"));
31749 if (!itemData || !itemData.content) return;
31750 } catch (err) {
31751 return false;
31752 }
31753
31754 itemAddedToTimeline = false;
31755 event.center = {
31756 x: event.clientX,
31757 y: event.clientY
31758 };
31759
31760 if (itemData.target !== 'item') {
31761 me.itemSet._onAddItem(event);
31762 } else {
31763 me.itemSet._onDropObjectOnItem(event);
31764 }
31765
31766 me.emit('drop', me.getEventProperties(event));
31767 return false;
31768 }
31769
31770 this.dom.center.addEventListener('dragover', handleDragOver.bind(this), false);
31771 this.dom.center.addEventListener('drop', handleDrop.bind(this), false);
31772 this.customTimes = []; // store state information needed for touch events
31773
31774 this.touch = {};
31775 this.redrawCount = 0;
31776 this.initialDrawDone = false;
31777 this.initialRangeChangeDone = false; // attach the root panel to the provided container
31778
31779 if (!container) throw new Error('No container provided');
31780 container.appendChild(this.dom.root);
31781 container.appendChild(this.dom.loadingScreen);
31782 }
31783 /**
31784 * Set options. Options will be passed to all components loaded in the Timeline.
31785 * @param {Object} [options]
31786 * {String} orientation
31787 * Vertical orientation for the Timeline,
31788 * can be 'bottom' (default) or 'top'.
31789 * {string | number} width
31790 * Width for the timeline, a number in pixels or
31791 * a css string like '1000px' or '75%'. '100%' by default.
31792 * {string | number} height
31793 * Fixed height for the Timeline, a number in pixels or
31794 * a css string like '400px' or '75%'. If undefined,
31795 * The Timeline will automatically size such that
31796 * its contents fit.
31797 * {string | number} minHeight
31798 * Minimum height for the Timeline, a number in pixels or
31799 * a css string like '400px' or '75%'.
31800 * {string | number} maxHeight
31801 * Maximum height for the Timeline, a number in pixels or
31802 * a css string like '400px' or '75%'.
31803 * {number | Date | string} start
31804 * Start date for the visible window
31805 * {number | Date | string} end
31806 * End date for the visible window
31807 */
31808
31809 }, {
31810 key: "setOptions",
31811 value: function setOptions(options) {
31812 if (options) {
31813 // copy the known options
31814 var fields = ['width', 'height', 'minHeight', 'maxHeight', 'autoResize', 'start', 'end', 'clickToUse', 'dataAttributes', 'hiddenDates', 'locale', 'locales', 'moment', 'preferZoom', 'rtl', 'zoomKey', 'horizontalScroll', 'verticalScroll'];
31815 util.selectiveExtend(fields, this.options, options);
31816 this.dom.rollingModeBtn.style.visibility = 'hidden';
31817
31818 if (this.options.rtl) {
31819 this.dom.container.style.direction = "rtl";
31820 this.dom.backgroundVertical.className = 'vis-panel vis-background vis-vertical-rtl';
31821 }
31822
31823 if (this.options.verticalScroll) {
31824 if (this.options.rtl) {
31825 this.dom.rightContainer.className = 'vis-panel vis-right vis-vertical-scroll';
31826 } else {
31827 this.dom.leftContainer.className = 'vis-panel vis-left vis-vertical-scroll';
31828 }
31829 }
31830
31831 if (_typeof(this.options.orientation) !== 'object') {
31832 this.options.orientation = {
31833 item: undefined,
31834 axis: undefined
31835 };
31836 }
31837
31838 if ('orientation' in options) {
31839 if (typeof options.orientation === 'string') {
31840 this.options.orientation = {
31841 item: options.orientation,
31842 axis: options.orientation
31843 };
31844 } else if (_typeof(options.orientation) === 'object') {
31845 if ('item' in options.orientation) {
31846 this.options.orientation.item = options.orientation.item;
31847 }
31848
31849 if ('axis' in options.orientation) {
31850 this.options.orientation.axis = options.orientation.axis;
31851 }
31852 }
31853 }
31854
31855 if (this.options.orientation.axis === 'both') {
31856 if (!this.timeAxis2) {
31857 var timeAxis2 = this.timeAxis2 = new TimeAxis(this.body);
31858
31859 timeAxis2.setOptions = function (options) {
31860 var _options = options ? util.extend({}, options) : {};
31861
31862 _options.orientation = 'top'; // override the orientation option, always top
31863
31864 TimeAxis.prototype.setOptions.call(timeAxis2, _options);
31865 };
31866
31867 this.components.push(timeAxis2);
31868 }
31869 } else {
31870 if (this.timeAxis2) {
31871 var index = this.components.indexOf(this.timeAxis2);
31872
31873 if (index !== -1) {
31874 this.components.splice(index, 1);
31875 }
31876
31877 this.timeAxis2.destroy();
31878 this.timeAxis2 = null;
31879 }
31880 } // if the graph2d's drawPoints is a function delegate the callback to the onRender property
31881
31882
31883 if (typeof options.drawPoints == 'function') {
31884 options.drawPoints = {
31885 onRender: options.drawPoints
31886 };
31887 }
31888
31889 if ('hiddenDates' in this.options) {
31890 convertHiddenOptions(this.options.moment, this.body, this.options.hiddenDates);
31891 }
31892
31893 if ('clickToUse' in options) {
31894 if (options.clickToUse) {
31895 if (!this.activator) {
31896 this.activator = new Activator(this.dom.root);
31897 }
31898 } else {
31899 if (this.activator) {
31900 this.activator.destroy();
31901 delete this.activator;
31902 }
31903 }
31904 } // enable/disable autoResize
31905
31906
31907 this._initAutoResize();
31908 } // propagate options to all components
31909
31910
31911 this.components.forEach(function (component) {
31912 return component.setOptions(options);
31913 }); // enable/disable configure
31914
31915 if ('configure' in options) {
31916 if (!this.configurator) {
31917 this.configurator = this._createConfigurator();
31918 }
31919
31920 this.configurator.setOptions(options.configure); // collect the settings of all components, and pass them to the configuration system
31921
31922 var appliedOptions = util.deepExtend({}, this.options);
31923 this.components.forEach(function (component) {
31924 util.deepExtend(appliedOptions, component.options);
31925 });
31926 this.configurator.setModuleOptions({
31927 global: appliedOptions
31928 });
31929 }
31930
31931 this._redraw();
31932 }
31933 /**
31934 * Returns true when the Timeline is active.
31935 * @returns {boolean}
31936 */
31937
31938 }, {
31939 key: "isActive",
31940 value: function isActive() {
31941 return !this.activator || this.activator.active;
31942 }
31943 /**
31944 * Destroy the Core, clean up all DOM elements and event listeners.
31945 */
31946
31947 }, {
31948 key: "destroy",
31949 value: function destroy() {
31950 // unbind datasets
31951 this.setItems(null);
31952 this.setGroups(null); // remove all event listeners
31953
31954 this.off(); // stop checking for changed size
31955
31956 this._stopAutoResize(); // remove from DOM
31957
31958
31959 if (this.dom.root.parentNode) {
31960 this.dom.root.parentNode.removeChild(this.dom.root);
31961 }
31962
31963 this.dom = null; // remove Activator
31964
31965 if (this.activator) {
31966 this.activator.destroy();
31967 delete this.activator;
31968 } // cleanup hammer touch events
31969
31970
31971 for (var event in this.listeners) {
31972 if (this.listeners.hasOwnProperty(event)) {
31973 delete this.listeners[event];
31974 }
31975 }
31976
31977 this.listeners = null;
31978 this.hammer && this.hammer.destroy();
31979 this.hammer = null; // give all components the opportunity to cleanup
31980
31981 this.components.forEach(function (component) {
31982 return component.destroy();
31983 });
31984 this.body = null;
31985 }
31986 /**
31987 * Set a custom time bar
31988 * @param {Date} time
31989 * @param {number} [id=undefined] Optional id of the custom time bar to be adjusted.
31990 */
31991
31992 }, {
31993 key: "setCustomTime",
31994 value: function setCustomTime(time, id) {
31995 var customTimes = this.customTimes.filter(function (component) {
31996 return id === component.options.id;
31997 });
31998
31999 if (customTimes.length === 0) {
32000 throw new Error("No custom time bar found with id ".concat(JSON.stringify(id)));
32001 }
32002
32003 if (customTimes.length > 0) {
32004 customTimes[0].setCustomTime(time);
32005 }
32006 }
32007 /**
32008 * Retrieve the current custom time.
32009 * @param {number} [id=undefined] Id of the custom time bar.
32010 * @return {Date | undefined} customTime
32011 */
32012
32013 }, {
32014 key: "getCustomTime",
32015 value: function getCustomTime(id) {
32016 var customTimes = this.customTimes.filter(function (component) {
32017 return component.options.id === id;
32018 });
32019
32020 if (customTimes.length === 0) {
32021 throw new Error("No custom time bar found with id ".concat(JSON.stringify(id)));
32022 }
32023
32024 return customTimes[0].getCustomTime();
32025 }
32026 /**
32027 * Set a custom marker for the custom time bar.
32028 * @param {string} [title] Title of the custom marker.
32029 * @param {number} [id=undefined] Id of the custom marker.
32030 * @param {boolean} [editable=false] Make the custom marker editable.
32031 */
32032
32033 }, {
32034 key: "setCustomTimeMarker",
32035 value: function setCustomTimeMarker(title, id, editable) {
32036 var customTimes = this.customTimes.filter(function (component) {
32037 return component.options.id === id;
32038 });
32039
32040 if (customTimes.length === 0) {
32041 throw new Error("No custom time bar found with id ".concat(JSON.stringify(id)));
32042 }
32043
32044 if (customTimes.length > 0) {
32045 customTimes[0].setCustomMarker(title, editable);
32046 }
32047 }
32048 /**
32049 * Set a custom title for the custom time bar.
32050 * @param {string} [title] Custom title
32051 * @param {number} [id=undefined] Id of the custom time bar.
32052 * @returns {*}
32053 */
32054
32055 }, {
32056 key: "setCustomTimeTitle",
32057 value: function setCustomTimeTitle(title, id) {
32058 var customTimes = this.customTimes.filter(function (component) {
32059 return component.options.id === id;
32060 });
32061
32062 if (customTimes.length === 0) {
32063 throw new Error("No custom time bar found with id ".concat(JSON.stringify(id)));
32064 }
32065
32066 if (customTimes.length > 0) {
32067 return customTimes[0].setCustomTitle(title);
32068 }
32069 }
32070 /**
32071 * Retrieve meta information from an event.
32072 * Should be overridden by classes extending Core
32073 * @param {Event} event
32074 * @return {Object} An object with related information.
32075 */
32076
32077 }, {
32078 key: "getEventProperties",
32079 value: function getEventProperties(event) {
32080 return {
32081 event: event
32082 };
32083 }
32084 /**
32085 * Add custom vertical bar
32086 * @param {Date | string | number} [time] A Date, unix timestamp, or
32087 * ISO date string. Time point where
32088 * the new bar should be placed.
32089 * If not provided, `new Date()` will
32090 * be used.
32091 * @param {number | string} [id=undefined] Id of the new bar. Optional
32092 * @return {number | string} Returns the id of the new bar
32093 */
32094
32095 }, {
32096 key: "addCustomTime",
32097 value: function addCustomTime(time, id) {
32098 var timestamp = time !== undefined ? util.convert(time, 'Date').valueOf() : new Date();
32099 var exists = this.customTimes.some(function (customTime) {
32100 return customTime.options.id === id;
32101 });
32102
32103 if (exists) {
32104 throw new Error("A custom time with id ".concat(JSON.stringify(id), " already exists"));
32105 }
32106
32107 var customTime = new CustomTime(this.body, util.extend({}, this.options, {
32108 time: timestamp,
32109 id: id
32110 }));
32111 this.customTimes.push(customTime);
32112 this.components.push(customTime);
32113
32114 this._redraw();
32115
32116 return id;
32117 }
32118 /**
32119 * Remove previously added custom bar
32120 * @param {int} id ID of the custom bar to be removed
32121 * [at]returns {boolean} True if the bar exists and is removed, false otherwise
32122 */
32123
32124 }, {
32125 key: "removeCustomTime",
32126 value: function removeCustomTime(id) {
32127 var _this2 = this;
32128
32129 var customTimes = this.customTimes.filter(function (bar) {
32130 return bar.options.id === id;
32131 });
32132
32133 if (customTimes.length === 0) {
32134 throw new Error("No custom time bar found with id ".concat(JSON.stringify(id)));
32135 }
32136
32137 customTimes.forEach(function (customTime) {
32138 _this2.customTimes.splice(_this2.customTimes.indexOf(customTime), 1);
32139
32140 _this2.components.splice(_this2.components.indexOf(customTime), 1);
32141
32142 customTime.destroy();
32143 });
32144 }
32145 /**
32146 * Get the id's of the currently visible items.
32147 * @returns {Array} The ids of the visible items
32148 */
32149
32150 }, {
32151 key: "getVisibleItems",
32152 value: function getVisibleItems() {
32153 return this.itemSet && this.itemSet.getVisibleItems() || [];
32154 }
32155 /**
32156 * Get the id's of the currently visible groups.
32157 * @returns {Array} The ids of the visible groups
32158 */
32159
32160 }, {
32161 key: "getVisibleGroups",
32162 value: function getVisibleGroups() {
32163 return this.itemSet && this.itemSet.getVisibleGroups() || [];
32164 }
32165 /**
32166 * Set Core window such that it fits all items
32167 * @param {Object} [options] Available options:
32168 * `animation: boolean | {duration: number, easingFunction: string}`
32169 * If true (default), the range is animated
32170 * smoothly to the new window. An object can be
32171 * provided to specify duration and easing function.
32172 * Default duration is 500 ms, and default easing
32173 * function is 'easeInOutQuad'.
32174 * @param {function} [callback] a callback funtion to be executed at the end of this function
32175 */
32176
32177 }, {
32178 key: "fit",
32179 value: function fit(options, callback) {
32180 var range = this.getDataRange(); // skip range set if there is no min and max date
32181
32182 if (range.min === null && range.max === null) {
32183 return;
32184 } // apply a margin of 1% left and right of the data
32185
32186
32187 var interval = range.max - range.min;
32188 var min = new Date(range.min.valueOf() - interval * 0.01);
32189 var max = new Date(range.max.valueOf() + interval * 0.01);
32190 var animation = options && options.animation !== undefined ? options.animation : true;
32191 this.range.setRange(min, max, {
32192 animation: animation
32193 }, callback);
32194 }
32195 /**
32196 * Calculate the data range of the items start and end dates
32197 * [at]returns {{min: [Date], max: [Date]}}
32198 * @protected
32199 */
32200
32201 }, {
32202 key: "getDataRange",
32203 value: function getDataRange() {
32204 // must be implemented by Timeline and Graph2d
32205 throw new Error('Cannot invoke abstract method getDataRange');
32206 }
32207 /**
32208 * Set the visible window. Both parameters are optional, you can change only
32209 * start or only end. Syntax:
32210 *
32211 * TimeLine.setWindow(start, end)
32212 * TimeLine.setWindow(start, end, options)
32213 * TimeLine.setWindow(range)
32214 *
32215 * Where start and end can be a Date, number, or string, and range is an
32216 * object with properties start and end.
32217 *
32218 * @param {Date | number | string | Object} [start] Start date of visible window
32219 * @param {Date | number | string} [end] End date of visible window
32220 * @param {Object} [options] Available options:
32221 * `animation: boolean | {duration: number, easingFunction: string}`
32222 * If true (default), the range is animated
32223 * smoothly to the new window. An object can be
32224 * provided to specify duration and easing function.
32225 * Default duration is 500 ms, and default easing
32226 * function is 'easeInOutQuad'.
32227 * @param {function} [callback] a callback funtion to be executed at the end of this function
32228 */
32229
32230 }, {
32231 key: "setWindow",
32232 value: function setWindow(start, end, options, callback) {
32233 if (typeof arguments[2] == "function") {
32234 callback = arguments[2];
32235 options = {};
32236 }
32237
32238 var animation;
32239 var range;
32240
32241 if (arguments.length == 1) {
32242 range = arguments[0];
32243 animation = range.animation !== undefined ? range.animation : true;
32244 this.range.setRange(range.start, range.end, {
32245 animation: animation
32246 });
32247 } else if (arguments.length == 2 && typeof arguments[1] == "function") {
32248 range = arguments[0];
32249 callback = arguments[1];
32250 animation = range.animation !== undefined ? range.animation : true;
32251 this.range.setRange(range.start, range.end, {
32252 animation: animation
32253 }, callback);
32254 } else {
32255 animation = options && options.animation !== undefined ? options.animation : true;
32256 this.range.setRange(start, end, {
32257 animation: animation
32258 }, callback);
32259 }
32260 }
32261 /**
32262 * Move the window such that given time is centered on screen.
32263 * @param {Date | number | string} time
32264 * @param {Object} [options] Available options:
32265 * `animation: boolean | {duration: number, easingFunction: string}`
32266 * If true (default), the range is animated
32267 * smoothly to the new window. An object can be
32268 * provided to specify duration and easing function.
32269 * Default duration is 500 ms, and default easing
32270 * function is 'easeInOutQuad'.
32271 * @param {function} [callback] a callback funtion to be executed at the end of this function
32272 */
32273
32274 }, {
32275 key: "moveTo",
32276 value: function moveTo(time, options, callback) {
32277 if (typeof arguments[1] == "function") {
32278 callback = arguments[1];
32279 options = {};
32280 }
32281
32282 var interval = this.range.end - this.range.start;
32283 var t = util.convert(time, 'Date').valueOf();
32284 var start = t - interval / 2;
32285 var end = t + interval / 2;
32286 var animation = options && options.animation !== undefined ? options.animation : true;
32287 this.range.setRange(start, end, {
32288 animation: animation
32289 }, callback);
32290 }
32291 /**
32292 * Get the visible window
32293 * @return {{start: Date, end: Date}} Visible range
32294 */
32295
32296 }, {
32297 key: "getWindow",
32298 value: function getWindow() {
32299 var range = this.range.getRange();
32300 return {
32301 start: new Date(range.start),
32302 end: new Date(range.end)
32303 };
32304 }
32305 /**
32306 * Zoom in the window such that given time is centered on screen.
32307 * @param {number} percentage - must be between [0..1]
32308 * @param {Object} [options] Available options:
32309 * `animation: boolean | {duration: number, easingFunction: string}`
32310 * If true (default), the range is animated
32311 * smoothly to the new window. An object can be
32312 * provided to specify duration and easing function.
32313 * Default duration is 500 ms, and default easing
32314 * function is 'easeInOutQuad'.
32315 * @param {function} [callback] a callback funtion to be executed at the end of this function
32316 */
32317
32318 }, {
32319 key: "zoomIn",
32320 value: function zoomIn(percentage, options, callback) {
32321 if (!percentage || percentage < 0 || percentage > 1) return;
32322
32323 if (typeof arguments[1] == "function") {
32324 callback = arguments[1];
32325 options = {};
32326 }
32327
32328 var range = this.getWindow();
32329 var start = range.start.valueOf();
32330 var end = range.end.valueOf();
32331 var interval = end - start;
32332 var newInterval = interval / (1 + percentage);
32333 var distance = (interval - newInterval) / 2;
32334 var newStart = start + distance;
32335 var newEnd = end - distance;
32336 this.setWindow(newStart, newEnd, options, callback);
32337 }
32338 /**
32339 * Zoom out the window such that given time is centered on screen.
32340 * @param {number} percentage - must be between [0..1]
32341 * @param {Object} [options] Available options:
32342 * `animation: boolean | {duration: number, easingFunction: string}`
32343 * If true (default), the range is animated
32344 * smoothly to the new window. An object can be
32345 * provided to specify duration and easing function.
32346 * Default duration is 500 ms, and default easing
32347 * function is 'easeInOutQuad'.
32348 * @param {function} [callback] a callback funtion to be executed at the end of this function
32349 */
32350
32351 }, {
32352 key: "zoomOut",
32353 value: function zoomOut(percentage, options, callback) {
32354 if (!percentage || percentage < 0 || percentage > 1) return;
32355
32356 if (typeof arguments[1] == "function") {
32357 callback = arguments[1];
32358 options = {};
32359 }
32360
32361 var range = this.getWindow();
32362 var start = range.start.valueOf();
32363 var end = range.end.valueOf();
32364 var interval = end - start;
32365 var newStart = start - interval * percentage / 2;
32366 var newEnd = end + interval * percentage / 2;
32367 this.setWindow(newStart, newEnd, options, callback);
32368 }
32369 /**
32370 * Force a redraw. Can be overridden by implementations of Core
32371 *
32372 * Note: this function will be overridden on construction with a trottled version
32373 */
32374
32375 }, {
32376 key: "redraw",
32377 value: function redraw() {
32378 this._redraw();
32379 }
32380 /**
32381 * Redraw for internal use. Redraws all components. See also the public
32382 * method redraw.
32383 * @protected
32384 */
32385
32386 }, {
32387 key: "_redraw",
32388 value: function _redraw() {
32389 this.redrawCount++;
32390 var dom = this.dom;
32391 if (!dom || !dom.container || dom.root.offsetWidth == 0) return; // when destroyed, or invisible
32392
32393 var resized = false;
32394 var options = this.options;
32395 var props = this.props;
32396 updateHiddenDates(this.options.moment, this.body, this.options.hiddenDates); // update class names
32397
32398 if (options.orientation == 'top') {
32399 util.addClassName(dom.root, 'vis-top');
32400 util.removeClassName(dom.root, 'vis-bottom');
32401 } else {
32402 util.removeClassName(dom.root, 'vis-top');
32403 util.addClassName(dom.root, 'vis-bottom');
32404 }
32405
32406 if (options.rtl) {
32407 util.addClassName(dom.root, 'vis-rtl');
32408 util.removeClassName(dom.root, 'vis-ltr');
32409 } else {
32410 util.addClassName(dom.root, 'vis-ltr');
32411 util.removeClassName(dom.root, 'vis-rtl');
32412 } // update root width and height options
32413
32414
32415 dom.root.style.maxHeight = util.option.asSize(options.maxHeight, '');
32416 dom.root.style.minHeight = util.option.asSize(options.minHeight, '');
32417 dom.root.style.width = util.option.asSize(options.width, '');
32418 var rootClientHeight = dom.root.clientHeight;
32419 var rootOffsetHeight = dom.root.offsetHeight;
32420 var rootOffsetWidth = dom.root.offsetWidth;
32421 var centerContainerClientHeight = dom.centerContainer.clientHeight; // calculate border widths
32422
32423 props.border.left = (dom.centerContainer.offsetWidth - dom.centerContainer.clientWidth) / 2;
32424 props.border.right = props.border.left;
32425 props.border.top = (dom.centerContainer.offsetHeight - centerContainerClientHeight) / 2;
32426 props.border.bottom = props.border.top;
32427 props.borderRootHeight = rootOffsetHeight - rootClientHeight;
32428 props.borderRootWidth = rootOffsetWidth - dom.root.clientWidth; // workaround for a bug in IE: the clientWidth of an element with
32429 // a height:0px and overflow:hidden is not calculated and always has value 0
32430
32431 if (centerContainerClientHeight === 0) {
32432 props.border.left = props.border.top;
32433 props.border.right = props.border.left;
32434 }
32435
32436 if (rootClientHeight === 0) {
32437 props.borderRootWidth = props.borderRootHeight;
32438 } // calculate the heights. If any of the side panels is empty, we set the height to
32439 // minus the border width, such that the border will be invisible
32440
32441
32442 props.center.height = dom.center.offsetHeight;
32443 props.left.height = dom.left.offsetHeight;
32444 props.right.height = dom.right.offsetHeight;
32445 props.top.height = dom.top.clientHeight || -props.border.top;
32446 props.bottom.height = dom.bottom.clientHeight || -props.border.bottom; // TODO: compensate borders when any of the panels is empty.
32447 // apply auto height
32448 // TODO: only calculate autoHeight when needed (else we cause an extra reflow/repaint of the DOM)
32449
32450 var contentHeight = Math.max(props.left.height, props.center.height, props.right.height);
32451 var autoHeight = props.top.height + contentHeight + props.bottom.height + props.borderRootHeight + props.border.top + props.border.bottom;
32452 dom.root.style.height = util.option.asSize(options.height, "".concat(autoHeight, "px")); // calculate heights of the content panels
32453
32454 props.root.height = dom.root.offsetHeight;
32455 props.background.height = props.root.height - props.borderRootHeight;
32456 var containerHeight = props.root.height - props.top.height - props.bottom.height - props.borderRootHeight;
32457 props.centerContainer.height = containerHeight;
32458 props.leftContainer.height = containerHeight;
32459 props.rightContainer.height = props.leftContainer.height; // calculate the widths of the panels
32460
32461 props.root.width = rootOffsetWidth;
32462 props.background.width = props.root.width - props.borderRootWidth;
32463
32464 if (!this.initialDrawDone) {
32465 props.scrollbarWidth = util.getScrollBarWidth();
32466 }
32467
32468 var leftContainerClientWidth = dom.leftContainer.clientWidth;
32469 var rightContainerClientWidth = dom.rightContainer.clientWidth;
32470
32471 if (options.verticalScroll) {
32472 if (options.rtl) {
32473 props.left.width = leftContainerClientWidth || -props.border.left;
32474 props.right.width = rightContainerClientWidth + props.scrollbarWidth || -props.border.right;
32475 } else {
32476 props.left.width = leftContainerClientWidth + props.scrollbarWidth || -props.border.left;
32477 props.right.width = rightContainerClientWidth || -props.border.right;
32478 }
32479 } else {
32480 props.left.width = leftContainerClientWidth || -props.border.left;
32481 props.right.width = rightContainerClientWidth || -props.border.right;
32482 }
32483
32484 this._setDOM(); // update the scrollTop, feasible range for the offset can be changed
32485 // when the height of the Core or of the contents of the center changed
32486
32487
32488 var offset = this._updateScrollTop(); // reposition the scrollable contents
32489
32490
32491 if (options.orientation.item != 'top') {
32492 offset += Math.max(props.centerContainer.height - props.center.height - props.border.top - props.border.bottom, 0);
32493 }
32494
32495 dom.center.style.transform = "translateY(".concat(offset, "px)"); // show shadows when vertical scrolling is available
32496
32497 var visibilityTop = props.scrollTop == 0 ? 'hidden' : '';
32498 var visibilityBottom = props.scrollTop == props.scrollTopMin ? 'hidden' : '';
32499 dom.shadowTop.style.visibility = visibilityTop;
32500 dom.shadowBottom.style.visibility = visibilityBottom;
32501 dom.shadowTopLeft.style.visibility = visibilityTop;
32502 dom.shadowBottomLeft.style.visibility = visibilityBottom;
32503 dom.shadowTopRight.style.visibility = visibilityTop;
32504 dom.shadowBottomRight.style.visibility = visibilityBottom;
32505
32506 if (options.verticalScroll) {
32507 dom.rightContainer.className = 'vis-panel vis-right vis-vertical-scroll';
32508 dom.leftContainer.className = 'vis-panel vis-left vis-vertical-scroll';
32509 dom.shadowTopRight.style.visibility = "hidden";
32510 dom.shadowBottomRight.style.visibility = "hidden";
32511 dom.shadowTopLeft.style.visibility = "hidden";
32512 dom.shadowBottomLeft.style.visibility = "hidden";
32513 dom.left.style.top = '0px';
32514 dom.right.style.top = '0px';
32515 }
32516
32517 if (!options.verticalScroll || props.center.height < props.centerContainer.height) {
32518 dom.left.style.top = "".concat(offset, "px");
32519 dom.right.style.top = "".concat(offset, "px");
32520 dom.rightContainer.className = dom.rightContainer.className.replace(new RegExp('(?:^|\\s)' + 'vis-vertical-scroll' + '(?:\\s|$)'), ' ');
32521 dom.leftContainer.className = dom.leftContainer.className.replace(new RegExp('(?:^|\\s)' + 'vis-vertical-scroll' + '(?:\\s|$)'), ' ');
32522 props.left.width = leftContainerClientWidth || -props.border.left;
32523 props.right.width = rightContainerClientWidth || -props.border.right;
32524
32525 this._setDOM();
32526 } // enable/disable vertical panning
32527
32528
32529 var contentsOverflow = props.center.height > props.centerContainer.height;
32530 this.hammer.get('pan').set({
32531 direction: contentsOverflow ? Hammer$1.DIRECTION_ALL : Hammer$1.DIRECTION_HORIZONTAL
32532 }); // redraw all components
32533
32534 this.components.forEach(function (component) {
32535 resized = component.redraw() || resized;
32536 });
32537 var MAX_REDRAW = 5;
32538
32539 if (resized) {
32540 if (this.redrawCount < MAX_REDRAW) {
32541 this.body.emitter.emit('_change');
32542 return;
32543 } else {
32544 console.log('WARNING: infinite loop in redraw?');
32545 }
32546 } else {
32547 this.redrawCount = 0;
32548 } //Emit public 'changed' event for UI updates, see issue #1592
32549
32550
32551 this.body.emitter.emit("changed");
32552 }
32553 /**
32554 * sets the basic DOM components needed for the timeline\graph2d
32555 */
32556
32557 }, {
32558 key: "_setDOM",
32559 value: function _setDOM() {
32560 var props = this.props;
32561 var dom = this.dom;
32562 props.leftContainer.width = props.left.width;
32563 props.rightContainer.width = props.right.width;
32564 var centerWidth = props.root.width - props.left.width - props.right.width - props.borderRootWidth;
32565 props.center.width = centerWidth;
32566 props.centerContainer.width = centerWidth;
32567 props.top.width = centerWidth;
32568 props.bottom.width = centerWidth; // resize the panels
32569
32570 dom.background.style.height = "".concat(props.background.height, "px");
32571 dom.backgroundVertical.style.height = "".concat(props.background.height, "px");
32572 dom.backgroundHorizontal.style.height = "".concat(props.centerContainer.height, "px");
32573 dom.centerContainer.style.height = "".concat(props.centerContainer.height, "px");
32574 dom.leftContainer.style.height = "".concat(props.leftContainer.height, "px");
32575 dom.rightContainer.style.height = "".concat(props.rightContainer.height, "px");
32576 dom.background.style.width = "".concat(props.background.width, "px");
32577 dom.backgroundVertical.style.width = "".concat(props.centerContainer.width, "px");
32578 dom.backgroundHorizontal.style.width = "".concat(props.background.width, "px");
32579 dom.centerContainer.style.width = "".concat(props.center.width, "px");
32580 dom.top.style.width = "".concat(props.top.width, "px");
32581 dom.bottom.style.width = "".concat(props.bottom.width, "px"); // reposition the panels
32582
32583 dom.background.style.left = '0';
32584 dom.background.style.top = '0';
32585 dom.backgroundVertical.style.left = "".concat(props.left.width + props.border.left, "px");
32586 dom.backgroundVertical.style.top = '0';
32587 dom.backgroundHorizontal.style.left = '0';
32588 dom.backgroundHorizontal.style.top = "".concat(props.top.height, "px");
32589 dom.centerContainer.style.left = "".concat(props.left.width, "px");
32590 dom.centerContainer.style.top = "".concat(props.top.height, "px");
32591 dom.leftContainer.style.left = '0';
32592 dom.leftContainer.style.top = "".concat(props.top.height, "px");
32593 dom.rightContainer.style.left = "".concat(props.left.width + props.center.width, "px");
32594 dom.rightContainer.style.top = "".concat(props.top.height, "px");
32595 dom.top.style.left = "".concat(props.left.width, "px");
32596 dom.top.style.top = '0';
32597 dom.bottom.style.left = "".concat(props.left.width, "px");
32598 dom.bottom.style.top = "".concat(props.top.height + props.centerContainer.height, "px");
32599 dom.center.style.left = '0';
32600 dom.left.style.left = '0';
32601 dom.right.style.left = '0';
32602 }
32603 /**
32604 * Set a current time. This can be used for example to ensure that a client's
32605 * time is synchronized with a shared server time.
32606 * Only applicable when option `showCurrentTime` is true.
32607 * @param {Date | string | number} time A Date, unix timestamp, or
32608 * ISO date string.
32609 */
32610
32611 }, {
32612 key: "setCurrentTime",
32613 value: function setCurrentTime(time) {
32614 if (!this.currentTime) {
32615 throw new Error('Option showCurrentTime must be true');
32616 }
32617
32618 this.currentTime.setCurrentTime(time);
32619 }
32620 /**
32621 * Get the current time.
32622 * Only applicable when option `showCurrentTime` is true.
32623 * @return {Date} Returns the current time.
32624 */
32625
32626 }, {
32627 key: "getCurrentTime",
32628 value: function getCurrentTime() {
32629 if (!this.currentTime) {
32630 throw new Error('Option showCurrentTime must be true');
32631 }
32632
32633 return this.currentTime.getCurrentTime();
32634 }
32635 /**
32636 * Convert a position on screen (pixels) to a datetime
32637 * @param {int} x Position on the screen in pixels
32638 * @return {Date} time The datetime the corresponds with given position x
32639 * @protected
32640 * TODO: move this function to Range
32641 */
32642
32643 }, {
32644 key: "_toTime",
32645 value: function _toTime(x) {
32646 return toTime(this, x, this.props.center.width);
32647 }
32648 /**
32649 * Convert a position on the global screen (pixels) to a datetime
32650 * @param {int} x Position on the screen in pixels
32651 * @return {Date} time The datetime the corresponds with given position x
32652 * @protected
32653 * TODO: move this function to Range
32654 */
32655
32656 }, {
32657 key: "_toGlobalTime",
32658 value: function _toGlobalTime(x) {
32659 return toTime(this, x, this.props.root.width); //var conversion = this.range.conversion(this.props.root.width);
32660 //return new Date(x / conversion.scale + conversion.offset);
32661 }
32662 /**
32663 * Convert a datetime (Date object) into a position on the screen
32664 * @param {Date} time A date
32665 * @return {int} x The position on the screen in pixels which corresponds
32666 * with the given date.
32667 * @protected
32668 * TODO: move this function to Range
32669 */
32670
32671 }, {
32672 key: "_toScreen",
32673 value: function _toScreen(time) {
32674 return toScreen(this, time, this.props.center.width);
32675 }
32676 /**
32677 * Convert a datetime (Date object) into a position on the root
32678 * This is used to get the pixel density estimate for the screen, not the center panel
32679 * @param {Date} time A date
32680 * @return {int} x The position on root in pixels which corresponds
32681 * with the given date.
32682 * @protected
32683 * TODO: move this function to Range
32684 */
32685
32686 }, {
32687 key: "_toGlobalScreen",
32688 value: function _toGlobalScreen(time) {
32689 return toScreen(this, time, this.props.root.width); //var conversion = this.range.conversion(this.props.root.width);
32690 //return (time.valueOf() - conversion.offset) * conversion.scale;
32691 }
32692 /**
32693 * Initialize watching when option autoResize is true
32694 * @private
32695 */
32696
32697 }, {
32698 key: "_initAutoResize",
32699 value: function _initAutoResize() {
32700 if (this.options.autoResize == true) {
32701 this._startAutoResize();
32702 } else {
32703 this._stopAutoResize();
32704 }
32705 }
32706 /**
32707 * Watch for changes in the size of the container. On resize, the Panel will
32708 * automatically redraw itself.
32709 * @private
32710 */
32711
32712 }, {
32713 key: "_startAutoResize",
32714 value: function _startAutoResize() {
32715 var me = this;
32716
32717 this._stopAutoResize();
32718
32719 this._onResize = function () {
32720 if (me.options.autoResize != true) {
32721 // stop watching when the option autoResize is changed to false
32722 me._stopAutoResize();
32723
32724 return;
32725 }
32726
32727 if (me.dom.root) {
32728 var rootOffsetHeight = me.dom.root.offsetHeight;
32729 var rootOffsetWidth = me.dom.root.offsetWidth; // check whether the frame is resized
32730 // Note: we compare offsetWidth here, not clientWidth. For some reason,
32731 // IE does not restore the clientWidth from 0 to the actual width after
32732 // changing the timeline's container display style from none to visible
32733
32734 if (rootOffsetWidth != me.props.lastWidth || rootOffsetHeight != me.props.lastHeight) {
32735 me.props.lastWidth = rootOffsetWidth;
32736 me.props.lastHeight = rootOffsetHeight;
32737 me.props.scrollbarWidth = util.getScrollBarWidth();
32738 me.body.emitter.emit('_change');
32739 }
32740 }
32741 }; // add event listener to window resize
32742
32743
32744 util.addEventListener(window, 'resize', this._onResize); //Prevent initial unnecessary redraw
32745
32746 if (me.dom.root) {
32747 me.props.lastWidth = me.dom.root.offsetWidth;
32748 me.props.lastHeight = me.dom.root.offsetHeight;
32749 }
32750
32751 this.watchTimer = setInterval(this._onResize, 1000);
32752 }
32753 /**
32754 * Stop watching for a resize of the frame.
32755 * @private
32756 */
32757
32758 }, {
32759 key: "_stopAutoResize",
32760 value: function _stopAutoResize() {
32761 if (this.watchTimer) {
32762 clearInterval(this.watchTimer);
32763 this.watchTimer = undefined;
32764 } // remove event listener on window.resize
32765
32766
32767 if (this._onResize) {
32768 util.removeEventListener(window, 'resize', this._onResize);
32769 this._onResize = null;
32770 }
32771 }
32772 /**
32773 * Start moving the timeline vertically
32774 * @param {Event} event
32775 * @private
32776 */
32777
32778 }, {
32779 key: "_onTouch",
32780 value: function _onTouch(event) {
32781 // eslint-disable-line no-unused-vars
32782 this.touch.allowDragging = true;
32783 this.touch.initialScrollTop = this.props.scrollTop;
32784 }
32785 /**
32786 * Start moving the timeline vertically
32787 * @param {Event} event
32788 * @private
32789 */
32790
32791 }, {
32792 key: "_onPinch",
32793 value: function _onPinch(event) {
32794 // eslint-disable-line no-unused-vars
32795 this.touch.allowDragging = false;
32796 }
32797 /**
32798 * Move the timeline vertically
32799 * @param {Event} event
32800 * @private
32801 */
32802
32803 }, {
32804 key: "_onDrag",
32805 value: function _onDrag(event) {
32806 if (!event) return; // refuse to drag when we where pinching to prevent the timeline make a jump
32807 // when releasing the fingers in opposite order from the touch screen
32808
32809 if (!this.touch.allowDragging) return;
32810 var delta = event.deltaY;
32811
32812 var oldScrollTop = this._getScrollTop();
32813
32814 var newScrollTop = this._setScrollTop(this.touch.initialScrollTop + delta);
32815
32816 if (this.options.verticalScroll) {
32817 this.dom.left.parentNode.scrollTop = -this.props.scrollTop;
32818 this.dom.right.parentNode.scrollTop = -this.props.scrollTop;
32819 }
32820
32821 if (newScrollTop != oldScrollTop) {
32822 this.emit("verticalDrag");
32823 }
32824 }
32825 /**
32826 * Apply a scrollTop
32827 * @param {number} scrollTop
32828 * @returns {number} scrollTop Returns the applied scrollTop
32829 * @private
32830 */
32831
32832 }, {
32833 key: "_setScrollTop",
32834 value: function _setScrollTop(scrollTop) {
32835 this.props.scrollTop = scrollTop;
32836
32837 this._updateScrollTop();
32838
32839 return this.props.scrollTop;
32840 }
32841 /**
32842 * Update the current scrollTop when the height of the containers has been changed
32843 * @returns {number} scrollTop Returns the applied scrollTop
32844 * @private
32845 */
32846
32847 }, {
32848 key: "_updateScrollTop",
32849 value: function _updateScrollTop() {
32850 // recalculate the scrollTopMin
32851 var scrollTopMin = Math.min(this.props.centerContainer.height - this.props.center.height, 0); // is negative or zero
32852
32853 if (scrollTopMin != this.props.scrollTopMin) {
32854 // in case of bottom orientation, change the scrollTop such that the contents
32855 // do not move relative to the time axis at the bottom
32856 if (this.options.orientation.item != 'top') {
32857 this.props.scrollTop += scrollTopMin - this.props.scrollTopMin;
32858 }
32859
32860 this.props.scrollTopMin = scrollTopMin;
32861 } // limit the scrollTop to the feasible scroll range
32862
32863
32864 if (this.props.scrollTop > 0) this.props.scrollTop = 0;
32865 if (this.props.scrollTop < scrollTopMin) this.props.scrollTop = scrollTopMin;
32866
32867 if (this.options.verticalScroll) {
32868 this.dom.left.parentNode.scrollTop = -this.props.scrollTop;
32869 this.dom.right.parentNode.scrollTop = -this.props.scrollTop;
32870 }
32871
32872 return this.props.scrollTop;
32873 }
32874 /**
32875 * Get the current scrollTop
32876 * @returns {number} scrollTop
32877 * @private
32878 */
32879
32880 }, {
32881 key: "_getScrollTop",
32882 value: function _getScrollTop() {
32883 return this.props.scrollTop;
32884 }
32885 /**
32886 * Load a configurator
32887 * [at]returns {Object}
32888 * @private
32889 */
32890
32891 }, {
32892 key: "_createConfigurator",
32893 value: function _createConfigurator() {
32894 throw new Error('Cannot invoke abstract method _createConfigurator');
32895 }
32896 }]);
32897
32898 return Core;
32899}(); // turn Core into an event emitter
32900
32901
32902emitterComponent(Core.prototype);
32903
32904/**
32905 * A current time bar
32906 */
32907
32908var CurrentTime =
32909/*#__PURE__*/
32910function (_Component) {
32911 _inherits(CurrentTime, _Component);
32912
32913 /**
32914 * @param {{range: Range, dom: Object, domProps: Object}} body
32915 * @param {Object} [options] Available parameters:
32916 * {Boolean} [showCurrentTime]
32917 * {String} [alignCurrentTime]
32918 * @constructor CurrentTime
32919 * @extends Component
32920 */
32921 function CurrentTime(body, options) {
32922 var _this;
32923
32924 _classCallCheck(this, CurrentTime);
32925
32926 _this = _possibleConstructorReturn(this, _getPrototypeOf(CurrentTime).call(this));
32927 _this.body = body; // default options
32928
32929 _this.defaultOptions = {
32930 rtl: false,
32931 showCurrentTime: true,
32932 alignCurrentTime: undefined,
32933 moment: moment$3,
32934 locales: locales,
32935 locale: 'en'
32936 };
32937 _this.options = util.extend({}, _this.defaultOptions);
32938
32939 _this.setOptions(options);
32940
32941 util.extend(_this.options.locales, locales, _this.options.locales);
32942 var defaultLocales = _this.defaultOptions.locales[_this.defaultOptions.locale];
32943 Object.keys(_this.options.locales).forEach(function (locale) {
32944 _this.options.locales[locale] = util.extend({}, defaultLocales, _this.options.locales[locale]);
32945 });
32946 _this.offset = 0;
32947
32948 _this._create();
32949
32950 return _this;
32951 }
32952 /**
32953 * Create the HTML DOM for the current time bar
32954 * @private
32955 */
32956
32957
32958 _createClass(CurrentTime, [{
32959 key: "_create",
32960 value: function _create() {
32961 var bar = document.createElement('div');
32962 bar.className = 'vis-current-time';
32963 bar.style.position = 'absolute';
32964 bar.style.top = '0px';
32965 bar.style.height = '100%';
32966 this.bar = bar;
32967 }
32968 /**
32969 * Destroy the CurrentTime bar
32970 */
32971
32972 }, {
32973 key: "destroy",
32974 value: function destroy() {
32975 this.options.showCurrentTime = false;
32976 this.redraw(); // will remove the bar from the DOM and stop refreshing
32977
32978 this.body = null;
32979 }
32980 /**
32981 * Set options for the component. Options will be merged in current options.
32982 * @param {Object} options Available parameters:
32983 * {boolean} [showCurrentTime]
32984 * {String} [alignCurrentTime]
32985 */
32986
32987 }, {
32988 key: "setOptions",
32989 value: function setOptions(options) {
32990 if (options) {
32991 // copy all options that we know
32992 util.selectiveExtend(['rtl', 'showCurrentTime', 'alignCurrentTime', 'moment', 'locale', 'locales'], this.options, options);
32993 }
32994 }
32995 /**
32996 * Repaint the component
32997 * @return {boolean} Returns true if the component is resized
32998 */
32999
33000 }, {
33001 key: "redraw",
33002 value: function redraw() {
33003 if (this.options.showCurrentTime) {
33004 var parent = this.body.dom.backgroundVertical;
33005
33006 if (this.bar.parentNode != parent) {
33007 // attach to the dom
33008 if (this.bar.parentNode) {
33009 this.bar.parentNode.removeChild(this.bar);
33010 }
33011
33012 parent.appendChild(this.bar);
33013 this.start();
33014 }
33015
33016 var now = this.options.moment(Date.now() + this.offset);
33017
33018 if (this.options.alignCurrentTime) {
33019 now = now.startOf(this.options.alignCurrentTime);
33020 }
33021
33022 var x = this.body.util.toScreen(now);
33023 var locale = this.options.locales[this.options.locale];
33024
33025 if (!locale) {
33026 if (!this.warned) {
33027 console.warn("WARNING: options.locales['".concat(this.options.locale, "'] not found. See https://visjs.github.io/vis-timeline/docs/timeline/#Localization"));
33028 this.warned = true;
33029 }
33030
33031 locale = this.options.locales['en']; // fall back on english when not available
33032 }
33033
33034 var title = "".concat(locale.current, " ").concat(locale.time, ": ").concat(now.format('dddd, MMMM Do YYYY, H:mm:ss'));
33035 title = title.charAt(0).toUpperCase() + title.substring(1);
33036
33037 if (this.options.rtl) {
33038 this.bar.style.transform = "translateX(".concat(x * -1, "px)");
33039 } else {
33040 this.bar.style.transform = "translateX(".concat(x, "px)");
33041 }
33042
33043 this.bar.title = title;
33044 } else {
33045 // remove the line from the DOM
33046 if (this.bar.parentNode) {
33047 this.bar.parentNode.removeChild(this.bar);
33048 }
33049
33050 this.stop();
33051 }
33052
33053 return false;
33054 }
33055 /**
33056 * Start auto refreshing the current time bar
33057 */
33058
33059 }, {
33060 key: "start",
33061 value: function start() {
33062 var me = this;
33063 /**
33064 * Updates the current time.
33065 */
33066
33067 function update() {
33068 me.stop(); // determine interval to refresh
33069
33070 var scale = me.body.range.conversion(me.body.domProps.center.width).scale;
33071 var interval = 1 / scale / 10;
33072 if (interval < 30) interval = 30;
33073 if (interval > 1000) interval = 1000;
33074 me.redraw();
33075 me.body.emitter.emit('currentTimeTick'); // start a renderTimer to adjust for the new time
33076
33077 me.currentTimeTimer = setTimeout(update, interval);
33078 }
33079
33080 update();
33081 }
33082 /**
33083 * Stop auto refreshing the current time bar
33084 */
33085
33086 }, {
33087 key: "stop",
33088 value: function stop() {
33089 if (this.currentTimeTimer !== undefined) {
33090 clearTimeout(this.currentTimeTimer);
33091 delete this.currentTimeTimer;
33092 }
33093 }
33094 /**
33095 * Set a current time. This can be used for example to ensure that a client's
33096 * time is synchronized with a shared server time.
33097 * @param {Date | string | number} time A Date, unix timestamp, or
33098 * ISO date string.
33099 */
33100
33101 }, {
33102 key: "setCurrentTime",
33103 value: function setCurrentTime(time) {
33104 var t = util.convert(time, 'Date').valueOf();
33105 var now = Date.now();
33106 this.offset = t - now;
33107 this.redraw();
33108 }
33109 /**
33110 * Get the current time.
33111 * @return {Date} Returns the current time.
33112 */
33113
33114 }, {
33115 key: "getCurrentTime",
33116 value: function getCurrentTime() {
33117 return new Date(Date.now() + this.offset);
33118 }
33119 }]);
33120
33121 return CurrentTime;
33122}(Component);
33123
33124var $find$1 = arrayIteration.find;
33125
33126
33127var FIND = 'find';
33128var SKIPS_HOLES = true;
33129
33130// Shouldn't skip holes
33131if (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });
33132
33133// `Array.prototype.find` method
33134// https://tc39.github.io/ecma262/#sec-array.prototype.find
33135_export({ target: 'Array', proto: true, forced: SKIPS_HOLES }, {
33136 find: function find(callbackfn /* , that = undefined */) {
33137 return $find$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
33138 }
33139});
33140
33141// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
33142addToUnscopables(FIND);
33143
33144var iterate_1 = createCommonjsModule(function (module) {
33145var Result = function (stopped, result) {
33146 this.stopped = stopped;
33147 this.result = result;
33148};
33149
33150var iterate = module.exports = function (iterable, fn, that, AS_ENTRIES, IS_ITERATOR) {
33151 var boundFunction = bindContext(fn, that, AS_ENTRIES ? 2 : 1);
33152 var iterator, iterFn, index, length, result, step;
33153
33154 if (IS_ITERATOR) {
33155 iterator = iterable;
33156 } else {
33157 iterFn = getIteratorMethod(iterable);
33158 if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
33159 // optimisation for array iterators
33160 if (isArrayIteratorMethod(iterFn)) {
33161 for (index = 0, length = toLength(iterable.length); length > index; index++) {
33162 result = AS_ENTRIES
33163 ? boundFunction(anObject(step = iterable[index])[0], step[1])
33164 : boundFunction(iterable[index]);
33165 if (result && result instanceof Result) return result;
33166 } return new Result(false);
33167 }
33168 iterator = iterFn.call(iterable);
33169 }
33170
33171 while (!(step = iterator.next()).done) {
33172 result = callWithSafeIterationClosing(iterator, boundFunction, step.value, AS_ENTRIES);
33173 if (result && result instanceof Result) return result;
33174 } return new Result(false);
33175};
33176
33177iterate.stop = function (result) {
33178 return new Result(true, result);
33179};
33180});
33181
33182var collection = function (CONSTRUCTOR_NAME, wrapper, common, IS_MAP, IS_WEAK) {
33183 var NativeConstructor = global_1[CONSTRUCTOR_NAME];
33184 var NativePrototype = NativeConstructor && NativeConstructor.prototype;
33185 var Constructor = NativeConstructor;
33186 var ADDER = IS_MAP ? 'set' : 'add';
33187 var exported = {};
33188
33189 var fixMethod = function (KEY) {
33190 var nativeMethod = NativePrototype[KEY];
33191 redefine(NativePrototype, KEY,
33192 KEY == 'add' ? function add(value) {
33193 nativeMethod.call(this, value === 0 ? 0 : value);
33194 return this;
33195 } : KEY == 'delete' ? function (key) {
33196 return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
33197 } : KEY == 'get' ? function get(key) {
33198 return IS_WEAK && !isObject(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key);
33199 } : KEY == 'has' ? function has(key) {
33200 return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);
33201 } : function set(key, value) {
33202 nativeMethod.call(this, key === 0 ? 0 : key, value);
33203 return this;
33204 }
33205 );
33206 };
33207
33208 // eslint-disable-next-line max-len
33209 if (isForced_1(CONSTRUCTOR_NAME, typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
33210 new NativeConstructor().entries().next();
33211 })))) {
33212 // create collection constructor
33213 Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
33214 internalMetadata.REQUIRED = true;
33215 } else if (isForced_1(CONSTRUCTOR_NAME, true)) {
33216 var instance = new Constructor();
33217 // early implementations not supports chaining
33218 var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
33219 // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
33220 var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
33221 // most early implementations doesn't supports iterables, most modern - not close it correctly
33222 // eslint-disable-next-line no-new
33223 var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
33224 // for early implementations -0 and +0 not the same
33225 var BUGGY_ZERO = !IS_WEAK && fails(function () {
33226 // V8 ~ Chromium 42- fails only with 5+ elements
33227 var $instance = new NativeConstructor();
33228 var index = 5;
33229 while (index--) $instance[ADDER](index, index);
33230 return !$instance.has(-0);
33231 });
33232
33233 if (!ACCEPT_ITERABLES) {
33234 Constructor = wrapper(function (dummy, iterable) {
33235 anInstance(dummy, Constructor, CONSTRUCTOR_NAME);
33236 var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);
33237 if (iterable != undefined) iterate_1(iterable, that[ADDER], that, IS_MAP);
33238 return that;
33239 });
33240 Constructor.prototype = NativePrototype;
33241 NativePrototype.constructor = Constructor;
33242 }
33243
33244 if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
33245 fixMethod('delete');
33246 fixMethod('has');
33247 IS_MAP && fixMethod('get');
33248 }
33249
33250 if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
33251
33252 // weak collections should not contains .clear method
33253 if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
33254 }
33255
33256 exported[CONSTRUCTOR_NAME] = Constructor;
33257 _export({ global: true, forced: Constructor != NativeConstructor }, exported);
33258
33259 setToStringTag(Constructor, CONSTRUCTOR_NAME);
33260
33261 if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);
33262
33263 return Constructor;
33264};
33265
33266var defineProperty$9 = objectDefineProperty.f;
33267
33268
33269
33270
33271
33272
33273
33274
33275var fastKey = internalMetadata.fastKey;
33276
33277
33278var setInternalState$3 = internalState.set;
33279var internalStateGetterFor = internalState.getterFor;
33280
33281var collectionStrong = {
33282 getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
33283 var C = wrapper(function (that, iterable) {
33284 anInstance(that, C, CONSTRUCTOR_NAME);
33285 setInternalState$3(that, {
33286 type: CONSTRUCTOR_NAME,
33287 index: objectCreate(null),
33288 first: undefined,
33289 last: undefined,
33290 size: 0
33291 });
33292 if (!descriptors) that.size = 0;
33293 if (iterable != undefined) iterate_1(iterable, that[ADDER], that, IS_MAP);
33294 });
33295
33296 var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);
33297
33298 var define = function (that, key, value) {
33299 var state = getInternalState(that);
33300 var entry = getEntry(that, key);
33301 var previous, index;
33302 // change existing entry
33303 if (entry) {
33304 entry.value = value;
33305 // create new entry
33306 } else {
33307 state.last = entry = {
33308 index: index = fastKey(key, true),
33309 key: key,
33310 value: value,
33311 previous: previous = state.last,
33312 next: undefined,
33313 removed: false
33314 };
33315 if (!state.first) state.first = entry;
33316 if (previous) previous.next = entry;
33317 if (descriptors) state.size++;
33318 else that.size++;
33319 // add to index
33320 if (index !== 'F') state.index[index] = entry;
33321 } return that;
33322 };
33323
33324 var getEntry = function (that, key) {
33325 var state = getInternalState(that);
33326 // fast case
33327 var index = fastKey(key);
33328 var entry;
33329 if (index !== 'F') return state.index[index];
33330 // frozen object case
33331 for (entry = state.first; entry; entry = entry.next) {
33332 if (entry.key == key) return entry;
33333 }
33334 };
33335
33336 redefineAll(C.prototype, {
33337 // 23.1.3.1 Map.prototype.clear()
33338 // 23.2.3.2 Set.prototype.clear()
33339 clear: function clear() {
33340 var that = this;
33341 var state = getInternalState(that);
33342 var data = state.index;
33343 var entry = state.first;
33344 while (entry) {
33345 entry.removed = true;
33346 if (entry.previous) entry.previous = entry.previous.next = undefined;
33347 delete data[entry.index];
33348 entry = entry.next;
33349 }
33350 state.first = state.last = undefined;
33351 if (descriptors) state.size = 0;
33352 else that.size = 0;
33353 },
33354 // 23.1.3.3 Map.prototype.delete(key)
33355 // 23.2.3.4 Set.prototype.delete(value)
33356 'delete': function (key) {
33357 var that = this;
33358 var state = getInternalState(that);
33359 var entry = getEntry(that, key);
33360 if (entry) {
33361 var next = entry.next;
33362 var prev = entry.previous;
33363 delete state.index[entry.index];
33364 entry.removed = true;
33365 if (prev) prev.next = next;
33366 if (next) next.previous = prev;
33367 if (state.first == entry) state.first = next;
33368 if (state.last == entry) state.last = prev;
33369 if (descriptors) state.size--;
33370 else that.size--;
33371 } return !!entry;
33372 },
33373 // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
33374 // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
33375 forEach: function forEach(callbackfn /* , that = undefined */) {
33376 var state = getInternalState(this);
33377 var boundFunction = bindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
33378 var entry;
33379 while (entry = entry ? entry.next : state.first) {
33380 boundFunction(entry.value, entry.key, this);
33381 // revert to the last existing entry
33382 while (entry && entry.removed) entry = entry.previous;
33383 }
33384 },
33385 // 23.1.3.7 Map.prototype.has(key)
33386 // 23.2.3.7 Set.prototype.has(value)
33387 has: function has(key) {
33388 return !!getEntry(this, key);
33389 }
33390 });
33391
33392 redefineAll(C.prototype, IS_MAP ? {
33393 // 23.1.3.6 Map.prototype.get(key)
33394 get: function get(key) {
33395 var entry = getEntry(this, key);
33396 return entry && entry.value;
33397 },
33398 // 23.1.3.9 Map.prototype.set(key, value)
33399 set: function set(key, value) {
33400 return define(this, key === 0 ? 0 : key, value);
33401 }
33402 } : {
33403 // 23.2.3.1 Set.prototype.add(value)
33404 add: function add(value) {
33405 return define(this, value = value === 0 ? 0 : value, value);
33406 }
33407 });
33408 if (descriptors) defineProperty$9(C.prototype, 'size', {
33409 get: function () {
33410 return getInternalState(this).size;
33411 }
33412 });
33413 return C;
33414 },
33415 setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) {
33416 var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator';
33417 var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME);
33418 var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME);
33419 // add .keys, .values, .entries, [@@iterator]
33420 // 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
33421 defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) {
33422 setInternalState$3(this, {
33423 type: ITERATOR_NAME,
33424 target: iterated,
33425 state: getInternalCollectionState(iterated),
33426 kind: kind,
33427 last: undefined
33428 });
33429 }, function () {
33430 var state = getInternalIteratorState(this);
33431 var kind = state.kind;
33432 var entry = state.last;
33433 // revert to the last existing entry
33434 while (entry && entry.removed) entry = entry.previous;
33435 // get next entry
33436 if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) {
33437 // or finish the iteration
33438 state.target = undefined;
33439 return { value: undefined, done: true };
33440 }
33441 // return step by kind
33442 if (kind == 'keys') return { value: entry.key, done: false };
33443 if (kind == 'values') return { value: entry.value, done: false };
33444 return { value: [entry.key, entry.value], done: false };
33445 }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
33446
33447 // add [@@species], 23.1.2.2, 23.2.2.2
33448 setSpecies(CONSTRUCTOR_NAME);
33449 }
33450};
33451
33452// `Set` constructor
33453// https://tc39.github.io/ecma262/#sec-set-objects
33454var es_set = collection('Set', function (get) {
33455 return function Set() { return get(this, arguments.length ? arguments[0] : undefined); };
33456}, collectionStrong);
33457
33458var $includes$1 = arrayIncludes.includes;
33459
33460
33461// `Array.prototype.includes` method
33462// https://tc39.github.io/ecma262/#sec-array.prototype.includes
33463_export({ target: 'Array', proto: true }, {
33464 includes: function includes(el /* , fromIndex = 0 */) {
33465 return $includes$1(this, el, arguments.length > 1 ? arguments[1] : undefined);
33466 }
33467});
33468
33469// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
33470addToUnscopables('includes');
33471
33472var notARegexp = function (it) {
33473 if (isRegexp(it)) {
33474 throw TypeError("The method doesn't accept regular expressions");
33475 } return it;
33476};
33477
33478var MATCH$2 = wellKnownSymbol('match');
33479
33480var correctIsRegexpLogic = function (METHOD_NAME) {
33481 var regexp = /./;
33482 try {
33483 '/./'[METHOD_NAME](regexp);
33484 } catch (e) {
33485 try {
33486 regexp[MATCH$2] = false;
33487 return '/./'[METHOD_NAME](regexp);
33488 } catch (f) { /* empty */ }
33489 } return false;
33490};
33491
33492// `String.prototype.includes` method
33493// https://tc39.github.io/ecma262/#sec-string.prototype.includes
33494_export({ target: 'String', proto: true, forced: !correctIsRegexpLogic('includes') }, {
33495 includes: function includes(searchString /* , position = 0 */) {
33496 return !!~String(requireObjectCoercible(this))
33497 .indexOf(notARegexp(searchString), arguments.length > 1 ? arguments[1] : undefined);
33498 }
33499});
33500
33501// Utility functions for ordering and stacking of items
33502var EPSILON = 0.001; // used when checking collisions, to prevent round-off errors
33503
33504/**
33505 * Order items by their start data
33506 * @param {Item[]} items
33507 */
33508
33509function orderByStart(items) {
33510 items.sort(function (a, b) {
33511 return a.data.start - b.data.start;
33512 });
33513}
33514/**
33515 * Order items by their end date. If they have no end date, their start date
33516 * is used.
33517 * @param {Item[]} items
33518 */
33519
33520function orderByEnd(items) {
33521 items.sort(function (a, b) {
33522 var aTime = 'end' in a.data ? a.data.end : a.data.start;
33523 var bTime = 'end' in b.data ? b.data.end : b.data.start;
33524 return aTime - bTime;
33525 });
33526}
33527/**
33528 * Adjust vertical positions of the items such that they don't overlap each
33529 * other.
33530 * @param {Item[]} items
33531 * All visible items
33532 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
33533 * Margins between items and between items and the axis.
33534 * @param {boolean} [force=false]
33535 * If true, all items will be repositioned. If false (default), only
33536 * items having a top===null will be re-stacked
33537 * @param {function} shouldBailItemsRedrawFunction
33538 * bailing function
33539 * @return {boolean} shouldBail
33540 */
33541
33542function stack(items, margin, force, shouldBailItemsRedrawFunction) {
33543 if (force) {
33544 // reset top position of all items
33545 for (var i = 0; i < items.length; i++) {
33546 items[i].top = null;
33547 }
33548 } // calculate new, non-overlapping positions
33549
33550
33551 for (var i = 0; i < items.length; i++) {
33552 // eslint-disable-line no-redeclare
33553 var item = items[i];
33554
33555 if (item.stack && item.top === null) {
33556 // initialize top position
33557 item.top = margin.axis;
33558 var shouldBail = false;
33559
33560 do {
33561 // TODO: optimize checking for overlap. when there is a gap without items,
33562 // you only need to check for items from the next item on, not from zero
33563 var collidingItem = null;
33564
33565 for (var j = 0, jj = items.length; j < jj; j++) {
33566 var other = items[j];
33567 shouldBail = shouldBailItemsRedrawFunction() || false;
33568
33569 if (shouldBail) {
33570 return true;
33571 }
33572
33573 if (other.top !== null && other !== item && other.stack && collision(item, other, margin.item, other.options.rtl)) {
33574 collidingItem = other;
33575 break;
33576 }
33577 }
33578
33579 if (collidingItem != null) {
33580 // There is a collision. Reposition the items above the colliding element
33581 item.top = collidingItem.top + collidingItem.height + margin.item.vertical;
33582 }
33583 } while (collidingItem);
33584 }
33585 }
33586
33587 return shouldBail;
33588}
33589/**
33590 * Adjust vertical positions of the items within a single subgroup such that they
33591 * don't overlap each other.
33592 * @param {Item[]} items
33593 * All items withina subgroup
33594 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
33595 * Margins between items and between items and the axis.
33596 * @param {subgroup} subgroup
33597 * The subgroup that is being stacked
33598 */
33599
33600function substack(items, margin, subgroup) {
33601 for (var i = 0; i < items.length; i++) {
33602 items[i].top = null;
33603 } // Set the initial height
33604
33605
33606 var subgroupHeight = subgroup.height; // calculate new, non-overlapping positions
33607
33608 for (i = 0; i < items.length; i++) {
33609 var item = items[i];
33610
33611 if (item.stack && item.top === null) {
33612 // initialize top position
33613 item.top = item.baseTop; //margin.axis + item.baseTop;
33614
33615 do {
33616 // TODO: optimize checking for overlap. when there is a gap without items,
33617 // you only need to check for items from the next item on, not from zero
33618 var collidingItem = null;
33619
33620 for (var j = 0, jj = items.length; j < jj; j++) {
33621 var other = items[j];
33622
33623 if (other.top !== null && other !== item
33624 /*&& other.stack*/
33625 && collision(item, other, margin.item, other.options.rtl)) {
33626 collidingItem = other;
33627 break;
33628 }
33629 }
33630
33631 if (collidingItem != null) {
33632 // There is a collision. Reposition the items above the colliding element
33633 item.top = collidingItem.top + collidingItem.height + margin.item.vertical; // + item.baseTop;
33634 }
33635
33636 if (item.top + item.height > subgroupHeight) {
33637 subgroupHeight = item.top + item.height;
33638 }
33639 } while (collidingItem);
33640 }
33641 } // Set the new height
33642
33643
33644 subgroup.height = subgroupHeight - subgroup.top + 0.5 * margin.item.vertical;
33645}
33646/**
33647 * Adjust vertical positions of the items without stacking them
33648 * @param {Item[]} items
33649 * All visible items
33650 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
33651 * Margins between items and between items and the axis.
33652 * @param {subgroups[]} subgroups
33653 * All subgroups
33654 * @param {boolean} isStackSubgroups
33655 */
33656
33657function nostack(items, margin, subgroups, isStackSubgroups) {
33658 for (var i = 0; i < items.length; i++) {
33659 if (items[i].data.subgroup == undefined) {
33660 items[i].top = margin.item.vertical;
33661 } else if (items[i].data.subgroup !== undefined && isStackSubgroups) {
33662 var newTop = 0;
33663
33664 for (var subgroup in subgroups) {
33665 if (subgroups.hasOwnProperty(subgroup)) {
33666 if (subgroups[subgroup].visible == true && subgroups[subgroup].index < subgroups[items[i].data.subgroup].index) {
33667 newTop += subgroups[subgroup].height;
33668 subgroups[items[i].data.subgroup].top = newTop;
33669 }
33670 }
33671 }
33672
33673 items[i].top = newTop + 0.5 * margin.item.vertical;
33674 }
33675 }
33676
33677 if (!isStackSubgroups) {
33678 stackSubgroups(items, margin, subgroups);
33679 }
33680}
33681/**
33682 * Adjust vertical positions of the subgroups such that they don't overlap each
33683 * other.
33684 * @param {Array.<timeline.Item>} items
33685 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin Margins between items and between items and the axis.
33686 * @param {subgroups[]} subgroups
33687 * All subgroups
33688 */
33689
33690function stackSubgroups(items, margin, subgroups) {
33691 for (var subgroup in subgroups) {
33692 if (subgroups.hasOwnProperty(subgroup)) {
33693 subgroups[subgroup].top = 0;
33694
33695 do {
33696 // TODO: optimize checking for overlap. when there is a gap without items,
33697 // you only need to check for items from the next item on, not from zero
33698 var collidingItem = null;
33699
33700 for (var otherSubgroup in subgroups) {
33701 if (subgroups[otherSubgroup].top !== null && otherSubgroup !== subgroup && subgroups[subgroup].index > subgroups[otherSubgroup].index && collisionByTimes(subgroups[subgroup], subgroups[otherSubgroup])) {
33702 collidingItem = subgroups[otherSubgroup];
33703 break;
33704 }
33705 }
33706
33707 if (collidingItem != null) {
33708 // There is a collision. Reposition the subgroups above the colliding element
33709 subgroups[subgroup].top = collidingItem.top + collidingItem.height;
33710 }
33711 } while (collidingItem);
33712 }
33713 }
33714
33715 for (var i = 0; i < items.length; i++) {
33716 if (items[i].data.subgroup !== undefined) {
33717 items[i].top = subgroups[items[i].data.subgroup].top + 0.5 * margin.item.vertical;
33718 }
33719 }
33720}
33721/**
33722 * Adjust vertical positions of the subgroups such that they don't overlap each
33723 * other, then stacks the contents of each subgroup individually.
33724 * @param {Item[]} subgroupItems
33725 * All the items in a subgroup
33726 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
33727 * Margins between items and between items and the axis.
33728 * @param {subgroups[]} subgroups
33729 * All subgroups
33730 */
33731
33732function stackSubgroupsWithInnerStack(subgroupItems, margin, subgroups) {
33733 var doSubStack = false; // Run subgroups in their order (if any)
33734
33735 var subgroupOrder = [];
33736
33737 for (var subgroup in subgroups) {
33738 if (subgroups[subgroup].hasOwnProperty("index")) {
33739 subgroupOrder[subgroups[subgroup].index] = subgroup;
33740 } else {
33741 subgroupOrder.push(subgroup);
33742 }
33743 }
33744
33745 for (var j = 0; j < subgroupOrder.length; j++) {
33746 subgroup = subgroupOrder[j];
33747
33748 if (subgroups.hasOwnProperty(subgroup)) {
33749 doSubStack = doSubStack || subgroups[subgroup].stack;
33750 subgroups[subgroup].top = 0;
33751
33752 for (var otherSubgroup in subgroups) {
33753 if (subgroups[otherSubgroup].visible && subgroups[subgroup].index > subgroups[otherSubgroup].index) {
33754 subgroups[subgroup].top += subgroups[otherSubgroup].height;
33755 }
33756 }
33757
33758 var items = subgroupItems[subgroup];
33759
33760 for (var i = 0; i < items.length; i++) {
33761 if (items[i].data.subgroup !== undefined) {
33762 items[i].top = subgroups[items[i].data.subgroup].top + 0.5 * margin.item.vertical;
33763
33764 if (subgroups[subgroup].stack) {
33765 items[i].baseTop = items[i].top;
33766 }
33767 }
33768 }
33769
33770 if (doSubStack && subgroups[subgroup].stack) {
33771 substack(subgroupItems[subgroup], margin, subgroups[subgroup]);
33772 }
33773 }
33774 }
33775}
33776/**
33777 * Test if the two provided items collide
33778 * The items must have parameters left, width, top, and height.
33779 * @param {Item} a The first item
33780 * @param {Item} b The second item
33781 * @param {{horizontal: number, vertical: number}} margin
33782 * An object containing a horizontal and vertical
33783 * minimum required margin.
33784 * @param {boolean} rtl
33785 * @return {boolean} true if a and b collide, else false
33786 */
33787
33788function collision(a, b, margin, rtl) {
33789 if (rtl) {
33790 return a.right - margin.horizontal + EPSILON < b.right + b.width && a.right + a.width + margin.horizontal - EPSILON > b.right && a.top - margin.vertical + EPSILON < b.top + b.height && a.top + a.height + margin.vertical - EPSILON > b.top;
33791 } else {
33792 return a.left - margin.horizontal + EPSILON < b.left + b.width && a.left + a.width + margin.horizontal - EPSILON > b.left && a.top - margin.vertical + EPSILON < b.top + b.height && a.top + a.height + margin.vertical - EPSILON > b.top;
33793 }
33794}
33795/**
33796 * Test if the two provided objects collide
33797 * The objects must have parameters start, end, top, and height.
33798 * @param {Object} a The first Object
33799 * @param {Object} b The second Object
33800 * @return {boolean} true if a and b collide, else false
33801 */
33802
33803function collisionByTimes(a, b) {
33804 return a.start <= b.start && a.end >= b.start && a.top < b.top + b.height && a.top + a.height > b.top || b.start <= a.start && b.end >= a.start && b.top < a.top + a.height && b.top + b.height > a.top;
33805}
33806
33807var stack$1 = /*#__PURE__*/Object.freeze({
33808 orderByStart: orderByStart,
33809 orderByEnd: orderByEnd,
33810 stack: stack,
33811 substack: substack,
33812 nostack: nostack,
33813 stackSubgroups: stackSubgroups,
33814 stackSubgroupsWithInnerStack: stackSubgroupsWithInnerStack,
33815 collision: collision,
33816 collisionByTimes: collisionByTimes
33817});
33818
33819var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
33820
33821var BACKGROUND = '__background__'; // reserved group id for background items without group
33822
33823var ReservedGroupIds = {
33824 UNGROUPED: UNGROUPED,
33825 BACKGROUND: BACKGROUND
33826 /**
33827 * @constructor Group
33828 */
33829
33830};
33831
33832var Group =
33833/*#__PURE__*/
33834function () {
33835 /**
33836 * @param {number | string} groupId
33837 * @param {Object} data
33838 * @param {ItemSet} itemSet
33839 * @constructor Group
33840 */
33841 function Group(groupId, data, itemSet) {
33842 _classCallCheck(this, Group);
33843
33844 this.groupId = groupId;
33845 this.subgroups = {};
33846 this.subgroupStack = {};
33847 this.subgroupStackAll = false;
33848 this.subgroupVisibility = {};
33849 this.doInnerStack = false;
33850 this.shouldBailStackItems = false;
33851 this.subgroupIndex = 0;
33852 this.subgroupOrderer = data && data.subgroupOrder;
33853 this.itemSet = itemSet;
33854 this.isVisible = null;
33855 this.stackDirty = true; // if true, items will be restacked on next redraw
33856
33857 if (data && data.nestedGroups) {
33858 this.nestedGroups = data.nestedGroups;
33859
33860 if (data.showNested == false) {
33861 this.showNested = false;
33862 } else {
33863 this.showNested = true;
33864 }
33865 }
33866
33867 if (data && data.subgroupStack) {
33868 if (typeof data.subgroupStack === "boolean") {
33869 this.doInnerStack = data.subgroupStack;
33870 this.subgroupStackAll = data.subgroupStack;
33871 } else {
33872 // We might be doing stacking on specific sub groups, but only
33873 // if at least one is set to do stacking
33874 for (var key in data.subgroupStack) {
33875 this.subgroupStack[key] = data.subgroupStack[key];
33876 this.doInnerStack = this.doInnerStack || data.subgroupStack[key];
33877 }
33878 }
33879 }
33880
33881 if (data && data.heightMode) {
33882 this.heightMode = data.heightMode;
33883 } else {
33884 this.heightMode = itemSet.options.groupHeightMode;
33885 }
33886
33887 this.nestedInGroup = null;
33888 this.dom = {};
33889 this.props = {
33890 label: {
33891 width: 0,
33892 height: 0
33893 }
33894 };
33895 this.className = null;
33896 this.items = {}; // items filtered by groupId of this group
33897
33898 this.visibleItems = []; // items currently visible in window
33899
33900 this.itemsInRange = []; // items currently in range
33901
33902 this.orderedItems = {
33903 byStart: [],
33904 byEnd: []
33905 };
33906 this.checkRangedItems = false; // needed to refresh the ranged items if the window is programatically changed with NO overlap.
33907
33908 var me = this;
33909 this.itemSet.body.emitter.on("checkRangedItems", function () {
33910 me.checkRangedItems = true;
33911 });
33912
33913 this._create();
33914
33915 this.setData(data);
33916 }
33917 /**
33918 * Create DOM elements for the group
33919 * @private
33920 */
33921
33922
33923 _createClass(Group, [{
33924 key: "_create",
33925 value: function _create() {
33926 var label = document.createElement('div');
33927
33928 if (this.itemSet.options.groupEditable.order) {
33929 label.className = 'vis-label draggable';
33930 } else {
33931 label.className = 'vis-label';
33932 }
33933
33934 this.dom.label = label;
33935 var inner = document.createElement('div');
33936 inner.className = 'vis-inner';
33937 label.appendChild(inner);
33938 this.dom.inner = inner;
33939 var foreground = document.createElement('div');
33940 foreground.className = 'vis-group';
33941 foreground['vis-group'] = this;
33942 this.dom.foreground = foreground;
33943 this.dom.background = document.createElement('div');
33944 this.dom.background.className = 'vis-group';
33945 this.dom.axis = document.createElement('div');
33946 this.dom.axis.className = 'vis-group'; // create a hidden marker to detect when the Timelines container is attached
33947 // to the DOM, or the style of a parent of the Timeline is changed from
33948 // display:none is changed to visible.
33949
33950 this.dom.marker = document.createElement('div');
33951 this.dom.marker.style.visibility = 'hidden';
33952 this.dom.marker.style.position = 'absolute';
33953 this.dom.marker.innerHTML = '';
33954 this.dom.background.appendChild(this.dom.marker);
33955 }
33956 /**
33957 * Set the group data for this group
33958 * @param {Object} data Group data, can contain properties content and className
33959 */
33960
33961 }, {
33962 key: "setData",
33963 value: function setData(data) {
33964 if (this.itemSet.groupTouchParams.isDragging) return; // update contents
33965
33966 var content;
33967 var templateFunction;
33968
33969 if (data && data.subgroupVisibility) {
33970 for (var key in data.subgroupVisibility) {
33971 this.subgroupVisibility[key] = data.subgroupVisibility[key];
33972 }
33973 }
33974
33975 if (this.itemSet.options && this.itemSet.options.groupTemplate) {
33976 templateFunction = this.itemSet.options.groupTemplate.bind(this);
33977 content = templateFunction(data, this.dom.inner);
33978 } else {
33979 content = data && data.content;
33980 }
33981
33982 if (content instanceof Element) {
33983 while (this.dom.inner.firstChild) {
33984 this.dom.inner.removeChild(this.dom.inner.firstChild);
33985 }
33986
33987 this.dom.inner.appendChild(content);
33988 } else if (content instanceof Object && content.isReactComponent) ; else if (content instanceof Object) {
33989 templateFunction(data, this.dom.inner);
33990 } else if (content !== undefined && content !== null) {
33991 this.dom.inner.innerHTML = content;
33992 } else {
33993 this.dom.inner.innerHTML = this.groupId || ''; // groupId can be null
33994 } // update title
33995
33996
33997 this.dom.label.title = data && data.title || '';
33998
33999 if (!this.dom.inner.firstChild) {
34000 util.addClassName(this.dom.inner, 'vis-hidden');
34001 } else {
34002 util.removeClassName(this.dom.inner, 'vis-hidden');
34003 }
34004
34005 if (data && data.nestedGroups) {
34006 if (!this.nestedGroups || this.nestedGroups != data.nestedGroups) {
34007 this.nestedGroups = data.nestedGroups;
34008 }
34009
34010 if (data.showNested !== undefined || this.showNested === undefined) {
34011 if (data.showNested == false) {
34012 this.showNested = false;
34013 } else {
34014 this.showNested = true;
34015 }
34016 }
34017
34018 util.addClassName(this.dom.label, 'vis-nesting-group');
34019
34020 if (this.showNested) {
34021 util.removeClassName(this.dom.label, 'collapsed');
34022 util.addClassName(this.dom.label, 'expanded');
34023 } else {
34024 util.removeClassName(this.dom.label, 'expanded');
34025 util.addClassName(this.dom.label, 'collapsed');
34026 }
34027 } else if (this.nestedGroups) {
34028 this.nestedGroups = null;
34029 util.removeClassName(this.dom.label, 'collapsed');
34030 util.removeClassName(this.dom.label, 'expanded');
34031 util.removeClassName(this.dom.label, 'vis-nesting-group');
34032 }
34033
34034 if (data && (data.treeLevel || data.nestedInGroup)) {
34035 util.addClassName(this.dom.label, 'vis-nested-group');
34036
34037 if (data.treeLevel) {
34038 util.addClassName(this.dom.label, 'vis-group-level-' + data.treeLevel);
34039 } else {
34040 // Nesting level is unknown, but we're sure it's at least 1
34041 util.addClassName(this.dom.label, 'vis-group-level-unknown-but-gte1');
34042 }
34043 } else {
34044 util.addClassName(this.dom.label, 'vis-group-level-0');
34045 } // update className
34046
34047
34048 var className = data && data.className || null;
34049
34050 if (className != this.className) {
34051 if (this.className) {
34052 util.removeClassName(this.dom.label, this.className);
34053 util.removeClassName(this.dom.foreground, this.className);
34054 util.removeClassName(this.dom.background, this.className);
34055 util.removeClassName(this.dom.axis, this.className);
34056 }
34057
34058 util.addClassName(this.dom.label, className);
34059 util.addClassName(this.dom.foreground, className);
34060 util.addClassName(this.dom.background, className);
34061 util.addClassName(this.dom.axis, className);
34062 this.className = className;
34063 } // update style
34064
34065
34066 if (this.style) {
34067 util.removeCssText(this.dom.label, this.style);
34068 this.style = null;
34069 }
34070
34071 if (data && data.style) {
34072 util.addCssText(this.dom.label, data.style);
34073 this.style = data.style;
34074 }
34075 }
34076 /**
34077 * Get the width of the group label
34078 * @return {number} width
34079 */
34080
34081 }, {
34082 key: "getLabelWidth",
34083 value: function getLabelWidth() {
34084 return this.props.label.width;
34085 }
34086 /**
34087 * check if group has had an initial height hange
34088 * @returns {boolean}
34089 */
34090
34091 }, {
34092 key: "_didMarkerHeightChange",
34093 value: function _didMarkerHeightChange() {
34094 var markerHeight = this.dom.marker.clientHeight;
34095
34096 if (markerHeight != this.lastMarkerHeight) {
34097 this.lastMarkerHeight = markerHeight;
34098 var redrawQueue = {};
34099 var redrawQueueLength = 0;
34100 util.forEach(this.items, function (item, key) {
34101 item.dirty = true;
34102
34103 if (item.displayed) {
34104 var returnQueue = true;
34105 redrawQueue[key] = item.redraw(returnQueue);
34106 redrawQueueLength = redrawQueue[key].length;
34107 }
34108 });
34109 var needRedraw = redrawQueueLength > 0;
34110
34111 if (needRedraw) {
34112 var _loop = function _loop(i) {
34113 util.forEach(redrawQueue, function (fns) {
34114 fns[i]();
34115 });
34116 };
34117
34118 // redraw all regular items
34119 for (var i = 0; i < redrawQueueLength; i++) {
34120 _loop(i);
34121 }
34122 }
34123
34124 return true;
34125 } else {
34126 return false;
34127 }
34128 }
34129 /**
34130 * calculate group dimentions and position
34131 * @param {number} pixels
34132 */
34133
34134 }, {
34135 key: "_calculateGroupSizeAndPosition",
34136 value: function _calculateGroupSizeAndPosition() {
34137 var _this$dom$foreground = this.dom.foreground,
34138 offsetTop = _this$dom$foreground.offsetTop,
34139 offsetLeft = _this$dom$foreground.offsetLeft,
34140 offsetWidth = _this$dom$foreground.offsetWidth;
34141 this.top = offsetTop;
34142 this.right = offsetLeft;
34143 this.width = offsetWidth;
34144 }
34145 /**
34146 * checks if should bail redraw of items
34147 * @returns {boolean} should bail
34148 */
34149
34150 }, {
34151 key: "_shouldBailItemsRedraw",
34152 value: function _shouldBailItemsRedraw() {
34153 var me = this;
34154 var timeoutOptions = this.itemSet.options.onTimeout;
34155 var bailOptions = {
34156 relativeBailingTime: this.itemSet.itemsSettingTime,
34157 bailTimeMs: timeoutOptions && timeoutOptions.timeoutMs,
34158 userBailFunction: timeoutOptions && timeoutOptions.callback,
34159 shouldBailStackItems: this.shouldBailStackItems
34160 };
34161 var bail = null;
34162
34163 if (!this.itemSet.initialDrawDone) {
34164 if (bailOptions.shouldBailStackItems) {
34165 return true;
34166 }
34167
34168 if (Math.abs(Date.now() - new Date(bailOptions.relativeBailingTime)) > bailOptions.bailTimeMs) {
34169 if (bailOptions.userBailFunction && this.itemSet.userContinueNotBail == null) {
34170 bailOptions.userBailFunction(function (didUserContinue) {
34171 me.itemSet.userContinueNotBail = didUserContinue;
34172 bail = !didUserContinue;
34173 });
34174 } else if (me.itemSet.userContinueNotBail == false) {
34175 bail = true;
34176 } else {
34177 bail = false;
34178 }
34179 }
34180 }
34181
34182 return bail;
34183 }
34184 /**
34185 * redraws items
34186 * @param {boolean} forceRestack
34187 * @param {boolean} lastIsVisible
34188 * @param {number} margin
34189 * @param {object} range
34190 * @private
34191 */
34192
34193 }, {
34194 key: "_redrawItems",
34195 value: function _redrawItems(forceRestack, lastIsVisible, margin, range) {
34196 var _this = this;
34197
34198 var restack = forceRestack || this.stackDirty || this.isVisible && !lastIsVisible; // if restacking, reposition visible items vertically
34199
34200 if (restack) {
34201 var visibleSubgroups = {};
34202 var orderedItems = {
34203 byEnd: this.orderedItems.byEnd.filter(function (item) {
34204 return !item.isCluster;
34205 }),
34206 byStart: this.orderedItems.byStart.filter(function (item) {
34207 return !item.isCluster;
34208 })
34209 };
34210 var orderedClusters = {
34211 byEnd: _toConsumableArray(new Set(this.orderedItems.byEnd.map(function (item) {
34212 return item.cluster;
34213 }).filter(function (item) {
34214 return !!item;
34215 }))),
34216 byStart: _toConsumableArray(new Set(this.orderedItems.byStart.map(function (item) {
34217 return item.cluster;
34218 }).filter(function (item) {
34219 return !!item;
34220 })))
34221 /**
34222 * Get all visible items in range
34223 * @return {array} items
34224 */
34225
34226 };
34227
34228 var getVisibleItems = function getVisibleItems() {
34229 var visibleItems = _this._updateItemsInRange(orderedItems, _this.visibleItems.filter(function (item) {
34230 return !item.isCluster;
34231 }), range);
34232
34233 var visibleClusters = _this._updateClustersInRange(orderedClusters, _this.visibleItems.filter(function (item) {
34234 return item.isCluster;
34235 }), range);
34236
34237 return [].concat(_toConsumableArray(visibleItems), _toConsumableArray(visibleClusters));
34238 };
34239
34240 if (typeof this.itemSet.options.order === 'function') {
34241 (function () {
34242 // a custom order function
34243 //show all items
34244 var me = _this;
34245
34246 if (_this.doInnerStack && _this.itemSet.options.stackSubgroups) {
34247 // Order the items within each subgroup
34248 for (var subgroup in _this.subgroups) {
34249 visibleSubgroups[subgroup] = _this.subgroups[subgroup].items.slice().sort(function (a, b) {
34250 return me.itemSet.options.order(a.data, b.data);
34251 });
34252 }
34253
34254 stackSubgroupsWithInnerStack(visibleSubgroups, margin, _this.subgroups);
34255 _this.visibleItems = getVisibleItems();
34256
34257 _this._updateSubGroupHeights(margin);
34258 } else {
34259 _this.visibleItems = getVisibleItems();
34260
34261 _this._updateSubGroupHeights(margin); // order all items and force a restacking
34262 // order all items outside clusters and force a restacking
34263
34264
34265 var customOrderedItems = _this.visibleItems.slice().filter(function (item) {
34266 return item.isCluster || !item.isCluster && !item.cluster;
34267 }).sort(function (a, b) {
34268 return me.itemSet.options.order(a.data, b.data);
34269 });
34270
34271 _this.shouldBailStackItems = stack(customOrderedItems, margin, true, _this._shouldBailItemsRedraw.bind(_this));
34272 }
34273 })();
34274 } else {
34275 // no custom order function, lazy stacking
34276 var visibleItems = this._updateItemsInRange(orderedItems, this.visibleItems.filter(function (item) {
34277 return !item.isCluster;
34278 }), range);
34279
34280 var visibleClusters = this._updateClustersInRange(orderedClusters, this.visibleItems.filter(function (item) {
34281 return item.isCluster;
34282 }), range);
34283
34284 this.visibleItems = [].concat(_toConsumableArray(visibleItems), _toConsumableArray(visibleClusters));
34285
34286 this._updateSubGroupHeights(margin);
34287
34288 if (this.itemSet.options.stack) {
34289 if (this.doInnerStack && this.itemSet.options.stackSubgroups) {
34290 for (var subgroup in this.subgroups) {
34291 visibleSubgroups[subgroup] = this.subgroups[subgroup].items;
34292 }
34293
34294 stackSubgroupsWithInnerStack(visibleSubgroups, margin, this.subgroups);
34295 } else {
34296 // TODO: ugly way to access options...
34297 this.shouldBailStackItems = stack(this.visibleItems, margin, true, this._shouldBailItemsRedraw.bind(this));
34298 }
34299 } else {
34300 // no stacking
34301 nostack(this.visibleItems, margin, this.subgroups, this.itemSet.options.stackSubgroups);
34302 }
34303 }
34304
34305 for (var i = 0; i < this.visibleItems.length; i++) {
34306 this.visibleItems[i].repositionX();
34307
34308 if (this.subgroupVisibility[this.visibleItems[i].data.subgroup] !== undefined) {
34309 if (!this.subgroupVisibility[this.visibleItems[i].data.subgroup]) {
34310 this.visibleItems[i].hide();
34311 }
34312 }
34313 }
34314
34315 if (this.itemSet.options.cluster) {
34316 util.forEach(this.items, function (item) {
34317 if (item.cluster && item.displayed) {
34318 item.hide();
34319 }
34320 });
34321 }
34322
34323 if (this.shouldBailStackItems) {
34324 this.itemSet.body.emitter.emit('destroyTimeline');
34325 }
34326
34327 this.stackDirty = false;
34328 }
34329 }
34330 /**
34331 * check if group resized
34332 * @param {boolean} resized
34333 * @param {number} height
34334 * @return {boolean} did resize
34335 */
34336
34337 }, {
34338 key: "_didResize",
34339 value: function _didResize(resized, height) {
34340 resized = util.updateProperty(this, 'height', height) || resized; // recalculate size of label
34341
34342 var labelWidth = this.dom.inner.clientWidth;
34343 var labelHeight = this.dom.inner.clientHeight;
34344 resized = util.updateProperty(this.props.label, 'width', labelWidth) || resized;
34345 resized = util.updateProperty(this.props.label, 'height', labelHeight) || resized;
34346 return resized;
34347 }
34348 /**
34349 * apply group height
34350 * @param {number} height
34351 */
34352
34353 }, {
34354 key: "_applyGroupHeight",
34355 value: function _applyGroupHeight(height) {
34356 this.dom.background.style.height = "".concat(height, "px");
34357 this.dom.foreground.style.height = "".concat(height, "px");
34358 this.dom.label.style.height = "".concat(height, "px");
34359 }
34360 /**
34361 * update vertical position of items after they are re-stacked and the height of the group is calculated
34362 * @param {number} margin
34363 */
34364
34365 }, {
34366 key: "_updateItemsVerticalPosition",
34367 value: function _updateItemsVerticalPosition(margin) {
34368 for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
34369 var item = this.visibleItems[i];
34370 item.repositionY(margin);
34371
34372 if (!this.isVisible && this.groupId != ReservedGroupIds.BACKGROUND) {
34373 if (item.displayed) item.hide();
34374 }
34375 }
34376 }
34377 /**
34378 * Repaint this group
34379 * @param {{start: number, end: number}} range
34380 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
34381 * @param {boolean} [forceRestack=false] Force restacking of all items
34382 * @param {boolean} [returnQueue=false] return the queue or if the group resized
34383 * @return {boolean} Returns true if the group is resized or the redraw queue if returnQueue=true
34384 */
34385
34386 }, {
34387 key: "redraw",
34388 value: function redraw(range, margin, forceRestack, returnQueue) {
34389 var _this2 = this;
34390
34391 var resized = false;
34392 var lastIsVisible = this.isVisible;
34393 var height;
34394 var queue = [function () {
34395 forceRestack = _this2._didMarkerHeightChange.call(_this2) || forceRestack;
34396 }, // recalculate the height of the subgroups
34397 this._updateSubGroupHeights.bind(this, margin), // calculate actual size and position
34398 this._calculateGroupSizeAndPosition.bind(this), function () {
34399 _this2.isVisible = _this2._isGroupVisible.bind(_this2)(range, margin);
34400 }, function () {
34401 _this2._redrawItems.bind(_this2)(forceRestack, lastIsVisible, margin, range);
34402 }, // update subgroups
34403 this._updateSubgroupsSizes.bind(this), function () {
34404 height = _this2._calculateHeight.bind(_this2)(margin);
34405 }, // calculate actual size and position again
34406 this._calculateGroupSizeAndPosition.bind(this), function () {
34407 resized = _this2._didResize.bind(_this2)(resized, height);
34408 }, function () {
34409 _this2._applyGroupHeight.bind(_this2)(height);
34410 }, function () {
34411 _this2._updateItemsVerticalPosition.bind(_this2)(margin);
34412 }, function () {
34413 if (!_this2.isVisible && _this2.height) {
34414 resized = false;
34415 }
34416
34417 return resized;
34418 }.bind(this)];
34419
34420 if (returnQueue) {
34421 return queue;
34422 } else {
34423 var result;
34424 queue.forEach(function (fn) {
34425 result = fn();
34426 });
34427 return result;
34428 }
34429 }
34430 /**
34431 * recalculate the height of the subgroups
34432 *
34433 * @param {{item: timeline.Item}} margin
34434 * @private
34435 */
34436
34437 }, {
34438 key: "_updateSubGroupHeights",
34439 value: function _updateSubGroupHeights(margin) {
34440 var _this3 = this;
34441
34442 if (Object.keys(this.subgroups).length > 0) {
34443 var me = this;
34444
34445 this._resetSubgroups();
34446
34447 util.forEach(this.visibleItems, function (item) {
34448 if (item.data.subgroup !== undefined) {
34449 me.subgroups[item.data.subgroup].height = Math.max(me.subgroups[item.data.subgroup].height, item.height + margin.item.vertical);
34450 me.subgroups[item.data.subgroup].visible = typeof _this3.subgroupVisibility[item.data.subgroup] === 'undefined' ? true : Boolean(_this3.subgroupVisibility[item.data.subgroup]);
34451 }
34452 });
34453 }
34454 }
34455 /**
34456 * check if group is visible
34457 *
34458 * @param {timeline.Range} range
34459 * @param {{axis: timeline.DataAxis}} margin
34460 * @returns {boolean} is visible
34461 * @private
34462 */
34463
34464 }, {
34465 key: "_isGroupVisible",
34466 value: function _isGroupVisible(range, margin) {
34467 return this.top <= range.body.domProps.centerContainer.height - range.body.domProps.scrollTop + margin.axis && this.top + this.height + margin.axis >= -range.body.domProps.scrollTop;
34468 }
34469 /**
34470 * recalculate the height of the group
34471 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
34472 * @returns {number} Returns the height
34473 * @private
34474 */
34475
34476 }, {
34477 key: "_calculateHeight",
34478 value: function _calculateHeight(margin) {
34479 // recalculate the height of the group
34480 var height;
34481 var items;
34482
34483 if (this.heightMode === 'fixed') {
34484 items = util.toArray(this.items);
34485 } else {
34486 // default or 'auto'
34487 items = this.visibleItems;
34488 }
34489
34490 if (items.length > 0) {
34491 var min = items[0].top;
34492 var max = items[0].top + items[0].height;
34493 util.forEach(items, function (item) {
34494 min = Math.min(min, item.top);
34495 max = Math.max(max, item.top + item.height);
34496 });
34497
34498 if (min > margin.axis) {
34499 // there is an empty gap between the lowest item and the axis
34500 var offset = min - margin.axis;
34501 max -= offset;
34502 util.forEach(items, function (item) {
34503 item.top -= offset;
34504 });
34505 }
34506
34507 height = max + margin.item.vertical / 2;
34508
34509 if (this.heightMode !== "fitItems") {
34510 height = Math.max(height, this.props.label.height);
34511 }
34512 } else {
34513 height = this.props.label.height;
34514 }
34515
34516 return height;
34517 }
34518 /**
34519 * Show this group: attach to the DOM
34520 */
34521
34522 }, {
34523 key: "show",
34524 value: function show() {
34525 if (!this.dom.label.parentNode) {
34526 this.itemSet.dom.labelSet.appendChild(this.dom.label);
34527 }
34528
34529 if (!this.dom.foreground.parentNode) {
34530 this.itemSet.dom.foreground.appendChild(this.dom.foreground);
34531 }
34532
34533 if (!this.dom.background.parentNode) {
34534 this.itemSet.dom.background.appendChild(this.dom.background);
34535 }
34536
34537 if (!this.dom.axis.parentNode) {
34538 this.itemSet.dom.axis.appendChild(this.dom.axis);
34539 }
34540 }
34541 /**
34542 * Hide this group: remove from the DOM
34543 */
34544
34545 }, {
34546 key: "hide",
34547 value: function hide() {
34548 var label = this.dom.label;
34549
34550 if (label.parentNode) {
34551 label.parentNode.removeChild(label);
34552 }
34553
34554 var foreground = this.dom.foreground;
34555
34556 if (foreground.parentNode) {
34557 foreground.parentNode.removeChild(foreground);
34558 }
34559
34560 var background = this.dom.background;
34561
34562 if (background.parentNode) {
34563 background.parentNode.removeChild(background);
34564 }
34565
34566 var axis = this.dom.axis;
34567
34568 if (axis.parentNode) {
34569 axis.parentNode.removeChild(axis);
34570 }
34571 }
34572 /**
34573 * Add an item to the group
34574 * @param {Item} item
34575 */
34576
34577 }, {
34578 key: "add",
34579 value: function add(item) {
34580 this.items[item.id] = item;
34581 item.setParent(this);
34582 this.stackDirty = true; // add to
34583
34584 if (item.data.subgroup !== undefined) {
34585 this._addToSubgroup(item);
34586
34587 this.orderSubgroups();
34588 }
34589
34590 if (!this.visibleItems.includes(item)) {
34591 var range = this.itemSet.body.range; // TODO: not nice accessing the range like this
34592
34593 this._checkIfVisible(item, this.visibleItems, range);
34594 }
34595 }
34596 /**
34597 * add item to subgroup
34598 * @param {object} item
34599 * @param {string} subgroupId
34600 */
34601
34602 }, {
34603 key: "_addToSubgroup",
34604 value: function _addToSubgroup(item) {
34605 var subgroupId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : item.data.subgroup;
34606
34607 if (subgroupId != undefined && this.subgroups[subgroupId] === undefined) {
34608 this.subgroups[subgroupId] = {
34609 height: 0,
34610 top: 0,
34611 start: item.data.start,
34612 end: item.data.end || item.data.start,
34613 visible: false,
34614 index: this.subgroupIndex,
34615 items: [],
34616 stack: this.subgroupStackAll || this.subgroupStack[subgroupId] || false
34617 };
34618 this.subgroupIndex++;
34619 }
34620
34621 if (new Date(item.data.start) < new Date(this.subgroups[subgroupId].start)) {
34622 this.subgroups[subgroupId].start = item.data.start;
34623 }
34624
34625 var itemEnd = item.data.end || item.data.start;
34626
34627 if (new Date(itemEnd) > new Date(this.subgroups[subgroupId].end)) {
34628 this.subgroups[subgroupId].end = itemEnd;
34629 }
34630
34631 this.subgroups[subgroupId].items.push(item);
34632 }
34633 /**
34634 * update subgroup sizes
34635 */
34636
34637 }, {
34638 key: "_updateSubgroupsSizes",
34639 value: function _updateSubgroupsSizes() {
34640 var me = this;
34641
34642 if (me.subgroups) {
34643 var _loop2 = function _loop2(subgroup) {
34644 var initialEnd = me.subgroups[subgroup].items[0].data.end || me.subgroups[subgroup].items[0].data.start;
34645 var newStart = me.subgroups[subgroup].items[0].data.start;
34646 var newEnd = initialEnd - 1;
34647 me.subgroups[subgroup].items.forEach(function (item) {
34648 if (new Date(item.data.start) < new Date(newStart)) {
34649 newStart = item.data.start;
34650 }
34651
34652 var itemEnd = item.data.end || item.data.start;
34653
34654 if (new Date(itemEnd) > new Date(newEnd)) {
34655 newEnd = itemEnd;
34656 }
34657 });
34658 me.subgroups[subgroup].start = newStart;
34659 me.subgroups[subgroup].end = new Date(newEnd - 1); // -1 to compensate for colliding end to start subgroups;
34660 };
34661
34662 for (var subgroup in me.subgroups) {
34663 _loop2(subgroup);
34664 }
34665 }
34666 }
34667 /**
34668 * order subgroups
34669 */
34670
34671 }, {
34672 key: "orderSubgroups",
34673 value: function orderSubgroups() {
34674 if (this.subgroupOrderer !== undefined) {
34675 var sortArray = [];
34676
34677 if (typeof this.subgroupOrderer == 'string') {
34678 for (var subgroup in this.subgroups) {
34679 sortArray.push({
34680 subgroup: subgroup,
34681 sortField: this.subgroups[subgroup].items[0].data[this.subgroupOrderer]
34682 });
34683 }
34684
34685 sortArray.sort(function (a, b) {
34686 return a.sortField - b.sortField;
34687 });
34688 } else if (typeof this.subgroupOrderer == 'function') {
34689 for (var _subgroup in this.subgroups) {
34690 sortArray.push(this.subgroups[_subgroup].items[0].data);
34691 }
34692
34693 sortArray.sort(this.subgroupOrderer);
34694 }
34695
34696 if (sortArray.length > 0) {
34697 for (var i = 0; i < sortArray.length; i++) {
34698 this.subgroups[sortArray[i].subgroup].index = i;
34699 }
34700 }
34701 }
34702 }
34703 /**
34704 * add item to subgroup
34705 */
34706
34707 }, {
34708 key: "_resetSubgroups",
34709 value: function _resetSubgroups() {
34710 for (var subgroup in this.subgroups) {
34711 if (this.subgroups.hasOwnProperty(subgroup)) {
34712 this.subgroups[subgroup].visible = false;
34713 this.subgroups[subgroup].height = 0;
34714 }
34715 }
34716 }
34717 /**
34718 * Remove an item from the group
34719 * @param {Item} item
34720 */
34721
34722 }, {
34723 key: "remove",
34724 value: function remove(item) {
34725 delete this.items[item.id];
34726 item.setParent(null);
34727 this.stackDirty = true; // remove from visible items
34728
34729 var index = this.visibleItems.indexOf(item);
34730 if (index != -1) this.visibleItems.splice(index, 1);
34731
34732 if (item.data.subgroup !== undefined) {
34733 this._removeFromSubgroup(item);
34734
34735 this.orderSubgroups();
34736 }
34737 }
34738 /**
34739 * remove item from subgroup
34740 * @param {object} item
34741 * @param {string} subgroupId
34742 */
34743
34744 }, {
34745 key: "_removeFromSubgroup",
34746 value: function _removeFromSubgroup(item) {
34747 var subgroupId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : item.data.subgroup;
34748
34749 if (subgroupId != undefined) {
34750 var subgroup = this.subgroups[subgroupId];
34751
34752 if (subgroup) {
34753 var itemIndex = subgroup.items.indexOf(item); // Check the item is actually in this subgroup. How should items not in the group be handled?
34754
34755 if (itemIndex >= 0) {
34756 subgroup.items.splice(itemIndex, 1);
34757
34758 if (!subgroup.items.length) {
34759 delete this.subgroups[subgroupId];
34760 } else {
34761 this._updateSubgroupsSizes();
34762 }
34763 }
34764 }
34765 }
34766 }
34767 /**
34768 * Remove an item from the corresponding DataSet
34769 * @param {Item} item
34770 */
34771
34772 }, {
34773 key: "removeFromDataSet",
34774 value: function removeFromDataSet(item) {
34775 this.itemSet.removeItem(item.id);
34776 }
34777 /**
34778 * Reorder the items
34779 */
34780
34781 }, {
34782 key: "order",
34783 value: function order() {
34784 var array = util.toArray(this.items);
34785 var startArray = [];
34786 var endArray = [];
34787
34788 for (var i = 0; i < array.length; i++) {
34789 if (array[i].data.end !== undefined) {
34790 endArray.push(array[i]);
34791 }
34792
34793 startArray.push(array[i]);
34794 }
34795
34796 this.orderedItems = {
34797 byStart: startArray,
34798 byEnd: endArray
34799 };
34800 orderByStart(this.orderedItems.byStart);
34801 orderByEnd(this.orderedItems.byEnd);
34802 }
34803 /**
34804 * Update the visible items
34805 * @param {{byStart: Item[], byEnd: Item[]}} orderedItems All items ordered by start date and by end date
34806 * @param {Item[]} oldVisibleItems The previously visible items.
34807 * @param {{start: number, end: number}} range Visible range
34808 * @return {Item[]} visibleItems The new visible items.
34809 * @private
34810 */
34811
34812 }, {
34813 key: "_updateItemsInRange",
34814 value: function _updateItemsInRange(orderedItems, oldVisibleItems, range) {
34815 var visibleItems = [];
34816 var visibleItemsLookup = {}; // we keep this to quickly look up if an item already exists in the list without using indexOf on visibleItems
34817
34818 if (!this.isVisible && this.groupId != ReservedGroupIds.BACKGROUND) {
34819 for (var i = 0; i < oldVisibleItems.length; i++) {
34820 var item = oldVisibleItems[i];
34821 if (item.displayed) item.hide();
34822 }
34823
34824 return visibleItems;
34825 }
34826
34827 var interval = (range.end - range.start) / 4;
34828 var lowerBound = range.start - interval;
34829 var upperBound = range.end + interval; // this function is used to do the binary search for items having start date only.
34830
34831 var startSearchFunction = function startSearchFunction(value) {
34832 if (value < lowerBound) {
34833 return -1;
34834 } else if (value <= upperBound) {
34835 return 0;
34836 } else {
34837 return 1;
34838 }
34839 }; // this function is used to do the binary search for items having start and end dates (range).
34840
34841
34842 var endSearchFunction = function endSearchFunction(value) {
34843 if (value < lowerBound) {
34844 return -1;
34845 } else {
34846 return 0;
34847 }
34848 }; // first check if the items that were in view previously are still in view.
34849 // IMPORTANT: this handles the case for the items with startdate before the window and enddate after the window!
34850 // also cleans up invisible items.
34851
34852
34853 if (oldVisibleItems.length > 0) {
34854 for (var _i = 0; _i < oldVisibleItems.length; _i++) {
34855 this._checkIfVisibleWithReference(oldVisibleItems[_i], visibleItems, visibleItemsLookup, range);
34856 }
34857 } // we do a binary search for the items that have only start values.
34858
34859
34860 var initialPosByStart = util.binarySearchCustom(orderedItems.byStart, startSearchFunction, 'data', 'start'); // trace the visible items from the inital start pos both ways until an invisible item is found, we only look at the start values.
34861
34862 this._traceVisible(initialPosByStart, orderedItems.byStart, visibleItems, visibleItemsLookup, function (item) {
34863 return item.data.start < lowerBound || item.data.start > upperBound;
34864 }); // if the window has changed programmatically without overlapping the old window, the ranged items with start < lowerBound and end > upperbound are not shown.
34865 // We therefore have to brute force check all items in the byEnd list
34866
34867
34868 if (this.checkRangedItems == true) {
34869 this.checkRangedItems = false;
34870
34871 for (var _i2 = 0; _i2 < orderedItems.byEnd.length; _i2++) {
34872 this._checkIfVisibleWithReference(orderedItems.byEnd[_i2], visibleItems, visibleItemsLookup, range);
34873 }
34874 } else {
34875 // we do a binary search for the items that have defined end times.
34876 var initialPosByEnd = util.binarySearchCustom(orderedItems.byEnd, endSearchFunction, 'data', 'end'); // trace the visible items from the inital start pos both ways until an invisible item is found, we only look at the end values.
34877
34878 this._traceVisible(initialPosByEnd, orderedItems.byEnd, visibleItems, visibleItemsLookup, function (item) {
34879 return item.data.end < lowerBound || item.data.start > upperBound;
34880 });
34881 }
34882
34883 var redrawQueue = {};
34884 var redrawQueueLength = 0;
34885
34886 for (var _i3 = 0; _i3 < visibleItems.length; _i3++) {
34887 var _item = visibleItems[_i3];
34888
34889 if (!_item.displayed) {
34890 var returnQueue = true;
34891 redrawQueue[_i3] = _item.redraw(returnQueue);
34892 redrawQueueLength = redrawQueue[_i3].length;
34893 }
34894 }
34895
34896 var needRedraw = redrawQueueLength > 0;
34897
34898 if (needRedraw) {
34899 var _loop3 = function _loop3(j) {
34900 util.forEach(redrawQueue, function (fns) {
34901 fns[j]();
34902 });
34903 };
34904
34905 // redraw all regular items
34906 for (var j = 0; j < redrawQueueLength; j++) {
34907 _loop3(j);
34908 }
34909 }
34910
34911 for (var _i4 = 0; _i4 < visibleItems.length; _i4++) {
34912 visibleItems[_i4].repositionX();
34913 }
34914
34915 return visibleItems;
34916 }
34917 /**
34918 * trace visible items in group
34919 * @param {number} initialPos
34920 * @param {array} items
34921 * @param {aray} visibleItems
34922 * @param {object} visibleItemsLookup
34923 * @param {function} breakCondition
34924 */
34925
34926 }, {
34927 key: "_traceVisible",
34928 value: function _traceVisible(initialPos, items, visibleItems, visibleItemsLookup, breakCondition) {
34929 if (initialPos != -1) {
34930 for (var i = initialPos; i >= 0; i--) {
34931 var item = items[i];
34932
34933 if (breakCondition(item)) {
34934 break;
34935 } else {
34936 if (!(item.isCluster && !item.hasItems()) && !item.cluster) {
34937 if (visibleItemsLookup[item.id] === undefined) {
34938 visibleItemsLookup[item.id] = true;
34939 visibleItems.push(item);
34940 }
34941 }
34942 }
34943 }
34944
34945 for (var _i5 = initialPos + 1; _i5 < items.length; _i5++) {
34946 var _item2 = items[_i5];
34947
34948 if (breakCondition(_item2)) {
34949 break;
34950 } else {
34951 if (!(_item2.isCluster && !_item2.hasItems()) && !_item2.cluster) {
34952 if (visibleItemsLookup[_item2.id] === undefined) {
34953 visibleItemsLookup[_item2.id] = true;
34954 visibleItems.push(_item2);
34955 }
34956 }
34957 }
34958 }
34959 }
34960 }
34961 /**
34962 * this function is very similar to the _checkIfInvisible() but it does not
34963 * return booleans, hides the item if it should not be seen and always adds to
34964 * the visibleItems.
34965 * this one is for brute forcing and hiding.
34966 *
34967 * @param {Item} item
34968 * @param {Array} visibleItems
34969 * @param {{start:number, end:number}} range
34970 * @private
34971 */
34972
34973 }, {
34974 key: "_checkIfVisible",
34975 value: function _checkIfVisible(item, visibleItems, range) {
34976 if (item.isVisible(range)) {
34977 if (!item.displayed) item.show(); // reposition item horizontally
34978
34979 item.repositionX();
34980 visibleItems.push(item);
34981 } else {
34982 if (item.displayed) item.hide();
34983 }
34984 }
34985 /**
34986 * this function is very similar to the _checkIfInvisible() but it does not
34987 * return booleans, hides the item if it should not be seen and always adds to
34988 * the visibleItems.
34989 * this one is for brute forcing and hiding.
34990 *
34991 * @param {Item} item
34992 * @param {Array.<timeline.Item>} visibleItems
34993 * @param {Object<number, boolean>} visibleItemsLookup
34994 * @param {{start:number, end:number}} range
34995 * @private
34996 */
34997
34998 }, {
34999 key: "_checkIfVisibleWithReference",
35000 value: function _checkIfVisibleWithReference(item, visibleItems, visibleItemsLookup, range) {
35001 if (item.isVisible(range)) {
35002 if (visibleItemsLookup[item.id] === undefined) {
35003 visibleItemsLookup[item.id] = true;
35004 visibleItems.push(item);
35005 }
35006 } else {
35007 if (item.displayed) item.hide();
35008 }
35009 }
35010 /**
35011 * Update the visible items
35012 * @param {array} orderedClusters
35013 * @param {array} oldVisibleClusters
35014 * @param {{start: number, end: number}} range
35015 * @return {Item[]} visibleItems
35016 * @private
35017 */
35018
35019 }, {
35020 key: "_updateClustersInRange",
35021 value: function _updateClustersInRange(orderedClusters, oldVisibleClusters, range) {
35022 // Clusters can overlap each other so we cannot use binary search here
35023 var visibleClusters = [];
35024 var visibleClustersLookup = {}; // we keep this to quickly look up if an item already exists in the list without using indexOf on visibleItems
35025
35026 if (oldVisibleClusters.length > 0) {
35027 for (var i = 0; i < oldVisibleClusters.length; i++) {
35028 this._checkIfVisibleWithReference(oldVisibleClusters[i], visibleClusters, visibleClustersLookup, range);
35029 }
35030 }
35031
35032 for (var _i6 = 0; _i6 < orderedClusters.byStart.length; _i6++) {
35033 this._checkIfVisibleWithReference(orderedClusters.byStart[_i6], visibleClusters, visibleClustersLookup, range);
35034 }
35035
35036 for (var _i7 = 0; _i7 < orderedClusters.byEnd.length; _i7++) {
35037 this._checkIfVisibleWithReference(orderedClusters.byEnd[_i7], visibleClusters, visibleClustersLookup, range);
35038 }
35039
35040 var redrawQueue = {};
35041 var redrawQueueLength = 0;
35042
35043 for (var _i8 = 0; _i8 < visibleClusters.length; _i8++) {
35044 var item = visibleClusters[_i8];
35045
35046 if (!item.displayed) {
35047 var returnQueue = true;
35048 redrawQueue[_i8] = item.redraw(returnQueue);
35049 redrawQueueLength = redrawQueue[_i8].length;
35050 }
35051 }
35052
35053 var needRedraw = redrawQueueLength > 0;
35054
35055 if (needRedraw) {
35056 // redraw all regular items
35057 for (var j = 0; j < redrawQueueLength; j++) {
35058 util.forEach(redrawQueue, function (fns) {
35059 fns[j]();
35060 });
35061 }
35062 }
35063
35064 for (var _i9 = 0; _i9 < visibleClusters.length; _i9++) {
35065 visibleClusters[_i9].repositionX();
35066 }
35067
35068 return visibleClusters;
35069 }
35070 /**
35071 * change item subgroup
35072 * @param {object} item
35073 * @param {string} oldSubgroup
35074 * @param {string} newSubgroup
35075 */
35076
35077 }, {
35078 key: "changeSubgroup",
35079 value: function changeSubgroup(item, oldSubgroup, newSubgroup) {
35080 this._removeFromSubgroup(item, oldSubgroup);
35081
35082 this._addToSubgroup(item, newSubgroup);
35083
35084 this.orderSubgroups();
35085 }
35086 }]);
35087
35088 return Group;
35089}();
35090
35091/**
35092 * @constructor BackgroundGroup
35093 * @extends Group
35094 */
35095
35096var BackgroundGroup =
35097/*#__PURE__*/
35098function (_Group) {
35099 _inherits(BackgroundGroup, _Group);
35100
35101 /**
35102 * @param {number | string} groupId
35103 * @param {Object} data
35104 * @param {ItemSet} itemSet
35105 */
35106 function BackgroundGroup(groupId, data, itemSet) {
35107 var _this;
35108
35109 _classCallCheck(this, BackgroundGroup);
35110
35111 _this = _possibleConstructorReturn(this, _getPrototypeOf(BackgroundGroup).call(this, groupId, data, itemSet)); // Group.call(this, groupId, data, itemSet);
35112
35113 _this.width = 0;
35114 _this.height = 0;
35115 _this.top = 0;
35116 _this.left = 0;
35117 return _this;
35118 }
35119 /**
35120 * Repaint this group
35121 * @param {{start: number, end: number}} range
35122 * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin
35123 * @param {boolean} [forceRestack=false] Force restacking of all items
35124 * @return {boolean} Returns true if the group is resized
35125 */
35126
35127
35128 _createClass(BackgroundGroup, [{
35129 key: "redraw",
35130 value: function redraw(range, margin, forceRestack) {
35131 // eslint-disable-line no-unused-vars
35132 var resized = false;
35133 this.visibleItems = this._updateItemsInRange(this.orderedItems, this.visibleItems, range); // calculate actual size
35134
35135 this.width = this.dom.background.offsetWidth; // apply new height (just always zero for BackgroundGroup
35136
35137 this.dom.background.style.height = '0'; // update vertical position of items after they are re-stacked and the height of the group is calculated
35138
35139 for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
35140 var item = this.visibleItems[i];
35141 item.repositionY(margin);
35142 }
35143
35144 return resized;
35145 }
35146 /**
35147 * Show this group: attach to the DOM
35148 */
35149
35150 }, {
35151 key: "show",
35152 value: function show() {
35153 if (!this.dom.background.parentNode) {
35154 this.itemSet.dom.background.appendChild(this.dom.background);
35155 }
35156 }
35157 }]);
35158
35159 return BackgroundGroup;
35160}(Group);
35161
35162/**
35163 * Item
35164 */
35165
35166var Item =
35167/*#__PURE__*/
35168function () {
35169 /**
35170 * @constructor Item
35171 * @param {Object} data Object containing (optional) parameters type,
35172 * start, end, content, group, className.
35173 * @param {{toScreen: function, toTime: function}} conversion
35174 * Conversion functions from time to screen and vice versa
35175 * @param {Object} options Configuration options
35176 * // TODO: describe available options
35177 */
35178 function Item(data, conversion, options) {
35179 var _this = this;
35180
35181 _classCallCheck(this, Item);
35182
35183 this.id = null;
35184 this.parent = null;
35185 this.data = data;
35186 this.dom = null;
35187 this.conversion = conversion || {};
35188 this.defaultOptions = {
35189 locales: locales,
35190 locale: 'en'
35191 };
35192 this.options = util.extend({}, this.defaultOptions, options);
35193 util.extend(this.options.locales, locales, this.options.locales);
35194 var defaultLocales = this.defaultOptions.locales[this.defaultOptions.locale];
35195 Object.keys(this.options.locales).forEach(function (locale) {
35196 _this.options.locales[locale] = util.extend({}, defaultLocales, _this.options.locales[locale]);
35197 });
35198 this.selected = false;
35199 this.displayed = false;
35200 this.groupShowing = true;
35201 this.selectable = options && options.selectable || false;
35202 this.dirty = true;
35203 this.top = null;
35204 this.right = null;
35205 this.left = null;
35206 this.width = null;
35207 this.height = null;
35208 this.setSelectability(data);
35209 this.editable = null;
35210
35211 this._updateEditStatus();
35212 }
35213 /**
35214 * Select current item
35215 */
35216
35217
35218 _createClass(Item, [{
35219 key: "select",
35220 value: function select() {
35221 if (this.selectable) {
35222 this.selected = true;
35223 this.dirty = true;
35224 if (this.displayed) this.redraw();
35225 }
35226 }
35227 /**
35228 * Unselect current item
35229 */
35230
35231 }, {
35232 key: "unselect",
35233 value: function unselect() {
35234 this.selected = false;
35235 this.dirty = true;
35236 if (this.displayed) this.redraw();
35237 }
35238 /**
35239 * Set data for the item. Existing data will be updated. The id should not
35240 * be changed. When the item is displayed, it will be redrawn immediately.
35241 * @param {Object} data
35242 */
35243
35244 }, {
35245 key: "setData",
35246 value: function setData(data) {
35247 var groupChanged = data.group != undefined && this.data.group != data.group;
35248
35249 if (groupChanged && this.parent != null) {
35250 this.parent.itemSet._moveToGroup(this, data.group);
35251 }
35252
35253 this.setSelectability(data);
35254
35255 if (this.parent) {
35256 this.parent.stackDirty = true;
35257 }
35258
35259 var subGroupChanged = data.subgroup != undefined && this.data.subgroup != data.subgroup;
35260
35261 if (subGroupChanged && this.parent != null) {
35262 this.parent.changeSubgroup(this, this.data.subgroup, data.subgroup);
35263 }
35264
35265 this.data = data;
35266
35267 this._updateEditStatus();
35268
35269 this.dirty = true;
35270 if (this.displayed) this.redraw();
35271 }
35272 /**
35273 * Set whether the item can be selected.
35274 * Can only be set/unset if the timeline's `selectable` configuration option is `true`.
35275 * @param {Object} data `data` from `constructor` and `setData`
35276 */
35277
35278 }, {
35279 key: "setSelectability",
35280 value: function setSelectability(data) {
35281 if (data) {
35282 this.selectable = typeof data.selectable === 'undefined' ? true : Boolean(data.selectable);
35283 }
35284 }
35285 /**
35286 * Set a parent for the item
35287 * @param {Group} parent
35288 */
35289
35290 }, {
35291 key: "setParent",
35292 value: function setParent(parent) {
35293 if (this.displayed) {
35294 this.hide();
35295 this.parent = parent;
35296
35297 if (this.parent) {
35298 this.show();
35299 }
35300 } else {
35301 this.parent = parent;
35302 }
35303 }
35304 /**
35305 * Check whether this item is visible inside given range
35306 * @param {timeline.Range} range with a timestamp for start and end
35307 * @returns {boolean} True if visible
35308 */
35309
35310 }, {
35311 key: "isVisible",
35312 value: function isVisible(range) {
35313 // eslint-disable-line no-unused-vars
35314 return false;
35315 }
35316 /**
35317 * Show the Item in the DOM (when not already visible)
35318 * @return {Boolean} changed
35319 */
35320
35321 }, {
35322 key: "show",
35323 value: function show() {
35324 return false;
35325 }
35326 /**
35327 * Hide the Item from the DOM (when visible)
35328 * @return {Boolean} changed
35329 */
35330
35331 }, {
35332 key: "hide",
35333 value: function hide() {
35334 return false;
35335 }
35336 /**
35337 * Repaint the item
35338 */
35339
35340 }, {
35341 key: "redraw",
35342 value: function redraw() {} // should be implemented by the item
35343
35344 /**
35345 * Reposition the Item horizontally
35346 */
35347
35348 }, {
35349 key: "repositionX",
35350 value: function repositionX() {} // should be implemented by the item
35351
35352 /**
35353 * Reposition the Item vertically
35354 */
35355
35356 }, {
35357 key: "repositionY",
35358 value: function repositionY() {} // should be implemented by the item
35359
35360 /**
35361 * Repaint a drag area on the center of the item when the item is selected
35362 * @protected
35363 */
35364
35365 }, {
35366 key: "_repaintDragCenter",
35367 value: function _repaintDragCenter() {
35368 if (this.selected && this.options.editable.updateTime && !this.dom.dragCenter) {
35369 var me = this; // create and show drag area
35370
35371 var dragCenter = document.createElement('div');
35372 dragCenter.className = 'vis-drag-center';
35373 dragCenter.dragCenterItem = this;
35374 this.hammerDragCenter = new Hammer$1(dragCenter);
35375 this.hammerDragCenter.on('tap', function (event) {
35376 me.parent.itemSet.body.emitter.emit('click', {
35377 event: event,
35378 item: me.id
35379 });
35380 });
35381 this.hammerDragCenter.on('doubletap', function (event) {
35382 event.stopPropagation();
35383
35384 me.parent.itemSet._onUpdateItem(me);
35385
35386 me.parent.itemSet.body.emitter.emit('doubleClick', {
35387 event: event,
35388 item: me.id
35389 });
35390 });
35391 this.hammerDragCenter.on('panstart', me.parent.itemSet._onDragStart.bind(me.parent.itemSet));
35392 this.hammerDragCenter.on('panmove', me.parent.itemSet._onDrag.bind(me.parent.itemSet));
35393 this.hammerDragCenter.on('panend', me.parent.itemSet._onDragEnd.bind(me.parent.itemSet));
35394
35395 if (this.dom.box) {
35396 if (this.dom.dragLeft) {
35397 this.dom.box.insertBefore(dragCenter, this.dom.dragLeft);
35398 } else {
35399 this.dom.box.appendChild(dragCenter);
35400 }
35401 } else if (this.dom.point) {
35402 this.dom.point.appendChild(dragCenter);
35403 }
35404
35405 this.dom.dragCenter = dragCenter;
35406 } else if (!this.selected && this.dom.dragCenter) {
35407 // delete drag area
35408 if (this.dom.dragCenter.parentNode) {
35409 this.dom.dragCenter.parentNode.removeChild(this.dom.dragCenter);
35410 }
35411
35412 this.dom.dragCenter = null;
35413
35414 if (this.hammerDragCenter) {
35415 this.hammerDragCenter.destroy();
35416 this.hammerDragCenter = null;
35417 }
35418 }
35419 }
35420 /**
35421 * Repaint a delete button on the top right of the item when the item is selected
35422 * @param {HTMLElement} anchor
35423 * @protected
35424 */
35425
35426 }, {
35427 key: "_repaintDeleteButton",
35428 value: function _repaintDeleteButton(anchor) {
35429 var editable = (this.options.editable.overrideItems || this.editable == null) && this.options.editable.remove || !this.options.editable.overrideItems && this.editable != null && this.editable.remove;
35430
35431 if (this.selected && editable && !this.dom.deleteButton) {
35432 // create and show button
35433 var me = this;
35434 var deleteButton = document.createElement('div');
35435
35436 if (this.options.rtl) {
35437 deleteButton.className = 'vis-delete-rtl';
35438 } else {
35439 deleteButton.className = 'vis-delete';
35440 }
35441
35442 var _locales = this.options.locales[this.options.locale];
35443
35444 if (!_locales) {
35445 if (!this.warned) {
35446 console.warn("WARNING: options.locales['".concat(this.options.locale, "'] not found. See https://visjs.github.io/vis-timeline/docs/timeline/#Localization"));
35447 this.warned = true;
35448 }
35449
35450 _locales = this.options.locales['en']; // fall back on english when not available
35451 }
35452
35453 deleteButton.title = _locales.deleteSelected; // TODO: be able to destroy the delete button
35454
35455 this.hammerDeleteButton = new Hammer$1(deleteButton).on('tap', function (event) {
35456 event.stopPropagation();
35457 me.parent.removeFromDataSet(me);
35458 });
35459 anchor.appendChild(deleteButton);
35460 this.dom.deleteButton = deleteButton;
35461 } else if (!this.selected && this.dom.deleteButton) {
35462 // remove button
35463 if (this.dom.deleteButton.parentNode) {
35464 this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton);
35465 }
35466
35467 this.dom.deleteButton = null;
35468
35469 if (this.hammerDeleteButton) {
35470 this.hammerDeleteButton.destroy();
35471 this.hammerDeleteButton = null;
35472 }
35473 }
35474 }
35475 /**
35476 * Repaint a onChange tooltip on the top right of the item when the item is selected
35477 * @param {HTMLElement} anchor
35478 * @protected
35479 */
35480
35481 }, {
35482 key: "_repaintOnItemUpdateTimeTooltip",
35483 value: function _repaintOnItemUpdateTimeTooltip(anchor) {
35484 if (!this.options.tooltipOnItemUpdateTime) return;
35485 var editable = (this.options.editable.updateTime || this.data.editable === true) && this.data.editable !== false;
35486
35487 if (this.selected && editable && !this.dom.onItemUpdateTimeTooltip) {
35488 var onItemUpdateTimeTooltip = document.createElement('div');
35489 onItemUpdateTimeTooltip.className = 'vis-onUpdateTime-tooltip';
35490 anchor.appendChild(onItemUpdateTimeTooltip);
35491 this.dom.onItemUpdateTimeTooltip = onItemUpdateTimeTooltip;
35492 } else if (!this.selected && this.dom.onItemUpdateTimeTooltip) {
35493 // remove button
35494 if (this.dom.onItemUpdateTimeTooltip.parentNode) {
35495 this.dom.onItemUpdateTimeTooltip.parentNode.removeChild(this.dom.onItemUpdateTimeTooltip);
35496 }
35497
35498 this.dom.onItemUpdateTimeTooltip = null;
35499 } // position onChange tooltip
35500
35501
35502 if (this.dom.onItemUpdateTimeTooltip) {
35503 // only show when editing
35504 this.dom.onItemUpdateTimeTooltip.style.visibility = this.parent.itemSet.touchParams.itemIsDragging ? 'visible' : 'hidden'; // position relative to item's content
35505
35506 this.dom.onItemUpdateTimeTooltip.style.transform = 'translateX(-50%)';
35507 this.dom.onItemUpdateTimeTooltip.style.left = '50%'; // position above or below the item depending on the item's position in the window
35508
35509 var tooltipOffset = 50; // TODO: should be tooltip height (depends on template)
35510
35511 var scrollTop = this.parent.itemSet.body.domProps.scrollTop; // TODO: this.top for orientation:true is actually the items distance from the bottom...
35512 // (should be this.bottom)
35513
35514 var itemDistanceFromTop;
35515
35516 if (this.options.orientation.item == 'top') {
35517 itemDistanceFromTop = this.top;
35518 } else {
35519 itemDistanceFromTop = this.parent.height - this.top - this.height;
35520 }
35521
35522 var isCloseToTop = itemDistanceFromTop + this.parent.top - tooltipOffset < -scrollTop;
35523
35524 if (isCloseToTop) {
35525 this.dom.onItemUpdateTimeTooltip.style.bottom = "";
35526 this.dom.onItemUpdateTimeTooltip.style.top = "".concat(this.height + 2, "px");
35527 } else {
35528 this.dom.onItemUpdateTimeTooltip.style.top = "";
35529 this.dom.onItemUpdateTimeTooltip.style.bottom = "".concat(this.height + 2, "px");
35530 } // handle tooltip content
35531
35532
35533 var content;
35534 var templateFunction;
35535
35536 if (this.options.tooltipOnItemUpdateTime && this.options.tooltipOnItemUpdateTime.template) {
35537 templateFunction = this.options.tooltipOnItemUpdateTime.template.bind(this);
35538 content = templateFunction(this.data);
35539 } else {
35540 content = "start: ".concat(moment$3(this.data.start).format('MM/DD/YYYY hh:mm'));
35541
35542 if (this.data.end) {
35543 content += "<br> end: ".concat(moment$3(this.data.end).format('MM/DD/YYYY hh:mm'));
35544 }
35545 }
35546
35547 this.dom.onItemUpdateTimeTooltip.innerHTML = content;
35548 }
35549 }
35550 /**
35551 * get item data
35552 * @return {object}
35553 * @private
35554 */
35555
35556 }, {
35557 key: "_getItemData",
35558 value: function _getItemData() {
35559 return this.parent.itemSet.itemsData.get(this.id);
35560 }
35561 /**
35562 * Set HTML contents for the item
35563 * @param {Element} element HTML element to fill with the contents
35564 * @private
35565 */
35566
35567 }, {
35568 key: "_updateContents",
35569 value: function _updateContents(element) {
35570 var content;
35571 var changed;
35572 var templateFunction;
35573 var itemVisibleFrameContent;
35574 var visibleFrameTemplateFunction;
35575
35576 var itemData = this._getItemData(); // get a clone of the data from the dataset
35577
35578
35579 var frameElement = this.dom.box || this.dom.point;
35580 var itemVisibleFrameContentElement = frameElement.getElementsByClassName('vis-item-visible-frame')[0];
35581
35582 if (this.options.visibleFrameTemplate) {
35583 visibleFrameTemplateFunction = this.options.visibleFrameTemplate.bind(this);
35584 itemVisibleFrameContent = visibleFrameTemplateFunction(itemData, itemVisibleFrameContentElement);
35585 } else {
35586 itemVisibleFrameContent = '';
35587 }
35588
35589 if (itemVisibleFrameContentElement) {
35590 if (itemVisibleFrameContent instanceof Object && !(itemVisibleFrameContent instanceof Element)) {
35591 visibleFrameTemplateFunction(itemData, itemVisibleFrameContentElement);
35592 } else {
35593 changed = this._contentToString(this.itemVisibleFrameContent) !== this._contentToString(itemVisibleFrameContent);
35594
35595 if (changed) {
35596 // only replace the content when changed
35597 if (itemVisibleFrameContent instanceof Element) {
35598 itemVisibleFrameContentElement.innerHTML = '';
35599 itemVisibleFrameContentElement.appendChild(itemVisibleFrameContent);
35600 } else if (itemVisibleFrameContent != undefined) {
35601 itemVisibleFrameContentElement.innerHTML = itemVisibleFrameContent;
35602 } else {
35603 if (!(this.data.type == 'background' && this.data.content === undefined)) {
35604 throw new Error("Property \"content\" missing in item ".concat(this.id));
35605 }
35606 }
35607
35608 this.itemVisibleFrameContent = itemVisibleFrameContent;
35609 }
35610 }
35611 }
35612
35613 if (this.options.template) {
35614 templateFunction = this.options.template.bind(this);
35615 content = templateFunction(itemData, element, this.data);
35616 } else {
35617 content = this.data.content;
35618 }
35619
35620 if (content instanceof Object && !(content instanceof Element)) {
35621 templateFunction(itemData, element);
35622 } else {
35623 changed = this._contentToString(this.content) !== this._contentToString(content);
35624
35625 if (changed) {
35626 // only replace the content when changed
35627 if (content instanceof Element) {
35628 element.innerHTML = '';
35629 element.appendChild(content);
35630 } else if (content != undefined) {
35631 element.innerHTML = content;
35632 } else {
35633 if (!(this.data.type == 'background' && this.data.content === undefined)) {
35634 throw new Error("Property \"content\" missing in item ".concat(this.id));
35635 }
35636 }
35637
35638 this.content = content;
35639 }
35640 }
35641 }
35642 /**
35643 * Process dataAttributes timeline option and set as data- attributes on dom.content
35644 * @param {Element} element HTML element to which the attributes will be attached
35645 * @private
35646 */
35647
35648 }, {
35649 key: "_updateDataAttributes",
35650 value: function _updateDataAttributes(element) {
35651 if (this.options.dataAttributes && this.options.dataAttributes.length > 0) {
35652 var attributes = [];
35653
35654 if (Array.isArray(this.options.dataAttributes)) {
35655 attributes = this.options.dataAttributes;
35656 } else if (this.options.dataAttributes == 'all') {
35657 attributes = Object.keys(this.data);
35658 } else {
35659 return;
35660 }
35661
35662 var _iteratorNormalCompletion = true;
35663 var _didIteratorError = false;
35664 var _iteratorError = undefined;
35665
35666 try {
35667 for (var _iterator = attributes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
35668 var name = _step.value;
35669 var value = this.data[name];
35670
35671 if (value != null) {
35672 element.setAttribute("data-".concat(name), value);
35673 } else {
35674 element.removeAttribute("data-".concat(name));
35675 }
35676 }
35677 } catch (err) {
35678 _didIteratorError = true;
35679 _iteratorError = err;
35680 } finally {
35681 try {
35682 if (!_iteratorNormalCompletion && _iterator.return != null) {
35683 _iterator.return();
35684 }
35685 } finally {
35686 if (_didIteratorError) {
35687 throw _iteratorError;
35688 }
35689 }
35690 }
35691 }
35692 }
35693 /**
35694 * Update custom styles of the element
35695 * @param {Element} element
35696 * @private
35697 */
35698
35699 }, {
35700 key: "_updateStyle",
35701 value: function _updateStyle(element) {
35702 // remove old styles
35703 if (this.style) {
35704 util.removeCssText(element, this.style);
35705 this.style = null;
35706 } // append new styles
35707
35708
35709 if (this.data.style) {
35710 util.addCssText(element, this.data.style);
35711 this.style = this.data.style;
35712 }
35713 }
35714 /**
35715 * Stringify the items contents
35716 * @param {string | Element | undefined} content
35717 * @returns {string | undefined}
35718 * @private
35719 */
35720
35721 }, {
35722 key: "_contentToString",
35723 value: function _contentToString(content) {
35724 if (typeof content === 'string') return content;
35725 if (content && 'outerHTML' in content) return content.outerHTML;
35726 return content;
35727 }
35728 /**
35729 * Update the editability of this item.
35730 */
35731
35732 }, {
35733 key: "_updateEditStatus",
35734 value: function _updateEditStatus() {
35735 if (this.options) {
35736 if (typeof this.options.editable === 'boolean') {
35737 this.editable = {
35738 updateTime: this.options.editable,
35739 updateGroup: this.options.editable,
35740 remove: this.options.editable
35741 };
35742 } else if (_typeof(this.options.editable) === 'object') {
35743 this.editable = {};
35744 util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, this.options.editable);
35745 }
35746 } // Item data overrides, except if options.editable.overrideItems is set.
35747
35748
35749 if (!this.options || !this.options.editable || this.options.editable.overrideItems !== true) {
35750 if (this.data) {
35751 if (typeof this.data.editable === 'boolean') {
35752 this.editable = {
35753 updateTime: this.data.editable,
35754 updateGroup: this.data.editable,
35755 remove: this.data.editable
35756 };
35757 } else if (_typeof(this.data.editable) === 'object') {
35758 // TODO: in timeline.js 5.0, we should change this to not reset options from the timeline configuration.
35759 // Basically just remove the next line...
35760 this.editable = {};
35761 util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, this.data.editable);
35762 }
35763 }
35764 }
35765 }
35766 /**
35767 * Return the width of the item left from its start date
35768 * @return {number}
35769 */
35770
35771 }, {
35772 key: "getWidthLeft",
35773 value: function getWidthLeft() {
35774 return 0;
35775 }
35776 /**
35777 * Return the width of the item right from the max of its start and end date
35778 * @return {number}
35779 */
35780
35781 }, {
35782 key: "getWidthRight",
35783 value: function getWidthRight() {
35784 return 0;
35785 }
35786 /**
35787 * Return the title of the item
35788 * @return {string | undefined}
35789 */
35790
35791 }, {
35792 key: "getTitle",
35793 value: function getTitle() {
35794 if (this.options.tooltip && this.options.tooltip.template) {
35795 var templateFunction = this.options.tooltip.template.bind(this);
35796 return templateFunction(this._getItemData(), this.data);
35797 }
35798
35799 return this.data.title;
35800 }
35801 }]);
35802
35803 return Item;
35804}();
35805
35806Item.prototype.stack = true;
35807
35808/**
35809 * @constructor BoxItem
35810 * @extends Item
35811 */
35812
35813var BoxItem =
35814/*#__PURE__*/
35815function (_Item) {
35816 _inherits(BoxItem, _Item);
35817
35818 /**
35819 * @param {Object} data Object containing parameters start
35820 * content, className.
35821 * @param {{toScreen: function, toTime: function}} conversion
35822 * Conversion functions from time to screen and vice versa
35823 * @param {Object} [options] Configuration options
35824 * // TODO: describe available options
35825 */
35826 function BoxItem(data, conversion, options) {
35827 var _this;
35828
35829 _classCallCheck(this, BoxItem);
35830
35831 _this = _possibleConstructorReturn(this, _getPrototypeOf(BoxItem).call(this));
35832 _this.props = {
35833 dot: {
35834 width: 0,
35835 height: 0
35836 },
35837 line: {
35838 width: 0,
35839 height: 0
35840 }
35841 };
35842 _this.options = options; // validate data
35843
35844 if (data) {
35845 if (data.start == undefined) {
35846 throw new Error("Property \"start\" missing in item ".concat(data));
35847 }
35848 }
35849
35850 Item.call(_assertThisInitialized(_this), data, conversion, options);
35851 return _this;
35852 }
35853 /**
35854 * Check whether this item is visible inside given range
35855 * @param {{start: number, end: number}} range with a timestamp for start and end
35856 * @returns {boolean} True if visible
35857 */
35858
35859
35860 _createClass(BoxItem, [{
35861 key: "isVisible",
35862 value: function isVisible(range) {
35863 if (this.cluster) {
35864 return false;
35865 } // determine visibility
35866
35867
35868 var isVisible;
35869 var align = this.data.align || this.options.align;
35870 var widthInMs = this.width * range.getMillisecondsPerPixel();
35871
35872 if (align == 'right') {
35873 isVisible = this.data.start.getTime() > range.start && this.data.start.getTime() - widthInMs < range.end;
35874 } else if (align == 'left') {
35875 isVisible = this.data.start.getTime() + widthInMs > range.start && this.data.start.getTime() < range.end;
35876 } else {
35877 // default or 'center'
35878 isVisible = this.data.start.getTime() + widthInMs / 2 > range.start && this.data.start.getTime() - widthInMs / 2 < range.end;
35879 }
35880
35881 return isVisible;
35882 }
35883 /**
35884 * create DOM element
35885 * @private
35886 */
35887
35888 }, {
35889 key: "_createDomElement",
35890 value: function _createDomElement() {
35891 if (!this.dom) {
35892 // create DOM
35893 this.dom = {}; // create main box
35894
35895 this.dom.box = document.createElement('DIV'); // contents box (inside the background box). used for making margins
35896
35897 this.dom.content = document.createElement('DIV');
35898 this.dom.content.className = 'vis-item-content';
35899 this.dom.box.appendChild(this.dom.content); // line to axis
35900
35901 this.dom.line = document.createElement('DIV');
35902 this.dom.line.className = 'vis-line'; // dot on axis
35903
35904 this.dom.dot = document.createElement('DIV');
35905 this.dom.dot.className = 'vis-dot'; // attach this item as attribute
35906
35907 this.dom.box['vis-item'] = this;
35908 this.dirty = true;
35909 }
35910 }
35911 /**
35912 * append DOM element
35913 * @private
35914 */
35915
35916 }, {
35917 key: "_appendDomElement",
35918 value: function _appendDomElement() {
35919 if (!this.parent) {
35920 throw new Error('Cannot redraw item: no parent attached');
35921 }
35922
35923 if (!this.dom.box.parentNode) {
35924 var foreground = this.parent.dom.foreground;
35925 if (!foreground) throw new Error('Cannot redraw item: parent has no foreground container element');
35926 foreground.appendChild(this.dom.box);
35927 }
35928
35929 if (!this.dom.line.parentNode) {
35930 var background = this.parent.dom.background;
35931 if (!background) throw new Error('Cannot redraw item: parent has no background container element');
35932 background.appendChild(this.dom.line);
35933 }
35934
35935 if (!this.dom.dot.parentNode) {
35936 var axis = this.parent.dom.axis;
35937 if (!background) throw new Error('Cannot redraw item: parent has no axis container element');
35938 axis.appendChild(this.dom.dot);
35939 }
35940
35941 this.displayed = true;
35942 }
35943 /**
35944 * update dirty DOM element
35945 * @private
35946 */
35947
35948 }, {
35949 key: "_updateDirtyDomComponents",
35950 value: function _updateDirtyDomComponents() {
35951 // An item is marked dirty when:
35952 // - the item is not yet rendered
35953 // - the item's data is changed
35954 // - the item is selected/deselected
35955 if (this.dirty) {
35956 this._updateContents(this.dom.content);
35957
35958 this._updateDataAttributes(this.dom.box);
35959
35960 this._updateStyle(this.dom.box);
35961
35962 var editable = this.editable.updateTime || this.editable.updateGroup; // update class
35963
35964 var className = (this.data.className ? ' ' + this.data.className : '') + (this.selected ? ' vis-selected' : '') + (editable ? ' vis-editable' : ' vis-readonly');
35965 this.dom.box.className = "vis-item vis-box".concat(className);
35966 this.dom.line.className = "vis-item vis-line".concat(className);
35967 this.dom.dot.className = "vis-item vis-dot".concat(className);
35968 }
35969 }
35970 /**
35971 * get DOM components sizes
35972 * @return {object}
35973 * @private
35974 */
35975
35976 }, {
35977 key: "_getDomComponentsSizes",
35978 value: function _getDomComponentsSizes() {
35979 return {
35980 previous: {
35981 right: this.dom.box.style.right,
35982 left: this.dom.box.style.left
35983 },
35984 dot: {
35985 height: this.dom.dot.offsetHeight,
35986 width: this.dom.dot.offsetWidth
35987 },
35988 line: {
35989 width: this.dom.line.offsetWidth
35990 },
35991 box: {
35992 width: this.dom.box.offsetWidth,
35993 height: this.dom.box.offsetHeight
35994 }
35995 };
35996 }
35997 /**
35998 * update DOM components sizes
35999 * @param {object} sizes
36000 * @private
36001 */
36002
36003 }, {
36004 key: "_updateDomComponentsSizes",
36005 value: function _updateDomComponentsSizes(sizes) {
36006 if (this.options.rtl) {
36007 this.dom.box.style.right = "0px";
36008 } else {
36009 this.dom.box.style.left = "0px";
36010 } // recalculate size
36011
36012
36013 this.props.dot.height = sizes.dot.height;
36014 this.props.dot.width = sizes.dot.width;
36015 this.props.line.width = sizes.line.width;
36016 this.width = sizes.box.width;
36017 this.height = sizes.box.height; // restore previous position
36018
36019 if (this.options.rtl) {
36020 this.dom.box.style.right = sizes.previous.right;
36021 } else {
36022 this.dom.box.style.left = sizes.previous.left;
36023 }
36024
36025 this.dirty = false;
36026 }
36027 /**
36028 * repaint DOM additionals
36029 * @private
36030 */
36031
36032 }, {
36033 key: "_repaintDomAdditionals",
36034 value: function _repaintDomAdditionals() {
36035 this._repaintOnItemUpdateTimeTooltip(this.dom.box);
36036
36037 this._repaintDragCenter();
36038
36039 this._repaintDeleteButton(this.dom.box);
36040 }
36041 /**
36042 * Repaint the item
36043 * @param {boolean} [returnQueue=false] return the queue
36044 * @return {boolean} the redraw queue if returnQueue=true
36045 */
36046
36047 }, {
36048 key: "redraw",
36049 value: function redraw(returnQueue) {
36050 var _this2 = this;
36051
36052 var sizes;
36053 var queue = [// create item DOM
36054 this._createDomElement.bind(this), // append DOM to parent DOM
36055 this._appendDomElement.bind(this), // update dirty DOM
36056 this._updateDirtyDomComponents.bind(this), function () {
36057 if (_this2.dirty) {
36058 sizes = _this2._getDomComponentsSizes();
36059 }
36060 }, function () {
36061 if (_this2.dirty) {
36062 _this2._updateDomComponentsSizes.bind(_this2)(sizes);
36063 }
36064 }, // repaint DOM additionals
36065 this._repaintDomAdditionals.bind(this)];
36066
36067 if (returnQueue) {
36068 return queue;
36069 } else {
36070 var result;
36071 queue.forEach(function (fn) {
36072 result = fn();
36073 });
36074 return result;
36075 }
36076 }
36077 /**
36078 * Show the item in the DOM (when not already visible). The items DOM will
36079 * be created when needed.
36080 * @param {boolean} [returnQueue=false] whether to return a queue of functions to execute instead of just executing them
36081 * @return {boolean} the redraw queue if returnQueue=true
36082 */
36083
36084 }, {
36085 key: "show",
36086 value: function show(returnQueue) {
36087 if (!this.displayed) {
36088 return this.redraw(returnQueue);
36089 }
36090 }
36091 /**
36092 * Hide the item from the DOM (when visible)
36093 */
36094
36095 }, {
36096 key: "hide",
36097 value: function hide() {
36098 if (this.displayed) {
36099 var dom = this.dom;
36100 if (dom.box.parentNode) dom.box.remove();
36101 if (dom.line.parentNode) dom.line.remove();
36102 if (dom.dot.parentNode) dom.dot.remove();
36103 this.displayed = false;
36104 }
36105 }
36106 /**
36107 * Reposition the item XY
36108 */
36109
36110 }, {
36111 key: "repositionXY",
36112 value: function repositionXY() {
36113 var rtl = this.options.rtl;
36114
36115 var repositionXY = function repositionXY(element, x, y) {
36116 var rtl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
36117 if (x === undefined && y === undefined) return; // If rtl invert the number.
36118
36119 var directionX = rtl ? x * -1 : x; //no y. translate x
36120
36121 if (y === undefined) {
36122 element.style.transform = "translateX(".concat(directionX, "px)");
36123 return;
36124 } //no x. translate y
36125
36126
36127 if (x === undefined) {
36128 element.style.transform = "translateY(".concat(y, "px)");
36129 return;
36130 }
36131
36132 element.style.transform = "translate(".concat(directionX, "px, ").concat(y, "px)");
36133 };
36134
36135 repositionXY(this.dom.box, this.boxX, this.boxY, rtl);
36136 repositionXY(this.dom.dot, this.dotX, this.dotY, rtl);
36137 repositionXY(this.dom.line, this.lineX, this.lineY, rtl);
36138 }
36139 /**
36140 * Reposition the item horizontally
36141 * @Override
36142 */
36143
36144 }, {
36145 key: "repositionX",
36146 value: function repositionX() {
36147 var start = this.conversion.toScreen(this.data.start);
36148 var align = this.options.align;
36149 var lineWidth = this.props.line.width;
36150 var dotWidth = this.props.dot.width;
36151
36152 if (align == 'right') {
36153 // calculate right position of the box
36154 this.boxX = start - this.width;
36155 this.lineX = start - lineWidth;
36156 this.dotX = start - lineWidth / 2 - dotWidth / 2;
36157 } else if (align == 'left') {
36158 // calculate left position of the box
36159 this.boxX = start;
36160 this.lineX = start;
36161 this.dotX = start + lineWidth / 2 - dotWidth / 2;
36162 } else {
36163 // default or 'center'
36164 this.boxX = start - this.width / 2;
36165 this.lineX = this.options.rtl ? start - lineWidth : start - lineWidth / 2;
36166 this.dotX = start - dotWidth / 2;
36167 }
36168
36169 if (this.options.rtl) this.right = this.boxX;else this.left = this.boxX;
36170 this.repositionXY();
36171 }
36172 /**
36173 * Reposition the item vertically
36174 * @Override
36175 */
36176
36177 }, {
36178 key: "repositionY",
36179 value: function repositionY() {
36180 var orientation = this.options.orientation.item;
36181 var lineStyle = this.dom.line.style;
36182
36183 if (orientation == 'top') {
36184 var lineHeight = this.parent.top + this.top + 1;
36185 this.boxY = this.top || 0;
36186 lineStyle.height = "".concat(lineHeight, "px");
36187 lineStyle.bottom = '';
36188 lineStyle.top = '0';
36189 } else {
36190 // orientation 'bottom'
36191 var itemSetHeight = this.parent.itemSet.props.height; // TODO: this is nasty
36192
36193 var _lineHeight = itemSetHeight - this.parent.top - this.parent.height + this.top;
36194
36195 this.boxY = this.parent.height - this.top - (this.height || 0);
36196 lineStyle.height = "".concat(_lineHeight, "px");
36197 lineStyle.top = '';
36198 lineStyle.bottom = '0';
36199 }
36200
36201 this.dotY = -this.props.dot.height / 2;
36202 this.repositionXY();
36203 }
36204 /**
36205 * Return the width of the item left from its start date
36206 * @return {number}
36207 */
36208
36209 }, {
36210 key: "getWidthLeft",
36211 value: function getWidthLeft() {
36212 return this.width / 2;
36213 }
36214 /**
36215 * Return the width of the item right from its start date
36216 * @return {number}
36217 */
36218
36219 }, {
36220 key: "getWidthRight",
36221 value: function getWidthRight() {
36222 return this.width / 2;
36223 }
36224 }]);
36225
36226 return BoxItem;
36227}(Item);
36228
36229/**
36230 * @constructor PointItem
36231 * @extends Item
36232 */
36233
36234var PointItem =
36235/*#__PURE__*/
36236function (_Item) {
36237 _inherits(PointItem, _Item);
36238
36239 /**
36240 * @param {Object} data Object containing parameters start
36241 * content, className.
36242 * @param {{toScreen: function, toTime: function}} conversion
36243 * Conversion functions from time to screen and vice versa
36244 * @param {Object} [options] Configuration options
36245 * // TODO: describe available options
36246 */
36247 function PointItem(data, conversion, options) {
36248 var _this;
36249
36250 _classCallCheck(this, PointItem);
36251
36252 _this = _possibleConstructorReturn(this, _getPrototypeOf(PointItem).call(this));
36253 _this.props = {
36254 dot: {
36255 top: 0,
36256 width: 0,
36257 height: 0
36258 },
36259 content: {
36260 height: 0,
36261 marginLeft: 0,
36262 marginRight: 0
36263 }
36264 };
36265 _this.options = options; // validate data
36266
36267 if (data) {
36268 if (data.start == undefined) {
36269 throw new Error("Property \"start\" missing in item ".concat(data));
36270 }
36271 }
36272
36273 Item.call(_assertThisInitialized(_this), data, conversion, options);
36274 return _this;
36275 }
36276 /**
36277 * Check whether this item is visible inside given range
36278 * @param {{start: number, end: number}} range with a timestamp for start and end
36279 * @returns {boolean} True if visible
36280 */
36281
36282
36283 _createClass(PointItem, [{
36284 key: "isVisible",
36285 value: function isVisible(range) {
36286 if (this.cluster) {
36287 return false;
36288 } // determine visibility
36289
36290
36291 var widthInMs = this.width * range.getMillisecondsPerPixel();
36292 return this.data.start.getTime() + widthInMs > range.start && this.data.start < range.end;
36293 }
36294 /**
36295 * create DOM element
36296 * @private
36297 */
36298
36299 }, {
36300 key: "_createDomElement",
36301 value: function _createDomElement() {
36302 if (!this.dom) {
36303 // create DOM
36304 this.dom = {}; // background box
36305
36306 this.dom.point = document.createElement('div'); // className is updated in redraw()
36307 // contents box, right from the dot
36308
36309 this.dom.content = document.createElement('div');
36310 this.dom.content.className = 'vis-item-content';
36311 this.dom.point.appendChild(this.dom.content); // dot at start
36312
36313 this.dom.dot = document.createElement('div');
36314 this.dom.point.appendChild(this.dom.dot); // attach this item as attribute
36315
36316 this.dom.point['vis-item'] = this;
36317 this.dirty = true;
36318 }
36319 }
36320 /**
36321 * append DOM element
36322 * @private
36323 */
36324
36325 }, {
36326 key: "_appendDomElement",
36327 value: function _appendDomElement() {
36328 if (!this.parent) {
36329 throw new Error('Cannot redraw item: no parent attached');
36330 }
36331
36332 if (!this.dom.point.parentNode) {
36333 var foreground = this.parent.dom.foreground;
36334
36335 if (!foreground) {
36336 throw new Error('Cannot redraw item: parent has no foreground container element');
36337 }
36338
36339 foreground.appendChild(this.dom.point);
36340 }
36341
36342 this.displayed = true;
36343 }
36344 /**
36345 * update dirty DOM components
36346 * @private
36347 */
36348
36349 }, {
36350 key: "_updateDirtyDomComponents",
36351 value: function _updateDirtyDomComponents() {
36352 // An item is marked dirty when:
36353 // - the item is not yet rendered
36354 // - the item's data is changed
36355 // - the item is selected/deselected
36356 if (this.dirty) {
36357 this._updateContents(this.dom.content);
36358
36359 this._updateDataAttributes(this.dom.point);
36360
36361 this._updateStyle(this.dom.point);
36362
36363 var editable = this.editable.updateTime || this.editable.updateGroup; // update class
36364
36365 var className = (this.data.className ? ' ' + this.data.className : '') + (this.selected ? ' vis-selected' : '') + (editable ? ' vis-editable' : ' vis-readonly');
36366 this.dom.point.className = "vis-item vis-point".concat(className);
36367 this.dom.dot.className = "vis-item vis-dot".concat(className);
36368 }
36369 }
36370 /**
36371 * get DOM component sizes
36372 * @return {object}
36373 * @private
36374 */
36375
36376 }, {
36377 key: "_getDomComponentsSizes",
36378 value: function _getDomComponentsSizes() {
36379 return {
36380 dot: {
36381 width: this.dom.dot.offsetWidth,
36382 height: this.dom.dot.offsetHeight
36383 },
36384 content: {
36385 width: this.dom.content.offsetWidth,
36386 height: this.dom.content.offsetHeight
36387 },
36388 point: {
36389 width: this.dom.point.offsetWidth,
36390 height: this.dom.point.offsetHeight
36391 }
36392 };
36393 }
36394 /**
36395 * update DOM components sizes
36396 * @param {array} sizes
36397 * @private
36398 */
36399
36400 }, {
36401 key: "_updateDomComponentsSizes",
36402 value: function _updateDomComponentsSizes(sizes) {
36403 // recalculate size of dot and contents
36404 this.props.dot.width = sizes.dot.width;
36405 this.props.dot.height = sizes.dot.height;
36406 this.props.content.height = sizes.content.height; // resize contents
36407
36408 if (this.options.rtl) {
36409 this.dom.content.style.marginRight = "".concat(2 * this.props.dot.width, "px");
36410 } else {
36411 this.dom.content.style.marginLeft = "".concat(2 * this.props.dot.width, "px");
36412 } //this.dom.content.style.marginRight = ... + 'px'; // TODO: margin right
36413 // recalculate size
36414
36415
36416 this.width = sizes.point.width;
36417 this.height = sizes.point.height; // reposition the dot
36418
36419 this.dom.dot.style.top = "".concat((this.height - this.props.dot.height) / 2, "px");
36420 var dotWidth = this.props.dot.width;
36421 var translateX = this.options.rtl ? dotWidth / 2 * -1 : dotWidth / 2;
36422 this.dom.dot.style.transform = "translateX(".concat(translateX, "px");
36423 this.dirty = false;
36424 }
36425 /**
36426 * Repain DOM additionals
36427 * @private
36428 */
36429
36430 }, {
36431 key: "_repaintDomAdditionals",
36432 value: function _repaintDomAdditionals() {
36433 this._repaintOnItemUpdateTimeTooltip(this.dom.point);
36434
36435 this._repaintDragCenter();
36436
36437 this._repaintDeleteButton(this.dom.point);
36438 }
36439 /**
36440 * Repaint the item
36441 * @param {boolean} [returnQueue=false] return the queue
36442 * @return {boolean} the redraw queue if returnQueue=true
36443 */
36444
36445 }, {
36446 key: "redraw",
36447 value: function redraw(returnQueue) {
36448 var _this2 = this;
36449
36450 var sizes;
36451 var queue = [// create item DOM
36452 this._createDomElement.bind(this), // append DOM to parent DOM
36453 this._appendDomElement.bind(this), // update dirty DOM
36454 this._updateDirtyDomComponents.bind(this), function () {
36455 if (_this2.dirty) {
36456 sizes = _this2._getDomComponentsSizes();
36457 }
36458 }, function () {
36459 if (_this2.dirty) {
36460 _this2._updateDomComponentsSizes.bind(_this2)(sizes);
36461 }
36462 }, // repaint DOM additionals
36463 this._repaintDomAdditionals.bind(this)];
36464
36465 if (returnQueue) {
36466 return queue;
36467 } else {
36468 var result;
36469 queue.forEach(function (fn) {
36470 result = fn();
36471 });
36472 return result;
36473 }
36474 }
36475 /**
36476 * Reposition XY
36477 */
36478
36479 }, {
36480 key: "repositionXY",
36481 value: function repositionXY() {
36482 var rtl = this.options.rtl;
36483
36484 var repositionXY = function repositionXY(element, x, y) {
36485 var rtl = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
36486 if (x === undefined && y === undefined) return; // If rtl invert the number.
36487
36488 var directionX = rtl ? x * -1 : x; //no y. translate x
36489
36490 if (y === undefined) {
36491 element.style.transform = "translateX(".concat(directionX, "px)");
36492 return;
36493 } //no x. translate y
36494
36495
36496 if (x === undefined) {
36497 element.style.transform = "translateY(".concat(y, "px)");
36498 return;
36499 }
36500
36501 element.style.transform = "translate(".concat(directionX, "px, ").concat(y, "px)");
36502 };
36503
36504 repositionXY(this.dom.point, this.pointX, this.pointY, rtl);
36505 }
36506 /**
36507 * Show the item in the DOM (when not already visible). The items DOM will
36508 * be created when needed.
36509 * @param {boolean} [returnQueue=false] whether to return a queue of functions to execute instead of just executing them
36510 * @return {boolean} the redraw queue if returnQueue=true
36511 */
36512
36513 }, {
36514 key: "show",
36515 value: function show(returnQueue) {
36516 if (!this.displayed) {
36517 return this.redraw(returnQueue);
36518 }
36519 }
36520 /**
36521 * Hide the item from the DOM (when visible)
36522 */
36523
36524 }, {
36525 key: "hide",
36526 value: function hide() {
36527 if (this.displayed) {
36528 if (this.dom.point.parentNode) {
36529 this.dom.point.parentNode.removeChild(this.dom.point);
36530 }
36531
36532 this.displayed = false;
36533 }
36534 }
36535 /**
36536 * Reposition the item horizontally
36537 * @Override
36538 */
36539
36540 }, {
36541 key: "repositionX",
36542 value: function repositionX() {
36543 var start = this.conversion.toScreen(this.data.start);
36544 this.pointX = start;
36545
36546 if (this.options.rtl) {
36547 this.right = start - this.props.dot.width;
36548 } else {
36549 this.left = start - this.props.dot.width;
36550 }
36551
36552 this.repositionXY();
36553 }
36554 /**
36555 * Reposition the item vertically
36556 * @Override
36557 */
36558
36559 }, {
36560 key: "repositionY",
36561 value: function repositionY() {
36562 var orientation = this.options.orientation.item;
36563
36564 if (orientation == 'top') {
36565 this.pointY = this.top;
36566 } else {
36567 this.pointY = this.parent.height - this.top - this.height;
36568 }
36569
36570 this.repositionXY();
36571 }
36572 /**
36573 * Return the width of the item left from its start date
36574 * @return {number}
36575 */
36576
36577 }, {
36578 key: "getWidthLeft",
36579 value: function getWidthLeft() {
36580 return this.props.dot.width;
36581 }
36582 /**
36583 * Return the width of the item right from its start date
36584 * @return {number}
36585 */
36586
36587 }, {
36588 key: "getWidthRight",
36589 value: function getWidthRight() {
36590 return this.props.dot.width;
36591 }
36592 }]);
36593
36594 return PointItem;
36595}(Item);
36596
36597/**
36598 * @constructor RangeItem
36599 * @extends Item
36600 */
36601
36602var RangeItem =
36603/*#__PURE__*/
36604function (_Item) {
36605 _inherits(RangeItem, _Item);
36606
36607 /**
36608 * @param {Object} data Object containing parameters start, end
36609 * content, className.
36610 * @param {{toScreen: function, toTime: function}} conversion
36611 * Conversion functions from time to screen and vice versa
36612 * @param {Object} [options] Configuration options
36613 * // TODO: describe options
36614 */
36615 function RangeItem(data, conversion, options) {
36616 var _this;
36617
36618 _classCallCheck(this, RangeItem);
36619
36620 _this = _possibleConstructorReturn(this, _getPrototypeOf(RangeItem).call(this));
36621 _this.props = {
36622 content: {
36623 width: 0
36624 }
36625 };
36626 _this.overflow = false; // if contents can overflow (css styling), this flag is set to true
36627
36628 _this.options = options; // validate data
36629
36630 if (data) {
36631 if (data.start == undefined) {
36632 throw new Error("Property \"start\" missing in item ".concat(data.id));
36633 }
36634
36635 if (data.end == undefined) {
36636 throw new Error("Property \"end\" missing in item ".concat(data.id));
36637 }
36638 }
36639
36640 Item.call(_assertThisInitialized(_this), data, conversion, options);
36641 return _this;
36642 }
36643 /**
36644 * Check whether this item is visible inside given range
36645 *
36646 * @param {timeline.Range} range with a timestamp for start and end
36647 * @returns {boolean} True if visible
36648 */
36649
36650
36651 _createClass(RangeItem, [{
36652 key: "isVisible",
36653 value: function isVisible(range) {
36654 if (this.cluster) {
36655 return false;
36656 } // determine visibility
36657
36658
36659 return this.data.start < range.end && this.data.end > range.start;
36660 }
36661 /**
36662 * create DOM elements
36663 * @private
36664 */
36665
36666 }, {
36667 key: "_createDomElement",
36668 value: function _createDomElement() {
36669 if (!this.dom) {
36670 // create DOM
36671 this.dom = {}; // background box
36672
36673 this.dom.box = document.createElement('div'); // className is updated in redraw()
36674 // frame box (to prevent the item contents from overflowing)
36675
36676 this.dom.frame = document.createElement('div');
36677 this.dom.frame.className = 'vis-item-overflow';
36678 this.dom.box.appendChild(this.dom.frame); // visible frame box (showing the frame that is always visible)
36679
36680 this.dom.visibleFrame = document.createElement('div');
36681 this.dom.visibleFrame.className = 'vis-item-visible-frame';
36682 this.dom.box.appendChild(this.dom.visibleFrame); // contents box
36683
36684 this.dom.content = document.createElement('div');
36685 this.dom.content.className = 'vis-item-content';
36686 this.dom.frame.appendChild(this.dom.content); // attach this item as attribute
36687
36688 this.dom.box['vis-item'] = this;
36689 this.dirty = true;
36690 }
36691 }
36692 /**
36693 * append element to DOM
36694 * @private
36695 */
36696
36697 }, {
36698 key: "_appendDomElement",
36699 value: function _appendDomElement() {
36700 if (!this.parent) {
36701 throw new Error('Cannot redraw item: no parent attached');
36702 }
36703
36704 if (!this.dom.box.parentNode) {
36705 var foreground = this.parent.dom.foreground;
36706
36707 if (!foreground) {
36708 throw new Error('Cannot redraw item: parent has no foreground container element');
36709 }
36710
36711 foreground.appendChild(this.dom.box);
36712 }
36713
36714 this.displayed = true;
36715 }
36716 /**
36717 * update dirty DOM components
36718 * @private
36719 */
36720
36721 }, {
36722 key: "_updateDirtyDomComponents",
36723 value: function _updateDirtyDomComponents() {
36724 // update dirty DOM. An item is marked dirty when:
36725 // - the item is not yet rendered
36726 // - the item's data is changed
36727 // - the item is selected/deselected
36728 if (this.dirty) {
36729 this._updateContents(this.dom.content);
36730
36731 this._updateDataAttributes(this.dom.box);
36732
36733 this._updateStyle(this.dom.box);
36734
36735 var editable = this.editable.updateTime || this.editable.updateGroup; // update class
36736
36737 var className = (this.data.className ? ' ' + this.data.className : '') + (this.selected ? ' vis-selected' : '') + (editable ? ' vis-editable' : ' vis-readonly');
36738 this.dom.box.className = this.baseClassName + className; // turn off max-width to be able to calculate the real width
36739 // this causes an extra browser repaint/reflow, but so be it
36740
36741 this.dom.content.style.maxWidth = 'none';
36742 }
36743 }
36744 /**
36745 * get DOM component sizes
36746 * @return {object}
36747 * @private
36748 */
36749
36750 }, {
36751 key: "_getDomComponentsSizes",
36752 value: function _getDomComponentsSizes() {
36753 // determine from css whether this box has overflow
36754 this.overflow = window.getComputedStyle(this.dom.frame).overflow !== 'hidden';
36755 this.whiteSpace = window.getComputedStyle(this.dom.content).whiteSpace !== 'nowrap';
36756 return {
36757 content: {
36758 width: this.dom.content.offsetWidth
36759 },
36760 box: {
36761 height: this.dom.box.offsetHeight
36762 }
36763 };
36764 }
36765 /**
36766 * update DOM component sizes
36767 * @param {array} sizes
36768 * @private
36769 */
36770
36771 }, {
36772 key: "_updateDomComponentsSizes",
36773 value: function _updateDomComponentsSizes(sizes) {
36774 this.props.content.width = sizes.content.width;
36775 this.height = sizes.box.height;
36776 this.dom.content.style.maxWidth = '';
36777 this.dirty = false;
36778 }
36779 /**
36780 * repaint DOM additional components
36781 * @private
36782 */
36783
36784 }, {
36785 key: "_repaintDomAdditionals",
36786 value: function _repaintDomAdditionals() {
36787 this._repaintOnItemUpdateTimeTooltip(this.dom.box);
36788
36789 this._repaintDeleteButton(this.dom.box);
36790
36791 this._repaintDragCenter();
36792
36793 this._repaintDragLeft();
36794
36795 this._repaintDragRight();
36796 }
36797 /**
36798 * Repaint the item
36799 * @param {boolean} [returnQueue=false] return the queue
36800 * @return {boolean} the redraw queue if returnQueue=true
36801 */
36802
36803 }, {
36804 key: "redraw",
36805 value: function redraw(returnQueue) {
36806 var _this2 = this;
36807
36808 var sizes;
36809 var queue = [// create item DOM
36810 this._createDomElement.bind(this), // append DOM to parent DOM
36811 this._appendDomElement.bind(this), // update dirty DOM
36812 this._updateDirtyDomComponents.bind(this), function () {
36813 if (_this2.dirty) {
36814 sizes = _this2._getDomComponentsSizes.bind(_this2)();
36815 }
36816 }, function () {
36817 if (_this2.dirty) {
36818 _this2._updateDomComponentsSizes.bind(_this2)(sizes);
36819 }
36820 }, // repaint DOM additionals
36821 this._repaintDomAdditionals.bind(this)];
36822
36823 if (returnQueue) {
36824 return queue;
36825 } else {
36826 var result;
36827 queue.forEach(function (fn) {
36828 result = fn();
36829 });
36830 return result;
36831 }
36832 }
36833 /**
36834 * Show the item in the DOM (when not already visible). The items DOM will
36835 * be created when needed.
36836 * @param {boolean} [returnQueue=false] whether to return a queue of functions to execute instead of just executing them
36837 * @return {boolean} the redraw queue if returnQueue=true
36838 */
36839
36840 }, {
36841 key: "show",
36842 value: function show(returnQueue) {
36843 if (!this.displayed) {
36844 return this.redraw(returnQueue);
36845 }
36846 }
36847 /**
36848 * Hide the item from the DOM (when visible)
36849 */
36850
36851 }, {
36852 key: "hide",
36853 value: function hide() {
36854 if (this.displayed) {
36855 var box = this.dom.box;
36856
36857 if (box.parentNode) {
36858 box.parentNode.removeChild(box);
36859 }
36860
36861 this.displayed = false;
36862 }
36863 }
36864 /**
36865 * Reposition the item horizontally
36866 * @param {boolean} [limitSize=true] If true (default), the width of the range
36867 * item will be limited, as the browser cannot
36868 * display very wide divs. This means though
36869 * that the applied left and width may
36870 * not correspond to the ranges start and end
36871 * @Override
36872 */
36873
36874 }, {
36875 key: "repositionX",
36876 value: function repositionX(limitSize) {
36877 var parentWidth = this.parent.width;
36878 var start = this.conversion.toScreen(this.data.start);
36879 var end = this.conversion.toScreen(this.data.end);
36880 var align = this.data.align === undefined ? this.options.align : this.data.align;
36881 var contentStartPosition;
36882 var contentWidth; // limit the width of the range, as browsers cannot draw very wide divs
36883 // unless limitSize: false is explicitly set in item data
36884
36885 if (this.data.limitSize !== false && (limitSize === undefined || limitSize === true)) {
36886 if (start < -parentWidth) {
36887 start = -parentWidth;
36888 }
36889
36890 if (end > 2 * parentWidth) {
36891 end = 2 * parentWidth;
36892 }
36893 } //round to 3 decimals to compensate floating-point values rounding
36894
36895
36896 var boxWidth = Math.max(Math.round((end - start) * 1000) / 1000, 1);
36897
36898 if (this.overflow) {
36899 if (this.options.rtl) {
36900 this.right = start;
36901 } else {
36902 this.left = start;
36903 }
36904
36905 this.width = boxWidth + this.props.content.width;
36906 contentWidth = this.props.content.width; // Note: The calculation of width is an optimistic calculation, giving
36907 // a width which will not change when moving the Timeline
36908 // So no re-stacking needed, which is nicer for the eye;
36909 } else {
36910 if (this.options.rtl) {
36911 this.right = start;
36912 } else {
36913 this.left = start;
36914 }
36915
36916 this.width = boxWidth;
36917 contentWidth = Math.min(end - start, this.props.content.width);
36918 }
36919
36920 if (this.options.rtl) {
36921 this.dom.box.style.transform = "translateX(".concat(this.right * -1, "px)");
36922 } else {
36923 this.dom.box.style.transform = "translateX(".concat(this.left, "px)");
36924 }
36925
36926 this.dom.box.style.width = "".concat(boxWidth, "px");
36927
36928 if (this.whiteSpace) {
36929 this.height = this.dom.box.offsetHeight;
36930 }
36931
36932 switch (align) {
36933 case 'left':
36934 this.dom.content.style.transform = 'translateX(0)';
36935 break;
36936
36937 case 'right':
36938 if (this.options.rtl) {
36939 var translateX = Math.max(boxWidth - contentWidth, 0) * -1;
36940 this.dom.content.style.transform = "translateX(".concat(translateX, "px)");
36941 } else {
36942 this.dom.content.style.transform = "translateX(".concat(Math.max(boxWidth - contentWidth, 0), "px)");
36943 }
36944
36945 break;
36946
36947 case 'center':
36948 if (this.options.rtl) {
36949 var _translateX = Math.max((boxWidth - contentWidth) / 2, 0) * -1;
36950
36951 this.dom.content.style.transform = "translateX(".concat(_translateX, "px)");
36952 } else {
36953 this.dom.content.style.transform = "translateX(".concat(Math.max((boxWidth - contentWidth) / 2, 0), "px)");
36954 }
36955
36956 break;
36957
36958 default:
36959 // 'auto'
36960 // when range exceeds left of the window, position the contents at the left of the visible area
36961 if (this.overflow) {
36962 if (end > 0) {
36963 contentStartPosition = Math.max(-start, 0);
36964 } else {
36965 contentStartPosition = -contentWidth; // ensure it's not visible anymore
36966 }
36967 } else {
36968 if (start < 0) {
36969 contentStartPosition = -start;
36970 } else {
36971 contentStartPosition = 0;
36972 }
36973 }
36974
36975 if (this.options.rtl) {
36976 var _translateX2 = contentStartPosition * -1;
36977
36978 this.dom.content.style.transform = "translateX(".concat(_translateX2, "px)");
36979 } else {
36980 this.dom.content.style.transform = "translateX(".concat(contentStartPosition, "px)"); // this.dom.content.style.width = `calc(100% - ${contentStartPosition}px)`;
36981 }
36982
36983 }
36984 }
36985 /**
36986 * Reposition the item vertically
36987 * @Override
36988 */
36989
36990 }, {
36991 key: "repositionY",
36992 value: function repositionY() {
36993 var orientation = this.options.orientation.item;
36994 var box = this.dom.box;
36995
36996 if (orientation == 'top') {
36997 box.style.top = "".concat(this.top, "px");
36998 } else {
36999 box.style.top = "".concat(this.parent.height - this.top - this.height, "px");
37000 }
37001 }
37002 /**
37003 * Repaint a drag area on the left side of the range when the range is selected
37004 * @protected
37005 */
37006
37007 }, {
37008 key: "_repaintDragLeft",
37009 value: function _repaintDragLeft() {
37010 if ((this.selected || this.options.itemsAlwaysDraggable.range) && this.options.editable.updateTime && !this.dom.dragLeft) {
37011 // create and show drag area
37012 var dragLeft = document.createElement('div');
37013 dragLeft.className = 'vis-drag-left';
37014 dragLeft.dragLeftItem = this;
37015 this.dom.box.appendChild(dragLeft);
37016 this.dom.dragLeft = dragLeft;
37017 } else if (!this.selected && !this.options.itemsAlwaysDraggable.range && this.dom.dragLeft) {
37018 // delete drag area
37019 if (this.dom.dragLeft.parentNode) {
37020 this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft);
37021 }
37022
37023 this.dom.dragLeft = null;
37024 }
37025 }
37026 /**
37027 * Repaint a drag area on the right side of the range when the range is selected
37028 * @protected
37029 */
37030
37031 }, {
37032 key: "_repaintDragRight",
37033 value: function _repaintDragRight() {
37034 if ((this.selected || this.options.itemsAlwaysDraggable.range) && this.options.editable.updateTime && !this.dom.dragRight) {
37035 // create and show drag area
37036 var dragRight = document.createElement('div');
37037 dragRight.className = 'vis-drag-right';
37038 dragRight.dragRightItem = this;
37039 this.dom.box.appendChild(dragRight);
37040 this.dom.dragRight = dragRight;
37041 } else if (!this.selected && !this.options.itemsAlwaysDraggable.range && this.dom.dragRight) {
37042 // delete drag area
37043 if (this.dom.dragRight.parentNode) {
37044 this.dom.dragRight.parentNode.removeChild(this.dom.dragRight);
37045 }
37046
37047 this.dom.dragRight = null;
37048 }
37049 }
37050 }]);
37051
37052 return RangeItem;
37053}(Item);
37054
37055RangeItem.prototype.baseClassName = 'vis-item vis-range';
37056
37057/**
37058 * @constructor BackgroundItem
37059 * @extends Item
37060 */
37061
37062var BackgroundItem =
37063/*#__PURE__*/
37064function (_Item) {
37065 _inherits(BackgroundItem, _Item);
37066
37067 /**
37068 * @constructor BackgroundItem
37069 * @param {Object} data Object containing parameters start, end
37070 * content, className.
37071 * @param {{toScreen: function, toTime: function}} conversion
37072 * Conversion functions from time to screen and vice versa
37073 * @param {Object} [options] Configuration options
37074 * // TODO: describe options
37075 * // TODO: implement support for the BackgroundItem just having a start, then being displayed as a sort of an annotation
37076 */
37077 function BackgroundItem(data, conversion, options) {
37078 var _this;
37079
37080 _classCallCheck(this, BackgroundItem);
37081
37082 _this = _possibleConstructorReturn(this, _getPrototypeOf(BackgroundItem).call(this));
37083 _this.props = {
37084 content: {
37085 width: 0
37086 }
37087 };
37088 _this.overflow = false; // if contents can overflow (css styling), this flag is set to true
37089 // validate data
37090
37091 if (data) {
37092 if (data.start == undefined) {
37093 throw new Error("Property \"start\" missing in item ".concat(data.id));
37094 }
37095
37096 if (data.end == undefined) {
37097 throw new Error("Property \"end\" missing in item ".concat(data.id));
37098 }
37099 }
37100
37101 Item.call(_assertThisInitialized(_this), data, conversion, options);
37102 return _this;
37103 }
37104 /**
37105 * Check whether this item is visible inside given range
37106 * @param {timeline.Range} range with a timestamp for start and end
37107 * @returns {boolean} True if visible
37108 */
37109
37110
37111 _createClass(BackgroundItem, [{
37112 key: "isVisible",
37113 value: function isVisible(range) {
37114 // determine visibility
37115 return this.data.start < range.end && this.data.end > range.start;
37116 }
37117 /**
37118 * create DOM element
37119 * @private
37120 */
37121
37122 }, {
37123 key: "_createDomElement",
37124 value: function _createDomElement() {
37125 if (!this.dom) {
37126 // create DOM
37127 this.dom = {}; // background box
37128
37129 this.dom.box = document.createElement('div'); // className is updated in redraw()
37130 // frame box (to prevent the item contents from overflowing
37131
37132 this.dom.frame = document.createElement('div');
37133 this.dom.frame.className = 'vis-item-overflow';
37134 this.dom.box.appendChild(this.dom.frame); // contents box
37135
37136 this.dom.content = document.createElement('div');
37137 this.dom.content.className = 'vis-item-content';
37138 this.dom.frame.appendChild(this.dom.content); // Note: we do NOT attach this item as attribute to the DOM,
37139 // such that background items cannot be selected
37140 //this.dom.box['vis-item'] = this;
37141
37142 this.dirty = true;
37143 }
37144 }
37145 /**
37146 * append DOM element
37147 * @private
37148 */
37149
37150 }, {
37151 key: "_appendDomElement",
37152 value: function _appendDomElement() {
37153 if (!this.parent) {
37154 throw new Error('Cannot redraw item: no parent attached');
37155 }
37156
37157 if (!this.dom.box.parentNode) {
37158 var background = this.parent.dom.background;
37159
37160 if (!background) {
37161 throw new Error('Cannot redraw item: parent has no background container element');
37162 }
37163
37164 background.appendChild(this.dom.box);
37165 }
37166
37167 this.displayed = true;
37168 }
37169 /**
37170 * update DOM Dirty components
37171 * @private
37172 */
37173
37174 }, {
37175 key: "_updateDirtyDomComponents",
37176 value: function _updateDirtyDomComponents() {
37177 // update dirty DOM. An item is marked dirty when:
37178 // - the item is not yet rendered
37179 // - the item's data is changed
37180 // - the item is selected/deselected
37181 if (this.dirty) {
37182 this._updateContents(this.dom.content);
37183
37184 this._updateDataAttributes(this.dom.content);
37185
37186 this._updateStyle(this.dom.box); // update class
37187
37188
37189 var className = (this.data.className ? ' ' + this.data.className : '') + (this.selected ? ' vis-selected' : '');
37190 this.dom.box.className = this.baseClassName + className;
37191 }
37192 }
37193 /**
37194 * get DOM components sizes
37195 * @return {object}
37196 * @private
37197 */
37198
37199 }, {
37200 key: "_getDomComponentsSizes",
37201 value: function _getDomComponentsSizes() {
37202 // determine from css whether this box has overflow
37203 this.overflow = window.getComputedStyle(this.dom.content).overflow !== 'hidden';
37204 return {
37205 content: {
37206 width: this.dom.content.offsetWidth
37207 }
37208 };
37209 }
37210 /**
37211 * update DOM components sizes
37212 * @param {object} sizes
37213 * @private
37214 */
37215
37216 }, {
37217 key: "_updateDomComponentsSizes",
37218 value: function _updateDomComponentsSizes(sizes) {
37219 // recalculate size
37220 this.props.content.width = sizes.content.width;
37221 this.height = 0; // set height zero, so this item will be ignored when stacking items
37222
37223 this.dirty = false;
37224 }
37225 /**
37226 * repaint DOM additionals
37227 * @private
37228 */
37229
37230 }, {
37231 key: "_repaintDomAdditionals",
37232 value: function _repaintDomAdditionals() {}
37233 /**
37234 * Repaint the item
37235 * @param {boolean} [returnQueue=false] return the queue
37236 * @return {boolean} the redraw result or the redraw queue if returnQueue=true
37237 */
37238
37239 }, {
37240 key: "redraw",
37241 value: function redraw(returnQueue) {
37242 var _this2 = this;
37243
37244 var sizes;
37245 var queue = [// create item DOM
37246 this._createDomElement.bind(this), // append DOM to parent DOM
37247 this._appendDomElement.bind(this), this._updateDirtyDomComponents.bind(this), function () {
37248 if (_this2.dirty) {
37249 sizes = _this2._getDomComponentsSizes.bind(_this2)();
37250 }
37251 }, function () {
37252 if (_this2.dirty) {
37253 _this2._updateDomComponentsSizes.bind(_this2)(sizes);
37254 }
37255 }, // repaint DOM additionals
37256 this._repaintDomAdditionals.bind(this)];
37257
37258 if (returnQueue) {
37259 return queue;
37260 } else {
37261 var result;
37262 queue.forEach(function (fn) {
37263 result = fn();
37264 });
37265 return result;
37266 }
37267 }
37268 /**
37269 * Reposition the item vertically
37270 * @Override
37271 */
37272
37273 }, {
37274 key: "repositionY",
37275 value: function repositionY(margin) {
37276 // eslint-disable-line no-unused-vars
37277 var height;
37278 var orientation = this.options.orientation.item; // special positioning for subgroups
37279
37280 if (this.data.subgroup !== undefined) {
37281 // TODO: instead of calculating the top position of the subgroups here for every BackgroundItem, calculate the top of the subgroup once in Itemset
37282 var itemSubgroup = this.data.subgroup;
37283 this.dom.box.style.height = "".concat(this.parent.subgroups[itemSubgroup].height, "px");
37284
37285 if (orientation == 'top') {
37286 this.dom.box.style.top = "".concat(this.parent.top + this.parent.subgroups[itemSubgroup].top, "px");
37287 } else {
37288 this.dom.box.style.top = "".concat(this.parent.top + this.parent.height - this.parent.subgroups[itemSubgroup].top - this.parent.subgroups[itemSubgroup].height, "px");
37289 }
37290
37291 this.dom.box.style.bottom = '';
37292 } // and in the case of no subgroups:
37293 else {
37294 // we want backgrounds with groups to only show in groups.
37295 if (this.parent instanceof BackgroundGroup) {
37296 // if the item is not in a group:
37297 height = Math.max(this.parent.height, this.parent.itemSet.body.domProps.center.height, this.parent.itemSet.body.domProps.centerContainer.height);
37298 this.dom.box.style.bottom = orientation == 'bottom' ? '0' : '';
37299 this.dom.box.style.top = orientation == 'top' ? '0' : '';
37300 } else {
37301 height = this.parent.height; // same alignment for items when orientation is top or bottom
37302
37303 this.dom.box.style.top = "".concat(this.parent.top, "px");
37304 this.dom.box.style.bottom = '';
37305 }
37306 }
37307
37308 this.dom.box.style.height = "".concat(height, "px");
37309 }
37310 }]);
37311
37312 return BackgroundItem;
37313}(Item);
37314
37315BackgroundItem.prototype.baseClassName = 'vis-item vis-background';
37316BackgroundItem.prototype.stack = false;
37317/**
37318 * Show the item in the DOM (when not already visible). The items DOM will
37319 * be created when needed.
37320 */
37321
37322BackgroundItem.prototype.show = RangeItem.prototype.show;
37323/**
37324 * Hide the item from the DOM (when visible)
37325 * @return {Boolean} changed
37326 */
37327
37328BackgroundItem.prototype.hide = RangeItem.prototype.hide;
37329/**
37330 * Reposition the item horizontally
37331 * @Override
37332 */
37333
37334BackgroundItem.prototype.repositionX = RangeItem.prototype.repositionX;
37335
37336/**
37337 * Popup is a class to create a popup window with some text
37338 */
37339
37340var Popup =
37341/*#__PURE__*/
37342function () {
37343 /**
37344 * @param {Element} container The container object.
37345 * @param {string} overflowMethod How the popup should act to overflowing ('flip', 'cap' or 'none')
37346 */
37347 function Popup(container, overflowMethod) {
37348 _classCallCheck(this, Popup);
37349
37350 this.container = container;
37351 this.overflowMethod = overflowMethod || 'cap';
37352 this.x = 0;
37353 this.y = 0;
37354 this.padding = 5;
37355 this.hidden = false; // create the frame
37356
37357 this.frame = document.createElement('div');
37358 this.frame.className = 'vis-tooltip';
37359 this.container.appendChild(this.frame);
37360 }
37361 /**
37362 * @param {number} x Horizontal position of the popup window
37363 * @param {number} y Vertical position of the popup window
37364 */
37365
37366
37367 _createClass(Popup, [{
37368 key: "setPosition",
37369 value: function setPosition(x, y) {
37370 this.x = parseInt(x);
37371 this.y = parseInt(y);
37372 }
37373 /**
37374 * Set the content for the popup window. This can be HTML code or text.
37375 * @param {string | Element} content
37376 */
37377
37378 }, {
37379 key: "setText",
37380 value: function setText(content) {
37381 if (content instanceof Element) {
37382 this.frame.innerHTML = '';
37383 this.frame.appendChild(content);
37384 } else {
37385 this.frame.innerHTML = content; // string containing text or HTML
37386 }
37387 }
37388 /**
37389 * Show the popup window
37390 * @param {boolean} [doShow] Show or hide the window
37391 */
37392
37393 }, {
37394 key: "show",
37395 value: function show(doShow) {
37396 if (doShow === undefined) {
37397 doShow = true;
37398 }
37399
37400 if (doShow === true) {
37401 var height = this.frame.clientHeight;
37402 var width = this.frame.clientWidth;
37403 var maxHeight = this.frame.parentNode.clientHeight;
37404 var maxWidth = this.frame.parentNode.clientWidth;
37405 var left = 0,
37406 top = 0;
37407
37408 if (this.overflowMethod == 'flip' || this.overflowMethod == 'none') {
37409 var isLeft = false,
37410 isTop = true; // Where around the position it's located
37411
37412 if (this.overflowMethod == 'flip') {
37413 if (this.y - height < this.padding) {
37414 isTop = false;
37415 }
37416
37417 if (this.x + width > maxWidth - this.padding) {
37418 isLeft = true;
37419 }
37420 }
37421
37422 if (isLeft) {
37423 left = this.x - width;
37424 } else {
37425 left = this.x;
37426 }
37427
37428 if (isTop) {
37429 top = this.y - height;
37430 } else {
37431 top = this.y;
37432 }
37433 } else {
37434 // this.overflowMethod == 'cap'
37435 top = this.y - height;
37436
37437 if (top + height + this.padding > maxHeight) {
37438 top = maxHeight - height - this.padding;
37439 }
37440
37441 if (top < this.padding) {
37442 top = this.padding;
37443 }
37444
37445 left = this.x;
37446
37447 if (left + width + this.padding > maxWidth) {
37448 left = maxWidth - width - this.padding;
37449 }
37450
37451 if (left < this.padding) {
37452 left = this.padding;
37453 }
37454 }
37455
37456 this.frame.style.left = left + "px";
37457 this.frame.style.top = top + "px";
37458 this.frame.style.visibility = "visible";
37459 this.hidden = false;
37460 } else {
37461 this.hide();
37462 }
37463 }
37464 /**
37465 * Hide the popup window
37466 */
37467
37468 }, {
37469 key: "hide",
37470 value: function hide() {
37471 this.hidden = true;
37472 this.frame.style.left = "0";
37473 this.frame.style.top = "0";
37474 this.frame.style.visibility = "hidden";
37475 }
37476 /**
37477 * Remove the popup window
37478 */
37479
37480 }, {
37481 key: "destroy",
37482 value: function destroy() {
37483 this.frame.parentNode.removeChild(this.frame); // Remove element from DOM
37484 }
37485 }]);
37486
37487 return Popup;
37488}();
37489
37490var $every$1 = arrayIteration.every;
37491
37492
37493// `Array.prototype.every` method
37494// https://tc39.github.io/ecma262/#sec-array.prototype.every
37495_export({ target: 'Array', proto: true, forced: sloppyArrayMethod('every') }, {
37496 every: function every(callbackfn /* , thisArg */) {
37497 return $every$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
37498 }
37499});
37500
37501/**
37502 * ClusterItem
37503 */
37504
37505var ClusterItem =
37506/*#__PURE__*/
37507function (_Item) {
37508 _inherits(ClusterItem, _Item);
37509
37510 /**
37511 * @constructor Item
37512 * @param {Object} data Object containing (optional) parameters type,
37513 * start, end, content, group, className.
37514 * @param {{toScreen: function, toTime: function}} conversion
37515 * Conversion functions from time to screen and vice versa
37516 * @param {Object} options Configuration options
37517 * // TODO: describe available options
37518 */
37519 function ClusterItem(data, conversion, options) {
37520 var _this;
37521
37522 _classCallCheck(this, ClusterItem);
37523
37524 _this = _possibleConstructorReturn(this, _getPrototypeOf(ClusterItem).call(this));
37525 _this.props = {
37526 content: {
37527 width: 0,
37528 height: 0
37529 }
37530 };
37531 _this.options = Object.assign({}, {
37532 fitOnDoubleClick: true
37533 }, options, {
37534 editable: false
37535 });
37536
37537 if (!data || data.uiItems == undefined) {
37538 throw new Error('Property "uiItems" missing in item ' + data.id);
37539 }
37540
37541 Item.call(_assertThisInitialized(_this), data, conversion, _this.options);
37542 _this.id = util.randomUUID();
37543 _this.group = data.group;
37544
37545 _this._setupRange();
37546
37547 _this.emitter = _this.data.eventEmitter;
37548 _this.range = _this.data.range;
37549 _this.attached = false;
37550 _this.isCluster = true;
37551 _this.data.isCluster = true;
37552 return _this;
37553 }
37554 /**
37555 * check if there are items
37556 * @return {boolean}
37557 */
37558
37559
37560 _createClass(ClusterItem, [{
37561 key: "hasItems",
37562 value: function hasItems() {
37563 return this.data.uiItems && this.data.uiItems.length && this.attached;
37564 }
37565 /**
37566 * set UI items
37567 * @param {array} items
37568 */
37569
37570 }, {
37571 key: "setUiItems",
37572 value: function setUiItems(items) {
37573 this.detach();
37574 this.data.uiItems = items;
37575
37576 this._setupRange();
37577
37578 this.attach();
37579 }
37580 /**
37581 * check is visible
37582 * @param {object} range
37583 * @return {boolean}
37584 */
37585
37586 }, {
37587 key: "isVisible",
37588 value: function isVisible(range) {
37589 var rangeWidth = this.data.end ? this.data.end - this.data.start : 0;
37590 var widthInMs = this.width * range.getMillisecondsPerPixel();
37591 var end = Math.max(rangeWidth, this.data.start.getTime() + widthInMs);
37592 return this.data.start < range.end && end > range.start && this.hasItems();
37593 }
37594 /**
37595 * get cluster data
37596 * @return {object}
37597 */
37598
37599 }, {
37600 key: "getData",
37601 value: function getData() {
37602 return {
37603 isCluster: true,
37604 id: this.id,
37605 items: this.data.items || [],
37606 data: this.data
37607 };
37608 }
37609 /**
37610 * redraw cluster item
37611 * @param {boolean} returnQueue
37612 * @return {boolean}
37613 */
37614
37615 }, {
37616 key: "redraw",
37617 value: function redraw(returnQueue) {
37618 var sizes;
37619 var queue = [// create item DOM
37620 this._createDomElement.bind(this), // append DOM to parent DOM
37621 this._appendDomElement.bind(this), // update dirty DOM
37622 this._updateDirtyDomComponents.bind(this), function () {
37623 if (this.dirty) {
37624 sizes = this._getDomComponentsSizes();
37625 }
37626 }.bind(this), function () {
37627 if (this.dirty) {
37628 this._updateDomComponentsSizes.bind(this)(sizes);
37629 }
37630 }.bind(this), // repaint DOM additionals
37631 this._repaintDomAdditionals.bind(this)];
37632
37633 if (returnQueue) {
37634 return queue;
37635 } else {
37636 var result;
37637 queue.forEach(function (fn) {
37638 result = fn();
37639 });
37640 return result;
37641 }
37642 }
37643 /**
37644 * show cluster item
37645 */
37646
37647 }, {
37648 key: "show",
37649 value: function show() {
37650 if (!this.displayed) {
37651 this.redraw();
37652 }
37653 }
37654 /**
37655 * Hide the item from the DOM (when visible)
37656 */
37657
37658 }, {
37659 key: "hide",
37660 value: function hide() {
37661 if (this.displayed) {
37662 var dom = this.dom;
37663
37664 if (dom.box.parentNode) {
37665 dom.box.parentNode.removeChild(dom.box);
37666 }
37667
37668 if (this.options.showStipes) {
37669 if (dom.line.parentNode) {
37670 dom.line.parentNode.removeChild(dom.line);
37671 }
37672
37673 if (dom.dot.parentNode) {
37674 dom.dot.parentNode.removeChild(dom.dot);
37675 }
37676 }
37677
37678 this.displayed = false;
37679 }
37680 }
37681 /**
37682 * reposition item x axis
37683 */
37684
37685 }, {
37686 key: "repositionX",
37687 value: function repositionX() {
37688 var start = this.conversion.toScreen(this.data.start);
37689 var end = this.data.end ? this.conversion.toScreen(this.data.end) : 0;
37690
37691 if (end) {
37692 this.repositionXWithRanges(start, end);
37693 } else {
37694 var align = this.data.align === undefined ? this.options.align : this.data.align;
37695 this.repositionXWithoutRanges(start, align);
37696 }
37697
37698 if (this.options.showStipes) {
37699 this.dom.line.style.display = this._isStipeVisible() ? 'block' : 'none';
37700 this.dom.dot.style.display = this._isStipeVisible() ? 'block' : 'none';
37701
37702 if (this._isStipeVisible()) {
37703 this.repositionStype(start, end);
37704 }
37705 }
37706 }
37707 /**
37708 * reposition item stype
37709 * @param {date} start
37710 * @param {date} end
37711 */
37712
37713 }, {
37714 key: "repositionStype",
37715 value: function repositionStype(start, end) {
37716 this.dom.line.style.display = 'block';
37717 this.dom.dot.style.display = 'block';
37718 var lineOffsetWidth = this.dom.line.offsetWidth;
37719 var dotOffsetWidth = this.dom.dot.offsetWidth;
37720
37721 if (end) {
37722 var lineOffset = lineOffsetWidth + start + (end - start) / 2;
37723 var dotOffset = lineOffset - dotOffsetWidth / 2;
37724 var lineOffsetDirection = this.options.rtl ? lineOffset * -1 : lineOffset;
37725 var dotOffsetDirection = this.options.rtl ? dotOffset * -1 : dotOffset;
37726 this.dom.line.style.transform = "translateX(".concat(lineOffsetDirection, ")px");
37727 this.dom.dot.style.transform = "translateX(".concat(dotOffsetDirection, "px)");
37728 } else {
37729 var _lineOffsetDirection = this.options.rtl ? start * -1 : start;
37730
37731 var _dotOffsetDirection = this.options.rtl ? (start - dotOffsetWidth / 2) * -1 : start - dotOffsetWidth / 2;
37732
37733 this.dom.line.style.transform = "".concat(_lineOffsetDirection, "px");
37734 this.dom.dot.style.transform = "".concat(_dotOffsetDirection, "px");
37735 }
37736 }
37737 /**
37738 * reposition x without ranges
37739 * @param {date} start
37740 * @param {string} align
37741 */
37742
37743 }, {
37744 key: "repositionXWithoutRanges",
37745 value: function repositionXWithoutRanges(start, align) {
37746 // calculate left position of the box
37747 if (align == 'right') {
37748 if (this.options.rtl) {
37749 this.right = start - this.width; // reposition box, line, and dot
37750
37751 this.dom.box.style.right = this.right + 'px';
37752 } else {
37753 this.left = start - this.width; // reposition box, line, and dot
37754
37755 this.dom.box.style.left = this.left + 'px';
37756 }
37757 } else if (align == 'left') {
37758 if (this.options.rtl) {
37759 this.right = start; // reposition box, line, and dot
37760
37761 this.dom.box.style.right = this.right + 'px';
37762 } else {
37763 this.left = start; // reposition box, line, and dot
37764
37765 this.dom.box.style.left = this.left + 'px';
37766 }
37767 } else {
37768 // default or 'center'
37769 if (this.options.rtl) {
37770 this.right = start - this.width / 2; // reposition box, line, and dot
37771
37772 this.dom.box.style.right = this.right + 'px';
37773 } else {
37774 this.left = start - this.width / 2; // reposition box, line, and dot
37775
37776 this.dom.box.style.left = this.left + 'px';
37777 }
37778 }
37779 }
37780 /**
37781 * reposition x with ranges
37782 * @param {date} start
37783 * @param {date} end
37784 */
37785
37786 }, {
37787 key: "repositionXWithRanges",
37788 value: function repositionXWithRanges(start, end) {
37789 var boxWidth = Math.round(Math.max(end - start + 0.5, 1));
37790
37791 if (this.options.rtl) {
37792 this.right = start;
37793 } else {
37794 this.left = start;
37795 }
37796
37797 this.width = Math.max(boxWidth, this.minWidth || 0);
37798
37799 if (this.options.rtl) {
37800 this.dom.box.style.right = this.right + 'px';
37801 } else {
37802 this.dom.box.style.left = this.left + 'px';
37803 }
37804
37805 this.dom.box.style.width = boxWidth + 'px';
37806 }
37807 /**
37808 * reposition item y axis
37809 */
37810
37811 }, {
37812 key: "repositionY",
37813 value: function repositionY() {
37814 var orientation = this.options.orientation.item;
37815 var box = this.dom.box;
37816
37817 if (orientation == 'top') {
37818 box.style.top = (this.top || 0) + 'px';
37819 } else {
37820 // orientation 'bottom'
37821 box.style.top = (this.parent.height - this.top - this.height || 0) + 'px';
37822 }
37823
37824 if (this.options.showStipes) {
37825 if (orientation == 'top') {
37826 this.dom.line.style.top = '0';
37827 this.dom.line.style.height = this.parent.top + this.top + 1 + 'px';
37828 this.dom.line.style.bottom = '';
37829 } else {
37830 // orientation 'bottom'
37831 var itemSetHeight = this.parent.itemSet.props.height;
37832 var lineHeight = itemSetHeight - this.parent.top - this.parent.height + this.top;
37833 this.dom.line.style.top = itemSetHeight - lineHeight + 'px';
37834 this.dom.line.style.bottom = '0';
37835 }
37836
37837 this.dom.dot.style.top = -this.dom.dot.offsetHeight / 2 + 'px';
37838 }
37839 }
37840 /**
37841 * get width left
37842 * @return {number}
37843 */
37844
37845 }, {
37846 key: "getWidthLeft",
37847 value: function getWidthLeft() {
37848 return this.width / 2;
37849 }
37850 /**
37851 * get width right
37852 * @return {number}
37853 */
37854
37855 }, {
37856 key: "getWidthRight",
37857 value: function getWidthRight() {
37858 return this.width / 2;
37859 }
37860 /**
37861 * move cluster item
37862 */
37863
37864 }, {
37865 key: "move",
37866 value: function move() {
37867 this.repositionX();
37868 this.repositionY();
37869 }
37870 /**
37871 * attach
37872 */
37873
37874 }, {
37875 key: "attach",
37876 value: function attach() {
37877 var _iteratorNormalCompletion = true;
37878 var _didIteratorError = false;
37879 var _iteratorError = undefined;
37880
37881 try {
37882 for (var _iterator = this.data.uiItems[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
37883 var item = _step.value;
37884 item.cluster = this;
37885 }
37886 } catch (err) {
37887 _didIteratorError = true;
37888 _iteratorError = err;
37889 } finally {
37890 try {
37891 if (!_iteratorNormalCompletion && _iterator.return != null) {
37892 _iterator.return();
37893 }
37894 } finally {
37895 if (_didIteratorError) {
37896 throw _iteratorError;
37897 }
37898 }
37899 }
37900
37901 this.data.items = this.data.uiItems.map(function (item) {
37902 return item.data;
37903 });
37904 this.attached = true;
37905 this.dirty = true;
37906 }
37907 /**
37908 * detach
37909 * @param {boolean} detachFromParent
37910 * @return {void}
37911 */
37912
37913 }, {
37914 key: "detach",
37915 value: function detach() {
37916 var detachFromParent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
37917
37918 if (!this.hasItems()) {
37919 return;
37920 }
37921
37922 var _iteratorNormalCompletion2 = true;
37923 var _didIteratorError2 = false;
37924 var _iteratorError2 = undefined;
37925
37926 try {
37927 for (var _iterator2 = this.data.uiItems[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
37928 var item = _step2.value;
37929 delete item.cluster;
37930 }
37931 } catch (err) {
37932 _didIteratorError2 = true;
37933 _iteratorError2 = err;
37934 } finally {
37935 try {
37936 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
37937 _iterator2.return();
37938 }
37939 } finally {
37940 if (_didIteratorError2) {
37941 throw _iteratorError2;
37942 }
37943 }
37944 }
37945
37946 this.attached = false;
37947
37948 if (detachFromParent && this.group) {
37949 this.group.remove(this);
37950 this.group = null;
37951 }
37952
37953 this.data.items = [];
37954 this.dirty = true;
37955 }
37956 /**
37957 * handle on double click
37958 */
37959
37960 }, {
37961 key: "_onDoubleClick",
37962 value: function _onDoubleClick() {
37963 this._fit();
37964 }
37965 /**
37966 * set range
37967 */
37968
37969 }, {
37970 key: "_setupRange",
37971 value: function _setupRange() {
37972 var stats = this.data.uiItems.map(function (item) {
37973 return {
37974 start: item.data.start.valueOf(),
37975 end: item.data.end ? item.data.end.valueOf() : item.data.start.valueOf()
37976 };
37977 });
37978 this.data.min = Math.min.apply(Math, _toConsumableArray(stats.map(function (s) {
37979 return Math.min(s.start, s.end || s.start);
37980 })));
37981 this.data.max = Math.max.apply(Math, _toConsumableArray(stats.map(function (s) {
37982 return Math.max(s.start, s.end || s.start);
37983 })));
37984 var centers = this.data.uiItems.map(function (item) {
37985 return item.center;
37986 });
37987 var avg = centers.reduce(function (sum, value) {
37988 return sum + value;
37989 }, 0) / this.data.uiItems.length;
37990
37991 if (this.data.uiItems.some(function (item) {
37992 return item.data.end;
37993 })) {
37994 // contains ranges
37995 this.data.start = new Date(this.data.min);
37996 this.data.end = new Date(this.data.max);
37997 } else {
37998 this.data.start = new Date(avg);
37999 this.data.end = null;
38000 }
38001 }
38002 /**
38003 * get UI items
38004 * @return {array}
38005 */
38006
38007 }, {
38008 key: "_getUiItems",
38009 value: function _getUiItems() {
38010 var _this2 = this;
38011
38012 if (this.data.uiItems && this.data.uiItems.length) {
38013 return this.data.uiItems.filter(function (item) {
38014 return item.cluster === _this2;
38015 });
38016 }
38017
38018 return [];
38019 }
38020 /**
38021 * create DOM element
38022 */
38023
38024 }, {
38025 key: "_createDomElement",
38026 value: function _createDomElement() {
38027 if (!this.dom) {
38028 // create DOM
38029 this.dom = {}; // create main box
38030
38031 this.dom.box = document.createElement('DIV'); // contents box (inside the background box). used for making margins
38032
38033 this.dom.content = document.createElement('DIV');
38034 this.dom.content.className = 'vis-item-content';
38035 this.dom.box.appendChild(this.dom.content);
38036
38037 if (this.options.showStipes) {
38038 // line to axis
38039 this.dom.line = document.createElement('DIV');
38040 this.dom.line.className = 'vis-cluster-line';
38041 this.dom.line.style.display = 'none'; // dot on axis
38042
38043 this.dom.dot = document.createElement('DIV');
38044 this.dom.dot.className = 'vis-cluster-dot';
38045 this.dom.dot.style.display = 'none';
38046 }
38047
38048 if (this.options.fitOnDoubleClick) {
38049 this.dom.box.ondblclick = ClusterItem.prototype._onDoubleClick.bind(this);
38050 } // attach this item as attribute
38051
38052
38053 this.dom.box['vis-item'] = this;
38054 this.dirty = true;
38055 }
38056 }
38057 /**
38058 * append element to DOM
38059 */
38060
38061 }, {
38062 key: "_appendDomElement",
38063 value: function _appendDomElement() {
38064 if (!this.parent) {
38065 throw new Error('Cannot redraw item: no parent attached');
38066 }
38067
38068 if (!this.dom.box.parentNode) {
38069 var foreground = this.parent.dom.foreground;
38070
38071 if (!foreground) {
38072 throw new Error('Cannot redraw item: parent has no foreground container element');
38073 }
38074
38075 foreground.appendChild(this.dom.box);
38076 }
38077
38078 var background = this.parent.dom.background;
38079
38080 if (this.options.showStipes) {
38081 if (!this.dom.line.parentNode) {
38082 if (!background) throw new Error('Cannot redraw item: parent has no background container element');
38083 background.appendChild(this.dom.line);
38084 }
38085
38086 if (!this.dom.dot.parentNode) {
38087 var axis = this.parent.dom.axis;
38088 if (!background) throw new Error('Cannot redraw item: parent has no axis container element');
38089 axis.appendChild(this.dom.dot);
38090 }
38091 }
38092
38093 this.displayed = true;
38094 }
38095 /**
38096 * update dirty DOM components
38097 */
38098
38099 }, {
38100 key: "_updateDirtyDomComponents",
38101 value: function _updateDirtyDomComponents() {
38102 // An item is marked dirty when:
38103 // - the item is not yet rendered
38104 // - the item's data is changed
38105 // - the item is selected/deselected
38106 if (this.dirty) {
38107 this._updateContents(this.dom.content);
38108
38109 this._updateDataAttributes(this.dom.box);
38110
38111 this._updateStyle(this.dom.box); // update class
38112
38113
38114 var className = this.baseClassName + ' ' + (this.data.className ? ' ' + this.data.className : '') + (this.selected ? ' vis-selected' : '') + ' vis-readonly';
38115 this.dom.box.className = 'vis-item ' + className;
38116
38117 if (this.options.showStipes) {
38118 this.dom.line.className = 'vis-item vis-cluster-line ' + (this.selected ? ' vis-selected' : '');
38119 this.dom.dot.className = 'vis-item vis-cluster-dot ' + (this.selected ? ' vis-selected' : '');
38120 }
38121
38122 if (this.data.end) {
38123 // turn off max-width to be able to calculate the real width
38124 // this causes an extra browser repaint/reflow, but so be it
38125 this.dom.content.style.maxWidth = 'none';
38126 }
38127 }
38128 }
38129 /**
38130 * get DOM components sizes
38131 * @return {object}
38132 */
38133
38134 }, {
38135 key: "_getDomComponentsSizes",
38136 value: function _getDomComponentsSizes() {
38137 return {
38138 previous: {
38139 right: this.dom.box.style.right,
38140 left: this.dom.box.style.left
38141 },
38142 box: {
38143 width: this.dom.box.offsetWidth,
38144 height: this.dom.box.offsetHeight
38145 }
38146 };
38147 }
38148 /**
38149 * update DOM components sizes
38150 * @param {object} sizes
38151 */
38152
38153 }, {
38154 key: "_updateDomComponentsSizes",
38155 value: function _updateDomComponentsSizes(sizes) {
38156 if (this.options.rtl) {
38157 this.dom.box.style.right = "0px";
38158 } else {
38159 this.dom.box.style.left = "0px";
38160 } // recalculate size
38161
38162
38163 if (!this.data.end) {
38164 this.width = sizes.box.width;
38165 } else {
38166 this.minWidth = sizes.box.width;
38167 }
38168
38169 this.height = sizes.box.height; // restore previous position
38170
38171 if (this.options.rtl) {
38172 this.dom.box.style.right = sizes.previous.right;
38173 } else {
38174 this.dom.box.style.left = sizes.previous.left;
38175 }
38176
38177 this.dirty = false;
38178 }
38179 /**
38180 * repaint DOM additional components
38181 */
38182
38183 }, {
38184 key: "_repaintDomAdditionals",
38185 value: function _repaintDomAdditionals() {
38186 this._repaintOnItemUpdateTimeTooltip(this.dom.box);
38187 }
38188 /**
38189 * check is stripe visible
38190 * @return {number}
38191 * @private
38192 */
38193
38194 }, {
38195 key: "_isStipeVisible",
38196 value: function _isStipeVisible() {
38197 return this.minWidth >= this.width || !this.data.end;
38198 }
38199 /**
38200 * get fit range
38201 * @return {object}
38202 * @private
38203 */
38204
38205 }, {
38206 key: "_getFitRange",
38207 value: function _getFitRange() {
38208 var offset = 0.05 * (this.data.max - this.data.min) / 2;
38209 return {
38210 fitStart: this.data.min - offset,
38211 fitEnd: this.data.max + offset
38212 };
38213 }
38214 /**
38215 * fit
38216 * @private
38217 */
38218
38219 }, {
38220 key: "_fit",
38221 value: function _fit() {
38222 if (this.emitter) {
38223 var _this$_getFitRange = this._getFitRange(),
38224 fitStart = _this$_getFitRange.fitStart,
38225 fitEnd = _this$_getFitRange.fitEnd;
38226
38227 var fitArgs = {
38228 start: new Date(fitStart),
38229 end: new Date(fitEnd),
38230 animation: true
38231 };
38232 this.emitter.emit('fit', fitArgs);
38233 }
38234 }
38235 /**
38236 * get item data
38237 * @return {object}
38238 * @private
38239 */
38240
38241 }, {
38242 key: "_getItemData",
38243 value: function _getItemData() {
38244 return this.data;
38245 }
38246 }]);
38247
38248 return ClusterItem;
38249}(Item);
38250
38251ClusterItem.prototype.baseClassName = 'vis-item vis-range vis-cluster';
38252
38253var UNGROUPED$1 = '__ungrouped__'; // reserved group id for ungrouped items
38254
38255var BACKGROUND$1 = '__background__'; // reserved group id for background items without group
38256
38257var ReservedGroupIds$1 = {
38258 UNGROUPED: UNGROUPED$1,
38259 BACKGROUND: BACKGROUND$1
38260 /**
38261 * An Cluster generator generates cluster items
38262 */
38263
38264};
38265
38266var ClusterGenerator =
38267/*#__PURE__*/
38268function () {
38269 /**
38270 * @param {ItemSet} itemSet itemsSet instance
38271 * @constructor ClusterGenerator
38272 */
38273 function ClusterGenerator(itemSet) {
38274 _classCallCheck(this, ClusterGenerator);
38275
38276 this.itemSet = itemSet;
38277 this.groups = {};
38278 this.cache = {};
38279 this.cache[-1] = [];
38280 }
38281 /**
38282 * @param {Object} itemData Object containing parameters start content, className.
38283 * @param {{toScreen: function, toTime: function}} conversion
38284 * Conversion functions from time to screen and vice versa
38285 * @param {Object} [options] Configuration options
38286 * @return {Object} newItem
38287 */
38288
38289
38290 _createClass(ClusterGenerator, [{
38291 key: "createClusterItem",
38292 value: function createClusterItem(itemData, conversion, options) {
38293 var newItem = new ClusterItem(itemData, conversion, options);
38294 return newItem;
38295 }
38296 /**
38297 * Set the items to be clustered.
38298 * This will clear cached clusters.
38299 * @param {Item[]} items
38300 * @param {Object} [options] Available options:
38301 * {boolean} applyOnChangedLevel
38302 * If true (default), the changed data is applied
38303 * as soon the cluster level changes. If false,
38304 * The changed data is applied immediately
38305 */
38306
38307 }, {
38308 key: "setItems",
38309 value: function setItems(items, options) {
38310 this.items = items || [];
38311 this.dataChanged = true;
38312 this.applyOnChangedLevel = false;
38313
38314 if (options && options.applyOnChangedLevel) {
38315 this.applyOnChangedLevel = options.applyOnChangedLevel;
38316 }
38317 }
38318 /**
38319 * Update the current data set: clear cache, and recalculate the clustering for
38320 * the current level
38321 */
38322
38323 }, {
38324 key: "updateData",
38325 value: function updateData() {
38326 this.dataChanged = true;
38327 this.applyOnChangedLevel = false;
38328 }
38329 /**
38330 * Cluster the items which are too close together
38331 * @param {array} oldClusters
38332 * @param {number} scale The scale of the current window : (windowWidth / (endDate - startDate))
38333 * @param {{maxItems: number, clusterCriteria: function, titleTemplate: string}} options
38334 * @return {array} clusters
38335 */
38336
38337 }, {
38338 key: "getClusters",
38339 value: function getClusters(oldClusters, scale, options) {
38340 var _ref = typeof options === "boolean" ? {} : options,
38341 maxItems = _ref.maxItems,
38342 clusterCriteria = _ref.clusterCriteria;
38343
38344 if (!clusterCriteria) {
38345 clusterCriteria = function clusterCriteria() {
38346 return true;
38347 };
38348 }
38349
38350 maxItems = maxItems || 1;
38351 var level = -1;
38352 var granularity = 2;
38353 var timeWindow = 0;
38354
38355 if (scale > 0) {
38356 if (scale >= 1) {
38357 return [];
38358 }
38359
38360 level = Math.abs(Math.round(Math.log(100 / scale) / Math.log(granularity)));
38361 timeWindow = Math.abs(Math.pow(granularity, level));
38362 } // clear the cache when and re-generate groups the data when needed.
38363
38364
38365 if (this.dataChanged) {
38366 var levelChanged = level != this.cacheLevel;
38367 var applyDataNow = this.applyOnChangedLevel ? levelChanged : true;
38368
38369 if (applyDataNow) {
38370 this._dropLevelsCache();
38371
38372 this._filterData();
38373 }
38374 }
38375
38376 this.cacheLevel = level;
38377 var clusters = this.cache[level];
38378
38379 if (!clusters) {
38380 clusters = [];
38381
38382 for (var groupName in this.groups) {
38383 if (this.groups.hasOwnProperty(groupName)) {
38384 var items = this.groups[groupName];
38385 var iMax = items.length;
38386 var i = 0;
38387
38388 while (i < iMax) {
38389 // find all items around current item, within the timeWindow
38390 var item = items[i];
38391 var neighbors = 1; // start at 1, to include itself)
38392 // loop through items left from the current item
38393
38394 var j = i - 1;
38395
38396 while (j >= 0 && item.center - items[j].center < timeWindow / 2) {
38397 if (!items[j].cluster && clusterCriteria(item.data, items[j].data)) {
38398 neighbors++;
38399 }
38400
38401 j--;
38402 } // loop through items right from the current item
38403
38404
38405 var k = i + 1;
38406
38407 while (k < items.length && items[k].center - item.center < timeWindow / 2) {
38408 if (clusterCriteria(item.data, items[k].data)) {
38409 neighbors++;
38410 }
38411
38412 k++;
38413 } // loop through the created clusters
38414
38415
38416 var l = clusters.length - 1;
38417
38418 while (l >= 0 && item.center - clusters[l].center < timeWindow) {
38419 if (item.group == clusters[l].group && clusterCriteria(item.data, clusters[l].data)) {
38420 neighbors++;
38421 }
38422
38423 l--;
38424 } // aggregate until the number of items is within maxItems
38425
38426
38427 if (neighbors > maxItems) {
38428 // too busy in this window.
38429 var num = neighbors - maxItems + 1;
38430 var clusterItems = []; // append the items to the cluster,
38431 // and calculate the average start for the cluster
38432
38433 var m = i;
38434
38435 while (clusterItems.length < num && m < items.length) {
38436 if (clusterCriteria(items[m].data, items[m].data)) {
38437 clusterItems.push(items[m]);
38438 }
38439
38440 m++;
38441 }
38442
38443 var groupId = this.itemSet.getGroupId(item.data);
38444 var group = this.itemSet.groups[groupId] || this.itemSet.groups[ReservedGroupIds$1.UNGROUPED];
38445
38446 var cluster = this._getClusterForItems(clusterItems, group, oldClusters, options);
38447
38448 clusters.push(cluster);
38449 i += num;
38450 } else {
38451 delete item.cluster;
38452 i += 1;
38453 }
38454 }
38455 }
38456 }
38457
38458 this.cache[level] = clusters;
38459 }
38460
38461 return clusters;
38462 }
38463 /**
38464 * Filter the items per group.
38465 * @private
38466 */
38467
38468 }, {
38469 key: "_filterData",
38470 value: function _filterData() {
38471 // filter per group
38472 var groups = {};
38473 this.groups = groups; // split the items per group
38474
38475 for (var _i = 0, _Object$values = Object.values(this.items); _i < _Object$values.length; _i++) {
38476 var item = _Object$values[_i];
38477 // put the item in the correct group
38478 var groupName = item.parent ? item.parent.groupId : '';
38479 var group = groups[groupName];
38480
38481 if (!group) {
38482 group = [];
38483 groups[groupName] = group;
38484 }
38485
38486 group.push(item); // calculate the center of the item
38487
38488 if (item.data.start) {
38489 if (item.data.end) {
38490 // range
38491 item.center = (item.data.start.valueOf() + item.data.end.valueOf()) / 2;
38492 } else {
38493 // box, dot
38494 item.center = item.data.start.valueOf();
38495 }
38496 }
38497 } // sort the items per group
38498
38499
38500 for (var currentGroupName in groups) {
38501 if (groups.hasOwnProperty(currentGroupName)) {
38502 groups[currentGroupName].sort(function (a, b) {
38503 return a.center - b.center;
38504 });
38505 }
38506 }
38507
38508 this.dataChanged = false;
38509 }
38510 /**
38511 * Create new cluster or return existing
38512 * @private
38513 * @param {array} clusterItems
38514 * @param {object} group
38515 * @param {array} oldClusters
38516 * @param {object} options
38517 * @returns {object} cluster
38518 */
38519
38520 }, {
38521 key: "_getClusterForItems",
38522 value: function _getClusterForItems(clusterItems, group, oldClusters, options) {
38523 var oldClustersLookup = (oldClusters || []).map(function (cluster) {
38524 return {
38525 cluster: cluster,
38526 itemsIds: new Set(cluster.data.uiItems.map(function (item) {
38527 return item.id;
38528 }))
38529 };
38530 });
38531 var cluster;
38532
38533 if (oldClustersLookup.length) {
38534 var _iteratorNormalCompletion = true;
38535 var _didIteratorError = false;
38536 var _iteratorError = undefined;
38537
38538 try {
38539 var _loop = function _loop() {
38540 var oldClusterData = _step.value;
38541
38542 if (oldClusterData.itemsIds.size === clusterItems.length && clusterItems.every(function (clusterItem) {
38543 return oldClusterData.itemsIds.has(clusterItem.id);
38544 })) {
38545 cluster = oldClusterData.cluster;
38546 return "break";
38547 }
38548 };
38549
38550 for (var _iterator = oldClustersLookup[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
38551 var _ret = _loop();
38552
38553 if (_ret === "break") break;
38554 }
38555 } catch (err) {
38556 _didIteratorError = true;
38557 _iteratorError = err;
38558 } finally {
38559 try {
38560 if (!_iteratorNormalCompletion && _iterator.return != null) {
38561 _iterator.return();
38562 }
38563 } finally {
38564 if (_didIteratorError) {
38565 throw _iteratorError;
38566 }
38567 }
38568 }
38569 }
38570
38571 if (cluster) {
38572 cluster.setUiItems(clusterItems);
38573
38574 if (cluster.group !== group) {
38575 if (cluster.group) {
38576 cluster.group.remove(cluster);
38577 }
38578
38579 if (group) {
38580 group.add(cluster);
38581 cluster.group = group;
38582 }
38583 }
38584
38585 return cluster;
38586 }
38587
38588 var titleTemplate = options.titleTemplate || '';
38589 var conversion = {
38590 toScreen: this.itemSet.body.util.toScreen,
38591 toTime: this.itemSet.body.util.toTime
38592 };
38593 var clusterContent = '<div title="' + title + '">' + clusterItems.length + '</div>';
38594 var title = titleTemplate.replace(/{count}/, clusterItems.length);
38595 var clusterOptions = Object.assign({}, options, this.itemSet.options);
38596 var data = {
38597 'content': clusterContent,
38598 'title': title,
38599 'group': group,
38600 'uiItems': clusterItems,
38601 'eventEmitter': this.itemSet.body.emitter,
38602 'range': this.itemSet.body.range
38603 };
38604 cluster = this.createClusterItem(data, conversion, clusterOptions);
38605
38606 if (group) {
38607 group.add(cluster);
38608 cluster.group = group;
38609 }
38610
38611 cluster.attach();
38612 return cluster;
38613 }
38614 /**
38615 * Drop cache
38616 * @private
38617 */
38618
38619 }, {
38620 key: "_dropLevelsCache",
38621 value: function _dropLevelsCache() {
38622 this.cache = {};
38623 this.cacheLevel = -1;
38624 this.cache[this.cacheLevel] = [];
38625 }
38626 }]);
38627
38628 return ClusterGenerator;
38629}();
38630
38631var UNGROUPED$2 = '__ungrouped__'; // reserved group id for ungrouped items
38632
38633var BACKGROUND$2 = '__background__'; // reserved group id for background items without group
38634
38635var ItemSet =
38636/*#__PURE__*/
38637function (_Component) {
38638 _inherits(ItemSet, _Component);
38639
38640 /**
38641 * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} body
38642 * @param {Object} [options] See ItemSet.setOptions for the available options.
38643 * @constructor ItemSet
38644 * @extends Component
38645 */
38646 function ItemSet(body, options) {
38647 var _this;
38648
38649 _classCallCheck(this, ItemSet);
38650
38651 _this = _possibleConstructorReturn(this, _getPrototypeOf(ItemSet).call(this));
38652 _this.body = body;
38653 _this.defaultOptions = {
38654 type: null,
38655 // 'box', 'point', 'range', 'background'
38656 orientation: {
38657 item: 'bottom' // item orientation: 'top' or 'bottom'
38658
38659 },
38660 align: 'auto',
38661 // alignment of box items
38662 stack: true,
38663 stackSubgroups: true,
38664 groupOrderSwap: function groupOrderSwap(fromGroup, toGroup, groups) {
38665 // eslint-disable-line no-unused-vars
38666 var targetOrder = toGroup.order;
38667 toGroup.order = fromGroup.order;
38668 fromGroup.order = targetOrder;
38669 },
38670 groupOrder: 'order',
38671 selectable: true,
38672 multiselect: false,
38673 itemsAlwaysDraggable: {
38674 item: false,
38675 range: false
38676 },
38677 editable: {
38678 updateTime: false,
38679 updateGroup: false,
38680 add: false,
38681 remove: false,
38682 overrideItems: false
38683 },
38684 groupEditable: {
38685 order: false,
38686 add: false,
38687 remove: false
38688 },
38689 snap: TimeStep.snap,
38690 // Only called when `objectData.target === 'item'.
38691 onDropObjectOnItem: function onDropObjectOnItem(objectData, item, callback) {
38692 callback(item);
38693 },
38694 onAdd: function onAdd(item, callback) {
38695 callback(item);
38696 },
38697 onUpdate: function onUpdate(item, callback) {
38698 callback(item);
38699 },
38700 onMove: function onMove(item, callback) {
38701 callback(item);
38702 },
38703 onRemove: function onRemove(item, callback) {
38704 callback(item);
38705 },
38706 onMoving: function onMoving(item, callback) {
38707 callback(item);
38708 },
38709 onAddGroup: function onAddGroup(item, callback) {
38710 callback(item);
38711 },
38712 onMoveGroup: function onMoveGroup(item, callback) {
38713 callback(item);
38714 },
38715 onRemoveGroup: function onRemoveGroup(item, callback) {
38716 callback(item);
38717 },
38718 margin: {
38719 item: {
38720 horizontal: 10,
38721 vertical: 10
38722 },
38723 axis: 20
38724 },
38725 showTooltips: true,
38726 tooltip: {
38727 followMouse: false,
38728 overflowMethod: 'flip',
38729 delay: 500
38730 },
38731 tooltipOnItemUpdateTime: false
38732 }; // options is shared by this ItemSet and all its items
38733
38734 _this.options = util.extend({}, _this.defaultOptions);
38735 _this.options.rtl = options.rtl;
38736 _this.options.onTimeout = options.onTimeout; // options for getting items from the DataSet with the correct type
38737
38738 _this.itemOptions = {
38739 type: {
38740 start: 'Date',
38741 end: 'Date'
38742 }
38743 };
38744 _this.conversion = {
38745 toScreen: body.util.toScreen,
38746 toTime: body.util.toTime
38747 };
38748 _this.dom = {};
38749 _this.props = {};
38750 _this.hammer = null;
38751
38752 var me = _assertThisInitialized(_this);
38753
38754 _this.itemsData = null; // DataSet
38755
38756 _this.groupsData = null; // DataSet
38757
38758 _this.itemsSettingTime = null;
38759 _this.initialItemSetDrawn = false;
38760 _this.userContinueNotBail = null;
38761 _this.sequentialSelection = false; // listeners for the DataSet of the items
38762
38763 _this.itemListeners = {
38764 'add': function add(event, params, senderId) {
38765 // eslint-disable-line no-unused-vars
38766 me._onAdd(params.items);
38767
38768 if (me.options.cluster) {
38769 me.clusterGenerator.setItems(me.items, {
38770 applyOnChangedLevel: false
38771 });
38772 }
38773
38774 me.redraw();
38775 },
38776 'update': function update(event, params, senderId) {
38777 // eslint-disable-line no-unused-vars
38778 me._onUpdate(params.items);
38779
38780 if (me.options.cluster) {
38781 me.clusterGenerator.setItems(me.items, {
38782 applyOnChangedLevel: false
38783 });
38784 }
38785
38786 me.redraw();
38787 },
38788 'remove': function remove(event, params, senderId) {
38789 // eslint-disable-line no-unused-vars
38790 me._onRemove(params.items);
38791
38792 if (me.options.cluster) {
38793 me.clusterGenerator.setItems(me.items, {
38794 applyOnChangedLevel: false
38795 });
38796 }
38797
38798 me.redraw();
38799 }
38800 }; // listeners for the DataSet of the groups
38801
38802 _this.groupListeners = {
38803 'add': function add(event, params, senderId) {
38804 // eslint-disable-line no-unused-vars
38805 me._onAddGroups(params.items);
38806
38807 if (me.groupsData && me.groupsData.length > 0) {
38808 var groupsData = me.groupsData.getDataSet();
38809 groupsData.get().forEach(function (groupData) {
38810 if (groupData.nestedGroups) {
38811 if (groupData.showNested != false) {
38812 groupData.showNested = true;
38813 }
38814
38815 var updatedGroups = [];
38816 groupData.nestedGroups.forEach(function (nestedGroupId) {
38817 var updatedNestedGroup = groupsData.get(nestedGroupId);
38818
38819 if (!updatedNestedGroup) {
38820 return;
38821 }
38822
38823 updatedNestedGroup.nestedInGroup = groupData.id;
38824
38825 if (groupData.showNested == false) {
38826 updatedNestedGroup.visible = false;
38827 }
38828
38829 updatedGroups = updatedGroups.concat(updatedNestedGroup);
38830 });
38831 groupsData.update(updatedGroups, senderId);
38832 }
38833 });
38834 }
38835 },
38836 'update': function update(event, params, senderId) {
38837 // eslint-disable-line no-unused-vars
38838 me._onUpdateGroups(params.items);
38839 },
38840 'remove': function remove(event, params, senderId) {
38841 // eslint-disable-line no-unused-vars
38842 me._onRemoveGroups(params.items);
38843 }
38844 };
38845 _this.items = {}; // object with an Item for every data item
38846
38847 _this.groups = {}; // Group object for every group
38848
38849 _this.groupIds = [];
38850 _this.selection = []; // list with the ids of all selected nodes
38851
38852 _this.popup = null;
38853 _this.popupTimer = null;
38854 _this.touchParams = {}; // stores properties while dragging
38855
38856 _this.groupTouchParams = {
38857 group: null,
38858 isDragging: false
38859 }; // create the HTML DOM
38860
38861 _this._create();
38862
38863 _this.setOptions(options);
38864
38865 _this.clusters = [];
38866 return _this;
38867 }
38868 /**
38869 * Create the HTML DOM for the ItemSet
38870 */
38871
38872
38873 _createClass(ItemSet, [{
38874 key: "_create",
38875 value: function _create() {
38876 var _this2 = this;
38877
38878 var frame = document.createElement('div');
38879 frame.className = 'vis-itemset';
38880 frame['vis-itemset'] = this;
38881 this.dom.frame = frame; // create background panel
38882
38883 var background = document.createElement('div');
38884 background.className = 'vis-background';
38885 frame.appendChild(background);
38886 this.dom.background = background; // create foreground panel
38887
38888 var foreground = document.createElement('div');
38889 foreground.className = 'vis-foreground';
38890 frame.appendChild(foreground);
38891 this.dom.foreground = foreground; // create axis panel
38892
38893 var axis = document.createElement('div');
38894 axis.className = 'vis-axis';
38895 this.dom.axis = axis; // create labelset
38896
38897 var labelSet = document.createElement('div');
38898 labelSet.className = 'vis-labelset';
38899 this.dom.labelSet = labelSet; // create ungrouped Group
38900
38901 this._updateUngrouped(); // create background Group
38902
38903
38904 var backgroundGroup = new BackgroundGroup(BACKGROUND$2, null, this);
38905 backgroundGroup.show();
38906 this.groups[BACKGROUND$2] = backgroundGroup; // attach event listeners
38907 // Note: we bind to the centerContainer for the case where the height
38908 // of the center container is larger than of the ItemSet, so we
38909 // can click in the empty area to create a new item or deselect an item.
38910
38911 this.hammer = new Hammer$1(this.body.dom.centerContainer); // drag items when selected
38912
38913 this.hammer.on('hammer.input', function (event) {
38914 if (event.isFirst) {
38915 _this2._onTouch(event);
38916 }
38917 });
38918 this.hammer.on('panstart', this._onDragStart.bind(this));
38919 this.hammer.on('panmove', this._onDrag.bind(this));
38920 this.hammer.on('panend', this._onDragEnd.bind(this));
38921 this.hammer.get('pan').set({
38922 threshold: 5,
38923 direction: Hammer$1.ALL
38924 }); // single select (or unselect) when tapping an item
38925
38926 this.hammer.on('tap', this._onSelectItem.bind(this)); // multi select when holding mouse/touch, or on ctrl+click
38927
38928 this.hammer.on('press', this._onMultiSelectItem.bind(this)); // add item on doubletap
38929
38930 this.hammer.on('doubletap', this._onAddItem.bind(this));
38931
38932 if (this.options.rtl) {
38933 this.groupHammer = new Hammer$1(this.body.dom.rightContainer);
38934 } else {
38935 this.groupHammer = new Hammer$1(this.body.dom.leftContainer);
38936 }
38937
38938 this.groupHammer.on('tap', this._onGroupClick.bind(this));
38939 this.groupHammer.on('panstart', this._onGroupDragStart.bind(this));
38940 this.groupHammer.on('panmove', this._onGroupDrag.bind(this));
38941 this.groupHammer.on('panend', this._onGroupDragEnd.bind(this));
38942 this.groupHammer.get('pan').set({
38943 threshold: 5,
38944 direction: Hammer$1.DIRECTION_VERTICAL
38945 });
38946 this.body.dom.centerContainer.addEventListener('mouseover', this._onMouseOver.bind(this));
38947 this.body.dom.centerContainer.addEventListener('mouseout', this._onMouseOut.bind(this));
38948 this.body.dom.centerContainer.addEventListener('mousemove', this._onMouseMove.bind(this)); // right-click on timeline
38949
38950 this.body.dom.centerContainer.addEventListener('contextmenu', this._onDragEnd.bind(this));
38951 this.body.dom.centerContainer.addEventListener('mousewheel', this._onMouseWheel.bind(this)); // attach to the DOM
38952
38953 this.show();
38954 }
38955 /**
38956 * Set options for the ItemSet. Existing options will be extended/overwritten.
38957 * @param {Object} [options] The following options are available:
38958 * {string} type
38959 * Default type for the items. Choose from 'box'
38960 * (default), 'point', 'range', or 'background'.
38961 * The default style can be overwritten by
38962 * individual items.
38963 * {string} align
38964 * Alignment for the items, only applicable for
38965 * BoxItem. Choose 'center' (default), 'left', or
38966 * 'right'.
38967 * {string} orientation.item
38968 * Orientation of the item set. Choose 'top' or
38969 * 'bottom' (default).
38970 * {Function} groupOrder
38971 * A sorting function for ordering groups
38972 * {boolean} stack
38973 * If true (default), items will be stacked on
38974 * top of each other.
38975 * {number} margin.axis
38976 * Margin between the axis and the items in pixels.
38977 * Default is 20.
38978 * {number} margin.item.horizontal
38979 * Horizontal margin between items in pixels.
38980 * Default is 10.
38981 * {number} margin.item.vertical
38982 * Vertical Margin between items in pixels.
38983 * Default is 10.
38984 * {number} margin.item
38985 * Margin between items in pixels in both horizontal
38986 * and vertical direction. Default is 10.
38987 * {number} margin
38988 * Set margin for both axis and items in pixels.
38989 * {boolean} selectable
38990 * If true (default), items can be selected.
38991 * {boolean} multiselect
38992 * If true, multiple items can be selected.
38993 * False by default.
38994 * {boolean} editable
38995 * Set all editable options to true or false
38996 * {boolean} editable.updateTime
38997 * Allow dragging an item to an other moment in time
38998 * {boolean} editable.updateGroup
38999 * Allow dragging an item to an other group
39000 * {boolean} editable.add
39001 * Allow creating new items on double tap
39002 * {boolean} editable.remove
39003 * Allow removing items by clicking the delete button
39004 * top right of a selected item.
39005 * {Function(item: Item, callback: Function)} onAdd
39006 * Callback function triggered when an item is about to be added:
39007 * when the user double taps an empty space in the Timeline.
39008 * {Function(item: Item, callback: Function)} onUpdate
39009 * Callback function fired when an item is about to be updated.
39010 * This function typically has to show a dialog where the user
39011 * change the item. If not implemented, nothing happens.
39012 * {Function(item: Item, callback: Function)} onMove
39013 * Fired when an item has been moved. If not implemented,
39014 * the move action will be accepted.
39015 * {Function(item: Item, callback: Function)} onRemove
39016 * Fired when an item is about to be deleted.
39017 * If not implemented, the item will be always removed.
39018 */
39019
39020 }, {
39021 key: "setOptions",
39022 value: function setOptions(options) {
39023 var _this3 = this;
39024
39025 if (options) {
39026 // copy all options that we know
39027 var fields = ['type', 'rtl', 'align', 'order', 'stack', 'stackSubgroups', 'selectable', 'multiselect', 'sequentialSelection', 'multiselectPerGroup', 'groupOrder', 'dataAttributes', 'template', 'groupTemplate', 'visibleFrameTemplate', 'hide', 'snap', 'groupOrderSwap', 'showTooltips', 'tooltip', 'tooltipOnItemUpdateTime', 'groupHeightMode', 'onTimeout'];
39028 util.selectiveExtend(fields, this.options, options);
39029
39030 if ('itemsAlwaysDraggable' in options) {
39031 if (typeof options.itemsAlwaysDraggable === 'boolean') {
39032 this.options.itemsAlwaysDraggable.item = options.itemsAlwaysDraggable;
39033 this.options.itemsAlwaysDraggable.range = false;
39034 } else if (_typeof(options.itemsAlwaysDraggable) === 'object') {
39035 util.selectiveExtend(['item', 'range'], this.options.itemsAlwaysDraggable, options.itemsAlwaysDraggable); // only allow range always draggable when item is always draggable as well
39036
39037 if (!this.options.itemsAlwaysDraggable.item) {
39038 this.options.itemsAlwaysDraggable.range = false;
39039 }
39040 }
39041 }
39042
39043 if ('sequentialSelection' in options) {
39044 if (typeof options.sequentialSelection === 'boolean') {
39045 this.options.sequentialSelection = options.sequentialSelection;
39046 }
39047 }
39048
39049 if ('orientation' in options) {
39050 if (typeof options.orientation === 'string') {
39051 this.options.orientation.item = options.orientation === 'top' ? 'top' : 'bottom';
39052 } else if (_typeof(options.orientation) === 'object' && 'item' in options.orientation) {
39053 this.options.orientation.item = options.orientation.item;
39054 }
39055 }
39056
39057 if ('margin' in options) {
39058 if (typeof options.margin === 'number') {
39059 this.options.margin.axis = options.margin;
39060 this.options.margin.item.horizontal = options.margin;
39061 this.options.margin.item.vertical = options.margin;
39062 } else if (_typeof(options.margin) === 'object') {
39063 util.selectiveExtend(['axis'], this.options.margin, options.margin);
39064
39065 if ('item' in options.margin) {
39066 if (typeof options.margin.item === 'number') {
39067 this.options.margin.item.horizontal = options.margin.item;
39068 this.options.margin.item.vertical = options.margin.item;
39069 } else if (_typeof(options.margin.item) === 'object') {
39070 util.selectiveExtend(['horizontal', 'vertical'], this.options.margin.item, options.margin.item);
39071 }
39072 }
39073 }
39074 }
39075
39076 ['locale', 'locales'].forEach(function (key) {
39077 if (key in options) {
39078 _this3.options[key] = options[key];
39079 }
39080 });
39081
39082 if ('editable' in options) {
39083 if (typeof options.editable === 'boolean') {
39084 this.options.editable.updateTime = options.editable;
39085 this.options.editable.updateGroup = options.editable;
39086 this.options.editable.add = options.editable;
39087 this.options.editable.remove = options.editable;
39088 this.options.editable.overrideItems = false;
39089 } else if (_typeof(options.editable) === 'object') {
39090 util.selectiveExtend(['updateTime', 'updateGroup', 'add', 'remove', 'overrideItems'], this.options.editable, options.editable);
39091 }
39092 }
39093
39094 if ('groupEditable' in options) {
39095 if (typeof options.groupEditable === 'boolean') {
39096 this.options.groupEditable.order = options.groupEditable;
39097 this.options.groupEditable.add = options.groupEditable;
39098 this.options.groupEditable.remove = options.groupEditable;
39099 } else if (_typeof(options.groupEditable) === 'object') {
39100 util.selectiveExtend(['order', 'add', 'remove'], this.options.groupEditable, options.groupEditable);
39101 }
39102 } // callback functions
39103
39104
39105 var addCallback = function addCallback(name) {
39106 var fn = options[name];
39107
39108 if (fn) {
39109 if (!(typeof fn === 'function')) {
39110 throw new Error("option ".concat(name, " must be a function ").concat(name, "(item, callback)"));
39111 }
39112
39113 _this3.options[name] = fn;
39114 }
39115 };
39116
39117 ['onDropObjectOnItem', 'onAdd', 'onUpdate', 'onRemove', 'onMove', 'onMoving', 'onAddGroup', 'onMoveGroup', 'onRemoveGroup'].forEach(addCallback);
39118
39119 if (options.cluster) {
39120 Object.assign(this.options, {
39121 cluster: options.cluster
39122 });
39123
39124 if (!this.clusterGenerator) {
39125 this.clusterGenerator = new ClusterGenerator(this);
39126 }
39127
39128 this.clusterGenerator.setItems(this.items, {
39129 applyOnChangedLevel: false
39130 });
39131 this.markDirty({
39132 refreshItems: true,
39133 restackGroups: true
39134 });
39135 this.redraw();
39136 } else if (this.clusterGenerator) {
39137 this._detachAllClusters();
39138
39139 this.clusters = [];
39140 this.clusterGenerator = null;
39141 this.options.cluster = undefined;
39142 this.markDirty({
39143 refreshItems: true,
39144 restackGroups: true
39145 });
39146 this.redraw();
39147 } else {
39148 // force the itemSet to refresh: options like orientation and margins may be changed
39149 this.markDirty();
39150 }
39151 }
39152 }
39153 /**
39154 * Mark the ItemSet dirty so it will refresh everything with next redraw.
39155 * Optionally, all items can be marked as dirty and be refreshed.
39156 * @param {{refreshItems: boolean}} [options]
39157 */
39158
39159 }, {
39160 key: "markDirty",
39161 value: function markDirty(options) {
39162 this.groupIds = [];
39163
39164 if (options) {
39165 if (options.refreshItems) {
39166 util.forEach(this.items, function (item) {
39167 item.dirty = true;
39168 if (item.displayed) item.redraw();
39169 });
39170 }
39171
39172 if (options.restackGroups) {
39173 util.forEach(this.groups, function (group, key) {
39174 if (key === BACKGROUND$2) return;
39175 group.stackDirty = true;
39176 });
39177 }
39178 }
39179 }
39180 /**
39181 * Destroy the ItemSet
39182 */
39183
39184 }, {
39185 key: "destroy",
39186 value: function destroy() {
39187 this.clearPopupTimer();
39188 this.hide();
39189 this.setItems(null);
39190 this.setGroups(null);
39191 this.hammer && this.hammer.destroy();
39192 this.groupHammer && this.groupHammer.destroy();
39193 this.hammer = null;
39194 this.body = null;
39195 this.conversion = null;
39196 }
39197 /**
39198 * Hide the component from the DOM
39199 */
39200
39201 }, {
39202 key: "hide",
39203 value: function hide() {
39204 // remove the frame containing the items
39205 if (this.dom.frame.parentNode) {
39206 this.dom.frame.parentNode.removeChild(this.dom.frame);
39207 } // remove the axis with dots
39208
39209
39210 if (this.dom.axis.parentNode) {
39211 this.dom.axis.parentNode.removeChild(this.dom.axis);
39212 } // remove the labelset containing all group labels
39213
39214
39215 if (this.dom.labelSet.parentNode) {
39216 this.dom.labelSet.parentNode.removeChild(this.dom.labelSet);
39217 }
39218 }
39219 /**
39220 * Show the component in the DOM (when not already visible).
39221 */
39222
39223 }, {
39224 key: "show",
39225 value: function show() {
39226 // show frame containing the items
39227 if (!this.dom.frame.parentNode) {
39228 this.body.dom.center.appendChild(this.dom.frame);
39229 } // show axis with dots
39230
39231
39232 if (!this.dom.axis.parentNode) {
39233 this.body.dom.backgroundVertical.appendChild(this.dom.axis);
39234 } // show labelset containing labels
39235
39236
39237 if (!this.dom.labelSet.parentNode) {
39238 if (this.options.rtl) {
39239 this.body.dom.right.appendChild(this.dom.labelSet);
39240 } else {
39241 this.body.dom.left.appendChild(this.dom.labelSet);
39242 }
39243 }
39244 }
39245 /**
39246 * Activates the popup timer to show the given popup after a fixed time.
39247 * @param {Popup} popup
39248 */
39249
39250 }, {
39251 key: "setPopupTimer",
39252 value: function setPopupTimer(popup) {
39253 this.clearPopupTimer();
39254
39255 if (popup) {
39256 var delay = this.options.tooltip.delay || typeof this.options.tooltip.delay === 'number' ? this.options.tooltip.delay : 500;
39257 this.popupTimer = setTimeout(function () {
39258 popup.show();
39259 }, delay);
39260 }
39261 }
39262 /**
39263 * Clears the popup timer for the tooltip.
39264 */
39265
39266 }, {
39267 key: "clearPopupTimer",
39268 value: function clearPopupTimer() {
39269 if (this.popupTimer != null) {
39270 clearTimeout(this.popupTimer);
39271 this.popupTimer = null;
39272 }
39273 }
39274 /**
39275 * Set selected items by their id. Replaces the current selection
39276 * Unknown id's are silently ignored.
39277 * @param {string[] | string} [ids] An array with zero or more id's of the items to be
39278 * selected, or a single item id. If ids is undefined
39279 * or an empty array, all items will be unselected.
39280 */
39281
39282 }, {
39283 key: "setSelection",
39284 value: function setSelection(ids) {
39285 if (ids == undefined) {
39286 ids = [];
39287 }
39288
39289 if (!Array.isArray(ids)) {
39290 ids = [ids];
39291 }
39292
39293 var idsToDeselect = this.selection.filter(function (id) {
39294 return ids.indexOf(id) === -1;
39295 }); // unselect currently selected items
39296
39297 var _iteratorNormalCompletion = true;
39298 var _didIteratorError = false;
39299 var _iteratorError = undefined;
39300
39301 try {
39302 for (var _iterator = idsToDeselect[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
39303 var selectedId = _step.value;
39304 var item = this.getItemById(selectedId);
39305
39306 if (item) {
39307 item.unselect();
39308 }
39309 } // select items
39310
39311 } catch (err) {
39312 _didIteratorError = true;
39313 _iteratorError = err;
39314 } finally {
39315 try {
39316 if (!_iteratorNormalCompletion && _iterator.return != null) {
39317 _iterator.return();
39318 }
39319 } finally {
39320 if (_didIteratorError) {
39321 throw _iteratorError;
39322 }
39323 }
39324 }
39325
39326 this.selection = _toConsumableArray(ids);
39327 var _iteratorNormalCompletion2 = true;
39328 var _didIteratorError2 = false;
39329 var _iteratorError2 = undefined;
39330
39331 try {
39332 for (var _iterator2 = ids[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
39333 var id = _step2.value;
39334
39335 var _item2 = this.getItemById(id);
39336
39337 if (_item2) {
39338 _item2.select();
39339 }
39340 }
39341 } catch (err) {
39342 _didIteratorError2 = true;
39343 _iteratorError2 = err;
39344 } finally {
39345 try {
39346 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
39347 _iterator2.return();
39348 }
39349 } finally {
39350 if (_didIteratorError2) {
39351 throw _iteratorError2;
39352 }
39353 }
39354 }
39355 }
39356 /**
39357 * Get the selected items by their id
39358 * @return {Array} ids The ids of the selected items
39359 */
39360
39361 }, {
39362 key: "getSelection",
39363 value: function getSelection() {
39364 return this.selection.concat([]);
39365 }
39366 /**
39367 * Get the id's of the currently visible items.
39368 * @returns {Array} The ids of the visible items
39369 */
39370
39371 }, {
39372 key: "getVisibleItems",
39373 value: function getVisibleItems() {
39374 var range = this.body.range.getRange();
39375 var right;
39376 var left;
39377
39378 if (this.options.rtl) {
39379 right = this.body.util.toScreen(range.start);
39380 left = this.body.util.toScreen(range.end);
39381 } else {
39382 left = this.body.util.toScreen(range.start);
39383 right = this.body.util.toScreen(range.end);
39384 }
39385
39386 var ids = [];
39387
39388 for (var groupId in this.groups) {
39389 if (this.groups.hasOwnProperty(groupId)) {
39390 var group = this.groups[groupId];
39391 var rawVisibleItems = group.isVisible ? group.visibleItems : []; // filter the "raw" set with visibleItems into a set which is really
39392 // visible by pixels
39393
39394 var _iteratorNormalCompletion3 = true;
39395 var _didIteratorError3 = false;
39396 var _iteratorError3 = undefined;
39397
39398 try {
39399 for (var _iterator3 = rawVisibleItems[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
39400 var item = _step3.value;
39401
39402 // TODO: also check whether visible vertically
39403 if (this.options.rtl) {
39404 if (item.right < left && item.right + item.width > right) {
39405 ids.push(item.id);
39406 }
39407 } else {
39408 if (item.left < right && item.left + item.width > left) {
39409 ids.push(item.id);
39410 }
39411 }
39412 }
39413 } catch (err) {
39414 _didIteratorError3 = true;
39415 _iteratorError3 = err;
39416 } finally {
39417 try {
39418 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
39419 _iterator3.return();
39420 }
39421 } finally {
39422 if (_didIteratorError3) {
39423 throw _iteratorError3;
39424 }
39425 }
39426 }
39427 }
39428 }
39429
39430 return ids;
39431 }
39432 /**
39433 * Get the id's of the currently visible groups.
39434 * @returns {Array} The ids of the visible groups
39435 */
39436
39437 }, {
39438 key: "getVisibleGroups",
39439 value: function getVisibleGroups() {
39440 var ids = [];
39441
39442 for (var groupId in this.groups) {
39443 if (this.groups.hasOwnProperty(groupId)) {
39444 var group = this.groups[groupId];
39445
39446 if (group.isVisible) {
39447 ids.push(groupId);
39448 }
39449 }
39450 }
39451
39452 return ids;
39453 }
39454 /**
39455 * get item by id
39456 * @param {string} id
39457 * @return {object} item
39458 */
39459
39460 }, {
39461 key: "getItemById",
39462 value: function getItemById(id) {
39463 return this.items[id] || this.clusters.find(function (cluster) {
39464 return cluster.id === id;
39465 });
39466 }
39467 /**
39468 * Deselect a selected item
39469 * @param {string | number} id
39470 * @private
39471 */
39472
39473 }, {
39474 key: "_deselect",
39475 value: function _deselect(id) {
39476 var selection = this.selection;
39477
39478 for (var i = 0, ii = selection.length; i < ii; i++) {
39479 if (selection[i] == id) {
39480 // non-strict comparison!
39481 selection.splice(i, 1);
39482 break;
39483 }
39484 }
39485 }
39486 /**
39487 * Repaint the component
39488 * @return {boolean} Returns true if the component is resized
39489 */
39490
39491 }, {
39492 key: "redraw",
39493 value: function redraw() {
39494 var _this4 = this;
39495
39496 var margin = this.options.margin;
39497 var range = this.body.range;
39498 var asSize = util.option.asSize;
39499 var options = this.options;
39500 var orientation = options.orientation.item;
39501 var resized = false;
39502 var frame = this.dom.frame; // recalculate absolute position (before redrawing groups)
39503
39504 this.props.top = this.body.domProps.top.height + this.body.domProps.border.top;
39505
39506 if (this.options.rtl) {
39507 this.props.right = this.body.domProps.right.width + this.body.domProps.border.right;
39508 } else {
39509 this.props.left = this.body.domProps.left.width + this.body.domProps.border.left;
39510 } // update class name
39511
39512
39513 frame.className = 'vis-itemset';
39514
39515 if (this.options.cluster) {
39516 this._clusterItems();
39517 } // reorder the groups (if needed)
39518
39519
39520 resized = this._orderGroups() || resized; // check whether zoomed (in that case we need to re-stack everything)
39521 // TODO: would be nicer to get this as a trigger from Range
39522
39523 var visibleInterval = range.end - range.start;
39524 var zoomed = visibleInterval != this.lastVisibleInterval || this.props.width != this.props.lastWidth;
39525 var scrolled = range.start != this.lastRangeStart;
39526 var changedStackOption = options.stack != this.lastStack;
39527 var changedStackSubgroupsOption = options.stackSubgroups != this.lastStackSubgroups;
39528 var forceRestack = zoomed || scrolled || changedStackOption || changedStackSubgroupsOption;
39529 this.lastVisibleInterval = visibleInterval;
39530 this.lastRangeStart = range.start;
39531 this.lastStack = options.stack;
39532 this.lastStackSubgroups = options.stackSubgroups;
39533 this.props.lastWidth = this.props.width;
39534
39535 var firstGroup = this._firstGroup();
39536
39537 var firstMargin = {
39538 item: margin.item,
39539 axis: margin.axis
39540 };
39541 var nonFirstMargin = {
39542 item: margin.item,
39543 axis: margin.item.vertical / 2
39544 };
39545 var height = 0;
39546 var minHeight = margin.axis + margin.item.vertical; // redraw the background group
39547
39548 this.groups[BACKGROUND$2].redraw(range, nonFirstMargin, forceRestack);
39549 var redrawQueue = {};
39550 var redrawQueueLength = 0; // collect redraw functions
39551
39552 util.forEach(this.groups, function (group, key) {
39553 if (key === BACKGROUND$2) return;
39554 var groupMargin = group == firstGroup ? firstMargin : nonFirstMargin;
39555 var returnQueue = true;
39556 redrawQueue[key] = group.redraw(range, groupMargin, forceRestack, returnQueue);
39557 redrawQueueLength = redrawQueue[key].length;
39558 });
39559 var needRedraw = redrawQueueLength > 0;
39560
39561 if (needRedraw) {
39562 (function () {
39563 var redrawResults = {};
39564
39565 var _loop = function _loop(i) {
39566 util.forEach(redrawQueue, function (fns, key) {
39567 redrawResults[key] = fns[i]();
39568 });
39569 };
39570
39571 for (var i = 0; i < redrawQueueLength; i++) {
39572 _loop(i);
39573 } // redraw all regular groups
39574
39575
39576 util.forEach(_this4.groups, function (group, key) {
39577 if (key === BACKGROUND$2) return;
39578 var groupResized = redrawResults[key];
39579 resized = groupResized || resized;
39580 height += group.height;
39581 });
39582 height = Math.max(height, minHeight);
39583 })();
39584 }
39585
39586 height = Math.max(height, minHeight); // update frame height
39587
39588 frame.style.height = asSize(height); // calculate actual size
39589
39590 this.props.width = frame.offsetWidth;
39591 this.props.height = height; // reposition axis
39592
39593 this.dom.axis.style.top = asSize(orientation == 'top' ? this.body.domProps.top.height + this.body.domProps.border.top : this.body.domProps.top.height + this.body.domProps.centerContainer.height);
39594
39595 if (this.options.rtl) {
39596 this.dom.axis.style.right = '0';
39597 } else {
39598 this.dom.axis.style.left = '0';
39599 }
39600
39601 this.initialItemSetDrawn = true; // check if this component is resized
39602
39603 resized = this._isResized() || resized;
39604 return resized;
39605 }
39606 /**
39607 * Get the first group, aligned with the axis
39608 * @return {Group | null} firstGroup
39609 * @private
39610 */
39611
39612 }, {
39613 key: "_firstGroup",
39614 value: function _firstGroup() {
39615 var firstGroupIndex = this.options.orientation.item == 'top' ? 0 : this.groupIds.length - 1;
39616 var firstGroupId = this.groupIds[firstGroupIndex];
39617 var firstGroup = this.groups[firstGroupId] || this.groups[UNGROUPED$2];
39618 return firstGroup || null;
39619 }
39620 /**
39621 * Create or delete the group holding all ungrouped items. This group is used when
39622 * there are no groups specified.
39623 * @protected
39624 */
39625
39626 }, {
39627 key: "_updateUngrouped",
39628 value: function _updateUngrouped() {
39629 var ungrouped = this.groups[UNGROUPED$2];
39630 var item;
39631 var itemId;
39632
39633 if (this.groupsData) {
39634 // remove the group holding all ungrouped items
39635 if (ungrouped) {
39636 ungrouped.hide();
39637 delete this.groups[UNGROUPED$2];
39638
39639 for (itemId in this.items) {
39640 if (this.items.hasOwnProperty(itemId)) {
39641 item = this.items[itemId];
39642 item.parent && item.parent.remove(item);
39643 var groupId = this.getGroupId(item.data);
39644 var group = this.groups[groupId];
39645 group && group.add(item) || item.hide();
39646 }
39647 }
39648 }
39649 } else {
39650 // create a group holding all (unfiltered) items
39651 if (!ungrouped) {
39652 var id = null;
39653 var data = null;
39654 ungrouped = new Group(id, data, this);
39655 this.groups[UNGROUPED$2] = ungrouped;
39656
39657 for (itemId in this.items) {
39658 if (this.items.hasOwnProperty(itemId)) {
39659 item = this.items[itemId];
39660 ungrouped.add(item);
39661 }
39662 }
39663
39664 ungrouped.show();
39665 }
39666 }
39667 }
39668 /**
39669 * Get the element for the labelset
39670 * @return {HTMLElement} labelSet
39671 */
39672
39673 }, {
39674 key: "getLabelSet",
39675 value: function getLabelSet() {
39676 return this.dom.labelSet;
39677 }
39678 /**
39679 * Set items
39680 * @param {vis.DataSet | null} items
39681 */
39682
39683 }, {
39684 key: "setItems",
39685 value: function setItems(items) {
39686 this.itemsSettingTime = new Date();
39687 var me = this;
39688 var ids;
39689 var oldItemsData = this.itemsData; // replace the dataset
39690
39691 if (!items) {
39692 this.itemsData = null;
39693 } else if (items instanceof DataSet || items instanceof DataView$2) {
39694 this.itemsData = items;
39695 } else {
39696 throw new TypeError('Data must be an instance of DataSet or DataView');
39697 }
39698
39699 if (oldItemsData) {
39700 // unsubscribe from old dataset
39701 util.forEach(this.itemListeners, function (callback, event) {
39702 oldItemsData.off(event, callback);
39703 }); // remove all drawn items
39704
39705 ids = oldItemsData.getIds();
39706
39707 this._onRemove(ids);
39708 }
39709
39710 if (this.itemsData) {
39711 // subscribe to new dataset
39712 var id = this.id;
39713 util.forEach(this.itemListeners, function (callback, event) {
39714 me.itemsData.on(event, callback, id);
39715 }); // add all new items
39716
39717 ids = this.itemsData.getIds();
39718
39719 this._onAdd(ids); // update the group holding all ungrouped items
39720
39721
39722 this._updateUngrouped();
39723 }
39724
39725 this.body.emitter.emit('_change', {
39726 queue: true
39727 });
39728 }
39729 /**
39730 * Get the current items
39731 * @returns {vis.DataSet | null}
39732 */
39733
39734 }, {
39735 key: "getItems",
39736 value: function getItems() {
39737 return this.itemsData;
39738 }
39739 /**
39740 * Set groups
39741 * @param {vis.DataSet} groups
39742 */
39743
39744 }, {
39745 key: "setGroups",
39746 value: function setGroups(groups) {
39747 var me = this;
39748 var ids; // unsubscribe from current dataset
39749
39750 if (this.groupsData) {
39751 util.forEach(this.groupListeners, function (callback, event) {
39752 me.groupsData.off(event, callback);
39753 }); // remove all drawn groups
39754
39755 ids = this.groupsData.getIds();
39756 this.groupsData = null;
39757
39758 this._onRemoveGroups(ids); // note: this will cause a redraw
39759
39760 } // replace the dataset
39761
39762
39763 if (!groups) {
39764 this.groupsData = null;
39765 } else if (groups instanceof DataSet || groups instanceof DataView$2) {
39766 this.groupsData = groups;
39767 } else {
39768 throw new TypeError('Data must be an instance of DataSet or DataView');
39769 }
39770
39771 if (this.groupsData) {
39772 // go over all groups nesting
39773 var groupsData = this.groupsData;
39774
39775 if (this.groupsData instanceof DataView$2) {
39776 groupsData = this.groupsData.getDataSet();
39777 }
39778
39779 groupsData.get().forEach(function (group) {
39780 if (group.nestedGroups) {
39781 group.nestedGroups.forEach(function (nestedGroupId) {
39782 var updatedNestedGroup = groupsData.get(nestedGroupId);
39783 updatedNestedGroup.nestedInGroup = group.id;
39784
39785 if (group.showNested == false) {
39786 updatedNestedGroup.visible = false;
39787 }
39788
39789 groupsData.update(updatedNestedGroup);
39790 });
39791 }
39792 }); // subscribe to new dataset
39793
39794 var id = this.id;
39795 util.forEach(this.groupListeners, function (callback, event) {
39796 me.groupsData.on(event, callback, id);
39797 }); // draw all ms
39798
39799 ids = this.groupsData.getIds();
39800
39801 this._onAddGroups(ids);
39802 } // update the group holding all ungrouped items
39803
39804
39805 this._updateUngrouped(); // update the order of all items in each group
39806
39807
39808 this._order();
39809
39810 if (this.options.cluster) {
39811 this.clusterGenerator.updateData();
39812
39813 this._clusterItems();
39814
39815 this.markDirty({
39816 refreshItems: true,
39817 restackGroups: true
39818 });
39819 }
39820
39821 this.body.emitter.emit('_change', {
39822 queue: true
39823 });
39824 }
39825 /**
39826 * Get the current groups
39827 * @returns {vis.DataSet | null} groups
39828 */
39829
39830 }, {
39831 key: "getGroups",
39832 value: function getGroups() {
39833 return this.groupsData;
39834 }
39835 /**
39836 * Remove an item by its id
39837 * @param {string | number} id
39838 */
39839
39840 }, {
39841 key: "removeItem",
39842 value: function removeItem(id) {
39843 var item = this.itemsData.get(id);
39844 var dataset = this.itemsData.getDataSet();
39845
39846 if (item) {
39847 // confirm deletion
39848 this.options.onRemove(item, function (item) {
39849 if (item) {
39850 // remove by id here, it is possible that an item has no id defined
39851 // itself, so better not delete by the item itself
39852 dataset.remove(id);
39853 }
39854 });
39855 }
39856 }
39857 /**
39858 * Get the time of an item based on it's data and options.type
39859 * @param {Object} itemData
39860 * @returns {string} Returns the type
39861 * @private
39862 */
39863
39864 }, {
39865 key: "_getType",
39866 value: function _getType(itemData) {
39867 return itemData.type || this.options.type || (itemData.end ? 'range' : 'box');
39868 }
39869 /**
39870 * Get the group id for an item
39871 * @param {Object} itemData
39872 * @returns {string} Returns the groupId
39873 * @private
39874 */
39875
39876 }, {
39877 key: "getGroupId",
39878 value: function getGroupId(itemData) {
39879 var type = this._getType(itemData);
39880
39881 if (type == 'background' && itemData.group == undefined) {
39882 return BACKGROUND$2;
39883 } else {
39884 return this.groupsData ? itemData.group : UNGROUPED$2;
39885 }
39886 }
39887 /**
39888 * Handle updated items
39889 * @param {number[]} ids
39890 * @protected
39891 */
39892
39893 }, {
39894 key: "_onUpdate",
39895 value: function _onUpdate(ids) {
39896 var _this5 = this;
39897
39898 var me = this;
39899 ids.forEach(function (id) {
39900 var itemData = me.itemsData.get(id, me.itemOptions);
39901 var item = me.items[id];
39902 var type = itemData ? me._getType(itemData) : null;
39903 var constructor = ItemSet.types[type];
39904 var selected;
39905
39906 if (item) {
39907 // update item
39908 if (!constructor || !(item instanceof constructor)) {
39909 // item type has changed, delete the item and recreate it
39910 selected = item.selected; // preserve selection of this item
39911
39912 me._removeItem(item);
39913
39914 item = null;
39915 } else {
39916 me._updateItem(item, itemData);
39917 }
39918 }
39919
39920 if (!item && itemData) {
39921 // create item
39922 if (constructor) {
39923 item = new constructor(itemData, me.conversion, me.options);
39924 item.id = id; // TODO: not so nice setting id afterwards
39925
39926 me._addItem(item);
39927
39928 if (selected) {
39929 _this5.selection.push(id);
39930
39931 item.select();
39932 }
39933 } else {
39934 throw new TypeError("Unknown item type \"".concat(type, "\""));
39935 }
39936 }
39937 });
39938
39939 this._order();
39940
39941 if (this.options.cluster) {
39942 this.clusterGenerator.setItems(this.items, {
39943 applyOnChangedLevel: false
39944 });
39945
39946 this._clusterItems();
39947 }
39948
39949 this.body.emitter.emit('_change', {
39950 queue: true
39951 });
39952 }
39953 /**
39954 * Handle removed items
39955 * @param {number[]} ids
39956 * @protected
39957 */
39958
39959 }, {
39960 key: "_onRemove",
39961 value: function _onRemove(ids) {
39962 var count = 0;
39963 var me = this;
39964 ids.forEach(function (id) {
39965 var item = me.items[id];
39966
39967 if (item) {
39968 count++;
39969
39970 me._removeItem(item);
39971 }
39972 });
39973
39974 if (count) {
39975 // update order
39976 this._order();
39977
39978 this.body.emitter.emit('_change', {
39979 queue: true
39980 });
39981 }
39982 }
39983 /**
39984 * Update the order of item in all groups
39985 * @private
39986 */
39987
39988 }, {
39989 key: "_order",
39990 value: function _order() {
39991 // reorder the items in all groups
39992 // TODO: optimization: only reorder groups affected by the changed items
39993 util.forEach(this.groups, function (group) {
39994 group.order();
39995 });
39996 }
39997 /**
39998 * Handle updated groups
39999 * @param {number[]} ids
40000 * @private
40001 */
40002
40003 }, {
40004 key: "_onUpdateGroups",
40005 value: function _onUpdateGroups(ids) {
40006 this._onAddGroups(ids);
40007 }
40008 /**
40009 * Handle changed groups (added or updated)
40010 * @param {number[]} ids
40011 * @private
40012 */
40013
40014 }, {
40015 key: "_onAddGroups",
40016 value: function _onAddGroups(ids) {
40017 var me = this;
40018 ids.forEach(function (id) {
40019 var groupData = me.groupsData.get(id);
40020 var group = me.groups[id];
40021
40022 if (!group) {
40023 // check for reserved ids
40024 if (id == UNGROUPED$2 || id == BACKGROUND$2) {
40025 throw new Error("Illegal group id. ".concat(id, " is a reserved id."));
40026 }
40027
40028 var groupOptions = Object.create(me.options);
40029 util.extend(groupOptions, {
40030 height: null
40031 });
40032 group = new Group(id, groupData, me);
40033 me.groups[id] = group; // add items with this groupId to the new group
40034
40035 for (var itemId in me.items) {
40036 if (me.items.hasOwnProperty(itemId)) {
40037 var item = me.items[itemId];
40038
40039 if (item.data.group == id) {
40040 group.add(item);
40041 }
40042 }
40043 }
40044
40045 group.order();
40046 group.show();
40047 } else {
40048 // update group
40049 group.setData(groupData);
40050 }
40051 });
40052 this.body.emitter.emit('_change', {
40053 queue: true
40054 });
40055 }
40056 /**
40057 * Handle removed groups
40058 * @param {number[]} ids
40059 * @private
40060 */
40061
40062 }, {
40063 key: "_onRemoveGroups",
40064 value: function _onRemoveGroups(ids) {
40065 var groups = this.groups;
40066 ids.forEach(function (id) {
40067 var group = groups[id];
40068
40069 if (group) {
40070 group.hide();
40071 delete groups[id];
40072 }
40073 });
40074
40075 if (this.options.cluster) {
40076 this.clusterGenerator.updateData();
40077
40078 this._clusterItems();
40079 }
40080
40081 this.markDirty({
40082 restackGroups: !!this.options.cluster
40083 });
40084 this.body.emitter.emit('_change', {
40085 queue: true
40086 });
40087 }
40088 /**
40089 * Reorder the groups if needed
40090 * @return {boolean} changed
40091 * @private
40092 */
40093
40094 }, {
40095 key: "_orderGroups",
40096 value: function _orderGroups() {
40097 if (this.groupsData) {
40098 // reorder the groups
40099 var groupIds = this.groupsData.getIds({
40100 order: this.options.groupOrder
40101 });
40102 groupIds = this._orderNestedGroups(groupIds);
40103 var changed = !util.equalArray(groupIds, this.groupIds);
40104
40105 if (changed) {
40106 // hide all groups, removes them from the DOM
40107 var groups = this.groups;
40108 groupIds.forEach(function (groupId) {
40109 groups[groupId].hide();
40110 }); // show the groups again, attach them to the DOM in correct order
40111
40112 groupIds.forEach(function (groupId) {
40113 groups[groupId].show();
40114 });
40115 this.groupIds = groupIds;
40116 }
40117
40118 return changed;
40119 } else {
40120 return false;
40121 }
40122 }
40123 /**
40124 * Reorder the nested groups
40125 *
40126 * @param {Array.<number>} groupIds
40127 * @returns {Array.<number>}
40128 * @private
40129 */
40130
40131 }, {
40132 key: "_orderNestedGroups",
40133 value: function _orderNestedGroups(groupIds) {
40134 var _this6 = this;
40135
40136 /**
40137 * Recursively order nested groups
40138 *
40139 * @param {ItemSet} t
40140 * @param {Array.<number>} groupIds
40141 * @returns {Array.<number>}
40142 * @private
40143 */
40144 function getOrderedNestedGroups(t, groupIds) {
40145 var result = [];
40146 groupIds.forEach(function (groupId) {
40147 result.push(groupId);
40148 var groupData = t.groupsData.get(groupId);
40149
40150 if (groupData.nestedGroups) {
40151 var nestedGroupIds = t.groupsData.get({
40152 filter: function filter(nestedGroup) {
40153 return nestedGroup.nestedInGroup == groupId;
40154 },
40155 order: t.options.groupOrder
40156 }).map(function (nestedGroup) {
40157 return nestedGroup.id;
40158 });
40159 result = result.concat(getOrderedNestedGroups(t, nestedGroupIds));
40160 }
40161 });
40162 return result;
40163 }
40164
40165 var topGroupIds = groupIds.filter(function (groupId) {
40166 return !_this6.groupsData.get(groupId).nestedInGroup;
40167 });
40168 return getOrderedNestedGroups(this, topGroupIds);
40169 }
40170 /**
40171 * Add a new item
40172 * @param {Item} item
40173 * @private
40174 */
40175
40176 }, {
40177 key: "_addItem",
40178 value: function _addItem(item) {
40179 this.items[item.id] = item; // add to group
40180
40181 var groupId = this.getGroupId(item.data);
40182 var group = this.groups[groupId];
40183
40184 if (!group) {
40185 item.groupShowing = false;
40186 } else if (group && group.data && group.data.showNested) {
40187 item.groupShowing = true;
40188 }
40189
40190 if (group) group.add(item);
40191 }
40192 /**
40193 * Update an existing item
40194 * @param {Item} item
40195 * @param {Object} itemData
40196 * @private
40197 */
40198
40199 }, {
40200 key: "_updateItem",
40201 value: function _updateItem(item, itemData) {
40202 // update the items data (will redraw the item when displayed)
40203 item.setData(itemData);
40204 var groupId = this.getGroupId(item.data);
40205 var group = this.groups[groupId];
40206
40207 if (!group) {
40208 item.groupShowing = false;
40209 } else if (group && group.data && group.data.showNested) {
40210 item.groupShowing = true;
40211 }
40212 }
40213 /**
40214 * Delete an item from the ItemSet: remove it from the DOM, from the map
40215 * with items, and from the map with visible items, and from the selection
40216 * @param {Item} item
40217 * @private
40218 */
40219
40220 }, {
40221 key: "_removeItem",
40222 value: function _removeItem(item) {
40223 // remove from DOM
40224 item.hide(); // remove from items
40225
40226 delete this.items[item.id]; // remove from selection
40227
40228 var index = this.selection.indexOf(item.id);
40229 if (index != -1) this.selection.splice(index, 1); // remove from group
40230
40231 item.parent && item.parent.remove(item); // remove Tooltip from DOM
40232
40233 if (this.popup != null) {
40234 this.popup.hide();
40235 }
40236 }
40237 /**
40238 * Create an array containing all items being a range (having an end date)
40239 * @param {Array.<Object>} array
40240 * @returns {Array}
40241 * @private
40242 */
40243
40244 }, {
40245 key: "_constructByEndArray",
40246 value: function _constructByEndArray(array) {
40247 var endArray = [];
40248
40249 for (var i = 0; i < array.length; i++) {
40250 if (array[i] instanceof RangeItem) {
40251 endArray.push(array[i]);
40252 }
40253 }
40254
40255 return endArray;
40256 }
40257 /**
40258 * Register the clicked item on touch, before dragStart is initiated.
40259 *
40260 * dragStart is initiated from a mousemove event, AFTER the mouse/touch is
40261 * already moving. Therefore, the mouse/touch can sometimes be above an other
40262 * DOM element than the item itself.
40263 *
40264 * @param {Event} event
40265 * @private
40266 */
40267
40268 }, {
40269 key: "_onTouch",
40270 value: function _onTouch(event) {
40271 // store the touched item, used in _onDragStart
40272 this.touchParams.item = this.itemFromTarget(event);
40273 this.touchParams.dragLeftItem = event.target.dragLeftItem || false;
40274 this.touchParams.dragRightItem = event.target.dragRightItem || false;
40275 this.touchParams.itemProps = null;
40276 }
40277 /**
40278 * Given an group id, returns the index it has.
40279 *
40280 * @param {number} groupId
40281 * @returns {number} index / groupId
40282 * @private
40283 */
40284
40285 }, {
40286 key: "_getGroupIndex",
40287 value: function _getGroupIndex(groupId) {
40288 for (var i = 0; i < this.groupIds.length; i++) {
40289 if (groupId == this.groupIds[i]) return i;
40290 }
40291 }
40292 /**
40293 * Start dragging the selected events
40294 * @param {Event} event
40295 * @private
40296 */
40297
40298 }, {
40299 key: "_onDragStart",
40300 value: function _onDragStart(event) {
40301 var _this7 = this;
40302
40303 if (this.touchParams.itemIsDragging) {
40304 return;
40305 }
40306
40307 var item = this.touchParams.item || null;
40308 var me = this;
40309 var props;
40310
40311 if (item && (item.selected || this.options.itemsAlwaysDraggable.item)) {
40312 if (this.options.editable.overrideItems && !this.options.editable.updateTime && !this.options.editable.updateGroup) {
40313 return;
40314 } // override options.editable
40315
40316
40317 if (item.editable != null && !item.editable.updateTime && !item.editable.updateGroup && !this.options.editable.overrideItems) {
40318 return;
40319 }
40320
40321 var dragLeftItem = this.touchParams.dragLeftItem;
40322 var dragRightItem = this.touchParams.dragRightItem;
40323 this.touchParams.itemIsDragging = true;
40324 this.touchParams.selectedItem = item;
40325
40326 if (dragLeftItem) {
40327 props = {
40328 item: dragLeftItem,
40329 initialX: event.center.x,
40330 dragLeft: true,
40331 data: this._cloneItemData(item.data)
40332 };
40333 this.touchParams.itemProps = [props];
40334 } else if (dragRightItem) {
40335 props = {
40336 item: dragRightItem,
40337 initialX: event.center.x,
40338 dragRight: true,
40339 data: this._cloneItemData(item.data)
40340 };
40341 this.touchParams.itemProps = [props];
40342 } else if (this.options.editable.add && (event.srcEvent.ctrlKey || event.srcEvent.metaKey)) {
40343 // create a new range item when dragging with ctrl key down
40344 this._onDragStartAddItem(event);
40345 } else {
40346 if (this.groupIds.length < 1) {
40347 // Mitigates a race condition if _onDragStart() is
40348 // called after markDirty() without redraw() being called between.
40349 this.redraw();
40350 }
40351
40352 var baseGroupIndex = this._getGroupIndex(item.data.group);
40353
40354 var itemsToDrag = this.options.itemsAlwaysDraggable.item && !item.selected ? [item.id] : this.getSelection();
40355 this.touchParams.itemProps = itemsToDrag.map(function (id) {
40356 var item = me.items[id];
40357
40358 var groupIndex = me._getGroupIndex(item.data.group);
40359
40360 return {
40361 item: item,
40362 initialX: event.center.x,
40363 groupOffset: baseGroupIndex - groupIndex,
40364 data: _this7._cloneItemData(item.data)
40365 };
40366 });
40367 }
40368
40369 event.stopPropagation();
40370 } else if (this.options.editable.add && (event.srcEvent.ctrlKey || event.srcEvent.metaKey)) {
40371 // create a new range item when dragging with ctrl key down
40372 this._onDragStartAddItem(event);
40373 }
40374 }
40375 /**
40376 * Start creating a new range item by dragging.
40377 * @param {Event} event
40378 * @private
40379 */
40380
40381 }, {
40382 key: "_onDragStartAddItem",
40383 value: function _onDragStartAddItem(event) {
40384 var snap = this.options.snap || null;
40385 var frameRect = this.dom.frame.getBoundingClientRect(); // plus (if rtl) 10 to compensate for the drag starting as soon as you've moved 10px
40386
40387 var x = this.options.rtl ? frameRect.right - event.center.x + 10 : event.center.x - frameRect.left - 10;
40388 var time = this.body.util.toTime(x);
40389 var scale = this.body.util.getScale();
40390 var step = this.body.util.getStep();
40391 var start = snap ? snap(time, scale, step) : time;
40392 var end = start;
40393 var itemData = {
40394 type: 'range',
40395 start: start,
40396 end: end,
40397 content: 'new item'
40398 };
40399 var id = util.randomUUID();
40400 itemData[this.itemsData._idProp] = id;
40401 var group = this.groupFromTarget(event);
40402
40403 if (group) {
40404 itemData.group = group.groupId;
40405 }
40406
40407 var newItem = new RangeItem(itemData, this.conversion, this.options);
40408 newItem.id = id; // TODO: not so nice setting id afterwards
40409
40410 newItem.data = this._cloneItemData(itemData);
40411
40412 this._addItem(newItem);
40413
40414 this.touchParams.selectedItem = newItem;
40415 var props = {
40416 item: newItem,
40417 initialX: event.center.x,
40418 data: newItem.data
40419 };
40420
40421 if (this.options.rtl) {
40422 props.dragLeft = true;
40423 } else {
40424 props.dragRight = true;
40425 }
40426
40427 this.touchParams.itemProps = [props];
40428 event.stopPropagation();
40429 }
40430 /**
40431 * Drag selected items
40432 * @param {Event} event
40433 * @private
40434 */
40435
40436 }, {
40437 key: "_onDrag",
40438 value: function _onDrag(event) {
40439 var _this8 = this;
40440
40441 if (this.popup != null && this.options.showTooltips && !this.popup.hidden) {
40442 // this.popup.hide();
40443 var container = this.body.dom.centerContainer;
40444 var containerRect = container.getBoundingClientRect();
40445 this.popup.setPosition(event.center.x - containerRect.left + container.offsetLeft, event.center.y - containerRect.top + container.offsetTop);
40446 this.popup.show(); // redraw
40447 }
40448
40449 if (this.touchParams.itemProps) {
40450 event.stopPropagation();
40451 var me = this;
40452 var snap = this.options.snap || null;
40453 var domRootOffsetLeft = this.body.dom.root.offsetLeft;
40454 var xOffset = this.options.rtl ? domRootOffsetLeft + this.body.domProps.right.width : domRootOffsetLeft + this.body.domProps.left.width;
40455 var scale = this.body.util.getScale();
40456 var step = this.body.util.getStep(); //only calculate the new group for the item that's actually dragged
40457
40458 var selectedItem = this.touchParams.selectedItem;
40459 var updateGroupAllowed = (this.options.editable.overrideItems || selectedItem.editable == null) && this.options.editable.updateGroup || !this.options.editable.overrideItems && selectedItem.editable != null && selectedItem.editable.updateGroup;
40460 var newGroupBase = null;
40461
40462 if (updateGroupAllowed && selectedItem) {
40463 if (selectedItem.data.group != undefined) {
40464 // drag from one group to another
40465 var group = me.groupFromTarget(event);
40466
40467 if (group) {
40468 //we know the offset for all items, so the new group for all items
40469 //will be relative to this one.
40470 newGroupBase = this._getGroupIndex(group.groupId);
40471 }
40472 }
40473 } // move
40474
40475
40476 this.touchParams.itemProps.forEach(function (props) {
40477 var current = me.body.util.toTime(event.center.x - xOffset);
40478 var initial = me.body.util.toTime(props.initialX - xOffset);
40479 var offset;
40480 var initialStart;
40481 var initialEnd;
40482 var start;
40483 var end;
40484
40485 if (_this8.options.rtl) {
40486 offset = -(current - initial); // ms
40487 } else {
40488 offset = current - initial; // ms
40489 }
40490
40491 var itemData = _this8._cloneItemData(props.item.data); // clone the data
40492
40493
40494 if (props.item.editable != null && !props.item.editable.updateTime && !props.item.editable.updateGroup && !me.options.editable.overrideItems) {
40495 return;
40496 }
40497
40498 var updateTimeAllowed = (_this8.options.editable.overrideItems || selectedItem.editable == null) && _this8.options.editable.updateTime || !_this8.options.editable.overrideItems && selectedItem.editable != null && selectedItem.editable.updateTime;
40499
40500 if (updateTimeAllowed) {
40501 if (props.dragLeft) {
40502 // drag left side of a range item
40503 if (_this8.options.rtl) {
40504 if (itemData.end != undefined) {
40505 initialEnd = util.convert(props.data.end, 'Date');
40506 end = new Date(initialEnd.valueOf() + offset); // TODO: pass a Moment instead of a Date to snap(). (Breaking change)
40507
40508 itemData.end = snap ? snap(end, scale, step) : end;
40509 }
40510 } else {
40511 if (itemData.start != undefined) {
40512 initialStart = util.convert(props.data.start, 'Date');
40513 start = new Date(initialStart.valueOf() + offset); // TODO: pass a Moment instead of a Date to snap(). (Breaking change)
40514
40515 itemData.start = snap ? snap(start, scale, step) : start;
40516 }
40517 }
40518 } else if (props.dragRight) {
40519 // drag right side of a range item
40520 if (_this8.options.rtl) {
40521 if (itemData.start != undefined) {
40522 initialStart = util.convert(props.data.start, 'Date');
40523 start = new Date(initialStart.valueOf() + offset); // TODO: pass a Moment instead of a Date to snap(). (Breaking change)
40524
40525 itemData.start = snap ? snap(start, scale, step) : start;
40526 }
40527 } else {
40528 if (itemData.end != undefined) {
40529 initialEnd = util.convert(props.data.end, 'Date');
40530 end = new Date(initialEnd.valueOf() + offset); // TODO: pass a Moment instead of a Date to snap(). (Breaking change)
40531
40532 itemData.end = snap ? snap(end, scale, step) : end;
40533 }
40534 }
40535 } else {
40536 // drag both start and end
40537 if (itemData.start != undefined) {
40538 initialStart = util.convert(props.data.start, 'Date').valueOf();
40539 start = new Date(initialStart + offset);
40540
40541 if (itemData.end != undefined) {
40542 initialEnd = util.convert(props.data.end, 'Date');
40543 var duration = initialEnd.valueOf() - initialStart.valueOf(); // TODO: pass a Moment instead of a Date to snap(). (Breaking change)
40544
40545 itemData.start = snap ? snap(start, scale, step) : start;
40546 itemData.end = new Date(itemData.start.valueOf() + duration);
40547 } else {
40548 // TODO: pass a Moment instead of a Date to snap(). (Breaking change)
40549 itemData.start = snap ? snap(start, scale, step) : start;
40550 }
40551 }
40552 }
40553 }
40554
40555 if (updateGroupAllowed && !props.dragLeft && !props.dragRight && newGroupBase != null) {
40556 if (itemData.group != undefined) {
40557 var newOffset = newGroupBase - props.groupOffset; //make sure we stay in bounds
40558
40559 newOffset = Math.max(0, newOffset);
40560 newOffset = Math.min(me.groupIds.length - 1, newOffset);
40561 itemData.group = me.groupIds[newOffset];
40562 }
40563 } // confirm moving the item
40564
40565
40566 itemData = _this8._cloneItemData(itemData); // convert start and end to the correct type
40567
40568 me.options.onMoving(itemData, function (itemData) {
40569 if (itemData) {
40570 props.item.setData(_this8._cloneItemData(itemData, 'Date'));
40571 }
40572 });
40573 });
40574 this.body.emitter.emit('_change');
40575 }
40576 }
40577 /**
40578 * Move an item to another group
40579 * @param {Item} item
40580 * @param {string | number} groupId
40581 * @private
40582 */
40583
40584 }, {
40585 key: "_moveToGroup",
40586 value: function _moveToGroup(item, groupId) {
40587 var group = this.groups[groupId];
40588
40589 if (group && group.groupId != item.data.group) {
40590 var oldGroup = item.parent;
40591 oldGroup.remove(item);
40592 oldGroup.order();
40593 item.data.group = group.groupId;
40594 group.add(item);
40595 group.order();
40596 }
40597 }
40598 /**
40599 * End of dragging selected items
40600 * @param {Event} event
40601 * @private
40602 */
40603
40604 }, {
40605 key: "_onDragEnd",
40606 value: function _onDragEnd(event) {
40607 var _this9 = this;
40608
40609 this.touchParams.itemIsDragging = false;
40610
40611 if (this.touchParams.itemProps) {
40612 event.stopPropagation();
40613 var me = this;
40614 var dataset = this.itemsData.getDataSet();
40615 var itemProps = this.touchParams.itemProps;
40616 this.touchParams.itemProps = null;
40617 itemProps.forEach(function (props) {
40618 var id = props.item.id;
40619 var exists = me.itemsData.get(id, me.itemOptions) != null;
40620
40621 if (!exists) {
40622 // add a new item
40623 me.options.onAdd(props.item.data, function (itemData) {
40624 me._removeItem(props.item); // remove temporary item
40625
40626
40627 if (itemData) {
40628 me.itemsData.getDataSet().add(itemData);
40629 } // force re-stacking of all items next redraw
40630
40631
40632 me.body.emitter.emit('_change');
40633 });
40634 } else {
40635 // update existing item
40636 var itemData = _this9._cloneItemData(props.item.data); // convert start and end to the correct type
40637
40638
40639 me.options.onMove(itemData, function (itemData) {
40640 if (itemData) {
40641 // apply changes
40642 itemData[dataset._idProp] = id; // ensure the item contains its id (can be undefined)
40643
40644 dataset.update(itemData);
40645 } else {
40646 // restore original values
40647 props.item.setData(props.data);
40648 me.body.emitter.emit('_change');
40649 }
40650 });
40651 }
40652 });
40653 }
40654 }
40655 /**
40656 * On group click
40657 * @param {Event} event
40658 * @private
40659 */
40660
40661 }, {
40662 key: "_onGroupClick",
40663 value: function _onGroupClick(event) {
40664 var _this10 = this;
40665
40666 var group = this.groupFromTarget(event);
40667 setTimeout(function () {
40668 _this10.toggleGroupShowNested(group);
40669 }, 1);
40670 }
40671 /**
40672 * Toggle show nested
40673 * @param {object} group
40674 * @param {boolean} force
40675 */
40676
40677 }, {
40678 key: "toggleGroupShowNested",
40679 value: function toggleGroupShowNested(group) {
40680 var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
40681 if (!group || !group.nestedGroups) return;
40682 var groupsData = this.groupsData.getDataSet();
40683
40684 if (force != undefined) {
40685 group.showNested = !!force;
40686 } else {
40687 group.showNested = !group.showNested;
40688 }
40689
40690 var nestingGroup = groupsData.get(group.groupId);
40691 nestingGroup.showNested = group.showNested;
40692 var fullNestedGroups = group.nestedGroups;
40693 var nextLevel = fullNestedGroups;
40694
40695 while (nextLevel.length > 0) {
40696 var current = nextLevel;
40697 nextLevel = [];
40698
40699 for (var i = 0; i < current.length; i++) {
40700 var node = groupsData.get(current[i]);
40701
40702 if (node.nestedGroups) {
40703 nextLevel = nextLevel.concat(node.nestedGroups);
40704 }
40705 }
40706
40707 if (nextLevel.length > 0) {
40708 fullNestedGroups = fullNestedGroups.concat(nextLevel);
40709 }
40710 }
40711
40712 var nestedGroups = groupsData.get(fullNestedGroups).map(function (nestedGroup) {
40713 if (nestedGroup.visible == undefined) {
40714 nestedGroup.visible = true;
40715 }
40716
40717 nestedGroup.visible = !!nestingGroup.showNested;
40718 return nestedGroup;
40719 });
40720 groupsData.update(nestedGroups.concat(nestingGroup));
40721
40722 if (nestingGroup.showNested) {
40723 util.removeClassName(group.dom.label, 'collapsed');
40724 util.addClassName(group.dom.label, 'expanded');
40725 } else {
40726 util.removeClassName(group.dom.label, 'expanded');
40727 util.addClassName(group.dom.label, 'collapsed');
40728 }
40729 }
40730 /**
40731 * Toggle group drag classname
40732 * @param {object} group
40733 */
40734
40735 }, {
40736 key: "toggleGroupDragClassName",
40737 value: function toggleGroupDragClassName(group) {
40738 group.dom.label.classList.toggle('vis-group-is-dragging');
40739 group.dom.foreground.classList.toggle('vis-group-is-dragging');
40740 }
40741 /**
40742 * on drag start
40743 * @param {Event} event
40744 * @return {void}
40745 * @private
40746 */
40747
40748 }, {
40749 key: "_onGroupDragStart",
40750 value: function _onGroupDragStart(event) {
40751 if (this.groupTouchParams.isDragging) return;
40752
40753 if (this.options.groupEditable.order) {
40754 this.groupTouchParams.group = this.groupFromTarget(event);
40755
40756 if (this.groupTouchParams.group) {
40757 event.stopPropagation();
40758 this.groupTouchParams.isDragging = true;
40759 this.toggleGroupDragClassName(this.groupTouchParams.group);
40760 this.groupTouchParams.originalOrder = this.groupsData.getIds({
40761 order: this.options.groupOrder
40762 });
40763 }
40764 }
40765 }
40766 /**
40767 * on drag
40768 * @param {Event} event
40769 * @return {void}
40770 * @private
40771 */
40772
40773 }, {
40774 key: "_onGroupDrag",
40775 value: function _onGroupDrag(event) {
40776 if (this.options.groupEditable.order && this.groupTouchParams.group) {
40777 event.stopPropagation();
40778 var groupsData = this.groupsData;
40779
40780 if (this.groupsData instanceof DataView$2) {
40781 groupsData = this.groupsData.getDataSet();
40782 } // drag from one group to another
40783
40784
40785 var group = this.groupFromTarget(event); // try to avoid toggling when groups differ in height
40786
40787 if (group && group.height != this.groupTouchParams.group.height) {
40788 var movingUp = group.top < this.groupTouchParams.group.top;
40789 var clientY = event.center ? event.center.y : event.clientY;
40790 var targetGroup = group.dom.foreground.getBoundingClientRect();
40791 var draggedGroupHeight = this.groupTouchParams.group.height;
40792
40793 if (movingUp) {
40794 // skip swapping the groups when the dragged group is not below clientY afterwards
40795 if (targetGroup.top + draggedGroupHeight < clientY) {
40796 return;
40797 }
40798 } else {
40799 var targetGroupHeight = group.height; // skip swapping the groups when the dragged group is not below clientY afterwards
40800
40801 if (targetGroup.top + targetGroupHeight - draggedGroupHeight > clientY) {
40802 return;
40803 }
40804 }
40805 }
40806
40807 if (group && group != this.groupTouchParams.group) {
40808 var _targetGroup = groupsData.get(group.groupId);
40809
40810 var draggedGroup = groupsData.get(this.groupTouchParams.group.groupId); // switch groups
40811
40812 if (draggedGroup && _targetGroup) {
40813 this.options.groupOrderSwap(draggedGroup, _targetGroup, groupsData);
40814 groupsData.update(draggedGroup);
40815 groupsData.update(_targetGroup);
40816 } // fetch current order of groups
40817
40818
40819 var newOrder = groupsData.getIds({
40820 order: this.options.groupOrder
40821 }); // in case of changes since _onGroupDragStart
40822
40823 if (!util.equalArray(newOrder, this.groupTouchParams.originalOrder)) {
40824 var origOrder = this.groupTouchParams.originalOrder;
40825 var draggedId = this.groupTouchParams.group.groupId;
40826 var numGroups = Math.min(origOrder.length, newOrder.length);
40827 var curPos = 0;
40828 var newOffset = 0;
40829 var orgOffset = 0;
40830
40831 while (curPos < numGroups) {
40832 // as long as the groups are where they should be step down along the groups order
40833 while (curPos + newOffset < numGroups && curPos + orgOffset < numGroups && newOrder[curPos + newOffset] == origOrder[curPos + orgOffset]) {
40834 curPos++;
40835 } // all ok
40836
40837
40838 if (curPos + newOffset >= numGroups) {
40839 break;
40840 } // not all ok
40841 // if dragged group was move upwards everything below should have an offset
40842
40843
40844 if (newOrder[curPos + newOffset] == draggedId) {
40845 newOffset = 1;
40846 } // if dragged group was move downwards everything above should have an offset
40847 else if (origOrder[curPos + orgOffset] == draggedId) {
40848 orgOffset = 1;
40849 } // found a group (apart from dragged group) that has the wrong position -> switch with the
40850 // group at the position where other one should be, fix index arrays and continue
40851 else {
40852 var slippedPosition = newOrder.indexOf(origOrder[curPos + orgOffset]);
40853 var switchGroup = groupsData.get(newOrder[curPos + newOffset]);
40854 var shouldBeGroup = groupsData.get(origOrder[curPos + orgOffset]);
40855 this.options.groupOrderSwap(switchGroup, shouldBeGroup, groupsData);
40856 groupsData.update(switchGroup);
40857 groupsData.update(shouldBeGroup);
40858 var switchGroupId = newOrder[curPos + newOffset];
40859 newOrder[curPos + newOffset] = origOrder[curPos + orgOffset];
40860 newOrder[slippedPosition] = switchGroupId;
40861 curPos++;
40862 }
40863 }
40864 }
40865 }
40866 }
40867 }
40868 /**
40869 * on drag end
40870 * @param {Event} event
40871 * @return {void}
40872 * @private
40873 */
40874
40875 }, {
40876 key: "_onGroupDragEnd",
40877 value: function _onGroupDragEnd(event) {
40878 this.groupTouchParams.isDragging = false;
40879
40880 if (this.options.groupEditable.order && this.groupTouchParams.group) {
40881 event.stopPropagation(); // update existing group
40882
40883 var me = this;
40884 var id = me.groupTouchParams.group.groupId;
40885 var dataset = me.groupsData.getDataSet();
40886 var groupData = util.extend({}, dataset.get(id)); // clone the data
40887
40888 me.options.onMoveGroup(groupData, function (groupData) {
40889 if (groupData) {
40890 // apply changes
40891 groupData[dataset._idProp] = id; // ensure the group contains its id (can be undefined)
40892
40893 dataset.update(groupData);
40894 } else {
40895 // fetch current order of groups
40896 var newOrder = dataset.getIds({
40897 order: me.options.groupOrder
40898 }); // restore original order
40899
40900 if (!util.equalArray(newOrder, me.groupTouchParams.originalOrder)) {
40901 var origOrder = me.groupTouchParams.originalOrder;
40902 var numGroups = Math.min(origOrder.length, newOrder.length);
40903 var curPos = 0;
40904
40905 while (curPos < numGroups) {
40906 // as long as the groups are where they should be step down along the groups order
40907 while (curPos < numGroups && newOrder[curPos] == origOrder[curPos]) {
40908 curPos++;
40909 } // all ok
40910
40911
40912 if (curPos >= numGroups) {
40913 break;
40914 } // found a group that has the wrong position -> switch with the
40915 // group at the position where other one should be, fix index arrays and continue
40916
40917
40918 var slippedPosition = newOrder.indexOf(origOrder[curPos]);
40919 var switchGroup = dataset.get(newOrder[curPos]);
40920 var shouldBeGroup = dataset.get(origOrder[curPos]);
40921 me.options.groupOrderSwap(switchGroup, shouldBeGroup, dataset);
40922 dataset.update(switchGroup);
40923 dataset.update(shouldBeGroup);
40924 var switchGroupId = newOrder[curPos];
40925 newOrder[curPos] = origOrder[curPos];
40926 newOrder[slippedPosition] = switchGroupId;
40927 curPos++;
40928 }
40929 }
40930 }
40931 });
40932 me.body.emitter.emit('groupDragged', {
40933 groupId: id
40934 });
40935 this.toggleGroupDragClassName(this.groupTouchParams.group);
40936 this.groupTouchParams.group = null;
40937 }
40938 }
40939 /**
40940 * Handle selecting/deselecting an item when tapping it
40941 * @param {Event} event
40942 * @private
40943 */
40944
40945 }, {
40946 key: "_onSelectItem",
40947 value: function _onSelectItem(event) {
40948 if (!this.options.selectable) return;
40949 var ctrlKey = event.srcEvent && (event.srcEvent.ctrlKey || event.srcEvent.metaKey);
40950 var shiftKey = event.srcEvent && event.srcEvent.shiftKey;
40951
40952 if (ctrlKey || shiftKey) {
40953 this._onMultiSelectItem(event);
40954
40955 return;
40956 }
40957
40958 var oldSelection = this.getSelection();
40959 var item = this.itemFromTarget(event);
40960 var selection = item && item.selectable ? [item.id] : [];
40961 this.setSelection(selection);
40962 var newSelection = this.getSelection(); // emit a select event,
40963 // except when old selection is empty and new selection is still empty
40964
40965 if (newSelection.length > 0 || oldSelection.length > 0) {
40966 this.body.emitter.emit('select', {
40967 items: newSelection,
40968 event: event
40969 });
40970 }
40971 }
40972 /**
40973 * Handle hovering an item
40974 * @param {Event} event
40975 * @private
40976 */
40977
40978 }, {
40979 key: "_onMouseOver",
40980 value: function _onMouseOver(event) {
40981 var item = this.itemFromTarget(event);
40982 if (!item) return; // Item we just left
40983
40984 var related = this.itemFromRelatedTarget(event);
40985
40986 if (item === related) {
40987 // We haven't changed item, just element in the item
40988 return;
40989 }
40990
40991 var title = item.getTitle();
40992
40993 if (this.options.showTooltips && title) {
40994 if (this.popup == null) {
40995 this.popup = new Popup(this.body.dom.root, this.options.tooltip.overflowMethod || 'flip');
40996 }
40997
40998 this.popup.setText(title);
40999 var container = this.body.dom.centerContainer;
41000 var containerRect = container.getBoundingClientRect();
41001 this.popup.setPosition(event.clientX - containerRect.left + container.offsetLeft, event.clientY - containerRect.top + container.offsetTop);
41002 this.setPopupTimer(this.popup);
41003 } else {
41004 // Hovering over item without a title, hide popup
41005 // Needed instead of _just_ in _onMouseOut due to #2572
41006 this.clearPopupTimer();
41007
41008 if (this.popup != null) {
41009 this.popup.hide();
41010 }
41011 }
41012
41013 this.body.emitter.emit('itemover', {
41014 item: item.id,
41015 event: event
41016 });
41017 }
41018 /**
41019 * on mouse start
41020 * @param {Event} event
41021 * @return {void}
41022 * @private
41023 */
41024
41025 }, {
41026 key: "_onMouseOut",
41027 value: function _onMouseOut(event) {
41028 var item = this.itemFromTarget(event);
41029 if (!item) return; // Item we are going to
41030
41031 var related = this.itemFromRelatedTarget(event);
41032
41033 if (item === related) {
41034 // We aren't changing item, just element in the item
41035 return;
41036 }
41037
41038 this.clearPopupTimer();
41039
41040 if (this.popup != null) {
41041 this.popup.hide();
41042 }
41043
41044 this.body.emitter.emit('itemout', {
41045 item: item.id,
41046 event: event
41047 });
41048 }
41049 /**
41050 * on mouse move
41051 * @param {Event} event
41052 * @return {void}
41053 * @private
41054 */
41055
41056 }, {
41057 key: "_onMouseMove",
41058 value: function _onMouseMove(event) {
41059 var item = this.itemFromTarget(event);
41060 if (!item) return;
41061
41062 if (this.popupTimer != null) {
41063 // restart timer
41064 this.setPopupTimer(this.popup);
41065 }
41066
41067 if (this.options.showTooltips && this.options.tooltip.followMouse && this.popup && !this.popup.hidden) {
41068 var container = this.body.dom.centerContainer;
41069 var containerRect = container.getBoundingClientRect();
41070 this.popup.setPosition(event.clientX - containerRect.left + container.offsetLeft, event.clientY - containerRect.top + container.offsetTop);
41071 this.popup.show(); // Redraw
41072 }
41073 }
41074 /**
41075 * Handle mousewheel
41076 * @param {Event} event The event
41077 * @private
41078 */
41079
41080 }, {
41081 key: "_onMouseWheel",
41082 value: function _onMouseWheel(event) {
41083 if (this.touchParams.itemIsDragging) {
41084 this._onDragEnd(event);
41085 }
41086 }
41087 /**
41088 * Handle updates of an item on double tap
41089 * @param {timeline.Item} item The item
41090 * @private
41091 */
41092
41093 }, {
41094 key: "_onUpdateItem",
41095 value: function _onUpdateItem(item) {
41096 if (!this.options.selectable) return;
41097 if (!this.options.editable.updateTime) return;
41098 if (!this.options.editable.updateGroup) return;
41099 var me = this;
41100
41101 if (item) {
41102 // execute async handler to update the item (or cancel it)
41103 var itemData = me.itemsData.get(item.id); // get a clone of the data from the dataset
41104
41105 this.options.onUpdate(itemData, function (itemData) {
41106 if (itemData) {
41107 me.itemsData.getDataSet().update(itemData);
41108 }
41109 });
41110 }
41111 }
41112 /**
41113 * Handle drop event of data on item
41114 * Only called when `objectData.target === 'item'.
41115 * @param {Event} event The event
41116 * @private
41117 */
41118
41119 }, {
41120 key: "_onDropObjectOnItem",
41121 value: function _onDropObjectOnItem(event) {
41122 var item = this.itemFromTarget(event);
41123 var objectData = JSON.parse(event.dataTransfer.getData("text"));
41124 this.options.onDropObjectOnItem(objectData, item);
41125 }
41126 /**
41127 * Handle creation of an item on double tap or drop of a drag event
41128 * @param {Event} event The event
41129 * @private
41130 */
41131
41132 }, {
41133 key: "_onAddItem",
41134 value: function _onAddItem(event) {
41135 if (!this.options.selectable) return;
41136 if (!this.options.editable.add) return;
41137 var me = this;
41138 var snap = this.options.snap || null; // add item
41139
41140 var frameRect = this.dom.frame.getBoundingClientRect();
41141 var x = this.options.rtl ? frameRect.right - event.center.x : event.center.x - frameRect.left;
41142 var start = this.body.util.toTime(x);
41143 var scale = this.body.util.getScale();
41144 var step = this.body.util.getStep();
41145 var end;
41146 var newItemData;
41147
41148 if (event.type == 'drop') {
41149 newItemData = JSON.parse(event.dataTransfer.getData("text"));
41150 newItemData.content = newItemData.content ? newItemData.content : 'new item';
41151 newItemData.start = newItemData.start ? newItemData.start : snap ? snap(start, scale, step) : start;
41152 newItemData.type = newItemData.type || 'box';
41153 newItemData[this.itemsData._idProp] = newItemData.id || util.randomUUID();
41154
41155 if (newItemData.type == 'range' && !newItemData.end) {
41156 end = this.body.util.toTime(x + this.props.width / 5);
41157 newItemData.end = snap ? snap(end, scale, step) : end;
41158 }
41159 } else {
41160 newItemData = {
41161 start: snap ? snap(start, scale, step) : start,
41162 content: 'new item'
41163 };
41164 newItemData[this.itemsData._idProp] = util.randomUUID(); // when default type is a range, add a default end date to the new item
41165
41166 if (this.options.type === 'range') {
41167 end = this.body.util.toTime(x + this.props.width / 5);
41168 newItemData.end = snap ? snap(end, scale, step) : end;
41169 }
41170 }
41171
41172 var group = this.groupFromTarget(event);
41173
41174 if (group) {
41175 newItemData.group = group.groupId;
41176 } // execute async handler to customize (or cancel) adding an item
41177
41178
41179 newItemData = this._cloneItemData(newItemData); // convert start and end to the correct type
41180
41181 this.options.onAdd(newItemData, function (item) {
41182 if (item) {
41183 me.itemsData.getDataSet().add(item);
41184
41185 if (event.type == 'drop') {
41186 me.setSelection([item.id]);
41187 } // TODO: need to trigger a redraw?
41188
41189 }
41190 });
41191 }
41192 /**
41193 * Handle selecting/deselecting multiple items when holding an item
41194 * @param {Event} event
41195 * @private
41196 */
41197
41198 }, {
41199 key: "_onMultiSelectItem",
41200 value: function _onMultiSelectItem(event) {
41201 var _this11 = this;
41202
41203 if (!this.options.selectable) return;
41204 var item = this.itemFromTarget(event);
41205
41206 if (item) {
41207 // multi select items (if allowed)
41208 var selection = this.options.multiselect ? this.getSelection() // take current selection
41209 : []; // deselect current selection
41210
41211 var shiftKey = event.srcEvent && event.srcEvent.shiftKey || false;
41212
41213 if ((shiftKey || this.options.sequentialSelection) && this.options.multiselect) {
41214 // select all items between the old selection and the tapped item
41215 var itemGroup = this.itemsData.get(item.id).group; // when filtering get the group of the last selected item
41216
41217 var lastSelectedGroup = undefined;
41218
41219 if (this.options.multiselectPerGroup) {
41220 if (selection.length > 0) {
41221 lastSelectedGroup = this.itemsData.get(selection[0]).group;
41222 }
41223 } // determine the selection range
41224
41225
41226 if (!this.options.multiselectPerGroup || lastSelectedGroup == undefined || lastSelectedGroup == itemGroup) {
41227 selection.push(item.id);
41228 }
41229
41230 var range = ItemSet._getItemRange(this.itemsData.get(selection, this.itemOptions));
41231
41232 if (!this.options.multiselectPerGroup || lastSelectedGroup == itemGroup) {
41233 // select all items within the selection range
41234 selection = [];
41235
41236 for (var id in this.items) {
41237 if (this.items.hasOwnProperty(id)) {
41238 var _item = this.items[id];
41239 var start = _item.data.start;
41240 var end = _item.data.end !== undefined ? _item.data.end : start;
41241
41242 if (start >= range.min && end <= range.max && (!this.options.multiselectPerGroup || lastSelectedGroup == this.itemsData.get(_item.id).group) && !(_item instanceof BackgroundItem)) {
41243 selection.push(_item.id); // do not use id but item.id, id itself is stringified
41244 }
41245 }
41246 }
41247 }
41248 } else {
41249 // add/remove this item from the current selection
41250 var index = selection.indexOf(item.id);
41251
41252 if (index == -1) {
41253 // item is not yet selected -> select it
41254 selection.push(item.id);
41255 } else {
41256 // item is already selected -> deselect it
41257 selection.splice(index, 1);
41258 }
41259 }
41260
41261 var filteredSelection = selection.filter(function (item) {
41262 return _this11.getItemById(item).selectable;
41263 });
41264 this.setSelection(filteredSelection);
41265 this.body.emitter.emit('select', {
41266 items: this.getSelection(),
41267 event: event
41268 });
41269 }
41270 }
41271 /**
41272 * Calculate the time range of a list of items
41273 * @param {Array.<Object>} itemsData
41274 * @return {{min: Date, max: Date}} Returns the range of the provided items
41275 * @private
41276 */
41277
41278 }, {
41279 key: "itemFromElement",
41280
41281 /**
41282 * Find an item from an element:
41283 * searches for the attribute 'vis-item' in the element's tree
41284 * @param {HTMLElement} element
41285 * @return {Item | null} item
41286 */
41287 value: function itemFromElement(element) {
41288 var cur = element;
41289
41290 while (cur) {
41291 if (cur.hasOwnProperty('vis-item')) {
41292 return cur['vis-item'];
41293 }
41294
41295 cur = cur.parentNode;
41296 }
41297
41298 return null;
41299 }
41300 /**
41301 * Find an item from an event target:
41302 * searches for the attribute 'vis-item' in the event target's element tree
41303 * @param {Event} event
41304 * @return {Item | null} item
41305 */
41306
41307 }, {
41308 key: "itemFromTarget",
41309 value: function itemFromTarget(event) {
41310 return this.itemFromElement(event.target);
41311 }
41312 /**
41313 * Find an item from an event's related target:
41314 * searches for the attribute 'vis-item' in the related target's element tree
41315 * @param {Event} event
41316 * @return {Item | null} item
41317 */
41318
41319 }, {
41320 key: "itemFromRelatedTarget",
41321 value: function itemFromRelatedTarget(event) {
41322 return this.itemFromElement(event.relatedTarget);
41323 }
41324 /**
41325 * Find the Group from an event target:
41326 * searches for the attribute 'vis-group' in the event target's element tree
41327 * @param {Event} event
41328 * @return {Group | null} group
41329 */
41330
41331 }, {
41332 key: "groupFromTarget",
41333 value: function groupFromTarget(event) {
41334 var clientY = event.center ? event.center.y : event.clientY;
41335 var groupIds = this.groupIds;
41336
41337 if (groupIds.length <= 0 && this.groupsData) {
41338 groupIds = this.groupsData.getIds({
41339 order: this.options.groupOrder
41340 });
41341 }
41342
41343 for (var i = 0; i < groupIds.length; i++) {
41344 var groupId = groupIds[i];
41345 var group = this.groups[groupId];
41346 var foreground = group.dom.foreground;
41347 var foregroundRect = foreground.getBoundingClientRect();
41348
41349 if (clientY >= foregroundRect.top && clientY < foregroundRect.top + foreground.offsetHeight) {
41350 return group;
41351 }
41352
41353 if (this.options.orientation.item === 'top') {
41354 if (i === this.groupIds.length - 1 && clientY > foregroundRect.top) {
41355 return group;
41356 }
41357 } else {
41358 if (i === 0 && clientY < foregroundRect.top + foreground.offset) {
41359 return group;
41360 }
41361 }
41362 }
41363
41364 return null;
41365 }
41366 /**
41367 * Find the ItemSet from an event target:
41368 * searches for the attribute 'vis-itemset' in the event target's element tree
41369 * @param {Event} event
41370 * @return {ItemSet | null} item
41371 */
41372
41373 }, {
41374 key: "_cloneItemData",
41375
41376 /**
41377 * Clone the data of an item, and "normalize" it: convert the start and end date
41378 * to the type (Date, Moment, ...) configured in the DataSet. If not configured,
41379 * start and end are converted to Date.
41380 * @param {Object} itemData, typically `item.data`
41381 * @param {string} [type] Optional Date type. If not provided, the type from the DataSet is taken
41382 * @return {Object} The cloned object
41383 * @private
41384 */
41385 value: function _cloneItemData(itemData, type) {
41386 var clone = util.extend({}, itemData);
41387
41388 if (!type) {
41389 // convert start and end date to the type (Date, Moment, ...) configured in the DataSet
41390 type = this.itemsData.getDataSet()._options.type;
41391 }
41392
41393 if (clone.start != undefined) {
41394 clone.start = util.convert(clone.start, type && type.start || 'Date');
41395 }
41396
41397 if (clone.end != undefined) {
41398 clone.end = util.convert(clone.end, type && type.end || 'Date');
41399 }
41400
41401 return clone;
41402 }
41403 /**
41404 * cluster items
41405 * @return {void}
41406 * @private
41407 */
41408
41409 }, {
41410 key: "_clusterItems",
41411 value: function _clusterItems() {
41412 if (!this.options.cluster) {
41413 return;
41414 }
41415
41416 var _this$body$range$conv = this.body.range.conversion(this.body.domProps.center.width),
41417 scale = _this$body$range$conv.scale;
41418
41419 var clusters = this.clusterGenerator.getClusters(this.clusters, scale, this.options.cluster);
41420
41421 if (this.clusters != clusters) {
41422 this._detachAllClusters();
41423
41424 if (clusters) {
41425 var _iteratorNormalCompletion4 = true;
41426 var _didIteratorError4 = false;
41427 var _iteratorError4 = undefined;
41428
41429 try {
41430 for (var _iterator4 = clusters[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
41431 var cluster = _step4.value;
41432 cluster.attach();
41433 }
41434 } catch (err) {
41435 _didIteratorError4 = true;
41436 _iteratorError4 = err;
41437 } finally {
41438 try {
41439 if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
41440 _iterator4.return();
41441 }
41442 } finally {
41443 if (_didIteratorError4) {
41444 throw _iteratorError4;
41445 }
41446 }
41447 }
41448
41449 this.clusters = clusters;
41450 }
41451
41452 this._updateClusters(clusters);
41453 }
41454 }
41455 /**
41456 * detach all cluster items
41457 * @private
41458 */
41459
41460 }, {
41461 key: "_detachAllClusters",
41462 value: function _detachAllClusters() {
41463 if (this.options.cluster) {
41464 if (this.clusters && this.clusters.length) {
41465 var _iteratorNormalCompletion5 = true;
41466 var _didIteratorError5 = false;
41467 var _iteratorError5 = undefined;
41468
41469 try {
41470 for (var _iterator5 = this.clusters[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
41471 var cluster = _step5.value;
41472 cluster.detach();
41473 }
41474 } catch (err) {
41475 _didIteratorError5 = true;
41476 _iteratorError5 = err;
41477 } finally {
41478 try {
41479 if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
41480 _iterator5.return();
41481 }
41482 } finally {
41483 if (_didIteratorError5) {
41484 throw _iteratorError5;
41485 }
41486 }
41487 }
41488 }
41489 }
41490 }
41491 /**
41492 * update clusters
41493 * @param {array} clusters
41494 * @private
41495 */
41496
41497 }, {
41498 key: "_updateClusters",
41499 value: function _updateClusters(clusters) {
41500 if (this.clusters && this.clusters.length) {
41501 var newClustersIds = new Set(clusters.map(function (cluster) {
41502 return cluster.id;
41503 }));
41504 var clustersToUnselect = this.clusters.filter(function (cluster) {
41505 return !newClustersIds.has(cluster.id);
41506 });
41507 var selectionChanged = false;
41508 var _iteratorNormalCompletion6 = true;
41509 var _didIteratorError6 = false;
41510 var _iteratorError6 = undefined;
41511
41512 try {
41513 for (var _iterator6 = clustersToUnselect[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
41514 var cluster = _step6.value;
41515 var selectedIdx = this.selection.indexOf(cluster.id);
41516
41517 if (selectedIdx !== -1) {
41518 cluster.unselect();
41519 this.selection.splice(selectedIdx, 1);
41520 selectionChanged = true;
41521 }
41522 }
41523 } catch (err) {
41524 _didIteratorError6 = true;
41525 _iteratorError6 = err;
41526 } finally {
41527 try {
41528 if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
41529 _iterator6.return();
41530 }
41531 } finally {
41532 if (_didIteratorError6) {
41533 throw _iteratorError6;
41534 }
41535 }
41536 }
41537
41538 if (selectionChanged) {
41539 var newSelection = this.getSelection();
41540 this.body.emitter.emit('select', {
41541 items: newSelection,
41542 event: event
41543 });
41544 }
41545 }
41546
41547 this.clusters = clusters || [];
41548 }
41549 }], [{
41550 key: "_getItemRange",
41551 value: function _getItemRange(itemsData) {
41552 var max = null;
41553 var min = null;
41554 itemsData.forEach(function (data) {
41555 if (min == null || data.start < min) {
41556 min = data.start;
41557 }
41558
41559 if (data.end != undefined) {
41560 if (max == null || data.end > max) {
41561 max = data.end;
41562 }
41563 } else {
41564 if (max == null || data.start > max) {
41565 max = data.start;
41566 }
41567 }
41568 });
41569 return {
41570 min: min,
41571 max: max
41572 };
41573 }
41574 }, {
41575 key: "itemSetFromTarget",
41576 value: function itemSetFromTarget(event) {
41577 var target = event.target;
41578
41579 while (target) {
41580 if (target.hasOwnProperty('vis-itemset')) {
41581 return target['vis-itemset'];
41582 }
41583
41584 target = target.parentNode;
41585 }
41586
41587 return null;
41588 }
41589 }]);
41590
41591 return ItemSet;
41592}(Component); // available item types will be registered here
41593
41594
41595ItemSet.types = {
41596 background: BackgroundItem,
41597 box: BoxItem,
41598 range: RangeItem,
41599 point: PointItem
41600};
41601/**
41602 * Handle added items
41603 * @param {number[]} ids
41604 * @protected
41605 */
41606
41607ItemSet.prototype._onAdd = ItemSet.prototype._onUpdate;
41608
41609var errorFound = false;
41610var allOptions;
41611var printStyle = 'background: #FFeeee; color: #dd0000';
41612/**
41613 * Used to validate options.
41614 */
41615
41616var Validator =
41617/*#__PURE__*/
41618function () {
41619 /**
41620 * @ignore
41621 */
41622 function Validator() {
41623 _classCallCheck(this, Validator);
41624 }
41625 /**
41626 * Main function to be called
41627 * @param {Object} options
41628 * @param {Object} referenceOptions
41629 * @param {Object} subObject
41630 * @returns {boolean}
41631 * @static
41632 */
41633
41634
41635 _createClass(Validator, null, [{
41636 key: "validate",
41637 value: function validate(options, referenceOptions, subObject) {
41638 errorFound = false;
41639 allOptions = referenceOptions;
41640 var usedOptions = referenceOptions;
41641
41642 if (subObject !== undefined) {
41643 usedOptions = referenceOptions[subObject];
41644 }
41645
41646 Validator.parse(options, usedOptions, []);
41647 return errorFound;
41648 }
41649 /**
41650 * Will traverse an object recursively and check every value
41651 * @param {Object} options
41652 * @param {Object} referenceOptions
41653 * @param {array} path | where to look for the actual option
41654 * @static
41655 */
41656
41657 }, {
41658 key: "parse",
41659 value: function parse(options, referenceOptions, path) {
41660 for (var option in options) {
41661 if (options.hasOwnProperty(option)) {
41662 Validator.check(option, options, referenceOptions, path);
41663 }
41664 }
41665 }
41666 /**
41667 * Check every value. If the value is an object, call the parse function on that object.
41668 * @param {string} option
41669 * @param {Object} options
41670 * @param {Object} referenceOptions
41671 * @param {array} path | where to look for the actual option
41672 * @static
41673 */
41674
41675 }, {
41676 key: "check",
41677 value: function check(option, options, referenceOptions, path) {
41678 if (referenceOptions[option] === undefined && referenceOptions.__any__ === undefined) {
41679 Validator.getSuggestion(option, referenceOptions, path);
41680 return;
41681 }
41682
41683 var referenceOption = option;
41684 var is_object = true;
41685
41686 if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {
41687 // NOTE: This only triggers if the __any__ is in the top level of the options object.
41688 // THAT'S A REALLY BAD PLACE TO ALLOW IT!!!!
41689 // TODO: Examine if needed, remove if possible
41690 // __any__ is a wildcard. Any value is accepted and will be further analysed by reference.
41691 referenceOption = '__any__'; // if the any-subgroup is not a predefined object in the configurator,
41692 // we do not look deeper into the object.
41693
41694 is_object = Validator.getType(options[option]) === 'object';
41695 }
41696
41697 var refOptionObj = referenceOptions[referenceOption];
41698
41699 if (is_object && refOptionObj.__type__ !== undefined) {
41700 refOptionObj = refOptionObj.__type__;
41701 }
41702
41703 Validator.checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path);
41704 }
41705 /**
41706 *
41707 * @param {string} option | the option property
41708 * @param {Object} options | The supplied options object
41709 * @param {Object} referenceOptions | The reference options containing all options and their allowed formats
41710 * @param {string} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
41711 * @param {string} refOptionObj | This is the type object from the reference options
41712 * @param {Array} path | where in the object is the option
41713 * @static
41714 */
41715
41716 }, {
41717 key: "checkFields",
41718 value: function checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path) {
41719 var log = function log(message) {
41720 console.log('%c' + message + Validator.printLocation(path, option), printStyle);
41721 };
41722
41723 var optionType = Validator.getType(options[option]);
41724 var refOptionType = refOptionObj[optionType];
41725
41726 if (refOptionType !== undefined) {
41727 // if the type is correct, we check if it is supposed to be one of a few select values
41728 if (Validator.getType(refOptionType) === 'array' && refOptionType.indexOf(options[option]) === -1) {
41729 log('Invalid option detected in "' + option + '".' + ' Allowed values are:' + Validator.print(refOptionType) + ' not "' + options[option] + '". ');
41730 errorFound = true;
41731 } else if (optionType === 'object' && referenceOption !== "__any__") {
41732 path = util.copyAndExtendArray(path, option);
41733 Validator.parse(options[option], referenceOptions[referenceOption], path);
41734 }
41735 } else if (refOptionObj['any'] === undefined) {
41736 // type of the field is incorrect and the field cannot be any
41737 log('Invalid type received for "' + option + '". Expected: ' + Validator.print(Object.keys(refOptionObj)) + '. Received [' + optionType + '] "' + options[option] + '"');
41738 errorFound = true;
41739 }
41740 }
41741 /**
41742 *
41743 * @param {Object|boolean|number|string|Array.<number>|Date|Node|Moment|undefined|null} object
41744 * @returns {string}
41745 * @static
41746 */
41747
41748 }, {
41749 key: "getType",
41750 value: function getType(object) {
41751 var type = _typeof(object);
41752
41753 if (type === 'object') {
41754 if (object === null) {
41755 return 'null';
41756 }
41757
41758 if (object instanceof Boolean) {
41759 return 'boolean';
41760 }
41761
41762 if (object instanceof Number) {
41763 return 'number';
41764 }
41765
41766 if (object instanceof String) {
41767 return 'string';
41768 }
41769
41770 if (Array.isArray(object)) {
41771 return 'array';
41772 }
41773
41774 if (object instanceof Date) {
41775 return 'date';
41776 }
41777
41778 if (object.nodeType !== undefined) {
41779 return 'dom';
41780 }
41781
41782 if (object._isAMomentObject === true) {
41783 return 'moment';
41784 }
41785
41786 return 'object';
41787 } else if (type === 'number') {
41788 return 'number';
41789 } else if (type === 'boolean') {
41790 return 'boolean';
41791 } else if (type === 'string') {
41792 return 'string';
41793 } else if (type === undefined) {
41794 return 'undefined';
41795 }
41796
41797 return type;
41798 }
41799 /**
41800 * @param {string} option
41801 * @param {Object} options
41802 * @param {Array.<string>} path
41803 * @static
41804 */
41805
41806 }, {
41807 key: "getSuggestion",
41808 value: function getSuggestion(option, options, path) {
41809 var localSearch = Validator.findInOptions(option, options, path, false);
41810 var globalSearch = Validator.findInOptions(option, allOptions, [], true);
41811 var localSearchThreshold = 8;
41812 var globalSearchThreshold = 4;
41813 var msg;
41814
41815 if (localSearch.indexMatch !== undefined) {
41816 msg = ' in ' + Validator.printLocation(localSearch.path, option, '') + 'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n';
41817 } else if (globalSearch.distance <= globalSearchThreshold && localSearch.distance > globalSearch.distance) {
41818 msg = ' in ' + Validator.printLocation(localSearch.path, option, '') + 'Perhaps it was misplaced? Matching option found at: ' + Validator.printLocation(globalSearch.path, globalSearch.closestMatch, '');
41819 } else if (localSearch.distance <= localSearchThreshold) {
41820 msg = '. Did you mean "' + localSearch.closestMatch + '"?' + Validator.printLocation(localSearch.path, option);
41821 } else {
41822 msg = '. Did you mean one of these: ' + Validator.print(Object.keys(options)) + Validator.printLocation(path, option);
41823 }
41824
41825 console.log('%cUnknown option detected: "' + option + '"' + msg, printStyle);
41826 errorFound = true;
41827 }
41828 /**
41829 * traverse the options in search for a match.
41830 * @param {string} option
41831 * @param {Object} options
41832 * @param {Array} path | where to look for the actual option
41833 * @param {boolean} [recursive=false]
41834 * @returns {{closestMatch: string, path: Array, distance: number}}
41835 * @static
41836 */
41837
41838 }, {
41839 key: "findInOptions",
41840 value: function findInOptions(option, options, path) {
41841 var recursive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
41842 var min = 1e9;
41843 var closestMatch = '';
41844 var closestMatchPath = [];
41845 var lowerCaseOption = option.toLowerCase();
41846 var indexMatch = undefined;
41847
41848 for (var op in options) {
41849 // eslint-disable-line guard-for-in
41850 var distance = void 0;
41851
41852 if (options[op].__type__ !== undefined && recursive === true) {
41853 var result = Validator.findInOptions(option, options[op], util.copyAndExtendArray(path, op));
41854
41855 if (min > result.distance) {
41856 closestMatch = result.closestMatch;
41857 closestMatchPath = result.path;
41858 min = result.distance;
41859 indexMatch = result.indexMatch;
41860 }
41861 } else {
41862 if (op.toLowerCase().indexOf(lowerCaseOption) !== -1) {
41863 indexMatch = op;
41864 }
41865
41866 distance = Validator.levenshteinDistance(option, op);
41867
41868 if (min > distance) {
41869 closestMatch = op;
41870 closestMatchPath = util.copyArray(path);
41871 min = distance;
41872 }
41873 }
41874 }
41875
41876 return {
41877 closestMatch: closestMatch,
41878 path: closestMatchPath,
41879 distance: min,
41880 indexMatch: indexMatch
41881 };
41882 }
41883 /**
41884 * @param {Array.<string>} path
41885 * @param {Object} option
41886 * @param {string} prefix
41887 * @returns {String}
41888 * @static
41889 */
41890
41891 }, {
41892 key: "printLocation",
41893 value: function printLocation(path, option) {
41894 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Problem value found at: \n';
41895 var str = '\n\n' + prefix + 'options = {\n';
41896
41897 for (var i = 0; i < path.length; i++) {
41898 for (var j = 0; j < i + 1; j++) {
41899 str += ' ';
41900 }
41901
41902 str += path[i] + ': {\n';
41903 }
41904
41905 for (var _j = 0; _j < path.length + 1; _j++) {
41906 str += ' ';
41907 }
41908
41909 str += option + '\n';
41910
41911 for (var _i = 0; _i < path.length + 1; _i++) {
41912 for (var _j2 = 0; _j2 < path.length - _i; _j2++) {
41913 str += ' ';
41914 }
41915
41916 str += '}\n';
41917 }
41918
41919 return str + '\n\n';
41920 }
41921 /**
41922 * @param {Object} options
41923 * @returns {String}
41924 * @static
41925 */
41926
41927 }, {
41928 key: "print",
41929 value: function print(options) {
41930 return JSON.stringify(options).replace(/(\")|(\[)|(\])|(,"__type__")/g, "").replace(/(\,)/g, ', ');
41931 }
41932 /**
41933 * Compute the edit distance between the two given strings
41934 * http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
41935 *
41936 * Copyright (c) 2011 Andrei Mackenzie
41937 *
41938 * 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:
41939 *
41940 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
41941 *
41942 * 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.
41943 *
41944 * @param {string} a
41945 * @param {string} b
41946 * @returns {Array.<Array.<number>>}}
41947 * @static
41948 */
41949
41950 }, {
41951 key: "levenshteinDistance",
41952 value: function levenshteinDistance(a, b) {
41953 if (a.length === 0) return b.length;
41954 if (b.length === 0) return a.length;
41955 var matrix = []; // increment along the first column of each row
41956
41957 var i;
41958
41959 for (i = 0; i <= b.length; i++) {
41960 matrix[i] = [i];
41961 } // increment each column in the first row
41962
41963
41964 var j;
41965
41966 for (j = 0; j <= a.length; j++) {
41967 matrix[0][j] = j;
41968 } // Fill in the rest of the matrix
41969
41970
41971 for (i = 1; i <= b.length; i++) {
41972 for (j = 1; j <= a.length; j++) {
41973 if (b.charAt(i - 1) == a.charAt(j - 1)) {
41974 matrix[i][j] = matrix[i - 1][j - 1];
41975 } else {
41976 matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
41977 Math.min(matrix[i][j - 1] + 1, // insertion
41978 matrix[i - 1][j] + 1)); // deletion
41979 }
41980 }
41981 }
41982
41983 return matrix[b.length][a.length];
41984 }
41985 }]);
41986
41987 return Validator;
41988}();
41989
41990/**
41991 * This object contains all possible options. It will check if the types are correct, if required if the option is one
41992 * of the allowed values.
41993 *
41994 * __any__ means that the name of the property does not matter.
41995 * __type__ is a required field for all objects and contains the allowed types of all objects
41996 */
41997var string = 'string';
41998var bool = 'boolean';
41999var number = 'number';
42000var array = 'array';
42001var date = 'date';
42002var object = 'object'; // should only be in a __type__ property
42003
42004var dom = 'dom';
42005var moment$4 = 'moment';
42006var any = 'any';
42007var allOptions$1 = {
42008 configure: {
42009 enabled: {
42010 'boolean': bool
42011 },
42012 filter: {
42013 'boolean': bool,
42014 'function': 'function'
42015 },
42016 container: {
42017 dom: dom
42018 },
42019 __type__: {
42020 object: object,
42021 'boolean': bool,
42022 'function': 'function'
42023 }
42024 },
42025 //globals :
42026 align: {
42027 string: string
42028 },
42029 alignCurrentTime: {
42030 string: string,
42031 'undefined': 'undefined'
42032 },
42033 rtl: {
42034 'boolean': bool,
42035 'undefined': 'undefined'
42036 },
42037 rollingMode: {
42038 follow: {
42039 'boolean': bool
42040 },
42041 offset: {
42042 number: number,
42043 'undefined': 'undefined'
42044 },
42045 __type__: {
42046 object: object
42047 }
42048 },
42049 onTimeout: {
42050 timeoutMs: {
42051 number: number
42052 },
42053 callback: {
42054 'function': 'function'
42055 },
42056 __type__: {
42057 object: object
42058 }
42059 },
42060 verticalScroll: {
42061 'boolean': bool,
42062 'undefined': 'undefined'
42063 },
42064 horizontalScroll: {
42065 'boolean': bool,
42066 'undefined': 'undefined'
42067 },
42068 autoResize: {
42069 'boolean': bool
42070 },
42071 throttleRedraw: {
42072 number: number
42073 },
42074 // TODO: DEPRICATED see https://github.com/almende/vis/issues/2511
42075 clickToUse: {
42076 'boolean': bool
42077 },
42078 dataAttributes: {
42079 string: string,
42080 array: array
42081 },
42082 editable: {
42083 add: {
42084 'boolean': bool,
42085 'undefined': 'undefined'
42086 },
42087 remove: {
42088 'boolean': bool,
42089 'undefined': 'undefined'
42090 },
42091 updateGroup: {
42092 'boolean': bool,
42093 'undefined': 'undefined'
42094 },
42095 updateTime: {
42096 'boolean': bool,
42097 'undefined': 'undefined'
42098 },
42099 overrideItems: {
42100 'boolean': bool,
42101 'undefined': 'undefined'
42102 },
42103 __type__: {
42104 'boolean': bool,
42105 object: object
42106 }
42107 },
42108 end: {
42109 number: number,
42110 date: date,
42111 string: string,
42112 moment: moment$4
42113 },
42114 format: {
42115 minorLabels: {
42116 millisecond: {
42117 string: string,
42118 'undefined': 'undefined'
42119 },
42120 second: {
42121 string: string,
42122 'undefined': 'undefined'
42123 },
42124 minute: {
42125 string: string,
42126 'undefined': 'undefined'
42127 },
42128 hour: {
42129 string: string,
42130 'undefined': 'undefined'
42131 },
42132 weekday: {
42133 string: string,
42134 'undefined': 'undefined'
42135 },
42136 day: {
42137 string: string,
42138 'undefined': 'undefined'
42139 },
42140 week: {
42141 string: string,
42142 'undefined': 'undefined'
42143 },
42144 month: {
42145 string: string,
42146 'undefined': 'undefined'
42147 },
42148 year: {
42149 string: string,
42150 'undefined': 'undefined'
42151 },
42152 __type__: {
42153 object: object,
42154 'function': 'function'
42155 }
42156 },
42157 majorLabels: {
42158 millisecond: {
42159 string: string,
42160 'undefined': 'undefined'
42161 },
42162 second: {
42163 string: string,
42164 'undefined': 'undefined'
42165 },
42166 minute: {
42167 string: string,
42168 'undefined': 'undefined'
42169 },
42170 hour: {
42171 string: string,
42172 'undefined': 'undefined'
42173 },
42174 weekday: {
42175 string: string,
42176 'undefined': 'undefined'
42177 },
42178 day: {
42179 string: string,
42180 'undefined': 'undefined'
42181 },
42182 week: {
42183 string: string,
42184 'undefined': 'undefined'
42185 },
42186 month: {
42187 string: string,
42188 'undefined': 'undefined'
42189 },
42190 year: {
42191 string: string,
42192 'undefined': 'undefined'
42193 },
42194 __type__: {
42195 object: object,
42196 'function': 'function'
42197 }
42198 },
42199 __type__: {
42200 object: object
42201 }
42202 },
42203 moment: {
42204 'function': 'function'
42205 },
42206 groupHeightMode: {
42207 string: string
42208 },
42209 groupOrder: {
42210 string: string,
42211 'function': 'function'
42212 },
42213 groupEditable: {
42214 add: {
42215 'boolean': bool,
42216 'undefined': 'undefined'
42217 },
42218 remove: {
42219 'boolean': bool,
42220 'undefined': 'undefined'
42221 },
42222 order: {
42223 'boolean': bool,
42224 'undefined': 'undefined'
42225 },
42226 __type__: {
42227 'boolean': bool,
42228 object: object
42229 }
42230 },
42231 groupOrderSwap: {
42232 'function': 'function'
42233 },
42234 height: {
42235 string: string,
42236 number: number
42237 },
42238 hiddenDates: {
42239 start: {
42240 date: date,
42241 number: number,
42242 string: string,
42243 moment: moment$4
42244 },
42245 end: {
42246 date: date,
42247 number: number,
42248 string: string,
42249 moment: moment$4
42250 },
42251 repeat: {
42252 string: string
42253 },
42254 __type__: {
42255 object: object,
42256 array: array
42257 }
42258 },
42259 itemsAlwaysDraggable: {
42260 item: {
42261 'boolean': bool,
42262 'undefined': 'undefined'
42263 },
42264 range: {
42265 'boolean': bool,
42266 'undefined': 'undefined'
42267 },
42268 __type__: {
42269 'boolean': bool,
42270 object: object
42271 }
42272 },
42273 limitSize: {
42274 'boolean': bool
42275 },
42276 locale: {
42277 string: string
42278 },
42279 locales: {
42280 __any__: {
42281 any: any
42282 },
42283 __type__: {
42284 object: object
42285 }
42286 },
42287 margin: {
42288 axis: {
42289 number: number
42290 },
42291 item: {
42292 horizontal: {
42293 number: number,
42294 'undefined': 'undefined'
42295 },
42296 vertical: {
42297 number: number,
42298 'undefined': 'undefined'
42299 },
42300 __type__: {
42301 object: object,
42302 number: number
42303 }
42304 },
42305 __type__: {
42306 object: object,
42307 number: number
42308 }
42309 },
42310 max: {
42311 date: date,
42312 number: number,
42313 string: string,
42314 moment: moment$4
42315 },
42316 maxHeight: {
42317 number: number,
42318 string: string
42319 },
42320 maxMinorChars: {
42321 number: number
42322 },
42323 min: {
42324 date: date,
42325 number: number,
42326 string: string,
42327 moment: moment$4
42328 },
42329 minHeight: {
42330 number: number,
42331 string: string
42332 },
42333 moveable: {
42334 'boolean': bool
42335 },
42336 multiselect: {
42337 'boolean': bool
42338 },
42339 multiselectPerGroup: {
42340 'boolean': bool
42341 },
42342 onAdd: {
42343 'function': 'function'
42344 },
42345 onDropObjectOnItem: {
42346 'function': 'function'
42347 },
42348 onUpdate: {
42349 'function': 'function'
42350 },
42351 onMove: {
42352 'function': 'function'
42353 },
42354 onMoving: {
42355 'function': 'function'
42356 },
42357 onRemove: {
42358 'function': 'function'
42359 },
42360 onAddGroup: {
42361 'function': 'function'
42362 },
42363 onMoveGroup: {
42364 'function': 'function'
42365 },
42366 onRemoveGroup: {
42367 'function': 'function'
42368 },
42369 onInitialDrawComplete: {
42370 'function': 'function'
42371 },
42372 order: {
42373 'function': 'function'
42374 },
42375 orientation: {
42376 axis: {
42377 string: string,
42378 'undefined': 'undefined'
42379 },
42380 item: {
42381 string: string,
42382 'undefined': 'undefined'
42383 },
42384 __type__: {
42385 string: string,
42386 object: object
42387 }
42388 },
42389 selectable: {
42390 'boolean': bool
42391 },
42392 sequentialSelection: {
42393 'boolean': bool
42394 },
42395 showCurrentTime: {
42396 'boolean': bool
42397 },
42398 showMajorLabels: {
42399 'boolean': bool
42400 },
42401 showMinorLabels: {
42402 'boolean': bool
42403 },
42404 stack: {
42405 'boolean': bool
42406 },
42407 stackSubgroups: {
42408 'boolean': bool
42409 },
42410 cluster: {
42411 maxItems: {
42412 'number': number,
42413 'undefined': 'undefined'
42414 },
42415 titleTemplate: {
42416 'string': string,
42417 'undefined': 'undefined'
42418 },
42419 clusterCriteria: {
42420 'function': 'function',
42421 'undefined': 'undefined'
42422 },
42423 showStipes: {
42424 'boolean': bool,
42425 'undefined': 'undefined'
42426 },
42427 fitOnDoubleClick: {
42428 'boolean': bool,
42429 'undefined': 'undefined'
42430 },
42431 __type__: {
42432 'boolean': bool,
42433 object: object
42434 }
42435 },
42436 snap: {
42437 'function': 'function',
42438 'null': 'null'
42439 },
42440 start: {
42441 date: date,
42442 number: number,
42443 string: string,
42444 moment: moment$4
42445 },
42446 template: {
42447 'function': 'function'
42448 },
42449 loadingScreenTemplate: {
42450 'function': 'function'
42451 },
42452 groupTemplate: {
42453 'function': 'function'
42454 },
42455 visibleFrameTemplate: {
42456 string: string,
42457 'function': 'function'
42458 },
42459 showTooltips: {
42460 'boolean': bool
42461 },
42462 tooltip: {
42463 followMouse: {
42464 'boolean': bool
42465 },
42466 overflowMethod: {
42467 'string': ['cap', 'flip', 'none']
42468 },
42469 delay: {
42470 number: number
42471 },
42472 template: {
42473 'function': 'function'
42474 },
42475 __type__: {
42476 object: object
42477 }
42478 },
42479 tooltipOnItemUpdateTime: {
42480 template: {
42481 'function': 'function'
42482 },
42483 __type__: {
42484 'boolean': bool,
42485 object: object
42486 }
42487 },
42488 timeAxis: {
42489 scale: {
42490 string: string,
42491 'undefined': 'undefined'
42492 },
42493 step: {
42494 number: number,
42495 'undefined': 'undefined'
42496 },
42497 __type__: {
42498 object: object
42499 }
42500 },
42501 type: {
42502 string: string
42503 },
42504 width: {
42505 string: string,
42506 number: number
42507 },
42508 preferZoom: {
42509 'boolean': bool
42510 },
42511 zoomable: {
42512 'boolean': bool
42513 },
42514 zoomKey: {
42515 string: ['ctrlKey', 'altKey', 'shiftKey', 'metaKey', '']
42516 },
42517 zoomFriction: {
42518 number: number
42519 },
42520 zoomMax: {
42521 number: number
42522 },
42523 zoomMin: {
42524 number: number
42525 },
42526 __type__: {
42527 object: object
42528 }
42529};
42530var configureOptions = {
42531 global: {
42532 align: ['center', 'left', 'right'],
42533 alignCurrentTime: ['none', 'year', 'month', 'quarter', 'week', 'isoWeek', 'day', 'date', 'hour', 'minute', 'second'],
42534 direction: false,
42535 autoResize: true,
42536 clickToUse: false,
42537 // dataAttributes: ['all'], // FIXME: can be 'all' or string[]
42538 editable: {
42539 add: false,
42540 remove: false,
42541 updateGroup: false,
42542 updateTime: false
42543 },
42544 end: '',
42545 format: {
42546 minorLabels: {
42547 millisecond: 'SSS',
42548 second: 's',
42549 minute: 'HH:mm',
42550 hour: 'HH:mm',
42551 weekday: 'ddd D',
42552 day: 'D',
42553 week: 'w',
42554 month: 'MMM',
42555 year: 'YYYY'
42556 },
42557 majorLabels: {
42558 millisecond: 'HH:mm:ss',
42559 second: 'D MMMM HH:mm',
42560 minute: 'ddd D MMMM',
42561 hour: 'ddd D MMMM',
42562 weekday: 'MMMM YYYY',
42563 day: 'MMMM YYYY',
42564 week: 'MMMM YYYY',
42565 month: 'YYYY',
42566 year: ''
42567 }
42568 },
42569 groupHeightMode: ['auto', 'fixed', 'fitItems'],
42570 //groupOrder: {string, 'function': 'function'},
42571 groupsDraggable: false,
42572 height: '',
42573 //hiddenDates: {object, array},
42574 locale: '',
42575 margin: {
42576 axis: [20, 0, 100, 1],
42577 item: {
42578 horizontal: [10, 0, 100, 1],
42579 vertical: [10, 0, 100, 1]
42580 }
42581 },
42582 max: '',
42583 maxHeight: '',
42584 maxMinorChars: [7, 0, 20, 1],
42585 min: '',
42586 minHeight: '',
42587 moveable: false,
42588 multiselect: false,
42589 multiselectPerGroup: false,
42590 //onAdd: {'function': 'function'},
42591 //onUpdate: {'function': 'function'},
42592 //onMove: {'function': 'function'},
42593 //onMoving: {'function': 'function'},
42594 //onRename: {'function': 'function'},
42595 //order: {'function': 'function'},
42596 orientation: {
42597 axis: ['both', 'bottom', 'top'],
42598 item: ['bottom', 'top']
42599 },
42600 preferZoom: false,
42601 selectable: true,
42602 showCurrentTime: false,
42603 showMajorLabels: true,
42604 showMinorLabels: true,
42605 stack: true,
42606 stackSubgroups: true,
42607 cluster: false,
42608 //snap: {'function': 'function', nada},
42609 start: '',
42610 //template: {'function': 'function'},
42611 //timeAxis: {
42612 // scale: ['millisecond', 'second', 'minute', 'hour', 'weekday', 'day', 'week', 'month', 'year'],
42613 // step: [1, 1, 10, 1]
42614 //},
42615 showTooltips: true,
42616 tooltip: {
42617 followMouse: false,
42618 overflowMethod: 'flip',
42619 delay: [500, 0, 99999, 100]
42620 },
42621 tooltipOnItemUpdateTime: false,
42622 type: ['box', 'point', 'range', 'background'],
42623 width: '100%',
42624 zoomable: true,
42625 zoomKey: ['ctrlKey', 'altKey', 'shiftKey', 'metaKey', ''],
42626 zoomMax: [315360000000000, 10, 315360000000000, 1],
42627 zoomMin: [10, 10, 315360000000000, 1]
42628 }
42629};
42630
42631// `Array.prototype.fill` method
42632// https://tc39.github.io/ecma262/#sec-array.prototype.fill
42633_export({ target: 'Array', proto: true }, {
42634 fill: arrayFill
42635});
42636
42637// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
42638addToUnscopables('fill');
42639
42640var htmlColors = {
42641 black: '#000000',
42642 navy: '#000080',
42643 darkblue: '#00008B',
42644 mediumblue: '#0000CD',
42645 blue: '#0000FF',
42646 darkgreen: '#006400',
42647 green: '#008000',
42648 teal: '#008080',
42649 darkcyan: '#008B8B',
42650 deepskyblue: '#00BFFF',
42651 darkturquoise: '#00CED1',
42652 mediumspringgreen: '#00FA9A',
42653 lime: '#00FF00',
42654 springgreen: '#00FF7F',
42655 aqua: '#00FFFF',
42656 cyan: '#00FFFF',
42657 midnightblue: '#191970',
42658 dodgerblue: '#1E90FF',
42659 lightseagreen: '#20B2AA',
42660 forestgreen: '#228B22',
42661 seagreen: '#2E8B57',
42662 darkslategray: '#2F4F4F',
42663 limegreen: '#32CD32',
42664 mediumseagreen: '#3CB371',
42665 turquoise: '#40E0D0',
42666 royalblue: '#4169E1',
42667 steelblue: '#4682B4',
42668 darkslateblue: '#483D8B',
42669 mediumturquoise: '#48D1CC',
42670 indigo: '#4B0082',
42671 darkolivegreen: '#556B2F',
42672 cadetblue: '#5F9EA0',
42673 cornflowerblue: '#6495ED',
42674 mediumaquamarine: '#66CDAA',
42675 dimgray: '#696969',
42676 slateblue: '#6A5ACD',
42677 olivedrab: '#6B8E23',
42678 slategray: '#708090',
42679 lightslategray: '#778899',
42680 mediumslateblue: '#7B68EE',
42681 lawngreen: '#7CFC00',
42682 chartreuse: '#7FFF00',
42683 aquamarine: '#7FFFD4',
42684 maroon: '#800000',
42685 purple: '#800080',
42686 olive: '#808000',
42687 gray: '#808080',
42688 skyblue: '#87CEEB',
42689 lightskyblue: '#87CEFA',
42690 blueviolet: '#8A2BE2',
42691 darkred: '#8B0000',
42692 darkmagenta: '#8B008B',
42693 saddlebrown: '#8B4513',
42694 darkseagreen: '#8FBC8F',
42695 lightgreen: '#90EE90',
42696 mediumpurple: '#9370D8',
42697 darkviolet: '#9400D3',
42698 palegreen: '#98FB98',
42699 darkorchid: '#9932CC',
42700 yellowgreen: '#9ACD32',
42701 sienna: '#A0522D',
42702 brown: '#A52A2A',
42703 darkgray: '#A9A9A9',
42704 lightblue: '#ADD8E6',
42705 greenyellow: '#ADFF2F',
42706 paleturquoise: '#AFEEEE',
42707 lightsteelblue: '#B0C4DE',
42708 powderblue: '#B0E0E6',
42709 firebrick: '#B22222',
42710 darkgoldenrod: '#B8860B',
42711 mediumorchid: '#BA55D3',
42712 rosybrown: '#BC8F8F',
42713 darkkhaki: '#BDB76B',
42714 silver: '#C0C0C0',
42715 mediumvioletred: '#C71585',
42716 indianred: '#CD5C5C',
42717 peru: '#CD853F',
42718 chocolate: '#D2691E',
42719 tan: '#D2B48C',
42720 lightgrey: '#D3D3D3',
42721 palevioletred: '#D87093',
42722 thistle: '#D8BFD8',
42723 orchid: '#DA70D6',
42724 goldenrod: '#DAA520',
42725 crimson: '#DC143C',
42726 gainsboro: '#DCDCDC',
42727 plum: '#DDA0DD',
42728 burlywood: '#DEB887',
42729 lightcyan: '#E0FFFF',
42730 lavender: '#E6E6FA',
42731 darksalmon: '#E9967A',
42732 violet: '#EE82EE',
42733 palegoldenrod: '#EEE8AA',
42734 lightcoral: '#F08080',
42735 khaki: '#F0E68C',
42736 aliceblue: '#F0F8FF',
42737 honeydew: '#F0FFF0',
42738 azure: '#F0FFFF',
42739 sandybrown: '#F4A460',
42740 wheat: '#F5DEB3',
42741 beige: '#F5F5DC',
42742 whitesmoke: '#F5F5F5',
42743 mintcream: '#F5FFFA',
42744 ghostwhite: '#F8F8FF',
42745 salmon: '#FA8072',
42746 antiquewhite: '#FAEBD7',
42747 linen: '#FAF0E6',
42748 lightgoldenrodyellow: '#FAFAD2',
42749 oldlace: '#FDF5E6',
42750 red: '#FF0000',
42751 fuchsia: '#FF00FF',
42752 magenta: '#FF00FF',
42753 deeppink: '#FF1493',
42754 orangered: '#FF4500',
42755 tomato: '#FF6347',
42756 hotpink: '#FF69B4',
42757 coral: '#FF7F50',
42758 darkorange: '#FF8C00',
42759 lightsalmon: '#FFA07A',
42760 orange: '#FFA500',
42761 lightpink: '#FFB6C1',
42762 pink: '#FFC0CB',
42763 gold: '#FFD700',
42764 peachpuff: '#FFDAB9',
42765 navajowhite: '#FFDEAD',
42766 moccasin: '#FFE4B5',
42767 bisque: '#FFE4C4',
42768 mistyrose: '#FFE4E1',
42769 blanchedalmond: '#FFEBCD',
42770 papayawhip: '#FFEFD5',
42771 lavenderblush: '#FFF0F5',
42772 seashell: '#FFF5EE',
42773 cornsilk: '#FFF8DC',
42774 lemonchiffon: '#FFFACD',
42775 floralwhite: '#FFFAF0',
42776 snow: '#FFFAFA',
42777 yellow: '#FFFF00',
42778 lightyellow: '#FFFFE0',
42779 ivory: '#FFFFF0',
42780 white: '#FFFFFF'
42781};
42782/**
42783 * @param {number} [pixelRatio=1]
42784 */
42785
42786var ColorPicker =
42787/*#__PURE__*/
42788function () {
42789 /**
42790 * @param {number} [pixelRatio=1]
42791 */
42792 function ColorPicker() {
42793 var pixelRatio = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
42794
42795 _classCallCheck(this, ColorPicker);
42796
42797 this.pixelRatio = pixelRatio;
42798 this.generated = false;
42799 this.centerCoordinates = {
42800 x: 289 / 2,
42801 y: 289 / 2
42802 };
42803 this.r = 289 * 0.49;
42804 this.color = {
42805 r: 255,
42806 g: 255,
42807 b: 255,
42808 a: 1.0
42809 };
42810 this.hueCircle = undefined;
42811 this.initialColor = {
42812 r: 255,
42813 g: 255,
42814 b: 255,
42815 a: 1.0
42816 };
42817 this.previousColor = undefined;
42818 this.applied = false; // bound by
42819
42820 this.updateCallback = function () {};
42821
42822 this.closeCallback = function () {}; // create all DOM elements
42823
42824
42825 this._create();
42826 }
42827 /**
42828 * this inserts the colorPicker into a div from the DOM
42829 * @param {Element} container
42830 */
42831
42832
42833 _createClass(ColorPicker, [{
42834 key: "insertTo",
42835 value: function insertTo(container) {
42836 if (this.hammer !== undefined) {
42837 this.hammer.destroy();
42838 this.hammer = undefined;
42839 }
42840
42841 this.container = container;
42842 this.container.appendChild(this.frame);
42843
42844 this._bindHammer();
42845
42846 this._setSize();
42847 }
42848 /**
42849 * the callback is executed on apply and save. Bind it to the application
42850 * @param {function} callback
42851 */
42852
42853 }, {
42854 key: "setUpdateCallback",
42855 value: function setUpdateCallback(callback) {
42856 if (typeof callback === 'function') {
42857 this.updateCallback = callback;
42858 } else {
42859 throw new Error("Function attempted to set as colorPicker update callback is not a function.");
42860 }
42861 }
42862 /**
42863 * the callback is executed on apply and save. Bind it to the application
42864 * @param {function} callback
42865 */
42866
42867 }, {
42868 key: "setCloseCallback",
42869 value: function setCloseCallback(callback) {
42870 if (typeof callback === 'function') {
42871 this.closeCallback = callback;
42872 } else {
42873 throw new Error("Function attempted to set as colorPicker closing callback is not a function.");
42874 }
42875 }
42876 /**
42877 *
42878 * @param {string} color
42879 * @returns {String}
42880 * @private
42881 */
42882
42883 }, {
42884 key: "_isColorString",
42885 value: function _isColorString(color) {
42886 if (typeof color === 'string') {
42887 return htmlColors[color];
42888 }
42889 }
42890 /**
42891 * Set the color of the colorPicker
42892 * Supported formats:
42893 * 'red' --> HTML color string
42894 * '#ffffff' --> hex string
42895 * 'rgb(255,255,255)' --> rgb string
42896 * 'rgba(255,255,255,1.0)' --> rgba string
42897 * {r:255,g:255,b:255} --> rgb object
42898 * {r:255,g:255,b:255,a:1.0} --> rgba object
42899 * @param {string|Object} color
42900 * @param {boolean} [setInitial=true]
42901 */
42902
42903 }, {
42904 key: "setColor",
42905 value: function setColor(color) {
42906 var setInitial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
42907
42908 if (color === 'none') {
42909 return;
42910 }
42911
42912 var rgba; // if a html color shorthand is used, convert to hex
42913
42914 var htmlColor = this._isColorString(color);
42915
42916 if (htmlColor !== undefined) {
42917 color = htmlColor;
42918 } // check format
42919
42920
42921 if (util.isString(color) === true) {
42922 if (util.isValidRGB(color) === true) {
42923 var rgbaArray = color.substr(4).substr(0, color.length - 5).split(',');
42924 rgba = {
42925 r: rgbaArray[0],
42926 g: rgbaArray[1],
42927 b: rgbaArray[2],
42928 a: 1.0
42929 };
42930 } else if (util.isValidRGBA(color) === true) {
42931 var _rgbaArray = color.substr(5).substr(0, color.length - 6).split(',');
42932
42933 rgba = {
42934 r: _rgbaArray[0],
42935 g: _rgbaArray[1],
42936 b: _rgbaArray[2],
42937 a: _rgbaArray[3]
42938 };
42939 } else if (util.isValidHex(color) === true) {
42940 var rgbObj = util.hexToRGB(color);
42941 rgba = {
42942 r: rgbObj.r,
42943 g: rgbObj.g,
42944 b: rgbObj.b,
42945 a: 1.0
42946 };
42947 }
42948 } else {
42949 if (color instanceof Object) {
42950 if (color.r !== undefined && color.g !== undefined && color.b !== undefined) {
42951 var alpha = color.a !== undefined ? color.a : '1.0';
42952 rgba = {
42953 r: color.r,
42954 g: color.g,
42955 b: color.b,
42956 a: alpha
42957 };
42958 }
42959 }
42960 } // set color
42961
42962
42963 if (rgba === undefined) {
42964 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));
42965 } else {
42966 this._setColor(rgba, setInitial);
42967 }
42968 }
42969 /**
42970 * this shows the color picker.
42971 * The hue circle is constructed once and stored.
42972 */
42973
42974 }, {
42975 key: "show",
42976 value: function show() {
42977 if (this.closeCallback !== undefined) {
42978 this.closeCallback();
42979 this.closeCallback = undefined;
42980 }
42981
42982 this.applied = false;
42983 this.frame.style.display = 'block';
42984
42985 this._generateHueCircle();
42986 } // ------------------------------------------ PRIVATE ----------------------------- //
42987
42988 /**
42989 * Hide the picker. Is called by the cancel button.
42990 * Optional boolean to store the previous color for easy access later on.
42991 * @param {boolean} [storePrevious=true]
42992 * @private
42993 */
42994
42995 }, {
42996 key: "_hide",
42997 value: function _hide() {
42998 var _this = this;
42999
43000 var storePrevious = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
43001
43002 // store the previous color for next time;
43003 if (storePrevious === true) {
43004 this.previousColor = util.extend({}, this.color);
43005 }
43006
43007 if (this.applied === true) {
43008 this.updateCallback(this.initialColor);
43009 }
43010
43011 this.frame.style.display = 'none'; // call the closing callback, restoring the onclick method.
43012 // this is in a setTimeout because it will trigger the show again before the click is done.
43013
43014 setTimeout(function () {
43015 if (_this.closeCallback !== undefined) {
43016 _this.closeCallback();
43017
43018 _this.closeCallback = undefined;
43019 }
43020 }, 0);
43021 }
43022 /**
43023 * bound to the save button. Saves and hides.
43024 * @private
43025 */
43026
43027 }, {
43028 key: "_save",
43029 value: function _save() {
43030 this.updateCallback(this.color);
43031 this.applied = false;
43032
43033 this._hide();
43034 }
43035 /**
43036 * Bound to apply button. Saves but does not close. Is undone by the cancel button.
43037 * @private
43038 */
43039
43040 }, {
43041 key: "_apply",
43042 value: function _apply() {
43043 this.applied = true;
43044 this.updateCallback(this.color);
43045
43046 this._updatePicker(this.color);
43047 }
43048 /**
43049 * load the color from the previous session.
43050 * @private
43051 */
43052
43053 }, {
43054 key: "_loadLast",
43055 value: function _loadLast() {
43056 if (this.previousColor !== undefined) {
43057 this.setColor(this.previousColor, false);
43058 } else {
43059 alert("There is no last color to load...");
43060 }
43061 }
43062 /**
43063 * set the color, place the picker
43064 * @param {Object} rgba
43065 * @param {boolean} [setInitial=true]
43066 * @private
43067 */
43068
43069 }, {
43070 key: "_setColor",
43071 value: function _setColor(rgba) {
43072 var setInitial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
43073
43074 // store the initial color
43075 if (setInitial === true) {
43076 this.initialColor = util.extend({}, rgba);
43077 }
43078
43079 this.color = rgba;
43080 var hsv = util.RGBToHSV(rgba.r, rgba.g, rgba.b);
43081 var angleConvert = 2 * Math.PI;
43082 var radius = this.r * hsv.s;
43083 var x = this.centerCoordinates.x + radius * Math.sin(angleConvert * hsv.h);
43084 var y = this.centerCoordinates.y + radius * Math.cos(angleConvert * hsv.h);
43085 this.colorPickerSelector.style.left = x - 0.5 * this.colorPickerSelector.clientWidth + 'px';
43086 this.colorPickerSelector.style.top = y - 0.5 * this.colorPickerSelector.clientHeight + 'px';
43087
43088 this._updatePicker(rgba);
43089 }
43090 /**
43091 * bound to opacity control
43092 * @param {number} value
43093 * @private
43094 */
43095
43096 }, {
43097 key: "_setOpacity",
43098 value: function _setOpacity(value) {
43099 this.color.a = value / 100;
43100
43101 this._updatePicker(this.color);
43102 }
43103 /**
43104 * bound to brightness control
43105 * @param {number} value
43106 * @private
43107 */
43108
43109 }, {
43110 key: "_setBrightness",
43111 value: function _setBrightness(value) {
43112 var hsv = util.RGBToHSV(this.color.r, this.color.g, this.color.b);
43113 hsv.v = value / 100;
43114 var rgba = util.HSVToRGB(hsv.h, hsv.s, hsv.v);
43115 rgba['a'] = this.color.a;
43116 this.color = rgba;
43117
43118 this._updatePicker();
43119 }
43120 /**
43121 * update the color picker. A black circle overlays the hue circle to mimic the brightness decreasing.
43122 * @param {Object} rgba
43123 * @private
43124 */
43125
43126 }, {
43127 key: "_updatePicker",
43128 value: function _updatePicker() {
43129 var rgba = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.color;
43130 var hsv = util.RGBToHSV(rgba.r, rgba.g, rgba.b);
43131 var ctx = this.colorPickerCanvas.getContext('2d');
43132
43133 if (this.pixelRation === undefined) {
43134 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
43135 }
43136
43137 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); // clear the canvas
43138
43139 var w = this.colorPickerCanvas.clientWidth;
43140 var h = this.colorPickerCanvas.clientHeight;
43141 ctx.clearRect(0, 0, w, h);
43142 ctx.putImageData(this.hueCircle, 0, 0);
43143 ctx.fillStyle = 'rgba(0,0,0,' + (1 - hsv.v) + ')';
43144 ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
43145 ctx.fill();
43146 this.brightnessRange.value = 100 * hsv.v;
43147 this.opacityRange.value = 100 * rgba.a;
43148 this.initialColorDiv.style.backgroundColor = 'rgba(' + this.initialColor.r + ',' + this.initialColor.g + ',' + this.initialColor.b + ',' + this.initialColor.a + ')';
43149 this.newColorDiv.style.backgroundColor = 'rgba(' + this.color.r + ',' + this.color.g + ',' + this.color.b + ',' + this.color.a + ')';
43150 }
43151 /**
43152 * used by create to set the size of the canvas.
43153 * @private
43154 */
43155
43156 }, {
43157 key: "_setSize",
43158 value: function _setSize() {
43159 this.colorPickerCanvas.style.width = '100%';
43160 this.colorPickerCanvas.style.height = '100%';
43161 this.colorPickerCanvas.width = 289 * this.pixelRatio;
43162 this.colorPickerCanvas.height = 289 * this.pixelRatio;
43163 }
43164 /**
43165 * create all dom elements
43166 * TODO: cleanup, lots of similar dom elements
43167 * @private
43168 */
43169
43170 }, {
43171 key: "_create",
43172 value: function _create() {
43173 this.frame = document.createElement('div');
43174 this.frame.className = 'vis-color-picker';
43175 this.colorPickerDiv = document.createElement('div');
43176 this.colorPickerSelector = document.createElement('div');
43177 this.colorPickerSelector.className = 'vis-selector';
43178 this.colorPickerDiv.appendChild(this.colorPickerSelector);
43179 this.colorPickerCanvas = document.createElement('canvas');
43180 this.colorPickerDiv.appendChild(this.colorPickerCanvas);
43181
43182 if (!this.colorPickerCanvas.getContext) {
43183 var noCanvas = document.createElement('DIV');
43184 noCanvas.style.color = 'red';
43185 noCanvas.style.fontWeight = 'bold';
43186 noCanvas.style.padding = '10px';
43187 noCanvas.innerHTML = 'Error: your browser does not support HTML canvas';
43188 this.colorPickerCanvas.appendChild(noCanvas);
43189 } else {
43190 var ctx = this.colorPickerCanvas.getContext("2d");
43191 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
43192 this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
43193 }
43194
43195 this.colorPickerDiv.className = 'vis-color';
43196 this.opacityDiv = document.createElement('div');
43197 this.opacityDiv.className = 'vis-opacity';
43198 this.brightnessDiv = document.createElement('div');
43199 this.brightnessDiv.className = 'vis-brightness';
43200 this.arrowDiv = document.createElement('div');
43201 this.arrowDiv.className = 'vis-arrow';
43202 this.opacityRange = document.createElement('input');
43203
43204 try {
43205 this.opacityRange.type = 'range'; // Not supported on IE9
43206
43207 this.opacityRange.min = '0';
43208 this.opacityRange.max = '100';
43209 } // TODO: Add some error handling and remove this lint exception
43210 catch (err) {} // eslint-disable-line no-empty
43211
43212
43213 this.opacityRange.value = '100';
43214 this.opacityRange.className = 'vis-range';
43215 this.brightnessRange = document.createElement('input');
43216
43217 try {
43218 this.brightnessRange.type = 'range'; // Not supported on IE9
43219
43220 this.brightnessRange.min = '0';
43221 this.brightnessRange.max = '100';
43222 } // TODO: Add some error handling and remove this lint exception
43223 catch (err) {} // eslint-disable-line no-empty
43224
43225
43226 this.brightnessRange.value = '100';
43227 this.brightnessRange.className = 'vis-range';
43228 this.opacityDiv.appendChild(this.opacityRange);
43229 this.brightnessDiv.appendChild(this.brightnessRange);
43230 var me = this;
43231
43232 this.opacityRange.onchange = function () {
43233 me._setOpacity(this.value);
43234 };
43235
43236 this.opacityRange.oninput = function () {
43237 me._setOpacity(this.value);
43238 };
43239
43240 this.brightnessRange.onchange = function () {
43241 me._setBrightness(this.value);
43242 };
43243
43244 this.brightnessRange.oninput = function () {
43245 me._setBrightness(this.value);
43246 };
43247
43248 this.brightnessLabel = document.createElement("div");
43249 this.brightnessLabel.className = "vis-label vis-brightness";
43250 this.brightnessLabel.innerHTML = 'brightness:';
43251 this.opacityLabel = document.createElement("div");
43252 this.opacityLabel.className = "vis-label vis-opacity";
43253 this.opacityLabel.innerHTML = 'opacity:';
43254 this.newColorDiv = document.createElement("div");
43255 this.newColorDiv.className = "vis-new-color";
43256 this.newColorDiv.innerHTML = 'new';
43257 this.initialColorDiv = document.createElement("div");
43258 this.initialColorDiv.className = "vis-initial-color";
43259 this.initialColorDiv.innerHTML = 'initial';
43260 this.cancelButton = document.createElement("div");
43261 this.cancelButton.className = "vis-button vis-cancel";
43262 this.cancelButton.innerHTML = 'cancel';
43263 this.cancelButton.onclick = this._hide.bind(this, false);
43264 this.applyButton = document.createElement("div");
43265 this.applyButton.className = "vis-button vis-apply";
43266 this.applyButton.innerHTML = 'apply';
43267 this.applyButton.onclick = this._apply.bind(this);
43268 this.saveButton = document.createElement("div");
43269 this.saveButton.className = "vis-button vis-save";
43270 this.saveButton.innerHTML = 'save';
43271 this.saveButton.onclick = this._save.bind(this);
43272 this.loadButton = document.createElement("div");
43273 this.loadButton.className = "vis-button vis-load";
43274 this.loadButton.innerHTML = 'load last';
43275 this.loadButton.onclick = this._loadLast.bind(this);
43276 this.frame.appendChild(this.colorPickerDiv);
43277 this.frame.appendChild(this.arrowDiv);
43278 this.frame.appendChild(this.brightnessLabel);
43279 this.frame.appendChild(this.brightnessDiv);
43280 this.frame.appendChild(this.opacityLabel);
43281 this.frame.appendChild(this.opacityDiv);
43282 this.frame.appendChild(this.newColorDiv);
43283 this.frame.appendChild(this.initialColorDiv);
43284 this.frame.appendChild(this.cancelButton);
43285 this.frame.appendChild(this.applyButton);
43286 this.frame.appendChild(this.saveButton);
43287 this.frame.appendChild(this.loadButton);
43288 }
43289 /**
43290 * bind hammer to the color picker
43291 * @private
43292 */
43293
43294 }, {
43295 key: "_bindHammer",
43296 value: function _bindHammer() {
43297 var _this2 = this;
43298
43299 this.drag = {};
43300 this.pinch = {};
43301 this.hammer = new Hammer$1(this.colorPickerCanvas);
43302 this.hammer.get('pinch').set({
43303 enable: true
43304 });
43305 onTouch(this.hammer, function (event) {
43306 _this2._moveSelector(event);
43307 });
43308 this.hammer.on('tap', function (event) {
43309 _this2._moveSelector(event);
43310 });
43311 this.hammer.on('panstart', function (event) {
43312 _this2._moveSelector(event);
43313 });
43314 this.hammer.on('panmove', function (event) {
43315 _this2._moveSelector(event);
43316 });
43317 this.hammer.on('panend', function (event) {
43318 _this2._moveSelector(event);
43319 });
43320 }
43321 /**
43322 * generate the hue circle. This is relatively heavy (200ms) and is done only once on the first time it is shown.
43323 * @private
43324 */
43325
43326 }, {
43327 key: "_generateHueCircle",
43328 value: function _generateHueCircle() {
43329 if (this.generated === false) {
43330 var ctx = this.colorPickerCanvas.getContext('2d');
43331
43332 if (this.pixelRation === undefined) {
43333 this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1);
43334 }
43335
43336 ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); // clear the canvas
43337
43338 var w = this.colorPickerCanvas.clientWidth;
43339 var h = this.colorPickerCanvas.clientHeight;
43340 ctx.clearRect(0, 0, w, h); // draw hue circle
43341
43342 var x, y, hue, sat;
43343 this.centerCoordinates = {
43344 x: w * 0.5,
43345 y: h * 0.5
43346 };
43347 this.r = 0.49 * w;
43348 var angleConvert = 2 * Math.PI / 360;
43349 var hfac = 1 / 360;
43350 var sfac = 1 / this.r;
43351 var rgb;
43352
43353 for (hue = 0; hue < 360; hue++) {
43354 for (sat = 0; sat < this.r; sat++) {
43355 x = this.centerCoordinates.x + sat * Math.sin(angleConvert * hue);
43356 y = this.centerCoordinates.y + sat * Math.cos(angleConvert * hue);
43357 rgb = util.HSVToRGB(hue * hfac, sat * sfac, 1);
43358 ctx.fillStyle = 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
43359 ctx.fillRect(x - 0.5, y - 0.5, 2, 2);
43360 }
43361 }
43362
43363 ctx.strokeStyle = 'rgba(0,0,0,1)';
43364 ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
43365 ctx.stroke();
43366 this.hueCircle = ctx.getImageData(0, 0, w, h);
43367 }
43368
43369 this.generated = true;
43370 }
43371 /**
43372 * move the selector. This is called by hammer functions.
43373 *
43374 * @param {Event} event The event
43375 * @private
43376 */
43377
43378 }, {
43379 key: "_moveSelector",
43380 value: function _moveSelector(event) {
43381 var rect = this.colorPickerDiv.getBoundingClientRect();
43382 var left = event.center.x - rect.left;
43383 var top = event.center.y - rect.top;
43384 var centerY = 0.5 * this.colorPickerDiv.clientHeight;
43385 var centerX = 0.5 * this.colorPickerDiv.clientWidth;
43386 var x = left - centerX;
43387 var y = top - centerY;
43388 var angle = Math.atan2(x, y);
43389 var radius = 0.98 * Math.min(Math.sqrt(x * x + y * y), centerX);
43390 var newTop = Math.cos(angle) * radius + centerY;
43391 var newLeft = Math.sin(angle) * radius + centerX;
43392 this.colorPickerSelector.style.top = newTop - 0.5 * this.colorPickerSelector.clientHeight + 'px';
43393 this.colorPickerSelector.style.left = newLeft - 0.5 * this.colorPickerSelector.clientWidth + 'px'; // set color
43394
43395 var h = angle / (2 * Math.PI);
43396 h = h < 0 ? h + 1 : h;
43397 var s = radius / this.r;
43398 var hsv = util.RGBToHSV(this.color.r, this.color.g, this.color.b);
43399 hsv.h = h;
43400 hsv.s = s;
43401 var rgba = util.HSVToRGB(hsv.h, hsv.s, hsv.v);
43402 rgba['a'] = this.color.a;
43403 this.color = rgba; // update previews
43404
43405 this.initialColorDiv.style.backgroundColor = 'rgba(' + this.initialColor.r + ',' + this.initialColor.g + ',' + this.initialColor.b + ',' + this.initialColor.a + ')';
43406 this.newColorDiv.style.backgroundColor = 'rgba(' + this.color.r + ',' + this.color.g + ',' + this.color.b + ',' + this.color.a + ')';
43407 }
43408 }]);
43409
43410 return ColorPicker;
43411}();
43412
43413/**
43414 * 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.
43415 * Boolean options are recognised as Boolean
43416 * Number options should be written as array: [default value, min value, max value, stepsize]
43417 * Colors should be written as array: ['color', '#ffffff']
43418 * Strings with should be written as array: [option1, option2, option3, ..]
43419 *
43420 * The options are matched with their counterparts in each of the modules and the values used in the configuration are
43421 */
43422
43423var Configurator =
43424/*#__PURE__*/
43425function () {
43426 /**
43427 * @param {Object} parentModule | the location where parentModule.setOptions() can be called
43428 * @param {Object} defaultContainer | the default container of the module
43429 * @param {Object} configureOptions | the fully configured and predefined options set found in allOptions.js
43430 * @param {number} pixelRatio | canvas pixel ratio
43431 */
43432 function Configurator(parentModule, defaultContainer, configureOptions) {
43433 var pixelRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
43434
43435 _classCallCheck(this, Configurator);
43436
43437 this.parent = parentModule;
43438 this.changedOptions = [];
43439 this.container = defaultContainer;
43440 this.allowCreation = false;
43441 this.options = {};
43442 this.initialized = false;
43443 this.popupCounter = 0;
43444 this.defaultOptions = {
43445 enabled: false,
43446 filter: true,
43447 container: undefined,
43448 showButton: true
43449 };
43450 util.extend(this.options, this.defaultOptions);
43451 this.configureOptions = configureOptions;
43452 this.moduleOptions = {};
43453 this.domElements = [];
43454 this.popupDiv = {};
43455 this.popupLimit = 5;
43456 this.popupHistory = {};
43457 this.colorPicker = new ColorPicker(pixelRatio);
43458 this.wrapper = undefined;
43459 }
43460 /**
43461 * refresh all options.
43462 * Because all modules parse their options by themselves, we just use their options. We copy them here.
43463 *
43464 * @param {Object} options
43465 */
43466
43467
43468 _createClass(Configurator, [{
43469 key: "setOptions",
43470 value: function setOptions(options) {
43471 if (options !== undefined) {
43472 // reset the popup history because the indices may have been changed.
43473 this.popupHistory = {};
43474
43475 this._removePopup();
43476
43477 var enabled = true;
43478
43479 if (typeof options === 'string') {
43480 this.options.filter = options;
43481 } else if (options instanceof Array) {
43482 this.options.filter = options.join();
43483 } else if (_typeof(options) === 'object') {
43484 if (options == null) {
43485 throw new TypeError('options cannot be null');
43486 }
43487
43488 if (options.container !== undefined) {
43489 this.options.container = options.container;
43490 }
43491
43492 if (options.filter !== undefined) {
43493 this.options.filter = options.filter;
43494 }
43495
43496 if (options.showButton !== undefined) {
43497 this.options.showButton = options.showButton;
43498 }
43499
43500 if (options.enabled !== undefined) {
43501 enabled = options.enabled;
43502 }
43503 } else if (typeof options === 'boolean') {
43504 this.options.filter = true;
43505 enabled = options;
43506 } else if (typeof options === 'function') {
43507 this.options.filter = options;
43508 enabled = true;
43509 }
43510
43511 if (this.options.filter === false) {
43512 enabled = false;
43513 }
43514
43515 this.options.enabled = enabled;
43516 }
43517
43518 this._clean();
43519 }
43520 /**
43521 *
43522 * @param {Object} moduleOptions
43523 */
43524
43525 }, {
43526 key: "setModuleOptions",
43527 value: function setModuleOptions(moduleOptions) {
43528 this.moduleOptions = moduleOptions;
43529
43530 if (this.options.enabled === true) {
43531 this._clean();
43532
43533 if (this.options.container !== undefined) {
43534 this.container = this.options.container;
43535 }
43536
43537 this._create();
43538 }
43539 }
43540 /**
43541 * Create all DOM elements
43542 * @private
43543 */
43544
43545 }, {
43546 key: "_create",
43547 value: function _create() {
43548 this._clean();
43549
43550 this.changedOptions = [];
43551 var filter = this.options.filter;
43552 var counter = 0;
43553 var show = false;
43554
43555 for (var option in this.configureOptions) {
43556 if (this.configureOptions.hasOwnProperty(option)) {
43557 this.allowCreation = false;
43558 show = false;
43559
43560 if (typeof filter === 'function') {
43561 show = filter(option, []);
43562 show = show || this._handleObject(this.configureOptions[option], [option], true);
43563 } else if (filter === true || filter.indexOf(option) !== -1) {
43564 show = true;
43565 }
43566
43567 if (show !== false) {
43568 this.allowCreation = true; // linebreak between categories
43569
43570 if (counter > 0) {
43571 this._makeItem([]);
43572 } // a header for the category
43573
43574
43575 this._makeHeader(option); // get the sub options
43576
43577
43578 this._handleObject(this.configureOptions[option], [option]);
43579 }
43580
43581 counter++;
43582 }
43583 }
43584
43585 this._makeButton();
43586
43587 this._push(); //~ this.colorPicker.insertTo(this.container);
43588
43589 }
43590 /**
43591 * draw all DOM elements on the screen
43592 * @private
43593 */
43594
43595 }, {
43596 key: "_push",
43597 value: function _push() {
43598 this.wrapper = document.createElement('div');
43599 this.wrapper.className = 'vis-configuration-wrapper';
43600 this.container.appendChild(this.wrapper);
43601
43602 for (var i = 0; i < this.domElements.length; i++) {
43603 this.wrapper.appendChild(this.domElements[i]);
43604 }
43605
43606 this._showPopupIfNeeded();
43607 }
43608 /**
43609 * delete all DOM elements
43610 * @private
43611 */
43612
43613 }, {
43614 key: "_clean",
43615 value: function _clean() {
43616 for (var i = 0; i < this.domElements.length; i++) {
43617 this.wrapper.removeChild(this.domElements[i]);
43618 }
43619
43620 if (this.wrapper !== undefined) {
43621 this.container.removeChild(this.wrapper);
43622 this.wrapper = undefined;
43623 }
43624
43625 this.domElements = [];
43626
43627 this._removePopup();
43628 }
43629 /**
43630 * get the value from the actualOptions if it exists
43631 * @param {array} path | where to look for the actual option
43632 * @returns {*}
43633 * @private
43634 */
43635
43636 }, {
43637 key: "_getValue",
43638 value: function _getValue(path) {
43639 var base = this.moduleOptions;
43640
43641 for (var i = 0; i < path.length; i++) {
43642 if (base[path[i]] !== undefined) {
43643 base = base[path[i]];
43644 } else {
43645 base = undefined;
43646 break;
43647 }
43648 }
43649
43650 return base;
43651 }
43652 /**
43653 * all option elements are wrapped in an item
43654 * @param {Array} path | where to look for the actual option
43655 * @param {Array.<Element>} domElements
43656 * @returns {number}
43657 * @private
43658 */
43659
43660 }, {
43661 key: "_makeItem",
43662 value: function _makeItem(path) {
43663 if (this.allowCreation === true) {
43664 var item = document.createElement('div');
43665 item.className = 'vis-configuration vis-config-item vis-config-s' + path.length;
43666
43667 for (var _len = arguments.length, domElements = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
43668 domElements[_key - 1] = arguments[_key];
43669 }
43670
43671 domElements.forEach(function (element) {
43672 item.appendChild(element);
43673 });
43674 this.domElements.push(item);
43675 return this.domElements.length;
43676 }
43677
43678 return 0;
43679 }
43680 /**
43681 * header for major subjects
43682 * @param {string} name
43683 * @private
43684 */
43685
43686 }, {
43687 key: "_makeHeader",
43688 value: function _makeHeader(name) {
43689 var div = document.createElement('div');
43690 div.className = 'vis-configuration vis-config-header';
43691 div.innerHTML = name;
43692
43693 this._makeItem([], div);
43694 }
43695 /**
43696 * make a label, if it is an object label, it gets different styling.
43697 * @param {string} name
43698 * @param {array} path | where to look for the actual option
43699 * @param {string} objectLabel
43700 * @returns {HTMLElement}
43701 * @private
43702 */
43703
43704 }, {
43705 key: "_makeLabel",
43706 value: function _makeLabel(name, path) {
43707 var objectLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
43708 var div = document.createElement('div');
43709 div.className = 'vis-configuration vis-config-label vis-config-s' + path.length;
43710
43711 if (objectLabel === true) {
43712 div.innerHTML = '<i><b>' + name + ':</b></i>';
43713 } else {
43714 div.innerHTML = name + ':';
43715 }
43716
43717 return div;
43718 }
43719 /**
43720 * make a dropdown list for multiple possible string optoins
43721 * @param {Array.<number>} arr
43722 * @param {number} value
43723 * @param {array} path | where to look for the actual option
43724 * @private
43725 */
43726
43727 }, {
43728 key: "_makeDropdown",
43729 value: function _makeDropdown(arr, value, path) {
43730 var select = document.createElement('select');
43731 select.className = 'vis-configuration vis-config-select';
43732 var selectedValue = 0;
43733
43734 if (value !== undefined) {
43735 if (arr.indexOf(value) !== -1) {
43736 selectedValue = arr.indexOf(value);
43737 }
43738 }
43739
43740 for (var i = 0; i < arr.length; i++) {
43741 var option = document.createElement('option');
43742 option.value = arr[i];
43743
43744 if (i === selectedValue) {
43745 option.selected = 'selected';
43746 }
43747
43748 option.innerHTML = arr[i];
43749 select.appendChild(option);
43750 }
43751
43752 var me = this;
43753
43754 select.onchange = function () {
43755 me._update(this.value, path);
43756 };
43757
43758 var label = this._makeLabel(path[path.length - 1], path);
43759
43760 this._makeItem(path, label, select);
43761 }
43762 /**
43763 * make a range object for numeric options
43764 * @param {Array.<number>} arr
43765 * @param {number} value
43766 * @param {array} path | where to look for the actual option
43767 * @private
43768 */
43769
43770 }, {
43771 key: "_makeRange",
43772 value: function _makeRange(arr, value, path) {
43773 var defaultValue = arr[0];
43774 var min = arr[1];
43775 var max = arr[2];
43776 var step = arr[3];
43777 var range = document.createElement('input');
43778 range.className = 'vis-configuration vis-config-range';
43779
43780 try {
43781 range.type = 'range'; // not supported on IE9
43782
43783 range.min = min;
43784 range.max = max;
43785 } // TODO: Add some error handling and remove this lint exception
43786 catch (err) {} // eslint-disable-line no-empty
43787
43788
43789 range.step = step; // set up the popup settings in case they are needed.
43790
43791 var popupString = '';
43792 var popupValue = 0;
43793
43794 if (value !== undefined) {
43795 var factor = 1.20;
43796
43797 if (value < 0 && value * factor < min) {
43798 range.min = Math.ceil(value * factor);
43799 popupValue = range.min;
43800 popupString = 'range increased';
43801 } else if (value / factor < min) {
43802 range.min = Math.ceil(value / factor);
43803 popupValue = range.min;
43804 popupString = 'range increased';
43805 }
43806
43807 if (value * factor > max && max !== 1) {
43808 range.max = Math.ceil(value * factor);
43809 popupValue = range.max;
43810 popupString = 'range increased';
43811 }
43812
43813 range.value = value;
43814 } else {
43815 range.value = defaultValue;
43816 }
43817
43818 var input = document.createElement('input');
43819 input.className = 'vis-configuration vis-config-rangeinput';
43820 input.value = range.value;
43821 var me = this;
43822
43823 range.onchange = function () {
43824 input.value = this.value;
43825
43826 me._update(Number(this.value), path);
43827 };
43828
43829 range.oninput = function () {
43830 input.value = this.value;
43831 };
43832
43833 var label = this._makeLabel(path[path.length - 1], path);
43834
43835 var itemIndex = this._makeItem(path, label, range, input); // if a popup is needed AND it has not been shown for this value, show it.
43836
43837
43838 if (popupString !== '' && this.popupHistory[itemIndex] !== popupValue) {
43839 this.popupHistory[itemIndex] = popupValue;
43840
43841 this._setupPopup(popupString, itemIndex);
43842 }
43843 }
43844 /**
43845 * make a button object
43846 * @private
43847 */
43848
43849 }, {
43850 key: "_makeButton",
43851 value: function _makeButton() {
43852 var _this = this;
43853
43854 if (this.options.showButton === true) {
43855 var generateButton = document.createElement('div');
43856 generateButton.className = 'vis-configuration vis-config-button';
43857 generateButton.innerHTML = 'generate options';
43858
43859 generateButton.onclick = function () {
43860 _this._printOptions();
43861 };
43862
43863 generateButton.onmouseover = function () {
43864 generateButton.className = 'vis-configuration vis-config-button hover';
43865 };
43866
43867 generateButton.onmouseout = function () {
43868 generateButton.className = 'vis-configuration vis-config-button';
43869 };
43870
43871 this.optionsContainer = document.createElement('div');
43872 this.optionsContainer.className = 'vis-configuration vis-config-option-container';
43873 this.domElements.push(this.optionsContainer);
43874 this.domElements.push(generateButton);
43875 }
43876 }
43877 /**
43878 * prepare the popup
43879 * @param {string} string
43880 * @param {number} index
43881 * @private
43882 */
43883
43884 }, {
43885 key: "_setupPopup",
43886 value: function _setupPopup(string, index) {
43887 var _this2 = this;
43888
43889 if (this.initialized === true && this.allowCreation === true && this.popupCounter < this.popupLimit) {
43890 var div = document.createElement("div");
43891 div.id = "vis-configuration-popup";
43892 div.className = "vis-configuration-popup";
43893 div.innerHTML = string;
43894
43895 div.onclick = function () {
43896 _this2._removePopup();
43897 };
43898
43899 this.popupCounter += 1;
43900 this.popupDiv = {
43901 html: div,
43902 index: index
43903 };
43904 }
43905 }
43906 /**
43907 * remove the popup from the dom
43908 * @private
43909 */
43910
43911 }, {
43912 key: "_removePopup",
43913 value: function _removePopup() {
43914 if (this.popupDiv.html !== undefined) {
43915 this.popupDiv.html.parentNode.removeChild(this.popupDiv.html);
43916 clearTimeout(this.popupDiv.hideTimeout);
43917 clearTimeout(this.popupDiv.deleteTimeout);
43918 this.popupDiv = {};
43919 }
43920 }
43921 /**
43922 * Show the popup if it is needed.
43923 * @private
43924 */
43925
43926 }, {
43927 key: "_showPopupIfNeeded",
43928 value: function _showPopupIfNeeded() {
43929 var _this3 = this;
43930
43931 if (this.popupDiv.html !== undefined) {
43932 var correspondingElement = this.domElements[this.popupDiv.index];
43933 var rect = correspondingElement.getBoundingClientRect();
43934 this.popupDiv.html.style.left = rect.left + "px";
43935 this.popupDiv.html.style.top = rect.top - 30 + "px"; // 30 is the height;
43936
43937 document.body.appendChild(this.popupDiv.html);
43938 this.popupDiv.hideTimeout = setTimeout(function () {
43939 _this3.popupDiv.html.style.opacity = 0;
43940 }, 1500);
43941 this.popupDiv.deleteTimeout = setTimeout(function () {
43942 _this3._removePopup();
43943 }, 1800);
43944 }
43945 }
43946 /**
43947 * make a checkbox for boolean options.
43948 * @param {number} defaultValue
43949 * @param {number} value
43950 * @param {array} path | where to look for the actual option
43951 * @private
43952 */
43953
43954 }, {
43955 key: "_makeCheckbox",
43956 value: function _makeCheckbox(defaultValue, value, path) {
43957 var checkbox = document.createElement('input');
43958 checkbox.type = 'checkbox';
43959 checkbox.className = 'vis-configuration vis-config-checkbox';
43960 checkbox.checked = defaultValue;
43961
43962 if (value !== undefined) {
43963 checkbox.checked = value;
43964
43965 if (value !== defaultValue) {
43966 if (_typeof(defaultValue) === 'object') {
43967 if (value !== defaultValue.enabled) {
43968 this.changedOptions.push({
43969 path: path,
43970 value: value
43971 });
43972 }
43973 } else {
43974 this.changedOptions.push({
43975 path: path,
43976 value: value
43977 });
43978 }
43979 }
43980 }
43981
43982 var me = this;
43983
43984 checkbox.onchange = function () {
43985 me._update(this.checked, path);
43986 };
43987
43988 var label = this._makeLabel(path[path.length - 1], path);
43989
43990 this._makeItem(path, label, checkbox);
43991 }
43992 /**
43993 * make a text input field for string options.
43994 * @param {number} defaultValue
43995 * @param {number} value
43996 * @param {array} path | where to look for the actual option
43997 * @private
43998 */
43999
44000 }, {
44001 key: "_makeTextInput",
44002 value: function _makeTextInput(defaultValue, value, path) {
44003 var checkbox = document.createElement('input');
44004 checkbox.type = 'text';
44005 checkbox.className = 'vis-configuration vis-config-text';
44006 checkbox.value = value;
44007
44008 if (value !== defaultValue) {
44009 this.changedOptions.push({
44010 path: path,
44011 value: value
44012 });
44013 }
44014
44015 var me = this;
44016
44017 checkbox.onchange = function () {
44018 me._update(this.value, path);
44019 };
44020
44021 var label = this._makeLabel(path[path.length - 1], path);
44022
44023 this._makeItem(path, label, checkbox);
44024 }
44025 /**
44026 * make a color field with a color picker for color fields
44027 * @param {Array.<number>} arr
44028 * @param {number} value
44029 * @param {array} path | where to look for the actual option
44030 * @private
44031 */
44032
44033 }, {
44034 key: "_makeColorField",
44035 value: function _makeColorField(arr, value, path) {
44036 var _this4 = this;
44037
44038 var defaultColor = arr[1];
44039 var div = document.createElement('div');
44040 value = value === undefined ? defaultColor : value;
44041
44042 if (value !== 'none') {
44043 div.className = 'vis-configuration vis-config-colorBlock';
44044 div.style.backgroundColor = value;
44045 } else {
44046 div.className = 'vis-configuration vis-config-colorBlock none';
44047 }
44048
44049 value = value === undefined ? defaultColor : value;
44050
44051 div.onclick = function () {
44052 _this4._showColorPicker(value, div, path);
44053 };
44054
44055 var label = this._makeLabel(path[path.length - 1], path);
44056
44057 this._makeItem(path, label, div);
44058 }
44059 /**
44060 * used by the color buttons to call the color picker.
44061 * @param {number} value
44062 * @param {HTMLElement} div
44063 * @param {array} path | where to look for the actual option
44064 * @private
44065 */
44066
44067 }, {
44068 key: "_showColorPicker",
44069 value: function _showColorPicker(value, div, path) {
44070 var _this5 = this;
44071
44072 // clear the callback from this div
44073 div.onclick = function () {};
44074
44075 this.colorPicker.insertTo(div);
44076 this.colorPicker.show();
44077 this.colorPicker.setColor(value);
44078 this.colorPicker.setUpdateCallback(function (color) {
44079 var colorString = 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',' + color.a + ')';
44080 div.style.backgroundColor = colorString;
44081
44082 _this5._update(colorString, path);
44083 }); // on close of the colorpicker, restore the callback.
44084
44085 this.colorPicker.setCloseCallback(function () {
44086 div.onclick = function () {
44087 _this5._showColorPicker(value, div, path);
44088 };
44089 });
44090 }
44091 /**
44092 * parse an object and draw the correct items
44093 * @param {Object} obj
44094 * @param {array} [path=[]] | where to look for the actual option
44095 * @param {boolean} [checkOnly=false]
44096 * @returns {boolean}
44097 * @private
44098 */
44099
44100 }, {
44101 key: "_handleObject",
44102 value: function _handleObject(obj) {
44103 var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
44104 var checkOnly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
44105 var show = false;
44106 var filter = this.options.filter;
44107 var visibleInSet = false;
44108
44109 for (var subObj in obj) {
44110 if (obj.hasOwnProperty(subObj)) {
44111 show = true;
44112 var item = obj[subObj];
44113 var newPath = util.copyAndExtendArray(path, subObj);
44114
44115 if (typeof filter === 'function') {
44116 show = filter(subObj, path); // if needed we must go deeper into the object.
44117
44118 if (show === false) {
44119 if (!(item instanceof Array) && typeof item !== 'string' && typeof item !== 'boolean' && item instanceof Object) {
44120 this.allowCreation = false;
44121 show = this._handleObject(item, newPath, true);
44122 this.allowCreation = checkOnly === false;
44123 }
44124 }
44125 }
44126
44127 if (show !== false) {
44128 visibleInSet = true;
44129
44130 var value = this._getValue(newPath);
44131
44132 if (item instanceof Array) {
44133 this._handleArray(item, value, newPath);
44134 } else if (typeof item === 'string') {
44135 this._makeTextInput(item, value, newPath);
44136 } else if (typeof item === 'boolean') {
44137 this._makeCheckbox(item, value, newPath);
44138 } else if (item instanceof Object) {
44139 // collapse the physics options that are not enabled
44140 var draw = true;
44141
44142 if (path.indexOf('physics') !== -1) {
44143 if (this.moduleOptions.physics.solver !== subObj) {
44144 draw = false;
44145 }
44146 }
44147
44148 if (draw === true) {
44149 // initially collapse options with an disabled enabled option.
44150 if (item.enabled !== undefined) {
44151 var enabledPath = util.copyAndExtendArray(newPath, 'enabled');
44152
44153 var enabledValue = this._getValue(enabledPath);
44154
44155 if (enabledValue === true) {
44156 var label = this._makeLabel(subObj, newPath, true);
44157
44158 this._makeItem(newPath, label);
44159
44160 visibleInSet = this._handleObject(item, newPath) || visibleInSet;
44161 } else {
44162 this._makeCheckbox(item, enabledValue, newPath);
44163 }
44164 } else {
44165 var _label = this._makeLabel(subObj, newPath, true);
44166
44167 this._makeItem(newPath, _label);
44168
44169 visibleInSet = this._handleObject(item, newPath) || visibleInSet;
44170 }
44171 }
44172 } else {
44173 console.error('dont know how to handle', item, subObj, newPath);
44174 }
44175 }
44176 }
44177 }
44178
44179 return visibleInSet;
44180 }
44181 /**
44182 * handle the array type of option
44183 * @param {Array.<number>} arr
44184 * @param {number} value
44185 * @param {array} path | where to look for the actual option
44186 * @private
44187 */
44188
44189 }, {
44190 key: "_handleArray",
44191 value: function _handleArray(arr, value, path) {
44192 if (typeof arr[0] === 'string' && arr[0] === 'color') {
44193 this._makeColorField(arr, value, path);
44194
44195 if (arr[1] !== value) {
44196 this.changedOptions.push({
44197 path: path,
44198 value: value
44199 });
44200 }
44201 } else if (typeof arr[0] === 'string') {
44202 this._makeDropdown(arr, value, path);
44203
44204 if (arr[0] !== value) {
44205 this.changedOptions.push({
44206 path: path,
44207 value: value
44208 });
44209 }
44210 } else if (typeof arr[0] === 'number') {
44211 this._makeRange(arr, value, path);
44212
44213 if (arr[0] !== value) {
44214 this.changedOptions.push({
44215 path: path,
44216 value: Number(value)
44217 });
44218 }
44219 }
44220 }
44221 /**
44222 * called to update the network with the new settings.
44223 * @param {number} value
44224 * @param {array} path | where to look for the actual option
44225 * @private
44226 */
44227
44228 }, {
44229 key: "_update",
44230 value: function _update(value, path) {
44231 var options = this._constructOptions(value, path);
44232
44233 if (this.parent.body && this.parent.body.emitter && this.parent.body.emitter.emit) {
44234 this.parent.body.emitter.emit("configChange", options);
44235 }
44236
44237 this.initialized = true;
44238 this.parent.setOptions(options);
44239 }
44240 /**
44241 *
44242 * @param {string|Boolean} value
44243 * @param {Array.<string>} path
44244 * @param {{}} optionsObj
44245 * @returns {{}}
44246 * @private
44247 */
44248
44249 }, {
44250 key: "_constructOptions",
44251 value: function _constructOptions(value, path) {
44252 var optionsObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
44253 var pointer = optionsObj; // when dropdown boxes can be string or boolean, we typecast it into correct types
44254
44255 value = value === 'true' ? true : value;
44256 value = value === 'false' ? false : value;
44257
44258 for (var i = 0; i < path.length; i++) {
44259 if (path[i] !== 'global') {
44260 if (pointer[path[i]] === undefined) {
44261 pointer[path[i]] = {};
44262 }
44263
44264 if (i !== path.length - 1) {
44265 pointer = pointer[path[i]];
44266 } else {
44267 pointer[path[i]] = value;
44268 }
44269 }
44270 }
44271
44272 return optionsObj;
44273 }
44274 /**
44275 * @private
44276 */
44277
44278 }, {
44279 key: "_printOptions",
44280 value: function _printOptions() {
44281 var options = this.getOptions();
44282 this.optionsContainer.innerHTML = '<pre>var options = ' + JSON.stringify(options, null, 2) + '</pre>';
44283 }
44284 /**
44285 *
44286 * @returns {{}} options
44287 */
44288
44289 }, {
44290 key: "getOptions",
44291 value: function getOptions() {
44292 var options = {};
44293
44294 for (var i = 0; i < this.changedOptions.length; i++) {
44295 this._constructOptions(this.changedOptions[i].value, this.changedOptions[i].path, options);
44296 }
44297
44298 return options;
44299 }
44300 }]);
44301
44302 return Configurator;
44303}();
44304
44305/**
44306 * Create a timeline visualization
44307 * @extends Core
44308 */
44309
44310var Timeline =
44311/*#__PURE__*/
44312function (_Core) {
44313 _inherits(Timeline, _Core);
44314
44315 /**
44316 * @param {HTMLElement} container
44317 * @param {vis.DataSet | vis.DataView | Array} [items]
44318 * @param {vis.DataSet | vis.DataView | Array} [groups]
44319 * @param {Object} [options] See Timeline.setOptions for the available options.
44320 * @constructor Timeline
44321 */
44322 function Timeline(container, items, groups, options) {
44323 var _this;
44324
44325 _classCallCheck(this, Timeline);
44326
44327 _this = _possibleConstructorReturn(this, _getPrototypeOf(Timeline).call(this));
44328 _this.initTime = new Date();
44329 _this.itemsDone = false;
44330
44331 if (!(_assertThisInitialized(_this) instanceof Timeline)) {
44332 throw new SyntaxError('Constructor must be called with the new operator');
44333 } // if the third element is options, the forth is groups (optionally);
44334
44335
44336 if (!(Array.isArray(groups) || groups instanceof DataSet || groups instanceof DataView$2) && groups instanceof Object) {
44337 var forthArgument = options;
44338 options = groups;
44339 groups = forthArgument;
44340 } // TODO: REMOVE THIS in the next MAJOR release
44341 // see https://github.com/almende/vis/issues/2511
44342
44343
44344 if (options && options.throttleRedraw) {
44345 console.warn("Timeline option \"throttleRedraw\" is DEPRICATED and no longer supported. It will be removed in the next MAJOR release.");
44346 }
44347
44348 var me = _assertThisInitialized(_this);
44349
44350 _this.defaultOptions = {
44351 autoResize: true,
44352 orientation: {
44353 axis: 'bottom',
44354 // axis orientation: 'bottom', 'top', or 'both'
44355 item: 'bottom' // not relevant
44356
44357 },
44358 moment: moment$3
44359 };
44360 _this.options = util.deepExtend({}, _this.defaultOptions); // Create the DOM, props, and emitter
44361
44362 _this._create(container);
44363
44364 if (!options || options && typeof options.rtl == "undefined") {
44365 _this.dom.root.style.visibility = 'hidden';
44366 var directionFromDom;
44367 var domNode = _this.dom.root;
44368
44369 while (!directionFromDom && domNode) {
44370 directionFromDom = window.getComputedStyle(domNode, null).direction;
44371 domNode = domNode.parentElement;
44372 }
44373
44374 _this.options.rtl = directionFromDom && directionFromDom.toLowerCase() == "rtl";
44375 } else {
44376 _this.options.rtl = options.rtl;
44377 }
44378
44379 if (options) {
44380 if (options.rollingMode) {
44381 _this.options.rollingMode = options.rollingMode;
44382 }
44383
44384 if (options.onInitialDrawComplete) {
44385 _this.options.onInitialDrawComplete = options.onInitialDrawComplete;
44386 }
44387
44388 if (options.onTimeout) {
44389 _this.options.onTimeout = options.onTimeout;
44390 }
44391
44392 if (options.loadingScreenTemplate) {
44393 _this.options.loadingScreenTemplate = options.loadingScreenTemplate;
44394 }
44395 } // Prepare loading screen
44396
44397
44398 var loadingScreenFragment = document.createElement('div');
44399
44400 if (_this.options.loadingScreenTemplate) {
44401 var templateFunction = _this.options.loadingScreenTemplate.bind(_assertThisInitialized(_this));
44402
44403 var loadingScreen = templateFunction(_this.dom.loadingScreen);
44404
44405 if (loadingScreen instanceof Object && !(loadingScreen instanceof Element)) {
44406 templateFunction(loadingScreenFragment);
44407 } else {
44408 if (loadingScreen instanceof Element) {
44409 loadingScreenFragment.innerHTML = '';
44410 loadingScreenFragment.appendChild(loadingScreen);
44411 } else if (loadingScreen != undefined) {
44412 loadingScreenFragment.innerHTML = loadingScreen;
44413 }
44414 }
44415 }
44416
44417 _this.dom.loadingScreen.appendChild(loadingScreenFragment); // all components listed here will be repainted automatically
44418
44419
44420 _this.components = [];
44421 _this.body = {
44422 dom: _this.dom,
44423 domProps: _this.props,
44424 emitter: {
44425 on: _this.on.bind(_assertThisInitialized(_this)),
44426 off: _this.off.bind(_assertThisInitialized(_this)),
44427 emit: _this.emit.bind(_assertThisInitialized(_this))
44428 },
44429 hiddenDates: [],
44430 util: {
44431 getScale: function getScale() {
44432 return me.timeAxis.step.scale;
44433 },
44434 getStep: function getStep() {
44435 return me.timeAxis.step.step;
44436 },
44437 toScreen: me._toScreen.bind(me),
44438 toGlobalScreen: me._toGlobalScreen.bind(me),
44439 // this refers to the root.width
44440 toTime: me._toTime.bind(me),
44441 toGlobalTime: me._toGlobalTime.bind(me)
44442 }
44443 }; // range
44444
44445 _this.range = new Range(_this.body, _this.options);
44446
44447 _this.components.push(_this.range);
44448
44449 _this.body.range = _this.range; // time axis
44450
44451 _this.timeAxis = new TimeAxis(_this.body, _this.options);
44452 _this.timeAxis2 = null; // used in case of orientation option 'both'
44453
44454 _this.components.push(_this.timeAxis); // current time bar
44455
44456
44457 _this.currentTime = new CurrentTime(_this.body, _this.options);
44458
44459 _this.components.push(_this.currentTime); // item set
44460
44461
44462 _this.itemSet = new ItemSet(_this.body, _this.options);
44463
44464 _this.components.push(_this.itemSet);
44465
44466 _this.itemsData = null; // DataSet
44467
44468 _this.groupsData = null; // DataSet
44469
44470 _this.dom.root.onclick = function (event) {
44471 me.emit('click', me.getEventProperties(event));
44472 };
44473
44474 _this.dom.root.ondblclick = function (event) {
44475 me.emit('doubleClick', me.getEventProperties(event));
44476 };
44477
44478 _this.dom.root.oncontextmenu = function (event) {
44479 me.emit('contextmenu', me.getEventProperties(event));
44480 };
44481
44482 _this.dom.root.onmouseover = function (event) {
44483 me.emit('mouseOver', me.getEventProperties(event));
44484 };
44485
44486 if (window.PointerEvent) {
44487 _this.dom.root.onpointerdown = function (event) {
44488 me.emit('mouseDown', me.getEventProperties(event));
44489 };
44490
44491 _this.dom.root.onpointermove = function (event) {
44492 me.emit('mouseMove', me.getEventProperties(event));
44493 };
44494
44495 _this.dom.root.onpointerup = function (event) {
44496 me.emit('mouseUp', me.getEventProperties(event));
44497 };
44498 } else {
44499 _this.dom.root.onmousemove = function (event) {
44500 me.emit('mouseMove', me.getEventProperties(event));
44501 };
44502
44503 _this.dom.root.onmousedown = function (event) {
44504 me.emit('mouseDown', me.getEventProperties(event));
44505 };
44506
44507 _this.dom.root.onmouseup = function (event) {
44508 me.emit('mouseUp', me.getEventProperties(event));
44509 };
44510 } //Single time autoscale/fit
44511
44512
44513 _this.initialFitDone = false;
44514
44515 _this.on('changed', function () {
44516 if (me.itemsData == null) return;
44517
44518 if (!me.initialFitDone && !me.options.rollingMode) {
44519 me.initialFitDone = true;
44520
44521 if (me.options.start != undefined || me.options.end != undefined) {
44522 if (me.options.start == undefined || me.options.end == undefined) {
44523 var range = me.getItemRange();
44524 }
44525
44526 var start = me.options.start != undefined ? me.options.start : range.min;
44527 var end = me.options.end != undefined ? me.options.end : range.max;
44528 me.setWindow(start, end, {
44529 animation: false
44530 });
44531 } else {
44532 me.fit({
44533 animation: false
44534 });
44535 }
44536 }
44537
44538 if (!me.initialDrawDone && (me.initialRangeChangeDone || !me.options.start && !me.options.end || me.options.rollingMode)) {
44539 me.initialDrawDone = true;
44540 me.itemSet.initialDrawDone = true;
44541 me.dom.root.style.visibility = 'visible';
44542 me.dom.loadingScreen.parentNode.removeChild(me.dom.loadingScreen);
44543
44544 if (me.options.onInitialDrawComplete) {
44545 setTimeout(function () {
44546 return me.options.onInitialDrawComplete();
44547 }, 0);
44548 }
44549 }
44550 });
44551
44552 _this.on('destroyTimeline', function () {
44553 me.destroy();
44554 }); // apply options
44555
44556
44557 if (options) {
44558 _this.setOptions(options);
44559 }
44560
44561 _this.body.emitter.on('fit', function (args) {
44562 _this._onFit(args);
44563
44564 _this.redraw();
44565 }); // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS!
44566
44567
44568 if (groups) {
44569 _this.setGroups(groups);
44570 } // create itemset
44571
44572
44573 if (items) {
44574 _this.setItems(items);
44575 } // draw for the first time
44576
44577
44578 _this._redraw();
44579
44580 return _this;
44581 }
44582 /**
44583 * Load a configurator
44584 * @return {Object}
44585 * @private
44586 */
44587
44588
44589 _createClass(Timeline, [{
44590 key: "_createConfigurator",
44591 value: function _createConfigurator() {
44592 return new Configurator(this, this.dom.container, configureOptions);
44593 }
44594 /**
44595 * Force a redraw. The size of all items will be recalculated.
44596 * Can be useful to manually redraw when option autoResize=false and the window
44597 * has been resized, or when the items CSS has been changed.
44598 *
44599 * Note: this function will be overridden on construction with a trottled version
44600 */
44601
44602 }, {
44603 key: "redraw",
44604 value: function redraw() {
44605 this.itemSet && this.itemSet.markDirty({
44606 refreshItems: true
44607 });
44608
44609 this._redraw();
44610 }
44611 /**
44612 * Remove an item from the group
44613 * @param {object} options
44614 */
44615
44616 }, {
44617 key: "setOptions",
44618 value: function setOptions(options) {
44619 // validate options
44620 var errorFound = Validator.validate(options, allOptions$1);
44621
44622 if (errorFound === true) {
44623 console.log('%cErrors have been found in the supplied options object.', printStyle);
44624 }
44625
44626 Core.prototype.setOptions.call(this, options);
44627
44628 if ('type' in options) {
44629 if (options.type !== this.options.type) {
44630 this.options.type = options.type; // force recreation of all items
44631
44632 var itemsData = this.itemsData;
44633
44634 if (itemsData) {
44635 var selection = this.getSelection();
44636 this.setItems(null); // remove all
44637
44638 this.setItems(itemsData); // add all
44639
44640 this.setSelection(selection); // restore selection
44641 }
44642 }
44643 }
44644 }
44645 /**
44646 * Set items
44647 * @param {vis.DataSet | Array | null} items
44648 */
44649
44650 }, {
44651 key: "setItems",
44652 value: function setItems(items) {
44653 this.itemsDone = false; // convert to type DataSet when needed
44654
44655 var newDataSet;
44656
44657 if (!items) {
44658 newDataSet = null;
44659 } else if (items instanceof DataSet || items instanceof DataView$2) {
44660 newDataSet = items;
44661 } else {
44662 // turn an array into a dataset
44663 newDataSet = new DataSet(items, {
44664 type: {
44665 start: 'Date',
44666 end: 'Date'
44667 }
44668 });
44669 } // set items
44670
44671
44672 this.itemsData = newDataSet;
44673 this.itemSet && this.itemSet.setItems(newDataSet);
44674 }
44675 /**
44676 * Set groups
44677 * @param {vis.DataSet | Array} groups
44678 */
44679
44680 }, {
44681 key: "setGroups",
44682 value: function setGroups(groups) {
44683 // convert to type DataSet when needed
44684 var newDataSet;
44685
44686 if (!groups) {
44687 newDataSet = null;
44688 } else {
44689 var filter = function filter(group) {
44690 return group.visible !== false;
44691 };
44692
44693 if (groups instanceof DataSet || groups instanceof DataView$2) {
44694 newDataSet = new DataView$2(groups, {
44695 filter: filter
44696 });
44697 } else {
44698 // turn an array into a dataset
44699 newDataSet = new DataSet(groups.filter(filter));
44700 }
44701 }
44702
44703 this.groupsData = newDataSet;
44704 this.itemSet.setGroups(newDataSet);
44705 }
44706 /**
44707 * Set both items and groups in one go
44708 * @param {{items: (Array | vis.DataSet), groups: (Array | vis.DataSet)}} data
44709 */
44710
44711 }, {
44712 key: "setData",
44713 value: function setData(data) {
44714 if (data && data.groups) {
44715 this.setGroups(data.groups);
44716 }
44717
44718 if (data && data.items) {
44719 this.setItems(data.items);
44720 }
44721 }
44722 /**
44723 * Set selected items by their id. Replaces the current selection
44724 * Unknown id's are silently ignored.
44725 * @param {string[] | string} [ids] An array with zero or more id's of the items to be
44726 * selected. If ids is an empty array, all items will be
44727 * unselected.
44728 * @param {Object} [options] Available options:
44729 * `focus: boolean`
44730 * If true, focus will be set to the selected item(s)
44731 * `animation: boolean | {duration: number, easingFunction: string}`
44732 * If true (default), the range is animated
44733 * smoothly to the new window. An object can be
44734 * provided to specify duration and easing function.
44735 * Default duration is 500 ms, and default easing
44736 * function is 'easeInOutQuad'.
44737 * Only applicable when option focus is true.
44738 */
44739
44740 }, {
44741 key: "setSelection",
44742 value: function setSelection(ids, options) {
44743 this.itemSet && this.itemSet.setSelection(ids);
44744
44745 if (options && options.focus) {
44746 this.focus(ids, options);
44747 }
44748 }
44749 /**
44750 * Get the selected items by their id
44751 * @return {Array} ids The ids of the selected items
44752 */
44753
44754 }, {
44755 key: "getSelection",
44756 value: function getSelection() {
44757 return this.itemSet && this.itemSet.getSelection() || [];
44758 }
44759 /**
44760 * Adjust the visible window such that the selected item (or multiple items)
44761 * are centered on screen.
44762 * @param {string | String[]} id An item id or array with item ids
44763 * @param {Object} [options] Available options:
44764 * `animation: boolean | {duration: number, easingFunction: string}`
44765 * If true (default), the range is animated
44766 * smoothly to the new window. An object can be
44767 * provided to specify duration and easing function.
44768 * Default duration is 500 ms, and default easing
44769 * function is 'easeInOutQuad'.
44770 */
44771
44772 }, {
44773 key: "focus",
44774 value: function focus(id, options) {
44775 if (!this.itemsData || id == undefined) return;
44776 var ids = Array.isArray(id) ? id : [id]; // get the specified item(s)
44777
44778 var itemsData = this.itemsData.getDataSet().get(ids, {
44779 type: {
44780 start: 'Date',
44781 end: 'Date'
44782 }
44783 }); // calculate minimum start and maximum end of specified items
44784
44785 var start = null;
44786 var end = null;
44787 itemsData.forEach(function (itemData) {
44788 var s = itemData.start.valueOf();
44789 var e = 'end' in itemData ? itemData.end.valueOf() : itemData.start.valueOf();
44790
44791 if (start === null || s < start) {
44792 start = s;
44793 }
44794
44795 if (end === null || e > end) {
44796 end = e;
44797 }
44798 });
44799
44800 if (start !== null && end !== null) {
44801 var me = this; // Use the first item for the vertical focus
44802
44803 var item = this.itemSet.items[ids[0]];
44804 var startPos = this._getScrollTop() * -1;
44805 var initialVerticalScroll = null; // Setup a handler for each frame of the vertical scroll
44806
44807 var verticalAnimationFrame = function verticalAnimationFrame(ease, willDraw, done) {
44808 var verticalScroll = getItemVerticalScroll(me, item);
44809
44810 if (verticalScroll === false) {
44811 return; // We don't need to scroll, so do nothing
44812 }
44813
44814 if (!initialVerticalScroll) {
44815 initialVerticalScroll = verticalScroll;
44816 }
44817
44818 if (initialVerticalScroll.itemTop == verticalScroll.itemTop && !initialVerticalScroll.shouldScroll) {
44819 return; // We don't need to scroll, so do nothing
44820 } else if (initialVerticalScroll.itemTop != verticalScroll.itemTop && verticalScroll.shouldScroll) {
44821 // The redraw shifted elements, so reset the animation to correct
44822 initialVerticalScroll = verticalScroll;
44823 startPos = me._getScrollTop() * -1;
44824 }
44825
44826 var from = startPos;
44827 var to = initialVerticalScroll.scrollOffset;
44828 var scrollTop = done ? to : from + (to - from) * ease;
44829
44830 me._setScrollTop(-scrollTop);
44831
44832 if (!willDraw) {
44833 me._redraw();
44834 }
44835 }; // Enforces the final vertical scroll position
44836
44837
44838 var setFinalVerticalPosition = function setFinalVerticalPosition() {
44839 var finalVerticalScroll = getItemVerticalScroll(me, item);
44840
44841 if (finalVerticalScroll.shouldScroll && finalVerticalScroll.itemTop != initialVerticalScroll.itemTop) {
44842 me._setScrollTop(-finalVerticalScroll.scrollOffset);
44843
44844 me._redraw();
44845 }
44846 }; // Perform one last check at the end to make sure the final vertical
44847 // position is correct
44848
44849
44850 var finalVerticalCallback = function finalVerticalCallback() {
44851 // Double check we ended at the proper scroll position
44852 setFinalVerticalPosition(); // Let the redraw settle and finalize the position.
44853
44854 setTimeout(setFinalVerticalPosition, 100);
44855 }; // calculate the new middle and interval for the window
44856
44857
44858 var middle = (start + end) / 2;
44859 var interval = (end - start) * 1.1;
44860 var animation = options && options.animation !== undefined ? options.animation : true;
44861
44862 if (!animation) {
44863 // We aren't animating so set a default so that the final callback forces the vertical location
44864 initialVerticalScroll = {
44865 shouldScroll: false,
44866 scrollOffset: -1,
44867 itemTop: -1
44868 };
44869 }
44870
44871 this.range.setRange(middle - interval / 2, middle + interval / 2, {
44872 animation: animation
44873 }, finalVerticalCallback, verticalAnimationFrame);
44874 }
44875 }
44876 /**
44877 * Set Timeline window such that it fits all items
44878 * @param {Object} [options] Available options:
44879 * `animation: boolean | {duration: number, easingFunction: string}`
44880 * If true (default), the range is animated
44881 * smoothly to the new window. An object can be
44882 * provided to specify duration and easing function.
44883 * Default duration is 500 ms, and default easing
44884 * function is 'easeInOutQuad'.
44885 * @param {function} [callback]
44886 */
44887
44888 }, {
44889 key: "fit",
44890 value: function fit(options, callback) {
44891 var animation = options && options.animation !== undefined ? options.animation : true;
44892 var range;
44893 var dataset = this.itemsData && this.itemsData.getDataSet();
44894
44895 if (dataset.length === 1 && dataset.get()[0].end === undefined) {
44896 // a single item -> don't fit, just show a range around the item from -4 to +3 days
44897 range = this.getDataRange();
44898 this.moveTo(range.min.valueOf(), {
44899 animation: animation
44900 }, callback);
44901 } else {
44902 // exactly fit the items (plus a small margin)
44903 range = this.getItemRange();
44904 this.range.setRange(range.min, range.max, {
44905 animation: animation
44906 }, callback);
44907 }
44908 }
44909 /**
44910 * Determine the range of the items, taking into account their actual width
44911 * and a margin of 10 pixels on both sides.
44912 *
44913 * @returns {{min: Date, max: Date}}
44914 */
44915
44916 }, {
44917 key: "getItemRange",
44918 value: function getItemRange() {
44919 var _this2 = this;
44920
44921 // get a rough approximation for the range based on the items start and end dates
44922 var range = this.getDataRange();
44923 var min = range.min !== null ? range.min.valueOf() : null;
44924 var max = range.max !== null ? range.max.valueOf() : null;
44925 var minItem = null;
44926 var maxItem = null;
44927
44928 if (min != null && max != null) {
44929 var interval = max - min; // ms
44930
44931 if (interval <= 0) {
44932 interval = 10;
44933 }
44934
44935 var factor = interval / this.props.center.width;
44936 var redrawQueue = {};
44937 var redrawQueueLength = 0; // collect redraw functions
44938
44939 util.forEach(this.itemSet.items, function (item, key) {
44940 if (item.groupShowing) {
44941 var returnQueue = true;
44942 redrawQueue[key] = item.redraw(returnQueue);
44943 redrawQueueLength = redrawQueue[key].length;
44944 }
44945 });
44946 var needRedraw = redrawQueueLength > 0;
44947
44948 if (needRedraw) {
44949 var _loop = function _loop(i) {
44950 util.forEach(redrawQueue, function (fns) {
44951 fns[i]();
44952 });
44953 };
44954
44955 // redraw all regular items
44956 for (var i = 0; i < redrawQueueLength; i++) {
44957 _loop(i);
44958 }
44959 } // calculate the date of the left side and right side of the items given
44960
44961
44962 util.forEach(this.itemSet.items, function (item) {
44963 var start = getStart(item);
44964 var end = getEnd(item);
44965 var startSide;
44966 var endSide;
44967
44968 if (_this2.options.rtl) {
44969 startSide = start - (item.getWidthRight() + 10) * factor;
44970 endSide = end + (item.getWidthLeft() + 10) * factor;
44971 } else {
44972 startSide = start - (item.getWidthLeft() + 10) * factor;
44973 endSide = end + (item.getWidthRight() + 10) * factor;
44974 }
44975
44976 if (startSide < min) {
44977 min = startSide;
44978 minItem = item;
44979 }
44980
44981 if (endSide > max) {
44982 max = endSide;
44983 maxItem = item;
44984 }
44985 });
44986
44987 if (minItem && maxItem) {
44988 var lhs = minItem.getWidthLeft() + 10;
44989 var rhs = maxItem.getWidthRight() + 10;
44990 var delta = this.props.center.width - lhs - rhs; // px
44991
44992 if (delta > 0) {
44993 if (this.options.rtl) {
44994 min = getStart(minItem) - rhs * interval / delta; // ms
44995
44996 max = getEnd(maxItem) + lhs * interval / delta; // ms
44997 } else {
44998 min = getStart(minItem) - lhs * interval / delta; // ms
44999
45000 max = getEnd(maxItem) + rhs * interval / delta; // ms
45001 }
45002 }
45003 }
45004 }
45005
45006 return {
45007 min: min != null ? new Date(min) : null,
45008 max: max != null ? new Date(max) : null
45009 };
45010 }
45011 /**
45012 * Calculate the data range of the items start and end dates
45013 * @returns {{min: Date, max: Date}}
45014 */
45015
45016 }, {
45017 key: "getDataRange",
45018 value: function getDataRange() {
45019 var min = null;
45020 var max = null;
45021 var dataset = this.itemsData && this.itemsData.getDataSet();
45022
45023 if (dataset) {
45024 dataset.forEach(function (item) {
45025 var start = util.convert(item.start, 'Date').valueOf();
45026 var end = util.convert(item.end != undefined ? item.end : item.start, 'Date').valueOf();
45027
45028 if (min === null || start < min) {
45029 min = start;
45030 }
45031
45032 if (max === null || end > max) {
45033 max = end;
45034 }
45035 });
45036 }
45037
45038 return {
45039 min: min != null ? new Date(min) : null,
45040 max: max != null ? new Date(max) : null
45041 };
45042 }
45043 /**
45044 * Generate Timeline related information from an event
45045 * @param {Event} event
45046 * @return {Object} An object with related information, like on which area
45047 * The event happened, whether clicked on an item, etc.
45048 */
45049
45050 }, {
45051 key: "getEventProperties",
45052 value: function getEventProperties(event) {
45053 var clientX = event.center ? event.center.x : event.clientX;
45054 var clientY = event.center ? event.center.y : event.clientY;
45055 var centerContainerRect = this.dom.centerContainer.getBoundingClientRect();
45056 var x = this.options.rtl ? centerContainerRect.right - clientX : clientX - centerContainerRect.left;
45057 var y = clientY - centerContainerRect.top;
45058 var item = this.itemSet.itemFromTarget(event);
45059 var group = this.itemSet.groupFromTarget(event);
45060 var customTime = CustomTime.customTimeFromTarget(event);
45061 var snap = this.itemSet.options.snap || null;
45062 var scale = this.body.util.getScale();
45063 var step = this.body.util.getStep();
45064
45065 var time = this._toTime(x);
45066
45067 var snappedTime = snap ? snap(time, scale, step) : time;
45068 var element = util.getTarget(event);
45069 var what = null;
45070
45071 if (item != null) {
45072 what = 'item';
45073 } else if (customTime != null) {
45074 what = 'custom-time';
45075 } else if (util.hasParent(element, this.timeAxis.dom.foreground)) {
45076 what = 'axis';
45077 } else if (this.timeAxis2 && util.hasParent(element, this.timeAxis2.dom.foreground)) {
45078 what = 'axis';
45079 } else if (util.hasParent(element, this.itemSet.dom.labelSet)) {
45080 what = 'group-label';
45081 } else if (util.hasParent(element, this.currentTime.bar)) {
45082 what = 'current-time';
45083 } else if (util.hasParent(element, this.dom.center)) {
45084 what = 'background';
45085 }
45086
45087 return {
45088 event: event,
45089 item: item ? item.id : null,
45090 isCluster: item ? !!item.isCluster : false,
45091 items: item ? item.items || [] : null,
45092 group: group ? group.groupId : null,
45093 customTime: customTime ? customTime.options.id : null,
45094 what: what,
45095 pageX: event.srcEvent ? event.srcEvent.pageX : event.pageX,
45096 pageY: event.srcEvent ? event.srcEvent.pageY : event.pageY,
45097 x: x,
45098 y: y,
45099 time: time,
45100 snappedTime: snappedTime
45101 };
45102 }
45103 /**
45104 * Toggle Timeline rolling mode
45105 */
45106
45107 }, {
45108 key: "toggleRollingMode",
45109 value: function toggleRollingMode() {
45110 if (this.range.rolling) {
45111 this.range.stopRolling();
45112 } else {
45113 if (this.options.rollingMode == undefined) {
45114 this.setOptions(this.options);
45115 }
45116
45117 this.range.startRolling();
45118 }
45119 }
45120 /**
45121 * redraw
45122 * @private
45123 */
45124
45125 }, {
45126 key: "_redraw",
45127 value: function _redraw() {
45128 Core.prototype._redraw.call(this);
45129 }
45130 /**
45131 * on fit callback
45132 * @param {object} args
45133 * @private
45134 */
45135
45136 }, {
45137 key: "_onFit",
45138 value: function _onFit(args) {
45139 var start = args.start,
45140 end = args.end,
45141 animation = args.animation;
45142
45143 if (!end) {
45144 this.moveTo(start.valueOf(), {
45145 animation: animation
45146 });
45147 } else {
45148 this.range.setRange(start, end, {
45149 animation: animation
45150 });
45151 }
45152 }
45153 }]);
45154
45155 return Timeline;
45156}(Core);
45157
45158function getStart(item) {
45159 return util.convert(item.data.start, 'Date').valueOf();
45160}
45161/**
45162 *
45163 * @param {timeline.Item} item
45164 * @returns {number}
45165 */
45166
45167
45168function getEnd(item) {
45169 var end = item.data.end != undefined ? item.data.end : item.data.start;
45170 return util.convert(end, 'Date').valueOf();
45171}
45172/**
45173 * @param {vis.Timeline} timeline
45174 * @param {timeline.Item} item
45175 * @return {{shouldScroll: bool, scrollOffset: number, itemTop: number}}
45176 */
45177
45178
45179function getItemVerticalScroll(timeline, item) {
45180 if (!item.parent) {
45181 // The item no longer exists, so ignore this focus.
45182 return false;
45183 }
45184
45185 var itemsetHeight = timeline.options.rtl ? timeline.props.rightContainer.height : timeline.props.leftContainer.height;
45186 var contentHeight = timeline.props.center.height;
45187 var group = item.parent;
45188 var offset = group.top;
45189 var shouldScroll = true;
45190 var orientation = timeline.timeAxis.options.orientation.axis;
45191
45192 var itemTop = function itemTop() {
45193 if (orientation == "bottom") {
45194 return group.height - item.top - item.height;
45195 } else {
45196 return item.top;
45197 }
45198 };
45199
45200 var currentScrollHeight = timeline._getScrollTop() * -1;
45201 var targetOffset = offset + itemTop();
45202 var height = item.height;
45203
45204 if (targetOffset < currentScrollHeight) {
45205 if (offset + itemsetHeight <= offset + itemTop() + height) {
45206 offset += itemTop() - timeline.itemSet.options.margin.item.vertical;
45207 }
45208 } else if (targetOffset + height > currentScrollHeight + itemsetHeight) {
45209 offset += itemTop() + height - itemsetHeight + timeline.itemSet.options.margin.item.vertical;
45210 } else {
45211 shouldScroll = false;
45212 }
45213
45214 offset = Math.min(offset, contentHeight - itemsetHeight);
45215 return {
45216 shouldScroll: shouldScroll,
45217 scrollOffset: offset,
45218 itemTop: targetOffset
45219 };
45220}
45221
45222var nativeToPrecision = 1.0.toPrecision;
45223
45224var FORCED$b = fails(function () {
45225 // IE7-
45226 return nativeToPrecision.call(1, undefined) !== '1';
45227}) || !fails(function () {
45228 // V8 ~ Android 4.3-
45229 nativeToPrecision.call({});
45230});
45231
45232// `Number.prototype.toPrecision` method
45233// https://tc39.github.io/ecma262/#sec-number.prototype.toprecision
45234_export({ target: 'Number', proto: true, forced: FORCED$b }, {
45235 toPrecision: function toPrecision(precision) {
45236 return precision === undefined
45237 ? nativeToPrecision.call(thisNumberValue(this))
45238 : nativeToPrecision.call(thisNumberValue(this), precision);
45239 }
45240});
45241
45242/** DataScale */
45243var DataScale =
45244/*#__PURE__*/
45245function () {
45246 /**
45247 *
45248 * @param {number} start
45249 * @param {number} end
45250 * @param {boolean} autoScaleStart
45251 * @param {boolean} autoScaleEnd
45252 * @param {number} containerHeight
45253 * @param {number} majorCharHeight
45254 * @param {boolean} zeroAlign
45255 * @param {function} formattingFunction
45256 * @constructor DataScale
45257 */
45258 function DataScale(start, end, autoScaleStart, autoScaleEnd, containerHeight, majorCharHeight) {
45259 var zeroAlign = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
45260 var formattingFunction = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
45261
45262 _classCallCheck(this, DataScale);
45263
45264 this.majorSteps = [1, 2, 5, 10];
45265 this.minorSteps = [0.25, 0.5, 1, 2];
45266 this.customLines = null;
45267 this.containerHeight = containerHeight;
45268 this.majorCharHeight = majorCharHeight;
45269 this._start = start;
45270 this._end = end;
45271 this.scale = 1;
45272 this.minorStepIdx = -1;
45273 this.magnitudefactor = 1;
45274 this.determineScale();
45275 this.zeroAlign = zeroAlign;
45276 this.autoScaleStart = autoScaleStart;
45277 this.autoScaleEnd = autoScaleEnd;
45278 this.formattingFunction = formattingFunction;
45279
45280 if (autoScaleStart || autoScaleEnd) {
45281 var me = this;
45282
45283 var roundToMinor = function roundToMinor(value) {
45284 var rounded = value - value % (me.magnitudefactor * me.minorSteps[me.minorStepIdx]);
45285
45286 if (value % (me.magnitudefactor * me.minorSteps[me.minorStepIdx]) > 0.5 * (me.magnitudefactor * me.minorSteps[me.minorStepIdx])) {
45287 return rounded + me.magnitudefactor * me.minorSteps[me.minorStepIdx];
45288 } else {
45289 return rounded;
45290 }
45291 };
45292
45293 if (autoScaleStart) {
45294 this._start -= this.magnitudefactor * 2 * this.minorSteps[this.minorStepIdx];
45295 this._start = roundToMinor(this._start);
45296 }
45297
45298 if (autoScaleEnd) {
45299 this._end += this.magnitudefactor * this.minorSteps[this.minorStepIdx];
45300 this._end = roundToMinor(this._end);
45301 }
45302
45303 this.determineScale();
45304 }
45305 }
45306 /**
45307 * set chart height
45308 * @param {number} majorCharHeight
45309 */
45310
45311
45312 _createClass(DataScale, [{
45313 key: "setCharHeight",
45314 value: function setCharHeight(majorCharHeight) {
45315 this.majorCharHeight = majorCharHeight;
45316 }
45317 /**
45318 * set height
45319 * @param {number} containerHeight
45320 */
45321
45322 }, {
45323 key: "setHeight",
45324 value: function setHeight(containerHeight) {
45325 this.containerHeight = containerHeight;
45326 }
45327 /**
45328 * determine scale
45329 */
45330
45331 }, {
45332 key: "determineScale",
45333 value: function determineScale() {
45334 var range = this._end - this._start;
45335 this.scale = this.containerHeight / range;
45336 var minimumStepValue = this.majorCharHeight / this.scale;
45337 var orderOfMagnitude = range > 0 ? Math.round(Math.log(range) / Math.LN10) : 0;
45338 this.minorStepIdx = -1;
45339 this.magnitudefactor = Math.pow(10, orderOfMagnitude);
45340 var start = 0;
45341
45342 if (orderOfMagnitude < 0) {
45343 start = orderOfMagnitude;
45344 }
45345
45346 var solutionFound = false;
45347
45348 for (var l = start; Math.abs(l) <= Math.abs(orderOfMagnitude); l++) {
45349 this.magnitudefactor = Math.pow(10, l);
45350
45351 for (var j = 0; j < this.minorSteps.length; j++) {
45352 var stepSize = this.magnitudefactor * this.minorSteps[j];
45353
45354 if (stepSize >= minimumStepValue) {
45355 solutionFound = true;
45356 this.minorStepIdx = j;
45357 break;
45358 }
45359 }
45360
45361 if (solutionFound === true) {
45362 break;
45363 }
45364 }
45365 }
45366 /**
45367 * returns if value is major
45368 * @param {number} value
45369 * @returns {boolean}
45370 */
45371
45372 }, {
45373 key: "is_major",
45374 value: function is_major(value) {
45375 return value % (this.magnitudefactor * this.majorSteps[this.minorStepIdx]) === 0;
45376 }
45377 /**
45378 * returns step size
45379 * @returns {number}
45380 */
45381
45382 }, {
45383 key: "getStep",
45384 value: function getStep() {
45385 return this.magnitudefactor * this.minorSteps[this.minorStepIdx];
45386 }
45387 /**
45388 * returns first major
45389 * @returns {number}
45390 */
45391
45392 }, {
45393 key: "getFirstMajor",
45394 value: function getFirstMajor() {
45395 var majorStep = this.magnitudefactor * this.majorSteps[this.minorStepIdx];
45396 return this.convertValue(this._start + (majorStep - this._start % majorStep) % majorStep);
45397 }
45398 /**
45399 * returns first major
45400 * @param {date} current
45401 * @returns {date} formatted date
45402 */
45403
45404 }, {
45405 key: "formatValue",
45406 value: function formatValue(current) {
45407 var returnValue = current.toPrecision(5);
45408
45409 if (typeof this.formattingFunction === 'function') {
45410 returnValue = this.formattingFunction(current);
45411 }
45412
45413 if (typeof returnValue === 'number') {
45414 return "".concat(returnValue);
45415 } else if (typeof returnValue === 'string') {
45416 return returnValue;
45417 } else {
45418 return current.toPrecision(5);
45419 }
45420 }
45421 /**
45422 * returns lines
45423 * @returns {object} lines
45424 */
45425
45426 }, {
45427 key: "getLines",
45428 value: function getLines() {
45429 var lines = [];
45430 var step = this.getStep();
45431 var bottomOffset = (step - this._start % step) % step;
45432
45433 for (var i = this._start + bottomOffset; this._end - i > 0.00001; i += step) {
45434 if (i != this._start) {
45435 //Skip the bottom line
45436 lines.push({
45437 major: this.is_major(i),
45438 y: this.convertValue(i),
45439 val: this.formatValue(i)
45440 });
45441 }
45442 }
45443
45444 return lines;
45445 }
45446 /**
45447 * follow scale
45448 * @param {object} other
45449 */
45450
45451 }, {
45452 key: "followScale",
45453 value: function followScale(other) {
45454 var oldStepIdx = this.minorStepIdx;
45455 var oldStart = this._start;
45456 var oldEnd = this._end;
45457 var me = this;
45458
45459 var increaseMagnitude = function increaseMagnitude() {
45460 me.magnitudefactor *= 2;
45461 };
45462
45463 var decreaseMagnitude = function decreaseMagnitude() {
45464 me.magnitudefactor /= 2;
45465 };
45466
45467 if (other.minorStepIdx <= 1 && this.minorStepIdx <= 1 || other.minorStepIdx > 1 && this.minorStepIdx > 1) ; else if (other.minorStepIdx < this.minorStepIdx) {
45468 //I'm 5, they are 4 per major.
45469 this.minorStepIdx = 1;
45470
45471 if (oldStepIdx == 2) {
45472 increaseMagnitude();
45473 } else {
45474 increaseMagnitude();
45475 increaseMagnitude();
45476 }
45477 } else {
45478 //I'm 4, they are 5 per major
45479 this.minorStepIdx = 2;
45480
45481 if (oldStepIdx == 1) {
45482 decreaseMagnitude();
45483 } else {
45484 decreaseMagnitude();
45485 decreaseMagnitude();
45486 }
45487 } //Get masters stats:
45488
45489
45490 var otherZero = other.convertValue(0);
45491 var otherStep = other.getStep() * other.scale;
45492 var done = false;
45493 var count = 0; //Loop until magnitude is correct for given constrains.
45494
45495 while (!done && count++ < 5) {
45496 //Get my stats:
45497 this.scale = otherStep / (this.minorSteps[this.minorStepIdx] * this.magnitudefactor);
45498 var newRange = this.containerHeight / this.scale; //For the case the magnitudefactor has changed:
45499
45500 this._start = oldStart;
45501 this._end = this._start + newRange;
45502 var myOriginalZero = this._end * this.scale;
45503 var majorStep = this.magnitudefactor * this.majorSteps[this.minorStepIdx];
45504 var majorOffset = this.getFirstMajor() - other.getFirstMajor();
45505
45506 if (this.zeroAlign) {
45507 var zeroOffset = otherZero - myOriginalZero;
45508 this._end += zeroOffset / this.scale;
45509 this._start = this._end - newRange;
45510 } else {
45511 if (!this.autoScaleStart) {
45512 this._start += majorStep - majorOffset / this.scale;
45513 this._end = this._start + newRange;
45514 } else {
45515 this._start -= majorOffset / this.scale;
45516 this._end = this._start + newRange;
45517 }
45518 }
45519
45520 if (!this.autoScaleEnd && this._end > oldEnd + 0.00001) {
45521 //Need to decrease magnitude to prevent scale overshoot! (end)
45522 decreaseMagnitude();
45523 done = false;
45524 continue;
45525 }
45526
45527 if (!this.autoScaleStart && this._start < oldStart - 0.00001) {
45528 if (this.zeroAlign && oldStart >= 0) {
45529 console.warn("Can't adhere to given 'min' range, due to zeroalign");
45530 } else {
45531 //Need to decrease magnitude to prevent scale overshoot! (start)
45532 decreaseMagnitude();
45533 done = false;
45534 continue;
45535 }
45536 }
45537
45538 if (this.autoScaleStart && this.autoScaleEnd && newRange < oldEnd - oldStart) {
45539 increaseMagnitude();
45540 done = false;
45541 continue;
45542 }
45543
45544 done = true;
45545 }
45546 }
45547 /**
45548 * convert value
45549 * @param {number} value
45550 * @returns {number}
45551 */
45552
45553 }, {
45554 key: "convertValue",
45555 value: function convertValue(value) {
45556 return this.containerHeight - (value - this._start) * this.scale;
45557 }
45558 /**
45559 * returns screen to value
45560 * @param {number} pixels
45561 * @returns {number}
45562 */
45563
45564 }, {
45565 key: "screenToValue",
45566 value: function screenToValue(pixels) {
45567 return (this.containerHeight - pixels) / this.scale + this._start;
45568 }
45569 }]);
45570
45571 return DataScale;
45572}();
45573
45574/** A horizontal time axis */
45575
45576var DataAxis =
45577/*#__PURE__*/
45578function (_Component) {
45579 _inherits(DataAxis, _Component);
45580
45581 /**
45582 * @param {Object} body
45583 * @param {Object} [options] See DataAxis.setOptions for the available
45584 * options.
45585 * @param {SVGElement} svg
45586 * @param {timeline.LineGraph.options} linegraphOptions
45587 * @constructor DataAxis
45588 * @extends Component
45589 */
45590 function DataAxis(body, options, svg, linegraphOptions) {
45591 var _this;
45592
45593 _classCallCheck(this, DataAxis);
45594
45595 _this = _possibleConstructorReturn(this, _getPrototypeOf(DataAxis).call(this));
45596 _this.id = util.randomUUID();
45597 _this.body = body;
45598 _this.defaultOptions = {
45599 orientation: 'left',
45600 // supported: 'left', 'right'
45601 showMinorLabels: true,
45602 showMajorLabels: true,
45603 icons: false,
45604 majorLinesOffset: 7,
45605 minorLinesOffset: 4,
45606 labelOffsetX: 10,
45607 labelOffsetY: 2,
45608 iconWidth: 20,
45609 width: '40px',
45610 visible: true,
45611 alignZeros: true,
45612 left: {
45613 range: {
45614 min: undefined,
45615 max: undefined
45616 },
45617 format: function format(value) {
45618 return "".concat(parseFloat(value.toPrecision(3)));
45619 },
45620 title: {
45621 text: undefined,
45622 style: undefined
45623 }
45624 },
45625 right: {
45626 range: {
45627 min: undefined,
45628 max: undefined
45629 },
45630 format: function format(value) {
45631 return "".concat(parseFloat(value.toPrecision(3)));
45632 },
45633 title: {
45634 text: undefined,
45635 style: undefined
45636 }
45637 }
45638 };
45639 _this.linegraphOptions = linegraphOptions;
45640 _this.linegraphSVG = svg;
45641 _this.props = {};
45642 _this.DOMelements = {
45643 // dynamic elements
45644 lines: {},
45645 labels: {},
45646 title: {}
45647 };
45648 _this.dom = {};
45649 _this.scale = undefined;
45650 _this.range = {
45651 start: 0,
45652 end: 0
45653 };
45654 _this.options = util.extend({}, _this.defaultOptions);
45655 _this.conversionFactor = 1;
45656
45657 _this.setOptions(options);
45658
45659 _this.width = Number("".concat(_this.options.width).replace("px", ""));
45660 _this.minWidth = _this.width;
45661 _this.height = _this.linegraphSVG.getBoundingClientRect().height;
45662 _this.hidden = false;
45663 _this.stepPixels = 25;
45664 _this.zeroCrossing = -1;
45665 _this.amountOfSteps = -1;
45666 _this.lineOffset = 0;
45667 _this.master = true;
45668 _this.masterAxis = null;
45669 _this.svgElements = {};
45670 _this.iconsRemoved = false;
45671 _this.groups = {};
45672 _this.amountOfGroups = 0; // create the HTML DOM
45673
45674 _this._create();
45675
45676 if (_this.scale == undefined) {
45677 _this._redrawLabels();
45678 }
45679
45680 _this.framework = {
45681 svg: _this.svg,
45682 svgElements: _this.svgElements,
45683 options: _this.options,
45684 groups: _this.groups
45685 };
45686
45687 var me = _assertThisInitialized(_this);
45688
45689 _this.body.emitter.on("verticalDrag", function () {
45690 me.dom.lineContainer.style.top = "".concat(me.body.domProps.scrollTop, "px");
45691 });
45692
45693 return _this;
45694 }
45695 /**
45696 * Adds group to data axis
45697 * @param {string} label
45698 * @param {object} graphOptions
45699 */
45700
45701
45702 _createClass(DataAxis, [{
45703 key: "addGroup",
45704 value: function addGroup(label, graphOptions) {
45705 if (!this.groups.hasOwnProperty(label)) {
45706 this.groups[label] = graphOptions;
45707 }
45708
45709 this.amountOfGroups += 1;
45710 }
45711 /**
45712 * updates group of data axis
45713 * @param {string} label
45714 * @param {object} graphOptions
45715 */
45716
45717 }, {
45718 key: "updateGroup",
45719 value: function updateGroup(label, graphOptions) {
45720 if (!this.groups.hasOwnProperty(label)) {
45721 this.amountOfGroups += 1;
45722 }
45723
45724 this.groups[label] = graphOptions;
45725 }
45726 /**
45727 * removes group of data axis
45728 * @param {string} label
45729 */
45730
45731 }, {
45732 key: "removeGroup",
45733 value: function removeGroup(label) {
45734 if (this.groups.hasOwnProperty(label)) {
45735 delete this.groups[label];
45736 this.amountOfGroups -= 1;
45737 }
45738 }
45739 /**
45740 * sets options
45741 * @param {object} options
45742 */
45743
45744 }, {
45745 key: "setOptions",
45746 value: function setOptions(options) {
45747 if (options) {
45748 var redraw = false;
45749
45750 if (this.options.orientation != options.orientation && options.orientation !== undefined) {
45751 redraw = true;
45752 }
45753
45754 var fields = ['orientation', 'showMinorLabels', 'showMajorLabels', 'icons', 'majorLinesOffset', 'minorLinesOffset', 'labelOffsetX', 'labelOffsetY', 'iconWidth', 'width', 'visible', 'left', 'right', 'alignZeros'];
45755 util.selectiveDeepExtend(fields, this.options, options);
45756 this.minWidth = Number("".concat(this.options.width).replace("px", ""));
45757
45758 if (redraw === true && this.dom.frame) {
45759 this.hide();
45760 this.show();
45761 }
45762 }
45763 }
45764 /**
45765 * Create the HTML DOM for the DataAxis
45766 */
45767
45768 }, {
45769 key: "_create",
45770 value: function _create() {
45771 this.dom.frame = document.createElement('div');
45772 this.dom.frame.style.width = this.options.width;
45773 this.dom.frame.style.height = this.height;
45774 this.dom.lineContainer = document.createElement('div');
45775 this.dom.lineContainer.style.width = '100%';
45776 this.dom.lineContainer.style.height = this.height;
45777 this.dom.lineContainer.style.position = 'relative';
45778 this.dom.lineContainer.style.visibility = 'visible';
45779 this.dom.lineContainer.style.display = 'block'; // create svg element for graph drawing.
45780
45781 this.svg = document.createElementNS('http://www.w3.org/2000/svg', "svg");
45782 this.svg.style.position = "absolute";
45783 this.svg.style.top = '0px';
45784 this.svg.style.height = '100%';
45785 this.svg.style.width = '100%';
45786 this.svg.style.display = "block";
45787 this.dom.frame.appendChild(this.svg);
45788 }
45789 /**
45790 * redraws groups icons
45791 */
45792
45793 }, {
45794 key: "_redrawGroupIcons",
45795 value: function _redrawGroupIcons() {
45796 prepareElements(this.svgElements);
45797 var x;
45798 var iconWidth = this.options.iconWidth;
45799 var iconHeight = 15;
45800 var iconOffset = 4;
45801 var y = iconOffset + 0.5 * iconHeight;
45802
45803 if (this.options.orientation === 'left') {
45804 x = iconOffset;
45805 } else {
45806 x = this.width - iconWidth - iconOffset;
45807 }
45808
45809 var groupArray = Object.keys(this.groups);
45810 groupArray.sort(function (a, b) {
45811 return a < b ? -1 : 1;
45812 });
45813
45814 for (var _i = 0, _groupArray = groupArray; _i < _groupArray.length; _i++) {
45815 var groupId = _groupArray[_i];
45816
45817 if (this.groups[groupId].visible === true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] === true)) {
45818 this.groups[groupId].getLegend(iconWidth, iconHeight, this.framework, x, y);
45819 y += iconHeight + iconOffset;
45820 }
45821 }
45822
45823 cleanupElements(this.svgElements);
45824 this.iconsRemoved = false;
45825 }
45826 /**
45827 * Cleans up icons
45828 */
45829
45830 }, {
45831 key: "_cleanupIcons",
45832 value: function _cleanupIcons() {
45833 if (this.iconsRemoved === false) {
45834 prepareElements(this.svgElements);
45835 cleanupElements(this.svgElements);
45836 this.iconsRemoved = true;
45837 }
45838 }
45839 /**
45840 * Create the HTML DOM for the DataAxis
45841 */
45842
45843 }, {
45844 key: "show",
45845 value: function show() {
45846 this.hidden = false;
45847
45848 if (!this.dom.frame.parentNode) {
45849 if (this.options.orientation === 'left') {
45850 this.body.dom.left.appendChild(this.dom.frame);
45851 } else {
45852 this.body.dom.right.appendChild(this.dom.frame);
45853 }
45854 }
45855
45856 if (!this.dom.lineContainer.parentNode) {
45857 this.body.dom.backgroundHorizontal.appendChild(this.dom.lineContainer);
45858 }
45859
45860 this.dom.lineContainer.style.display = 'block';
45861 }
45862 /**
45863 * Create the HTML DOM for the DataAxis
45864 */
45865
45866 }, {
45867 key: "hide",
45868 value: function hide() {
45869 this.hidden = true;
45870
45871 if (this.dom.frame.parentNode) {
45872 this.dom.frame.parentNode.removeChild(this.dom.frame);
45873 }
45874
45875 this.dom.lineContainer.style.display = 'none';
45876 }
45877 /**
45878 * Set a range (start and end)
45879 * @param {number} start
45880 * @param {number} end
45881 */
45882
45883 }, {
45884 key: "setRange",
45885 value: function setRange(start, end) {
45886 this.range.start = start;
45887 this.range.end = end;
45888 }
45889 /**
45890 * Repaint the component
45891 * @return {boolean} Returns true if the component is resized
45892 */
45893
45894 }, {
45895 key: "redraw",
45896 value: function redraw() {
45897 var resized = false;
45898 var activeGroups = 0; // Make sure the line container adheres to the vertical scrolling.
45899
45900 this.dom.lineContainer.style.top = "".concat(this.body.domProps.scrollTop, "px");
45901
45902 for (var groupId in this.groups) {
45903 if (this.groups.hasOwnProperty(groupId)) {
45904 if (this.groups[groupId].visible === true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] === true)) {
45905 activeGroups++;
45906 }
45907 }
45908 }
45909
45910 if (this.amountOfGroups === 0 || activeGroups === 0) {
45911 this.hide();
45912 } else {
45913 this.show();
45914 this.height = Number(this.linegraphSVG.style.height.replace("px", "")); // svg offsetheight did not work in firefox and explorer...
45915
45916 this.dom.lineContainer.style.height = "".concat(this.height, "px");
45917 this.width = this.options.visible === true ? Number("".concat(this.options.width).replace("px", "")) : 0;
45918 var props = this.props;
45919 var frame = this.dom.frame; // update classname
45920
45921 frame.className = 'vis-data-axis'; // calculate character width and height
45922
45923 this._calculateCharSize();
45924
45925 var orientation = this.options.orientation;
45926 var showMinorLabels = this.options.showMinorLabels;
45927 var showMajorLabels = this.options.showMajorLabels;
45928 var backgroundHorizontalOffsetWidth = this.body.dom.backgroundHorizontal.offsetWidth; // determine the width and height of the elements for the axis
45929
45930 props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0;
45931 props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0;
45932 props.minorLineWidth = backgroundHorizontalOffsetWidth - this.lineOffset - this.width + 2 * this.options.minorLinesOffset;
45933 props.minorLineHeight = 1;
45934 props.majorLineWidth = backgroundHorizontalOffsetWidth - this.lineOffset - this.width + 2 * this.options.majorLinesOffset;
45935 props.majorLineHeight = 1; // take frame offline while updating (is almost twice as fast)
45936
45937 if (orientation === 'left') {
45938 frame.style.top = '0';
45939 frame.style.left = '0';
45940 frame.style.bottom = '';
45941 frame.style.width = "".concat(this.width, "px");
45942 frame.style.height = "".concat(this.height, "px");
45943 this.props.width = this.body.domProps.left.width;
45944 this.props.height = this.body.domProps.left.height;
45945 } else {
45946 // right
45947 frame.style.top = '';
45948 frame.style.bottom = '0';
45949 frame.style.left = '0';
45950 frame.style.width = "".concat(this.width, "px");
45951 frame.style.height = "".concat(this.height, "px");
45952 this.props.width = this.body.domProps.right.width;
45953 this.props.height = this.body.domProps.right.height;
45954 }
45955
45956 resized = this._redrawLabels();
45957 resized = this._isResized() || resized;
45958
45959 if (this.options.icons === true) {
45960 this._redrawGroupIcons();
45961 } else {
45962 this._cleanupIcons();
45963 }
45964
45965 this._redrawTitle(orientation);
45966 }
45967
45968 return resized;
45969 }
45970 /**
45971 * Repaint major and minor text labels and vertical grid lines
45972 *
45973 * @returns {boolean}
45974 * @private
45975 */
45976
45977 }, {
45978 key: "_redrawLabels",
45979 value: function _redrawLabels() {
45980 var _this2 = this;
45981
45982 var resized = false;
45983 prepareElements(this.DOMelements.lines);
45984 prepareElements(this.DOMelements.labels);
45985 var orientation = this.options['orientation'];
45986 var customRange = this.options[orientation].range != undefined ? this.options[orientation].range : {}; //Override range with manual options:
45987
45988 var autoScaleEnd = true;
45989
45990 if (customRange.max != undefined) {
45991 this.range.end = customRange.max;
45992 autoScaleEnd = false;
45993 }
45994
45995 var autoScaleStart = true;
45996
45997 if (customRange.min != undefined) {
45998 this.range.start = customRange.min;
45999 autoScaleStart = false;
46000 }
46001
46002 this.scale = new DataScale(this.range.start, this.range.end, autoScaleStart, autoScaleEnd, this.dom.frame.offsetHeight, this.props.majorCharHeight, this.options.alignZeros, this.options[orientation].format);
46003
46004 if (this.master === false && this.masterAxis != undefined) {
46005 this.scale.followScale(this.masterAxis.scale);
46006 this.dom.lineContainer.style.display = 'none';
46007 } else {
46008 this.dom.lineContainer.style.display = 'block';
46009 } //Is updated in side-effect of _redrawLabel():
46010
46011
46012 this.maxLabelSize = 0;
46013 var lines = this.scale.getLines();
46014 lines.forEach(function (line) {
46015 var y = line.y;
46016 var isMajor = line.major;
46017
46018 if (_this2.options['showMinorLabels'] && isMajor === false) {
46019 _this2._redrawLabel(y - 2, line.val, orientation, 'vis-y-axis vis-minor', _this2.props.minorCharHeight);
46020 }
46021
46022 if (isMajor) {
46023 if (y >= 0) {
46024 _this2._redrawLabel(y - 2, line.val, orientation, 'vis-y-axis vis-major', _this2.props.majorCharHeight);
46025 }
46026 }
46027
46028 if (_this2.master === true) {
46029 if (isMajor) {
46030 _this2._redrawLine(y, orientation, 'vis-grid vis-horizontal vis-major', _this2.options.majorLinesOffset, _this2.props.majorLineWidth);
46031 } else {
46032 _this2._redrawLine(y, orientation, 'vis-grid vis-horizontal vis-minor', _this2.options.minorLinesOffset, _this2.props.minorLineWidth);
46033 }
46034 }
46035 }); // Note that title is rotated, so we're using the height, not width!
46036
46037 var titleWidth = 0;
46038
46039 if (this.options[orientation].title !== undefined && this.options[orientation].title.text !== undefined) {
46040 titleWidth = this.props.titleCharHeight;
46041 }
46042
46043 var offset = this.options.icons === true ? Math.max(this.options.iconWidth, titleWidth) + this.options.labelOffsetX + 15 : titleWidth + this.options.labelOffsetX + 15; // this will resize the yAxis to accommodate the labels.
46044
46045 if (this.maxLabelSize > this.width - offset && this.options.visible === true) {
46046 this.width = this.maxLabelSize + offset;
46047 this.options.width = "".concat(this.width, "px");
46048 cleanupElements(this.DOMelements.lines);
46049 cleanupElements(this.DOMelements.labels);
46050 this.redraw();
46051 resized = true;
46052 } // this will resize the yAxis if it is too big for the labels.
46053 else if (this.maxLabelSize < this.width - offset && this.options.visible === true && this.width > this.minWidth) {
46054 this.width = Math.max(this.minWidth, this.maxLabelSize + offset);
46055 this.options.width = "".concat(this.width, "px");
46056 cleanupElements(this.DOMelements.lines);
46057 cleanupElements(this.DOMelements.labels);
46058 this.redraw();
46059 resized = true;
46060 } else {
46061 cleanupElements(this.DOMelements.lines);
46062 cleanupElements(this.DOMelements.labels);
46063 resized = false;
46064 }
46065
46066 return resized;
46067 }
46068 /**
46069 * converts value
46070 * @param {number} value
46071 * @returns {number} converted number
46072 */
46073
46074 }, {
46075 key: "convertValue",
46076 value: function convertValue(value) {
46077 return this.scale.convertValue(value);
46078 }
46079 /**
46080 * converts value
46081 * @param {number} x
46082 * @returns {number} screen value
46083 */
46084
46085 }, {
46086 key: "screenToValue",
46087 value: function screenToValue(x) {
46088 return this.scale.screenToValue(x);
46089 }
46090 /**
46091 * Create a label for the axis at position x
46092 *
46093 * @param {number} y
46094 * @param {string} text
46095 * @param {'top'|'right'|'bottom'|'left'} orientation
46096 * @param {string} className
46097 * @param {number} characterHeight
46098 * @private
46099 */
46100
46101 }, {
46102 key: "_redrawLabel",
46103 value: function _redrawLabel(y, text, orientation, className, characterHeight) {
46104 // reuse redundant label
46105 var label = getDOMElement('div', this.DOMelements.labels, this.dom.frame); //this.dom.redundant.labels.shift();
46106
46107 label.className = className;
46108 label.innerHTML = text;
46109
46110 if (orientation === 'left') {
46111 label.style.left = "-".concat(this.options.labelOffsetX, "px");
46112 label.style.textAlign = "right";
46113 } else {
46114 label.style.right = "-".concat(this.options.labelOffsetX, "px");
46115 label.style.textAlign = "left";
46116 }
46117
46118 label.style.top = "".concat(y - 0.5 * characterHeight + this.options.labelOffsetY, "px");
46119 text += '';
46120 var largestWidth = Math.max(this.props.majorCharWidth, this.props.minorCharWidth);
46121
46122 if (this.maxLabelSize < text.length * largestWidth) {
46123 this.maxLabelSize = text.length * largestWidth;
46124 }
46125 }
46126 /**
46127 * Create a minor line for the axis at position y
46128 * @param {number} y
46129 * @param {'top'|'right'|'bottom'|'left'} orientation
46130 * @param {string} className
46131 * @param {number} offset
46132 * @param {number} width
46133 */
46134
46135 }, {
46136 key: "_redrawLine",
46137 value: function _redrawLine(y, orientation, className, offset, width) {
46138 if (this.master === true) {
46139 var line = getDOMElement('div', this.DOMelements.lines, this.dom.lineContainer); //this.dom.redundant.lines.shift();
46140
46141 line.className = className;
46142 line.innerHTML = '';
46143
46144 if (orientation === 'left') {
46145 line.style.left = "".concat(this.width - offset, "px");
46146 } else {
46147 line.style.right = "".concat(this.width - offset, "px");
46148 }
46149
46150 line.style.width = "".concat(width, "px");
46151 line.style.top = "".concat(y, "px");
46152 }
46153 }
46154 /**
46155 * Create a title for the axis
46156 * @private
46157 * @param {'top'|'right'|'bottom'|'left'} orientation
46158 */
46159
46160 }, {
46161 key: "_redrawTitle",
46162 value: function _redrawTitle(orientation) {
46163 prepareElements(this.DOMelements.title); // Check if the title is defined for this axes
46164
46165 if (this.options[orientation].title !== undefined && this.options[orientation].title.text !== undefined) {
46166 var title = getDOMElement('div', this.DOMelements.title, this.dom.frame);
46167 title.className = "vis-y-axis vis-title vis-".concat(orientation);
46168 title.innerHTML = this.options[orientation].title.text; // Add style - if provided
46169
46170 if (this.options[orientation].title.style !== undefined) {
46171 util.addCssText(title, this.options[orientation].title.style);
46172 }
46173
46174 if (orientation === 'left') {
46175 title.style.left = "".concat(this.props.titleCharHeight, "px");
46176 } else {
46177 title.style.right = "".concat(this.props.titleCharHeight, "px");
46178 }
46179
46180 title.style.width = "".concat(this.height, "px");
46181 } // we need to clean up in case we did not use all elements.
46182
46183
46184 cleanupElements(this.DOMelements.title);
46185 }
46186 /**
46187 * Determine the size of text on the axis (both major and minor axis).
46188 * The size is calculated only once and then cached in this.props.
46189 * @private
46190 */
46191
46192 }, {
46193 key: "_calculateCharSize",
46194 value: function _calculateCharSize() {
46195 // determine the char width and height on the minor axis
46196 if (!('minorCharHeight' in this.props)) {
46197 var textMinor = document.createTextNode('0');
46198 var measureCharMinor = document.createElement('div');
46199 measureCharMinor.className = 'vis-y-axis vis-minor vis-measure';
46200 measureCharMinor.appendChild(textMinor);
46201 this.dom.frame.appendChild(measureCharMinor);
46202 this.props.minorCharHeight = measureCharMinor.clientHeight;
46203 this.props.minorCharWidth = measureCharMinor.clientWidth;
46204 this.dom.frame.removeChild(measureCharMinor);
46205 }
46206
46207 if (!('majorCharHeight' in this.props)) {
46208 var textMajor = document.createTextNode('0');
46209 var measureCharMajor = document.createElement('div');
46210 measureCharMajor.className = 'vis-y-axis vis-major vis-measure';
46211 measureCharMajor.appendChild(textMajor);
46212 this.dom.frame.appendChild(measureCharMajor);
46213 this.props.majorCharHeight = measureCharMajor.clientHeight;
46214 this.props.majorCharWidth = measureCharMajor.clientWidth;
46215 this.dom.frame.removeChild(measureCharMajor);
46216 }
46217
46218 if (!('titleCharHeight' in this.props)) {
46219 var textTitle = document.createTextNode('0');
46220 var measureCharTitle = document.createElement('div');
46221 measureCharTitle.className = 'vis-y-axis vis-title vis-measure';
46222 measureCharTitle.appendChild(textTitle);
46223 this.dom.frame.appendChild(measureCharTitle);
46224 this.props.titleCharHeight = measureCharTitle.clientHeight;
46225 this.props.titleCharWidth = measureCharTitle.clientWidth;
46226 this.dom.frame.removeChild(measureCharTitle);
46227 }
46228 }
46229 }]);
46230
46231 return DataAxis;
46232}(Component);
46233
46234/**
46235 *
46236 * @param {number | string} groupId
46237 * @param {Object} options // TODO: Describe options
46238 *
46239 * @constructor Points
46240 */
46241
46242function Points(groupId, options) {} // eslint-disable-line no-unused-vars
46243
46244/**
46245 * draw the data points
46246 *
46247 * @param {Array} dataset
46248 * @param {GraphGroup} group
46249 * @param {Object} framework | SVG DOM element
46250 * @param {number} [offset]
46251 */
46252
46253
46254Points.draw = function (dataset, group, framework, offset) {
46255 offset = offset || 0;
46256 var callback = getCallback(framework, group);
46257
46258 for (var i = 0; i < dataset.length; i++) {
46259 if (!callback) {
46260 // draw the point the simple way.
46261 drawPoint(dataset[i].screen_x + offset, dataset[i].screen_y, getGroupTemplate(group), framework.svgElements, framework.svg, dataset[i].label);
46262 } else {
46263 var callbackResult = callback(dataset[i], group); // result might be true, false or an object
46264
46265 if (callbackResult === true || _typeof(callbackResult) === 'object') {
46266 drawPoint(dataset[i].screen_x + offset, dataset[i].screen_y, getGroupTemplate(group, callbackResult), framework.svgElements, framework.svg, dataset[i].label);
46267 }
46268 }
46269 }
46270};
46271
46272Points.drawIcon = function (group, x, y, iconWidth, iconHeight, framework) {
46273 var fillHeight = iconHeight * 0.5;
46274 var outline = getSVGElement("rect", framework.svgElements, framework.svg);
46275 outline.setAttributeNS(null, "x", x);
46276 outline.setAttributeNS(null, "y", y - fillHeight);
46277 outline.setAttributeNS(null, "width", iconWidth);
46278 outline.setAttributeNS(null, "height", 2 * fillHeight);
46279 outline.setAttributeNS(null, "class", "vis-outline"); //Don't call callback on icon
46280
46281 drawPoint(x + 0.5 * iconWidth, y, getGroupTemplate(group), framework.svgElements, framework.svg);
46282};
46283/**
46284 *
46285 * @param {vis.Group} group
46286 * @param {any} callbackResult
46287 * @returns {{style: *, styles: (*|string), size: *, className: *}}
46288 */
46289
46290
46291function getGroupTemplate(group, callbackResult) {
46292 callbackResult = typeof callbackResult === 'undefined' ? {} : callbackResult;
46293 return {
46294 style: callbackResult.style || group.options.drawPoints.style,
46295 styles: callbackResult.styles || group.options.drawPoints.styles,
46296 size: callbackResult.size || group.options.drawPoints.size,
46297 className: callbackResult.className || group.className
46298 };
46299}
46300/**
46301 *
46302 * @param {Object} framework | SVG DOM element
46303 * @param {vis.Group} group
46304 * @returns {function}
46305 */
46306
46307
46308function getCallback(framework, group) {
46309 var callback = undefined; // check for the graph2d onRender
46310
46311 if (framework.options && framework.options.drawPoints && framework.options.drawPoints.onRender && typeof framework.options.drawPoints.onRender == 'function') {
46312 callback = framework.options.drawPoints.onRender;
46313 } // override it with the group onRender if defined
46314
46315
46316 if (group.group.options && group.group.options.drawPoints && group.group.options.drawPoints.onRender && typeof group.group.options.drawPoints.onRender == 'function') {
46317 callback = group.group.options.drawPoints.onRender;
46318 }
46319
46320 return callback;
46321}
46322
46323/**
46324 *
46325 * @param {vis.GraphGroup.id} groupId
46326 * @param {Object} options // TODO: Describe options
46327 * @constructor Bargraph
46328 */
46329
46330function Bargraph(groupId, options) {// eslint-disable-line no-unused-vars
46331}
46332
46333Bargraph.drawIcon = function (group, x, y, iconWidth, iconHeight, framework) {
46334 var fillHeight = iconHeight * 0.5;
46335 var outline = getSVGElement("rect", framework.svgElements, framework.svg);
46336 outline.setAttributeNS(null, "x", x);
46337 outline.setAttributeNS(null, "y", y - fillHeight);
46338 outline.setAttributeNS(null, "width", iconWidth);
46339 outline.setAttributeNS(null, "height", 2 * fillHeight);
46340 outline.setAttributeNS(null, "class", "vis-outline");
46341 var barWidth = Math.round(0.3 * iconWidth);
46342 var originalWidth = group.options.barChart.width;
46343 var scale = originalWidth / barWidth;
46344 var bar1Height = Math.round(0.4 * iconHeight);
46345 var bar2Height = Math.round(0.75 * iconHeight);
46346 var offset = Math.round((iconWidth - 2 * barWidth) / 3);
46347 drawBar(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, barWidth, bar1Height, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
46348 drawBar(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, barWidth, bar2Height, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
46349
46350 if (group.options.drawPoints.enabled == true) {
46351 var groupTemplate = {
46352 style: group.options.drawPoints.style,
46353 styles: group.options.drawPoints.styles,
46354 size: group.options.drawPoints.size / scale,
46355 className: group.className
46356 };
46357 drawPoint(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, groupTemplate, framework.svgElements, framework.svg);
46358 drawPoint(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, groupTemplate, framework.svgElements, framework.svg);
46359 }
46360};
46361/**
46362 * draw a bar graph
46363 *
46364 * @param {Array.<vis.GraphGroup.id>} groupIds
46365 * @param {Object} processedGroupData
46366 * @param {{svg: Object, svgElements: Array.<Object>, options: Object, groups: Array.<vis.Group>}} framework
46367 */
46368
46369
46370Bargraph.draw = function (groupIds, processedGroupData, framework) {
46371 var combinedData = [];
46372 var intersections = {};
46373 var coreDistance;
46374 var key, drawData;
46375 var group;
46376 var i, j;
46377 var barPoints = 0; // combine all barchart data
46378
46379 for (i = 0; i < groupIds.length; i++) {
46380 group = framework.groups[groupIds[i]];
46381
46382 if (group.options.style === 'bar') {
46383 if (group.visible === true && (framework.options.groups.visibility[groupIds[i]] === undefined || framework.options.groups.visibility[groupIds[i]] === true)) {
46384 for (j = 0; j < processedGroupData[groupIds[i]].length; j++) {
46385 combinedData.push({
46386 screen_x: processedGroupData[groupIds[i]][j].screen_x,
46387 screen_end: processedGroupData[groupIds[i]][j].screen_end,
46388 screen_y: processedGroupData[groupIds[i]][j].screen_y,
46389 x: processedGroupData[groupIds[i]][j].x,
46390 end: processedGroupData[groupIds[i]][j].end,
46391 y: processedGroupData[groupIds[i]][j].y,
46392 groupId: groupIds[i],
46393 label: processedGroupData[groupIds[i]][j].label
46394 });
46395 barPoints += 1;
46396 }
46397 }
46398 }
46399 }
46400
46401 if (barPoints === 0) {
46402 return;
46403 } // sort by time and by group
46404
46405
46406 combinedData.sort(function (a, b) {
46407 if (a.screen_x === b.screen_x) {
46408 return a.groupId < b.groupId ? -1 : 1;
46409 } else {
46410 return a.screen_x - b.screen_x;
46411 }
46412 }); // get intersections
46413
46414 Bargraph._getDataIntersections(intersections, combinedData); // plot barchart
46415
46416
46417 for (i = 0; i < combinedData.length; i++) {
46418 group = framework.groups[combinedData[i].groupId];
46419 var minWidth = group.options.barChart.minWidth != undefined ? group.options.barChart.minWidth : 0.1 * group.options.barChart.width;
46420 key = combinedData[i].screen_x;
46421 var heightOffset = 0;
46422
46423 if (intersections[key] === undefined) {
46424 if (i + 1 < combinedData.length) {
46425 coreDistance = Math.abs(combinedData[i + 1].screen_x - key);
46426 }
46427
46428 drawData = Bargraph._getSafeDrawData(coreDistance, group, minWidth);
46429 } else {
46430 var nextKey = i + (intersections[key].amount - intersections[key].resolved);
46431
46432 if (nextKey < combinedData.length) {
46433 coreDistance = Math.abs(combinedData[nextKey].screen_x - key);
46434 }
46435
46436 drawData = Bargraph._getSafeDrawData(coreDistance, group, minWidth);
46437 intersections[key].resolved += 1;
46438
46439 if (group.options.stack === true && group.options.excludeFromStacking !== true) {
46440 if (combinedData[i].screen_y < group.zeroPosition) {
46441 heightOffset = intersections[key].accumulatedNegative;
46442 intersections[key].accumulatedNegative += group.zeroPosition - combinedData[i].screen_y;
46443 } else {
46444 heightOffset = intersections[key].accumulatedPositive;
46445 intersections[key].accumulatedPositive += group.zeroPosition - combinedData[i].screen_y;
46446 }
46447 } else if (group.options.barChart.sideBySide === true) {
46448 drawData.width = drawData.width / intersections[key].amount;
46449 drawData.offset += intersections[key].resolved * drawData.width - 0.5 * drawData.width * (intersections[key].amount + 1);
46450 }
46451 }
46452
46453 var dataWidth = drawData.width;
46454 var start = combinedData[i].screen_x; // are we drawing explicit boxes? (we supplied an end value)
46455
46456 if (combinedData[i].screen_end != undefined) {
46457 dataWidth = combinedData[i].screen_end - combinedData[i].screen_x;
46458 start += dataWidth * 0.5;
46459 } else {
46460 start += drawData.offset;
46461 }
46462
46463 drawBar(start, combinedData[i].screen_y - heightOffset, dataWidth, group.zeroPosition - combinedData[i].screen_y, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style); // draw points
46464
46465 if (group.options.drawPoints.enabled === true) {
46466 var pointData = {
46467 screen_x: combinedData[i].screen_x,
46468 screen_y: combinedData[i].screen_y - heightOffset,
46469 x: combinedData[i].x,
46470 y: combinedData[i].y,
46471 groupId: combinedData[i].groupId,
46472 label: combinedData[i].label
46473 };
46474 Points.draw([pointData], group, framework, drawData.offset); //DOMutil.drawPoint(combinedData[i].x + drawData.offset, combinedData[i].y, group, framework.svgElements, framework.svg);
46475 }
46476 }
46477};
46478/**
46479 * Fill the intersections object with counters of how many datapoints share the same x coordinates
46480 * @param {Object} intersections
46481 * @param {Array.<Object>} combinedData
46482 * @private
46483 */
46484
46485
46486Bargraph._getDataIntersections = function (intersections, combinedData) {
46487 // get intersections
46488 var coreDistance;
46489
46490 for (var i = 0; i < combinedData.length; i++) {
46491 if (i + 1 < combinedData.length) {
46492 coreDistance = Math.abs(combinedData[i + 1].screen_x - combinedData[i].screen_x);
46493 }
46494
46495 if (i > 0) {
46496 coreDistance = Math.min(coreDistance, Math.abs(combinedData[i - 1].screen_x - combinedData[i].screen_x));
46497 }
46498
46499 if (coreDistance === 0) {
46500 if (intersections[combinedData[i].screen_x] === undefined) {
46501 intersections[combinedData[i].screen_x] = {
46502 amount: 0,
46503 resolved: 0,
46504 accumulatedPositive: 0,
46505 accumulatedNegative: 0
46506 };
46507 }
46508
46509 intersections[combinedData[i].screen_x].amount += 1;
46510 }
46511 }
46512};
46513/**
46514 * Get the width and offset for bargraphs based on the coredistance between datapoints
46515 *
46516 * @param {number} coreDistance
46517 * @param {vis.Group} group
46518 * @param {number} minWidth
46519 * @returns {{width: number, offset: number}}
46520 * @private
46521 */
46522
46523
46524Bargraph._getSafeDrawData = function (coreDistance, group, minWidth) {
46525 var width, offset;
46526
46527 if (coreDistance < group.options.barChart.width && coreDistance > 0) {
46528 width = coreDistance < minWidth ? minWidth : coreDistance;
46529 offset = 0; // recalculate offset with the new width;
46530
46531 if (group.options.barChart.align === 'left') {
46532 offset -= 0.5 * coreDistance;
46533 } else if (group.options.barChart.align === 'right') {
46534 offset += 0.5 * coreDistance;
46535 }
46536 } else {
46537 // default settings
46538 width = group.options.barChart.width;
46539 offset = 0;
46540
46541 if (group.options.barChart.align === 'left') {
46542 offset -= 0.5 * group.options.barChart.width;
46543 } else if (group.options.barChart.align === 'right') {
46544 offset += 0.5 * group.options.barChart.width;
46545 }
46546 }
46547
46548 return {
46549 width: width,
46550 offset: offset
46551 };
46552};
46553
46554Bargraph.getStackedYRange = function (combinedData, groupRanges, groupIds, groupLabel, orientation) {
46555 if (combinedData.length > 0) {
46556 // sort by time and by group
46557 combinedData.sort(function (a, b) {
46558 if (a.screen_x === b.screen_x) {
46559 return a.groupId < b.groupId ? -1 : 1;
46560 } else {
46561 return a.screen_x - b.screen_x;
46562 }
46563 });
46564 var intersections = {};
46565
46566 Bargraph._getDataIntersections(intersections, combinedData);
46567
46568 groupRanges[groupLabel] = Bargraph._getStackedYRange(intersections, combinedData);
46569 groupRanges[groupLabel].yAxisOrientation = orientation;
46570 groupIds.push(groupLabel);
46571 }
46572};
46573
46574Bargraph._getStackedYRange = function (intersections, combinedData) {
46575 var key;
46576 var yMin = combinedData[0].screen_y;
46577 var yMax = combinedData[0].screen_y;
46578
46579 for (var i = 0; i < combinedData.length; i++) {
46580 key = combinedData[i].screen_x;
46581
46582 if (intersections[key] === undefined) {
46583 yMin = yMin > combinedData[i].screen_y ? combinedData[i].screen_y : yMin;
46584 yMax = yMax < combinedData[i].screen_y ? combinedData[i].screen_y : yMax;
46585 } else {
46586 if (combinedData[i].screen_y < 0) {
46587 intersections[key].accumulatedNegative += combinedData[i].screen_y;
46588 } else {
46589 intersections[key].accumulatedPositive += combinedData[i].screen_y;
46590 }
46591 }
46592 }
46593
46594 for (var xpos in intersections) {
46595 if (intersections.hasOwnProperty(xpos)) {
46596 yMin = yMin > intersections[xpos].accumulatedNegative ? intersections[xpos].accumulatedNegative : yMin;
46597 yMin = yMin > intersections[xpos].accumulatedPositive ? intersections[xpos].accumulatedPositive : yMin;
46598 yMax = yMax < intersections[xpos].accumulatedNegative ? intersections[xpos].accumulatedNegative : yMax;
46599 yMax = yMax < intersections[xpos].accumulatedPositive ? intersections[xpos].accumulatedPositive : yMax;
46600 }
46601 }
46602
46603 return {
46604 min: yMin,
46605 max: yMax
46606 };
46607};
46608
46609/**
46610 *
46611 * @param {vis.GraphGroup.id} groupId
46612 * @param {Object} options // TODO: Describe options
46613 * @constructor Line
46614 */
46615
46616function Line(groupId, options) {// eslint-disable-line no-unused-vars
46617}
46618
46619Line.calcPath = function (dataset, group) {
46620 if (dataset != null) {
46621 if (dataset.length > 0) {
46622 var d = []; // construct path from dataset
46623
46624 if (group.options.interpolation.enabled == true) {
46625 d = Line._catmullRom(dataset, group);
46626 } else {
46627 d = Line._linear(dataset);
46628 }
46629
46630 return d;
46631 }
46632 }
46633};
46634
46635Line.drawIcon = function (group, x, y, iconWidth, iconHeight, framework) {
46636 var fillHeight = iconHeight * 0.5;
46637 var path, fillPath;
46638 var outline = getSVGElement("rect", framework.svgElements, framework.svg);
46639 outline.setAttributeNS(null, "x", x);
46640 outline.setAttributeNS(null, "y", y - fillHeight);
46641 outline.setAttributeNS(null, "width", iconWidth);
46642 outline.setAttributeNS(null, "height", 2 * fillHeight);
46643 outline.setAttributeNS(null, "class", "vis-outline");
46644 path = getSVGElement("path", framework.svgElements, framework.svg);
46645 path.setAttributeNS(null, "class", group.className);
46646
46647 if (group.style !== undefined) {
46648 path.setAttributeNS(null, "style", group.style);
46649 }
46650
46651 path.setAttributeNS(null, "d", "M" + x + "," + y + " L" + (x + iconWidth) + "," + y + "");
46652
46653 if (group.options.shaded.enabled == true) {
46654 fillPath = getSVGElement("path", framework.svgElements, framework.svg);
46655
46656 if (group.options.shaded.orientation == 'top') {
46657 fillPath.setAttributeNS(null, "d", "M" + x + ", " + (y - fillHeight) + "L" + x + "," + y + " L" + (x + iconWidth) + "," + y + " L" + (x + iconWidth) + "," + (y - fillHeight));
46658 } else {
46659 fillPath.setAttributeNS(null, "d", "M" + x + "," + y + " " + "L" + x + "," + (y + fillHeight) + " " + "L" + (x + iconWidth) + "," + (y + fillHeight) + "L" + (x + iconWidth) + "," + y);
46660 }
46661
46662 fillPath.setAttributeNS(null, "class", group.className + " vis-icon-fill");
46663
46664 if (group.options.shaded.style !== undefined && group.options.shaded.style !== "") {
46665 fillPath.setAttributeNS(null, "style", group.options.shaded.style);
46666 }
46667 }
46668
46669 if (group.options.drawPoints.enabled == true) {
46670 var groupTemplate = {
46671 style: group.options.drawPoints.style,
46672 styles: group.options.drawPoints.styles,
46673 size: group.options.drawPoints.size,
46674 className: group.className
46675 };
46676 drawPoint(x + 0.5 * iconWidth, y, groupTemplate, framework.svgElements, framework.svg);
46677 }
46678};
46679
46680Line.drawShading = function (pathArray, group, subPathArray, framework) {
46681 // append shading to the path
46682 if (group.options.shaded.enabled == true) {
46683 var svgHeight = Number(framework.svg.style.height.replace('px', ''));
46684 var fillPath = getSVGElement('path', framework.svgElements, framework.svg);
46685 var type = "L";
46686
46687 if (group.options.interpolation.enabled == true) {
46688 type = "C";
46689 }
46690
46691 var dFill;
46692 var zero = 0;
46693
46694 if (group.options.shaded.orientation == 'top') {
46695 zero = 0;
46696 } else if (group.options.shaded.orientation == 'bottom') {
46697 zero = svgHeight;
46698 } else {
46699 zero = Math.min(Math.max(0, group.zeroPosition), svgHeight);
46700 }
46701
46702 if (group.options.shaded.orientation == 'group' && subPathArray != null && subPathArray != undefined) {
46703 dFill = 'M' + pathArray[0][0] + "," + pathArray[0][1] + " " + this.serializePath(pathArray, type, false) + ' L' + subPathArray[subPathArray.length - 1][0] + "," + subPathArray[subPathArray.length - 1][1] + " " + this.serializePath(subPathArray, type, true) + subPathArray[0][0] + "," + subPathArray[0][1] + " Z";
46704 } else {
46705 dFill = 'M' + pathArray[0][0] + "," + pathArray[0][1] + " " + this.serializePath(pathArray, type, false) + ' V' + zero + ' H' + pathArray[0][0] + " Z";
46706 }
46707
46708 fillPath.setAttributeNS(null, 'class', group.className + ' vis-fill');
46709
46710 if (group.options.shaded.style !== undefined) {
46711 fillPath.setAttributeNS(null, 'style', group.options.shaded.style);
46712 }
46713
46714 fillPath.setAttributeNS(null, 'd', dFill);
46715 }
46716};
46717/**
46718 * draw a line graph
46719 *
46720 * @param {Array.<Object>} pathArray
46721 * @param {vis.Group} group
46722 * @param {{svg: Object, svgElements: Array.<Object>, options: Object, groups: Array.<vis.Group>}} framework
46723 */
46724
46725
46726Line.draw = function (pathArray, group, framework) {
46727 if (pathArray != null && pathArray != undefined) {
46728 var path = getSVGElement('path', framework.svgElements, framework.svg);
46729 path.setAttributeNS(null, "class", group.className);
46730
46731 if (group.style !== undefined) {
46732 path.setAttributeNS(null, "style", group.style);
46733 }
46734
46735 var type = "L";
46736
46737 if (group.options.interpolation.enabled == true) {
46738 type = "C";
46739 } // copy properties to path for drawing.
46740
46741
46742 path.setAttributeNS(null, 'd', 'M' + pathArray[0][0] + "," + pathArray[0][1] + " " + this.serializePath(pathArray, type, false));
46743 }
46744};
46745
46746Line.serializePath = function (pathArray, type, inverse) {
46747 if (pathArray.length < 2) {
46748 //Too little data to create a path.
46749 return "";
46750 }
46751
46752 var d = type;
46753 var i;
46754
46755 if (inverse) {
46756 for (i = pathArray.length - 2; i > 0; i--) {
46757 d += pathArray[i][0] + "," + pathArray[i][1] + " ";
46758 }
46759 } else {
46760 for (i = 1; i < pathArray.length; i++) {
46761 d += pathArray[i][0] + "," + pathArray[i][1] + " ";
46762 }
46763 }
46764
46765 return d;
46766};
46767/**
46768 * This uses an uniform parametrization of the interpolation algorithm:
46769 * 'On the Parameterization of Catmull-Rom Curves' by Cem Yuksel et al.
46770 * @param {Array.<Object>} data
46771 * @returns {string}
46772 * @private
46773 */
46774
46775
46776Line._catmullRomUniform = function (data) {
46777 // catmull rom
46778 var p0, p1, p2, p3, bp1, bp2;
46779 var d = [];
46780 d.push([Math.round(data[0].screen_x), Math.round(data[0].screen_y)]);
46781 var normalization = 1 / 6;
46782 var length = data.length;
46783
46784 for (var i = 0; i < length - 1; i++) {
46785 p0 = i == 0 ? data[0] : data[i - 1];
46786 p1 = data[i];
46787 p2 = data[i + 1];
46788 p3 = i + 2 < length ? data[i + 2] : p2; // Catmull-Rom to Cubic Bezier conversion matrix
46789 // 0 1 0 0
46790 // -1/6 1 1/6 0
46791 // 0 1/6 1 -1/6
46792 // 0 0 1 0
46793 // bp0 = { x: p1.x, y: p1.y };
46794
46795 bp1 = {
46796 screen_x: (-p0.screen_x + 6 * p1.screen_x + p2.screen_x) * normalization,
46797 screen_y: (-p0.screen_y + 6 * p1.screen_y + p2.screen_y) * normalization
46798 };
46799 bp2 = {
46800 screen_x: (p1.screen_x + 6 * p2.screen_x - p3.screen_x) * normalization,
46801 screen_y: (p1.screen_y + 6 * p2.screen_y - p3.screen_y) * normalization
46802 }; // bp0 = { x: p2.x, y: p2.y };
46803
46804 d.push([bp1.screen_x, bp1.screen_y]);
46805 d.push([bp2.screen_x, bp2.screen_y]);
46806 d.push([p2.screen_x, p2.screen_y]);
46807 }
46808
46809 return d;
46810};
46811/**
46812 * This uses either the chordal or centripetal parameterization of the catmull-rom algorithm.
46813 * By default, the centripetal parameterization is used because this gives the nicest results.
46814 * These parameterizations are relatively heavy because the distance between 4 points have to be calculated.
46815 *
46816 * One optimization can be used to reuse distances since this is a sliding window approach.
46817 * @param {Array.<Object>} data
46818 * @param {vis.GraphGroup} group
46819 * @returns {string}
46820 * @private
46821 */
46822
46823
46824Line._catmullRom = function (data, group) {
46825 var alpha = group.options.interpolation.alpha;
46826
46827 if (alpha == 0 || alpha === undefined) {
46828 return this._catmullRomUniform(data);
46829 } else {
46830 var p0, p1, p2, p3, bp1, bp2, d1, d2, d3, A, B, N, M;
46831 var d3powA, d2powA, d3pow2A, d2pow2A, d1pow2A, d1powA;
46832 var d = [];
46833 d.push([Math.round(data[0].screen_x), Math.round(data[0].screen_y)]);
46834 var length = data.length;
46835
46836 for (var i = 0; i < length - 1; i++) {
46837 p0 = i == 0 ? data[0] : data[i - 1];
46838 p1 = data[i];
46839 p2 = data[i + 1];
46840 p3 = i + 2 < length ? data[i + 2] : p2;
46841 d1 = Math.sqrt(Math.pow(p0.screen_x - p1.screen_x, 2) + Math.pow(p0.screen_y - p1.screen_y, 2));
46842 d2 = Math.sqrt(Math.pow(p1.screen_x - p2.screen_x, 2) + Math.pow(p1.screen_y - p2.screen_y, 2));
46843 d3 = Math.sqrt(Math.pow(p2.screen_x - p3.screen_x, 2) + Math.pow(p2.screen_y - p3.screen_y, 2)); // Catmull-Rom to Cubic Bezier conversion matrix
46844 // A = 2d1^2a + 3d1^a * d2^a + d3^2a
46845 // B = 2d3^2a + 3d3^a * d2^a + d2^2a
46846 // [ 0 1 0 0 ]
46847 // [ -d2^2a /N A/N d1^2a /N 0 ]
46848 // [ 0 d3^2a /M B/M -d2^2a /M ]
46849 // [ 0 0 1 0 ]
46850
46851 d3powA = Math.pow(d3, alpha);
46852 d3pow2A = Math.pow(d3, 2 * alpha);
46853 d2powA = Math.pow(d2, alpha);
46854 d2pow2A = Math.pow(d2, 2 * alpha);
46855 d1powA = Math.pow(d1, alpha);
46856 d1pow2A = Math.pow(d1, 2 * alpha);
46857 A = 2 * d1pow2A + 3 * d1powA * d2powA + d2pow2A;
46858 B = 2 * d3pow2A + 3 * d3powA * d2powA + d2pow2A;
46859 N = 3 * d1powA * (d1powA + d2powA);
46860
46861 if (N > 0) {
46862 N = 1 / N;
46863 }
46864
46865 M = 3 * d3powA * (d3powA + d2powA);
46866
46867 if (M > 0) {
46868 M = 1 / M;
46869 }
46870
46871 bp1 = {
46872 screen_x: (-d2pow2A * p0.screen_x + A * p1.screen_x + d1pow2A * p2.screen_x) * N,
46873 screen_y: (-d2pow2A * p0.screen_y + A * p1.screen_y + d1pow2A * p2.screen_y) * N
46874 };
46875 bp2 = {
46876 screen_x: (d3pow2A * p1.screen_x + B * p2.screen_x - d2pow2A * p3.screen_x) * M,
46877 screen_y: (d3pow2A * p1.screen_y + B * p2.screen_y - d2pow2A * p3.screen_y) * M
46878 };
46879
46880 if (bp1.screen_x == 0 && bp1.screen_y == 0) {
46881 bp1 = p1;
46882 }
46883
46884 if (bp2.screen_x == 0 && bp2.screen_y == 0) {
46885 bp2 = p2;
46886 }
46887
46888 d.push([bp1.screen_x, bp1.screen_y]);
46889 d.push([bp2.screen_x, bp2.screen_y]);
46890 d.push([p2.screen_x, p2.screen_y]);
46891 }
46892
46893 return d;
46894 }
46895};
46896/**
46897 * this generates the SVG path for a linear drawing between datapoints.
46898 * @param {Array.<Object>} data
46899 * @returns {string}
46900 * @private
46901 */
46902
46903
46904Line._linear = function (data) {
46905 // linear
46906 var d = [];
46907
46908 for (var i = 0; i < data.length; i++) {
46909 d.push([data[i].screen_x, data[i].screen_y]);
46910 }
46911
46912 return d;
46913};
46914
46915/**
46916 * /**
46917 * @param {object} group | the object of the group from the dataset
46918 * @param {string} groupId | ID of the group
46919 * @param {object} options | the default options
46920 * @param {array} groupsUsingDefaultStyles | this array has one entree.
46921 * It is passed as an array so it is passed by reference.
46922 * It enumerates through the default styles
46923 * @constructor GraphGroup
46924 */
46925
46926function GraphGroup(group, groupId, options, groupsUsingDefaultStyles) {
46927 this.id = groupId;
46928 var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'drawPoints', 'shaded', 'interpolation', 'zIndex', 'excludeFromStacking', 'excludeFromLegend'];
46929 this.options = util.selectiveBridgeObject(fields, options);
46930 this.usingDefaultStyle = group.className === undefined;
46931 this.groupsUsingDefaultStyles = groupsUsingDefaultStyles;
46932 this.zeroPosition = 0;
46933 this.update(group);
46934
46935 if (this.usingDefaultStyle == true) {
46936 this.groupsUsingDefaultStyles[0] += 1;
46937 }
46938
46939 this.itemsData = [];
46940 this.visible = group.visible === undefined ? true : group.visible;
46941}
46942/**
46943 * this loads a reference to all items in this group into this group.
46944 * @param {array} items
46945 */
46946
46947
46948GraphGroup.prototype.setItems = function (items) {
46949 if (items != null) {
46950 this.itemsData = items;
46951
46952 if (this.options.sort == true) {
46953 util.insertSort(this.itemsData, function (a, b) {
46954 return a.x > b.x ? 1 : -1;
46955 });
46956 }
46957 } else {
46958 this.itemsData = [];
46959 }
46960};
46961
46962GraphGroup.prototype.getItems = function () {
46963 return this.itemsData;
46964};
46965/**
46966 * this is used for barcharts and shading, this way, we only have to calculate it once.
46967 * @param {number} pos
46968 */
46969
46970
46971GraphGroup.prototype.setZeroPosition = function (pos) {
46972 this.zeroPosition = pos;
46973};
46974/**
46975 * set the options of the graph group over the default options.
46976 * @param {Object} options
46977 */
46978
46979
46980GraphGroup.prototype.setOptions = function (options) {
46981 if (options !== undefined) {
46982 var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'zIndex', 'excludeFromStacking', 'excludeFromLegend'];
46983 util.selectiveDeepExtend(fields, this.options, options); // if the group's drawPoints is a function delegate the callback to the onRender property
46984
46985 if (typeof options.drawPoints == 'function') {
46986 options.drawPoints = {
46987 onRender: options.drawPoints
46988 };
46989 }
46990
46991 util.mergeOptions(this.options, options, 'interpolation');
46992 util.mergeOptions(this.options, options, 'drawPoints');
46993 util.mergeOptions(this.options, options, 'shaded');
46994
46995 if (options.interpolation) {
46996 if (_typeof(options.interpolation) == 'object') {
46997 if (options.interpolation.parametrization) {
46998 if (options.interpolation.parametrization == 'uniform') {
46999 this.options.interpolation.alpha = 0;
47000 } else if (options.interpolation.parametrization == 'chordal') {
47001 this.options.interpolation.alpha = 1.0;
47002 } else {
47003 this.options.interpolation.parametrization = 'centripetal';
47004 this.options.interpolation.alpha = 0.5;
47005 }
47006 }
47007 }
47008 }
47009 }
47010};
47011/**
47012 * this updates the current group class with the latest group dataset entree, used in _updateGroup in linegraph
47013 * @param {vis.Group} group
47014 */
47015
47016
47017GraphGroup.prototype.update = function (group) {
47018 this.group = group;
47019 this.content = group.content || 'graph';
47020 this.className = group.className || this.className || 'vis-graph-group' + this.groupsUsingDefaultStyles[0] % 10;
47021 this.visible = group.visible === undefined ? true : group.visible;
47022 this.style = group.style;
47023 this.setOptions(group.options);
47024};
47025/**
47026 * return the legend entree for this group.
47027 *
47028 * @param {number} iconWidth
47029 * @param {number} iconHeight
47030 * @param {{svg: (*|Element), svgElements: Object, options: Object, groups: Array.<Object>}} framework
47031 * @param {number} x
47032 * @param {number} y
47033 * @returns {{icon: (*|Element), label: (*|string), orientation: *}}
47034 */
47035
47036
47037GraphGroup.prototype.getLegend = function (iconWidth, iconHeight, framework, x, y) {
47038 if (framework == undefined || framework == null) {
47039 var svg = document.createElementNS('http://www.w3.org/2000/svg', "svg");
47040 framework = {
47041 svg: svg,
47042 svgElements: {},
47043 options: this.options,
47044 groups: [this]
47045 };
47046 }
47047
47048 if (x == undefined || x == null) {
47049 x = 0;
47050 }
47051
47052 if (y == undefined || y == null) {
47053 y = 0.5 * iconHeight;
47054 }
47055
47056 switch (this.options.style) {
47057 case "line":
47058 Line.drawIcon(this, x, y, iconWidth, iconHeight, framework);
47059 break;
47060
47061 case "points": //explicit no break
47062
47063 case "point":
47064 Points.drawIcon(this, x, y, iconWidth, iconHeight, framework);
47065 break;
47066
47067 case "bar":
47068 Bargraph.drawIcon(this, x, y, iconWidth, iconHeight, framework);
47069 break;
47070 }
47071
47072 return {
47073 icon: framework.svg,
47074 label: this.content,
47075 orientation: this.options.yAxisOrientation
47076 };
47077};
47078
47079GraphGroup.prototype.getYRange = function (groupData) {
47080 var yMin = groupData[0].y;
47081 var yMax = groupData[0].y;
47082
47083 for (var j = 0; j < groupData.length; j++) {
47084 yMin = yMin > groupData[j].y ? groupData[j].y : yMin;
47085 yMax = yMax < groupData[j].y ? groupData[j].y : yMax;
47086 }
47087
47088 return {
47089 min: yMin,
47090 max: yMax,
47091 yAxisOrientation: this.options.yAxisOrientation
47092 };
47093};
47094
47095/**
47096 * Legend for Graph2d
47097 *
47098 * @param {vis.Graph2d.body} body
47099 * @param {vis.Graph2d.options} options
47100 * @param {number} side
47101 * @param {vis.LineGraph.options} linegraphOptions
47102 * @constructor Legend
47103 * @extends Component
47104 */
47105
47106function Legend(body, options, side, linegraphOptions) {
47107 this.body = body;
47108 this.defaultOptions = {
47109 enabled: false,
47110 icons: true,
47111 iconSize: 20,
47112 iconSpacing: 6,
47113 left: {
47114 visible: true,
47115 position: 'top-left' // top/bottom - left,center,right
47116
47117 },
47118 right: {
47119 visible: true,
47120 position: 'top-right' // top/bottom - left,center,right
47121
47122 }
47123 };
47124 this.side = side;
47125 this.options = util.extend({}, this.defaultOptions);
47126 this.linegraphOptions = linegraphOptions;
47127 this.svgElements = {};
47128 this.dom = {};
47129 this.groups = {};
47130 this.amountOfGroups = 0;
47131
47132 this._create();
47133
47134 this.framework = {
47135 svg: this.svg,
47136 svgElements: this.svgElements,
47137 options: this.options,
47138 groups: this.groups
47139 };
47140 this.setOptions(options);
47141}
47142
47143Legend.prototype = new Component();
47144
47145Legend.prototype.clear = function () {
47146 this.groups = {};
47147 this.amountOfGroups = 0;
47148};
47149
47150Legend.prototype.addGroup = function (label, graphOptions) {
47151 // Include a group only if the group option 'excludeFromLegend: false' is not set.
47152 if (graphOptions.options.excludeFromLegend != true) {
47153 if (!this.groups.hasOwnProperty(label)) {
47154 this.groups[label] = graphOptions;
47155 }
47156
47157 this.amountOfGroups += 1;
47158 }
47159};
47160
47161Legend.prototype.updateGroup = function (label, graphOptions) {
47162 this.groups[label] = graphOptions;
47163};
47164
47165Legend.prototype.removeGroup = function (label) {
47166 if (this.groups.hasOwnProperty(label)) {
47167 delete this.groups[label];
47168 this.amountOfGroups -= 1;
47169 }
47170};
47171
47172Legend.prototype._create = function () {
47173 this.dom.frame = document.createElement('div');
47174 this.dom.frame.className = 'vis-legend';
47175 this.dom.frame.style.position = "absolute";
47176 this.dom.frame.style.top = "10px";
47177 this.dom.frame.style.display = "block";
47178 this.dom.textArea = document.createElement('div');
47179 this.dom.textArea.className = 'vis-legend-text';
47180 this.dom.textArea.style.position = "relative";
47181 this.dom.textArea.style.top = "0px";
47182 this.svg = document.createElementNS('http://www.w3.org/2000/svg', "svg");
47183 this.svg.style.position = 'absolute';
47184 this.svg.style.top = 0 + 'px';
47185 this.svg.style.width = this.options.iconSize + 5 + 'px';
47186 this.svg.style.height = '100%';
47187 this.dom.frame.appendChild(this.svg);
47188 this.dom.frame.appendChild(this.dom.textArea);
47189};
47190/**
47191 * Hide the component from the DOM
47192 */
47193
47194
47195Legend.prototype.hide = function () {
47196 // remove the frame containing the items
47197 if (this.dom.frame.parentNode) {
47198 this.dom.frame.parentNode.removeChild(this.dom.frame);
47199 }
47200};
47201/**
47202 * Show the component in the DOM (when not already visible).
47203 */
47204
47205
47206Legend.prototype.show = function () {
47207 // show frame containing the items
47208 if (!this.dom.frame.parentNode) {
47209 this.body.dom.center.appendChild(this.dom.frame);
47210 }
47211};
47212
47213Legend.prototype.setOptions = function (options) {
47214 var fields = ['enabled', 'orientation', 'icons', 'left', 'right'];
47215 util.selectiveDeepExtend(fields, this.options, options);
47216};
47217
47218Legend.prototype.redraw = function () {
47219 var activeGroups = 0;
47220 var groupArray = Object.keys(this.groups);
47221 groupArray.sort(function (a, b) {
47222 return a < b ? -1 : 1;
47223 });
47224
47225 for (var i = 0; i < groupArray.length; i++) {
47226 var groupId = groupArray[i];
47227
47228 if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) {
47229 activeGroups++;
47230 }
47231 }
47232
47233 if (this.options[this.side].visible == false || this.amountOfGroups == 0 || this.options.enabled == false || activeGroups == 0) {
47234 this.hide();
47235 } else {
47236 this.show();
47237
47238 if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'bottom-left') {
47239 this.dom.frame.style.left = '4px';
47240 this.dom.frame.style.textAlign = "left";
47241 this.dom.textArea.style.textAlign = "left";
47242 this.dom.textArea.style.left = this.options.iconSize + 15 + 'px';
47243 this.dom.textArea.style.right = '';
47244 this.svg.style.left = 0 + 'px';
47245 this.svg.style.right = '';
47246 } else {
47247 this.dom.frame.style.right = '4px';
47248 this.dom.frame.style.textAlign = "right";
47249 this.dom.textArea.style.textAlign = "right";
47250 this.dom.textArea.style.right = this.options.iconSize + 15 + 'px';
47251 this.dom.textArea.style.left = '';
47252 this.svg.style.right = 0 + 'px';
47253 this.svg.style.left = '';
47254 }
47255
47256 if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'top-right') {
47257 this.dom.frame.style.top = 4 - Number(this.body.dom.center.style.top.replace("px", "")) + 'px';
47258 this.dom.frame.style.bottom = '';
47259 } else {
47260 var scrollableHeight = this.body.domProps.center.height - this.body.domProps.centerContainer.height;
47261 this.dom.frame.style.bottom = 4 + scrollableHeight + Number(this.body.dom.center.style.top.replace("px", "")) + 'px';
47262 this.dom.frame.style.top = '';
47263 }
47264
47265 if (this.options.icons == false) {
47266 this.dom.frame.style.width = this.dom.textArea.offsetWidth + 10 + 'px';
47267 this.dom.textArea.style.right = '';
47268 this.dom.textArea.style.left = '';
47269 this.svg.style.width = '0px';
47270 } else {
47271 this.dom.frame.style.width = this.options.iconSize + 15 + this.dom.textArea.offsetWidth + 10 + 'px';
47272 this.drawLegendIcons();
47273 }
47274
47275 var content = '';
47276
47277 for (i = 0; i < groupArray.length; i++) {
47278 groupId = groupArray[i];
47279
47280 if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) {
47281 content += this.groups[groupId].content + '<br />';
47282 }
47283 }
47284
47285 this.dom.textArea.innerHTML = content;
47286 this.dom.textArea.style.lineHeight = 0.75 * this.options.iconSize + this.options.iconSpacing + 'px';
47287 }
47288};
47289
47290Legend.prototype.drawLegendIcons = function () {
47291 if (this.dom.frame.parentNode) {
47292 var groupArray = Object.keys(this.groups);
47293 groupArray.sort(function (a, b) {
47294 return a < b ? -1 : 1;
47295 }); // this resets the elements so the order is maintained
47296
47297 resetElements(this.svgElements);
47298 var padding = window.getComputedStyle(this.dom.frame).paddingTop;
47299 var iconOffset = Number(padding.replace('px', ''));
47300 var x = iconOffset;
47301 var iconWidth = this.options.iconSize;
47302 var iconHeight = 0.75 * this.options.iconSize;
47303 var y = iconOffset + 0.5 * iconHeight + 3;
47304 this.svg.style.width = iconWidth + 5 + iconOffset + 'px';
47305
47306 for (var i = 0; i < groupArray.length; i++) {
47307 var groupId = groupArray[i];
47308
47309 if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) {
47310 this.groups[groupId].getLegend(iconWidth, iconHeight, this.framework, x, y);
47311 y += iconHeight + this.options.iconSpacing;
47312 }
47313 }
47314 }
47315};
47316
47317var UNGROUPED$3 = '__ungrouped__'; // reserved group id for ungrouped items
47318
47319/**
47320 * This is the constructor of the LineGraph. It requires a Timeline body and options.
47321 *
47322 * @param {vis.Timeline.body} body
47323 * @param {Object} options
47324 * @constructor LineGraph
47325 * @extends Component
47326 */
47327
47328function LineGraph(body, options) {
47329 this.id = util.randomUUID();
47330 this.body = body;
47331 this.defaultOptions = {
47332 yAxisOrientation: 'left',
47333 defaultGroup: 'default',
47334 sort: true,
47335 sampling: true,
47336 stack: false,
47337 graphHeight: '400px',
47338 shaded: {
47339 enabled: false,
47340 orientation: 'bottom' // top, bottom, zero
47341
47342 },
47343 style: 'line',
47344 // line, bar
47345 barChart: {
47346 width: 50,
47347 sideBySide: false,
47348 align: 'center' // left, center, right
47349
47350 },
47351 interpolation: {
47352 enabled: true,
47353 parametrization: 'centripetal',
47354 // uniform (alpha = 0.0), chordal (alpha = 1.0), centripetal (alpha = 0.5)
47355 alpha: 0.5
47356 },
47357 drawPoints: {
47358 enabled: true,
47359 size: 6,
47360 style: 'square' // square, circle
47361
47362 },
47363 dataAxis: {},
47364 //Defaults are done on DataAxis level
47365 legend: {},
47366 //Defaults are done on Legend level
47367 groups: {
47368 visibility: {}
47369 }
47370 }; // options is shared by this lineGraph and all its items
47371
47372 this.options = util.extend({}, this.defaultOptions);
47373 this.dom = {};
47374 this.props = {};
47375 this.hammer = null;
47376 this.groups = {};
47377 this.abortedGraphUpdate = false;
47378 this.updateSVGheight = false;
47379 this.updateSVGheightOnResize = false;
47380 this.forceGraphUpdate = true;
47381 var me = this;
47382 this.itemsData = null; // DataSet
47383
47384 this.groupsData = null; // DataSet
47385 // listeners for the DataSet of the items
47386
47387 this.itemListeners = {
47388 'add': function add(event, params, senderId) {
47389 // eslint-disable-line no-unused-vars
47390 me._onAdd(params.items);
47391 },
47392 'update': function update(event, params, senderId) {
47393 // eslint-disable-line no-unused-vars
47394 me._onUpdate(params.items);
47395 },
47396 'remove': function remove(event, params, senderId) {
47397 // eslint-disable-line no-unused-vars
47398 me._onRemove(params.items);
47399 }
47400 }; // listeners for the DataSet of the groups
47401
47402 this.groupListeners = {
47403 'add': function add(event, params, senderId) {
47404 // eslint-disable-line no-unused-vars
47405 me._onAddGroups(params.items);
47406 },
47407 'update': function update(event, params, senderId) {
47408 // eslint-disable-line no-unused-vars
47409 me._onUpdateGroups(params.items);
47410 },
47411 'remove': function remove(event, params, senderId) {
47412 // eslint-disable-line no-unused-vars
47413 me._onRemoveGroups(params.items);
47414 }
47415 };
47416 this.items = {}; // object with an Item for every data item
47417
47418 this.selection = []; // list with the ids of all selected nodes
47419
47420 this.lastStart = this.body.range.start;
47421 this.touchParams = {}; // stores properties while dragging
47422
47423 this.svgElements = {};
47424 this.setOptions(options);
47425 this.groupsUsingDefaultStyles = [0];
47426 this.body.emitter.on('rangechanged', function () {
47427 me.lastStart = me.body.range.start;
47428 me.svg.style.left = util.option.asSize(-me.props.width);
47429 me.forceGraphUpdate = true; //Is this local redraw necessary? (Core also does a change event!)
47430
47431 me.redraw.call(me);
47432 }); // create the HTML DOM
47433
47434 this._create();
47435
47436 this.framework = {
47437 svg: this.svg,
47438 svgElements: this.svgElements,
47439 options: this.options,
47440 groups: this.groups
47441 };
47442}
47443
47444LineGraph.prototype = new Component();
47445/**
47446 * Create the HTML DOM for the ItemSet
47447 */
47448
47449LineGraph.prototype._create = function () {
47450 var frame = document.createElement('div');
47451 frame.className = 'vis-line-graph';
47452 this.dom.frame = frame; // create svg element for graph drawing.
47453
47454 this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
47455 this.svg.style.position = 'relative';
47456 this.svg.style.height = ('' + this.options.graphHeight).replace('px', '') + 'px';
47457 this.svg.style.display = 'block';
47458 frame.appendChild(this.svg); // data axis
47459
47460 this.options.dataAxis.orientation = 'left';
47461 this.yAxisLeft = new DataAxis(this.body, this.options.dataAxis, this.svg, this.options.groups);
47462 this.options.dataAxis.orientation = 'right';
47463 this.yAxisRight = new DataAxis(this.body, this.options.dataAxis, this.svg, this.options.groups);
47464 delete this.options.dataAxis.orientation; // legends
47465
47466 this.legendLeft = new Legend(this.body, this.options.legend, 'left', this.options.groups);
47467 this.legendRight = new Legend(this.body, this.options.legend, 'right', this.options.groups);
47468 this.show();
47469};
47470/**
47471 * set the options of the LineGraph. the mergeOptions is used for subObjects that have an enabled element.
47472 * @param {object} options
47473 */
47474
47475
47476LineGraph.prototype.setOptions = function (options) {
47477 if (options) {
47478 var fields = ['sampling', 'defaultGroup', 'stack', 'height', 'graphHeight', 'yAxisOrientation', 'style', 'barChart', 'dataAxis', 'sort', 'groups'];
47479
47480 if (options.graphHeight === undefined && options.height !== undefined) {
47481 this.updateSVGheight = true;
47482 this.updateSVGheightOnResize = true;
47483 } else if (this.body.domProps.centerContainer.height !== undefined && options.graphHeight !== undefined) {
47484 if (parseInt((options.graphHeight + '').replace("px", '')) < this.body.domProps.centerContainer.height) {
47485 this.updateSVGheight = true;
47486 }
47487 }
47488
47489 util.selectiveDeepExtend(fields, this.options, options);
47490 util.mergeOptions(this.options, options, 'interpolation');
47491 util.mergeOptions(this.options, options, 'drawPoints');
47492 util.mergeOptions(this.options, options, 'shaded');
47493 util.mergeOptions(this.options, options, 'legend');
47494
47495 if (options.interpolation) {
47496 if (_typeof(options.interpolation) == 'object') {
47497 if (options.interpolation.parametrization) {
47498 if (options.interpolation.parametrization == 'uniform') {
47499 this.options.interpolation.alpha = 0;
47500 } else if (options.interpolation.parametrization == 'chordal') {
47501 this.options.interpolation.alpha = 1.0;
47502 } else {
47503 this.options.interpolation.parametrization = 'centripetal';
47504 this.options.interpolation.alpha = 0.5;
47505 }
47506 }
47507 }
47508 }
47509
47510 if (this.yAxisLeft) {
47511 if (options.dataAxis !== undefined) {
47512 this.yAxisLeft.setOptions(this.options.dataAxis);
47513 this.yAxisRight.setOptions(this.options.dataAxis);
47514 }
47515 }
47516
47517 if (this.legendLeft) {
47518 if (options.legend !== undefined) {
47519 this.legendLeft.setOptions(this.options.legend);
47520 this.legendRight.setOptions(this.options.legend);
47521 }
47522 }
47523
47524 if (this.groups.hasOwnProperty(UNGROUPED$3)) {
47525 this.groups[UNGROUPED$3].setOptions(options);
47526 }
47527 } // this is used to redraw the graph if the visibility of the groups is changed.
47528
47529
47530 if (this.dom.frame) {
47531 //not on initial run?
47532 this.forceGraphUpdate = true;
47533 this.body.emitter.emit("_change", {
47534 queue: true
47535 });
47536 }
47537};
47538/**
47539 * Hide the component from the DOM
47540 */
47541
47542
47543LineGraph.prototype.hide = function () {
47544 // remove the frame containing the items
47545 if (this.dom.frame.parentNode) {
47546 this.dom.frame.parentNode.removeChild(this.dom.frame);
47547 }
47548};
47549/**
47550 * Show the component in the DOM (when not already visible).
47551 */
47552
47553
47554LineGraph.prototype.show = function () {
47555 // show frame containing the items
47556 if (!this.dom.frame.parentNode) {
47557 this.body.dom.center.appendChild(this.dom.frame);
47558 }
47559};
47560/**
47561 * Set items
47562 * @param {vis.DataSet | null} items
47563 */
47564
47565
47566LineGraph.prototype.setItems = function (items) {
47567 var me = this,
47568 ids,
47569 oldItemsData = this.itemsData; // replace the dataset
47570
47571 if (!items) {
47572 this.itemsData = null;
47573 } else if (items instanceof DataSet || items instanceof DataView$2) {
47574 this.itemsData = items;
47575 } else {
47576 throw new TypeError('Data must be an instance of DataSet or DataView');
47577 }
47578
47579 if (oldItemsData) {
47580 // unsubscribe from old dataset
47581 util.forEach(this.itemListeners, function (callback, event) {
47582 oldItemsData.off(event, callback);
47583 }); // remove all drawn items
47584
47585 ids = oldItemsData.getIds();
47586
47587 this._onRemove(ids);
47588 }
47589
47590 if (this.itemsData) {
47591 // subscribe to new dataset
47592 var id = this.id;
47593 util.forEach(this.itemListeners, function (callback, event) {
47594 me.itemsData.on(event, callback, id);
47595 }); // add all new items
47596
47597 ids = this.itemsData.getIds();
47598
47599 this._onAdd(ids);
47600 }
47601};
47602/**
47603 * Set groups
47604 * @param {vis.DataSet} groups
47605 */
47606
47607
47608LineGraph.prototype.setGroups = function (groups) {
47609 var me = this;
47610 var ids; // unsubscribe from current dataset
47611
47612 if (this.groupsData) {
47613 util.forEach(this.groupListeners, function (callback, event) {
47614 me.groupsData.off(event, callback);
47615 }); // remove all drawn groups
47616
47617 ids = this.groupsData.getIds();
47618 this.groupsData = null;
47619
47620 for (var i = 0; i < ids.length; i++) {
47621 this._removeGroup(ids[i]);
47622 }
47623 } // replace the dataset
47624
47625
47626 if (!groups) {
47627 this.groupsData = null;
47628 } else if (groups instanceof DataSet || groups instanceof DataView$2) {
47629 this.groupsData = groups;
47630 } else {
47631 throw new TypeError('Data must be an instance of DataSet or DataView');
47632 }
47633
47634 if (this.groupsData) {
47635 // subscribe to new dataset
47636 var id = this.id;
47637 util.forEach(this.groupListeners, function (callback, event) {
47638 me.groupsData.on(event, callback, id);
47639 }); // draw all ms
47640
47641 ids = this.groupsData.getIds();
47642
47643 this._onAddGroups(ids);
47644 }
47645};
47646
47647LineGraph.prototype._onUpdate = function (ids) {
47648 this._updateAllGroupData(ids);
47649};
47650
47651LineGraph.prototype._onAdd = function (ids) {
47652 this._onUpdate(ids);
47653};
47654
47655LineGraph.prototype._onRemove = function (ids) {
47656 this._onUpdate(ids);
47657};
47658
47659LineGraph.prototype._onUpdateGroups = function (groupIds) {
47660 this._updateAllGroupData(null, groupIds);
47661};
47662
47663LineGraph.prototype._onAddGroups = function (groupIds) {
47664 this._onUpdateGroups(groupIds);
47665};
47666/**
47667 * this cleans the group out off the legends and the dataaxis, updates the ungrouped and updates the graph
47668 * @param {Array} groupIds
47669 * @private
47670 */
47671
47672
47673LineGraph.prototype._onRemoveGroups = function (groupIds) {
47674 for (var i = 0; i < groupIds.length; i++) {
47675 this._removeGroup(groupIds[i]);
47676 }
47677
47678 this.forceGraphUpdate = true;
47679 this.body.emitter.emit("_change", {
47680 queue: true
47681 });
47682};
47683/**
47684 * this cleans the group out off the legends and the dataaxis
47685 * @param {vis.GraphGroup.id} groupId
47686 * @private
47687 */
47688
47689
47690LineGraph.prototype._removeGroup = function (groupId) {
47691 if (this.groups.hasOwnProperty(groupId)) {
47692 if (this.groups[groupId].options.yAxisOrientation == 'right') {
47693 this.yAxisRight.removeGroup(groupId);
47694 this.legendRight.removeGroup(groupId);
47695 this.legendRight.redraw();
47696 } else {
47697 this.yAxisLeft.removeGroup(groupId);
47698 this.legendLeft.removeGroup(groupId);
47699 this.legendLeft.redraw();
47700 }
47701
47702 delete this.groups[groupId];
47703 }
47704};
47705/**
47706 * update a group object with the group dataset entree
47707 *
47708 * @param {vis.GraphGroup} group
47709 * @param {vis.GraphGroup.id} groupId
47710 * @private
47711 */
47712
47713
47714LineGraph.prototype._updateGroup = function (group, groupId) {
47715 if (!this.groups.hasOwnProperty(groupId)) {
47716 this.groups[groupId] = new GraphGroup(group, groupId, this.options, this.groupsUsingDefaultStyles);
47717
47718 if (this.groups[groupId].options.yAxisOrientation == 'right') {
47719 this.yAxisRight.addGroup(groupId, this.groups[groupId]);
47720 this.legendRight.addGroup(groupId, this.groups[groupId]);
47721 } else {
47722 this.yAxisLeft.addGroup(groupId, this.groups[groupId]);
47723 this.legendLeft.addGroup(groupId, this.groups[groupId]);
47724 }
47725 } else {
47726 this.groups[groupId].update(group);
47727
47728 if (this.groups[groupId].options.yAxisOrientation == 'right') {
47729 this.yAxisRight.updateGroup(groupId, this.groups[groupId]);
47730 this.legendRight.updateGroup(groupId, this.groups[groupId]); //If yAxisOrientation changed, clean out the group from the other axis.
47731
47732 this.yAxisLeft.removeGroup(groupId);
47733 this.legendLeft.removeGroup(groupId);
47734 } else {
47735 this.yAxisLeft.updateGroup(groupId, this.groups[groupId]);
47736 this.legendLeft.updateGroup(groupId, this.groups[groupId]); //If yAxisOrientation changed, clean out the group from the other axis.
47737
47738 this.yAxisRight.removeGroup(groupId);
47739 this.legendRight.removeGroup(groupId);
47740 }
47741 }
47742
47743 this.legendLeft.redraw();
47744 this.legendRight.redraw();
47745};
47746/**
47747 * this updates all groups, it is used when there is an update the the itemset.
47748 *
47749 * @param {Array} ids
47750 * @param {Array} groupIds
47751 * @private
47752 */
47753
47754
47755LineGraph.prototype._updateAllGroupData = function (ids, groupIds) {
47756 if (this.itemsData != null) {
47757 var groupsContent = {};
47758 var items = this.itemsData.get();
47759 var fieldId = this.itemsData._idProp;
47760 var idMap = {};
47761
47762 if (ids) {
47763 ids.map(function (id) {
47764 idMap[id] = id;
47765 });
47766 } //pre-Determine array sizes, for more efficient memory claim
47767
47768
47769 var groupCounts = {};
47770
47771 for (var i = 0; i < items.length; i++) {
47772 var item = items[i];
47773 var groupId = item.group;
47774
47775 if (groupId === null || groupId === undefined) {
47776 groupId = UNGROUPED$3;
47777 }
47778
47779 groupCounts.hasOwnProperty(groupId) ? groupCounts[groupId]++ : groupCounts[groupId] = 1;
47780 } //Pre-load arrays from existing groups if items are not changed (not in ids)
47781
47782
47783 var existingItemsMap = {};
47784
47785 if (!groupIds && ids) {
47786 for (groupId in this.groups) {
47787 if (this.groups.hasOwnProperty(groupId)) {
47788 group = this.groups[groupId];
47789 var existing_items = group.getItems();
47790 groupsContent[groupId] = existing_items.filter(function (item) {
47791 existingItemsMap[item[fieldId]] = item[fieldId];
47792 return item[fieldId] !== idMap[item[fieldId]];
47793 });
47794 var newLength = groupCounts[groupId];
47795 groupCounts[groupId] -= groupsContent[groupId].length;
47796
47797 if (groupsContent[groupId].length < newLength) {
47798 groupsContent[groupId][newLength - 1] = {};
47799 }
47800 }
47801 }
47802 } //Now insert data into the arrays.
47803
47804
47805 for (i = 0; i < items.length; i++) {
47806 item = items[i];
47807 groupId = item.group;
47808
47809 if (groupId === null || groupId === undefined) {
47810 groupId = UNGROUPED$3;
47811 }
47812
47813 if (!groupIds && ids && item[fieldId] !== idMap[item[fieldId]] && existingItemsMap.hasOwnProperty(item[fieldId])) {
47814 continue;
47815 }
47816
47817 if (!groupsContent.hasOwnProperty(groupId)) {
47818 groupsContent[groupId] = new Array(groupCounts[groupId]);
47819 } //Copy data (because of unmodifiable DataView input.
47820
47821
47822 var extended = util.bridgeObject(item);
47823 extended.x = util.convert(item.x, 'Date');
47824 extended.end = util.convert(item.end, 'Date');
47825 extended.orginalY = item.y; //real Y
47826
47827 extended.y = Number(item.y);
47828 extended[fieldId] = item[fieldId];
47829 var index = groupsContent[groupId].length - groupCounts[groupId]--;
47830 groupsContent[groupId][index] = extended;
47831 } //Make sure all groups are present, to allow removal of old groups
47832
47833
47834 for (groupId in this.groups) {
47835 if (this.groups.hasOwnProperty(groupId)) {
47836 if (!groupsContent.hasOwnProperty(groupId)) {
47837 groupsContent[groupId] = new Array(0);
47838 }
47839 }
47840 } //Update legendas, style and axis
47841
47842
47843 for (groupId in groupsContent) {
47844 if (groupsContent.hasOwnProperty(groupId)) {
47845 if (groupsContent[groupId].length == 0) {
47846 if (this.groups.hasOwnProperty(groupId)) {
47847 this._removeGroup(groupId);
47848 }
47849 } else {
47850 var group = undefined;
47851
47852 if (this.groupsData != undefined) {
47853 group = this.groupsData.get(groupId);
47854 }
47855
47856 if (group == undefined) {
47857 group = {
47858 id: groupId,
47859 content: this.options.defaultGroup + groupId
47860 };
47861 }
47862
47863 this._updateGroup(group, groupId);
47864
47865 this.groups[groupId].setItems(groupsContent[groupId]);
47866 }
47867 }
47868 }
47869
47870 this.forceGraphUpdate = true;
47871 this.body.emitter.emit("_change", {
47872 queue: true
47873 });
47874 }
47875};
47876/**
47877 * Redraw the component, mandatory function
47878 * @return {boolean} Returns true if the component is resized
47879 */
47880
47881
47882LineGraph.prototype.redraw = function () {
47883 var resized = false; // calculate actual size and position
47884
47885 this.props.width = this.dom.frame.offsetWidth;
47886 this.props.height = this.body.domProps.centerContainer.height - this.body.domProps.border.top - this.body.domProps.border.bottom; // check if this component is resized
47887
47888 resized = this._isResized() || resized; // check whether zoomed (in that case we need to re-stack everything)
47889
47890 var visibleInterval = this.body.range.end - this.body.range.start;
47891 var zoomed = visibleInterval != this.lastVisibleInterval;
47892 this.lastVisibleInterval = visibleInterval; // the svg element is three times as big as the width, this allows for fully dragging left and right
47893 // without reloading the graph. the controls for this are bound to events in the constructor
47894
47895 if (resized == true) {
47896 this.svg.style.width = util.option.asSize(3 * this.props.width);
47897 this.svg.style.left = util.option.asSize(-this.props.width); // if the height of the graph is set as proportional, change the height of the svg
47898
47899 if ((this.options.height + '').indexOf("%") != -1 || this.updateSVGheightOnResize == true) {
47900 this.updateSVGheight = true;
47901 }
47902 } // update the height of the graph on each redraw of the graph.
47903
47904
47905 if (this.updateSVGheight == true) {
47906 if (this.options.graphHeight != this.props.height + 'px') {
47907 this.options.graphHeight = this.props.height + 'px';
47908 this.svg.style.height = this.props.height + 'px';
47909 }
47910
47911 this.updateSVGheight = false;
47912 } else {
47913 this.svg.style.height = ('' + this.options.graphHeight).replace('px', '') + 'px';
47914 } // zoomed is here to ensure that animations are shown correctly.
47915
47916
47917 if (resized == true || zoomed == true || this.abortedGraphUpdate == true || this.forceGraphUpdate == true) {
47918 resized = this._updateGraph() || resized;
47919 this.forceGraphUpdate = false;
47920 } else {
47921 // move the whole svg while dragging
47922 if (this.lastStart != 0) {
47923 var offset = this.body.range.start - this.lastStart;
47924 var range = this.body.range.end - this.body.range.start;
47925
47926 if (this.props.width != 0) {
47927 var rangePerPixelInv = this.props.width / range;
47928 var xOffset = offset * rangePerPixelInv;
47929 this.svg.style.left = -this.props.width - xOffset + 'px';
47930 }
47931 }
47932 }
47933
47934 this.legendLeft.redraw();
47935 this.legendRight.redraw();
47936 return resized;
47937};
47938
47939LineGraph.prototype._getSortedGroupIds = function () {
47940 // getting group Ids
47941 var grouplist = [];
47942
47943 for (var groupId in this.groups) {
47944 if (this.groups.hasOwnProperty(groupId)) {
47945 var group = this.groups[groupId];
47946
47947 if (group.visible == true && (this.options.groups.visibility[groupId] === undefined || this.options.groups.visibility[groupId] == true)) {
47948 grouplist.push({
47949 id: groupId,
47950 zIndex: group.options.zIndex
47951 });
47952 }
47953 }
47954 }
47955
47956 util.insertSort(grouplist, function (a, b) {
47957 var az = a.zIndex;
47958 var bz = b.zIndex;
47959 if (az === undefined) az = 0;
47960 if (bz === undefined) bz = 0;
47961 return az == bz ? 0 : az < bz ? -1 : 1;
47962 });
47963 var groupIds = new Array(grouplist.length);
47964
47965 for (var i = 0; i < grouplist.length; i++) {
47966 groupIds[i] = grouplist[i].id;
47967 }
47968
47969 return groupIds;
47970};
47971/**
47972 * Update and redraw the graph.
47973 *
47974 * @returns {boolean}
47975 * @private
47976 */
47977
47978
47979LineGraph.prototype._updateGraph = function () {
47980 // reset the svg elements
47981 prepareElements(this.svgElements);
47982
47983 if (this.props.width != 0 && this.itemsData != null) {
47984 var group, i;
47985 var groupRanges = {};
47986 var changeCalled = false; // this is the range of the SVG canvas
47987
47988 var minDate = this.body.util.toGlobalTime(-this.body.domProps.root.width);
47989 var maxDate = this.body.util.toGlobalTime(2 * this.body.domProps.root.width); // getting group Ids
47990
47991 var groupIds = this._getSortedGroupIds();
47992
47993 if (groupIds.length > 0) {
47994 var groupsData = {}; // fill groups data, this only loads the data we require based on the timewindow
47995
47996 this._getRelevantData(groupIds, groupsData, minDate, maxDate); // apply sampling, if disabled, it will pass through this function.
47997
47998
47999 this._applySampling(groupIds, groupsData); // we transform the X coordinates to detect collisions
48000
48001
48002 for (i = 0; i < groupIds.length; i++) {
48003 this._convertXcoordinates(groupsData[groupIds[i]]);
48004 } // now all needed data has been collected we start the processing.
48005
48006
48007 this._getYRanges(groupIds, groupsData, groupRanges); // update the Y axis first, we use this data to draw at the correct Y points
48008
48009
48010 changeCalled = this._updateYAxis(groupIds, groupRanges); // at changeCalled, abort this update cycle as the graph needs another update with new Width input from the Redraw container.
48011 // Cleanup SVG elements on abort.
48012
48013 if (changeCalled == true) {
48014 cleanupElements(this.svgElements);
48015 this.abortedGraphUpdate = true;
48016 return true;
48017 }
48018
48019 this.abortedGraphUpdate = false; // With the yAxis scaled correctly, use this to get the Y values of the points.
48020
48021 var below = undefined;
48022
48023 for (i = 0; i < groupIds.length; i++) {
48024 group = this.groups[groupIds[i]];
48025
48026 if (this.options.stack === true && this.options.style === 'line') {
48027 if (group.options.excludeFromStacking == undefined || !group.options.excludeFromStacking) {
48028 if (below != undefined) {
48029 this._stack(groupsData[group.id], groupsData[below.id]);
48030
48031 if (group.options.shaded.enabled == true && group.options.shaded.orientation !== "group") {
48032 if (group.options.shaded.orientation == "top" && below.options.shaded.orientation !== "group") {
48033 below.options.shaded.orientation = "group";
48034 below.options.shaded.groupId = group.id;
48035 } else {
48036 group.options.shaded.orientation = "group";
48037 group.options.shaded.groupId = below.id;
48038 }
48039 }
48040 }
48041
48042 below = group;
48043 }
48044 }
48045
48046 this._convertYcoordinates(groupsData[groupIds[i]], group);
48047 } //Precalculate paths and draw shading if appropriate. This will make sure the shading is always behind any lines.
48048
48049
48050 var paths = {};
48051
48052 for (i = 0; i < groupIds.length; i++) {
48053 group = this.groups[groupIds[i]];
48054
48055 if (group.options.style === 'line' && group.options.shaded.enabled == true) {
48056 var dataset = groupsData[groupIds[i]];
48057
48058 if (dataset == null || dataset.length == 0) {
48059 continue;
48060 }
48061
48062 if (!paths.hasOwnProperty(groupIds[i])) {
48063 paths[groupIds[i]] = Line.calcPath(dataset, group);
48064 }
48065
48066 if (group.options.shaded.orientation === "group") {
48067 var subGroupId = group.options.shaded.groupId;
48068
48069 if (groupIds.indexOf(subGroupId) === -1) {
48070 console.log(group.id + ": Unknown shading group target given:" + subGroupId);
48071 continue;
48072 }
48073
48074 if (!paths.hasOwnProperty(subGroupId)) {
48075 paths[subGroupId] = Line.calcPath(groupsData[subGroupId], this.groups[subGroupId]);
48076 }
48077
48078 Line.drawShading(paths[groupIds[i]], group, paths[subGroupId], this.framework);
48079 } else {
48080 Line.drawShading(paths[groupIds[i]], group, undefined, this.framework);
48081 }
48082 }
48083 } // draw the groups, calculating paths if still necessary.
48084
48085
48086 Bargraph.draw(groupIds, groupsData, this.framework);
48087
48088 for (i = 0; i < groupIds.length; i++) {
48089 group = this.groups[groupIds[i]];
48090
48091 if (groupsData[groupIds[i]].length > 0) {
48092 switch (group.options.style) {
48093 case "line":
48094 if (!paths.hasOwnProperty(groupIds[i])) {
48095 paths[groupIds[i]] = Line.calcPath(groupsData[groupIds[i]], group);
48096 }
48097
48098 Line.draw(paths[groupIds[i]], group, this.framework);
48099 // eslint-disable-line no-fallthrough
48100
48101 case "point": // eslint-disable-line no-fallthrough
48102
48103 case "points":
48104 if (group.options.style == "point" || group.options.style == "points" || group.options.drawPoints.enabled == true) {
48105 Points.draw(groupsData[groupIds[i]], group, this.framework);
48106 }
48107
48108 break;
48109
48110 case "bar": // bar needs to be drawn enmasse
48111 // eslint-disable-line no-fallthrough
48112
48113 default: //do nothing...
48114
48115 }
48116 }
48117 }
48118 }
48119 } // cleanup unused svg elements
48120
48121
48122 cleanupElements(this.svgElements);
48123 return false;
48124};
48125
48126LineGraph.prototype._stack = function (data, subData) {
48127 var index, dx, dy, subPrevPoint, subNextPoint;
48128 index = 0; // for each data point we look for a matching on in the set below
48129
48130 for (var j = 0; j < data.length; j++) {
48131 subPrevPoint = undefined;
48132 subNextPoint = undefined; // we look for time matches or a before-after point
48133
48134 for (var k = index; k < subData.length; k++) {
48135 // if times match exactly
48136 if (subData[k].x === data[j].x) {
48137 subPrevPoint = subData[k];
48138 subNextPoint = subData[k];
48139 index = k;
48140 break;
48141 } else if (subData[k].x > data[j].x) {
48142 // overshoot
48143 subNextPoint = subData[k];
48144
48145 if (k == 0) {
48146 subPrevPoint = subNextPoint;
48147 } else {
48148 subPrevPoint = subData[k - 1];
48149 }
48150
48151 index = k;
48152 break;
48153 }
48154 } // in case the last data point has been used, we assume it stays like this.
48155
48156
48157 if (subNextPoint === undefined) {
48158 subPrevPoint = subData[subData.length - 1];
48159 subNextPoint = subData[subData.length - 1];
48160 } // linear interpolation
48161
48162
48163 dx = subNextPoint.x - subPrevPoint.x;
48164 dy = subNextPoint.y - subPrevPoint.y;
48165
48166 if (dx == 0) {
48167 data[j].y = data[j].orginalY + subNextPoint.y;
48168 } else {
48169 data[j].y = data[j].orginalY + dy / dx * (data[j].x - subPrevPoint.x) + subPrevPoint.y; // ax + b where b is data[j].y
48170 }
48171 }
48172};
48173/**
48174 * first select and preprocess the data from the datasets.
48175 * the groups have their preselection of data, we now loop over this data to see
48176 * what data we need to draw. Sorted data is much faster.
48177 * more optimization is possible by doing the sampling before and using the binary search
48178 * to find the end date to determine the increment.
48179 *
48180 * @param {array} groupIds
48181 * @param {object} groupsData
48182 * @param {date} minDate
48183 * @param {date} maxDate
48184 * @private
48185 */
48186
48187
48188LineGraph.prototype._getRelevantData = function (groupIds, groupsData, minDate, maxDate) {
48189 var group, i, j, item;
48190
48191 if (groupIds.length > 0) {
48192 for (i = 0; i < groupIds.length; i++) {
48193 group = this.groups[groupIds[i]];
48194 var itemsData = group.getItems(); // optimization for sorted data
48195
48196 if (group.options.sort == true) {
48197 var dateComparator = function dateComparator(a, b) {
48198 return a.getTime() == b.getTime() ? 0 : a < b ? -1 : 1;
48199 };
48200
48201 var first = Math.max(0, util.binarySearchValue(itemsData, minDate, 'x', 'before', dateComparator));
48202 var last = Math.min(itemsData.length, util.binarySearchValue(itemsData, maxDate, 'x', 'after', dateComparator) + 1);
48203
48204 if (last <= 0) {
48205 last = itemsData.length;
48206 }
48207
48208 var dataContainer = new Array(last - first);
48209
48210 for (j = first; j < last; j++) {
48211 item = group.itemsData[j];
48212 dataContainer[j - first] = item;
48213 }
48214
48215 groupsData[groupIds[i]] = dataContainer;
48216 } else {
48217 // If unsorted data, all data is relevant, just returning entire structure
48218 groupsData[groupIds[i]] = group.itemsData;
48219 }
48220 }
48221 }
48222};
48223/**
48224 *
48225 * @param {Array.<vis.GraphGroup.id>} groupIds
48226 * @param {vis.DataSet} groupsData
48227 * @private
48228 */
48229
48230
48231LineGraph.prototype._applySampling = function (groupIds, groupsData) {
48232 var group;
48233
48234 if (groupIds.length > 0) {
48235 for (var i = 0; i < groupIds.length; i++) {
48236 group = this.groups[groupIds[i]];
48237
48238 if (group.options.sampling == true) {
48239 var dataContainer = groupsData[groupIds[i]];
48240
48241 if (dataContainer.length > 0) {
48242 var increment = 1;
48243 var amountOfPoints = dataContainer.length; // the global screen is used because changing the width of the yAxis may affect the increment, resulting in an endless loop
48244 // of width changing of the yAxis.
48245 //TODO: This assumes sorted data, but that's not guaranteed!
48246
48247 var xDistance = this.body.util.toGlobalScreen(dataContainer[dataContainer.length - 1].x) - this.body.util.toGlobalScreen(dataContainer[0].x);
48248 var pointsPerPixel = amountOfPoints / xDistance;
48249 increment = Math.min(Math.ceil(0.2 * amountOfPoints), Math.max(1, Math.round(pointsPerPixel)));
48250 var sampledData = new Array(amountOfPoints);
48251
48252 for (var j = 0; j < amountOfPoints; j += increment) {
48253 var idx = Math.round(j / increment);
48254 sampledData[idx] = dataContainer[j];
48255 }
48256
48257 groupsData[groupIds[i]] = sampledData.splice(0, Math.round(amountOfPoints / increment));
48258 }
48259 }
48260 }
48261 }
48262};
48263/**
48264 *
48265 * @param {Array.<vis.GraphGroup.id>} groupIds
48266 * @param {vis.DataSet} groupsData
48267 * @param {object} groupRanges | this is being filled here
48268 * @private
48269 */
48270
48271
48272LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) {
48273 var groupData, group, i;
48274 var combinedDataLeft = [];
48275 var combinedDataRight = [];
48276 var options;
48277
48278 if (groupIds.length > 0) {
48279 for (i = 0; i < groupIds.length; i++) {
48280 groupData = groupsData[groupIds[i]];
48281 options = this.groups[groupIds[i]].options;
48282
48283 if (groupData.length > 0) {
48284 group = this.groups[groupIds[i]]; // if bar graphs are stacked, their range need to be handled differently and accumulated over all groups.
48285
48286 if (options.stack === true && options.style === 'bar') {
48287 if (options.yAxisOrientation === 'left') {
48288 combinedDataLeft = combinedDataLeft.concat(groupData);
48289 } else {
48290 combinedDataRight = combinedDataRight.concat(groupData);
48291 }
48292 } else {
48293 groupRanges[groupIds[i]] = group.getYRange(groupData, groupIds[i]);
48294 }
48295 }
48296 } // if bar graphs are stacked, their range need to be handled differently and accumulated over all groups.
48297
48298
48299 Bargraph.getStackedYRange(combinedDataLeft, groupRanges, groupIds, '__barStackLeft', 'left');
48300 Bargraph.getStackedYRange(combinedDataRight, groupRanges, groupIds, '__barStackRight', 'right');
48301 }
48302};
48303/**
48304 * this sets the Y ranges for the Y axis. It also determines which of the axis should be shown or hidden.
48305 * @param {Array.<vis.GraphGroup.id>} groupIds
48306 * @param {Object} groupRanges
48307 * @returns {boolean} resized
48308 * @private
48309 */
48310
48311
48312LineGraph.prototype._updateYAxis = function (groupIds, groupRanges) {
48313 var resized = false;
48314 var yAxisLeftUsed = false;
48315 var yAxisRightUsed = false;
48316 var minLeft = 1e9,
48317 minRight = 1e9,
48318 maxLeft = -1e9,
48319 maxRight = -1e9,
48320 minVal,
48321 maxVal; // if groups are present
48322
48323 if (groupIds.length > 0) {
48324 // this is here to make sure that if there are no items in the axis but there are groups, that there is no infinite draw/redraw loop.
48325 for (var i = 0; i < groupIds.length; i++) {
48326 var group = this.groups[groupIds[i]];
48327
48328 if (group && group.options.yAxisOrientation != 'right') {
48329 yAxisLeftUsed = true;
48330 minLeft = 1e9;
48331 maxLeft = -1e9;
48332 } else if (group && group.options.yAxisOrientation) {
48333 yAxisRightUsed = true;
48334 minRight = 1e9;
48335 maxRight = -1e9;
48336 }
48337 } // if there are items:
48338
48339
48340 for (i = 0; i < groupIds.length; i++) {
48341 if (groupRanges.hasOwnProperty(groupIds[i])) {
48342 if (groupRanges[groupIds[i]].ignore !== true) {
48343 minVal = groupRanges[groupIds[i]].min;
48344 maxVal = groupRanges[groupIds[i]].max;
48345
48346 if (groupRanges[groupIds[i]].yAxisOrientation != 'right') {
48347 yAxisLeftUsed = true;
48348 minLeft = minLeft > minVal ? minVal : minLeft;
48349 maxLeft = maxLeft < maxVal ? maxVal : maxLeft;
48350 } else {
48351 yAxisRightUsed = true;
48352 minRight = minRight > minVal ? minVal : minRight;
48353 maxRight = maxRight < maxVal ? maxVal : maxRight;
48354 }
48355 }
48356 }
48357 }
48358
48359 if (yAxisLeftUsed == true) {
48360 this.yAxisLeft.setRange(minLeft, maxLeft);
48361 }
48362
48363 if (yAxisRightUsed == true) {
48364 this.yAxisRight.setRange(minRight, maxRight);
48365 }
48366 }
48367
48368 resized = this._toggleAxisVisiblity(yAxisLeftUsed, this.yAxisLeft) || resized;
48369 resized = this._toggleAxisVisiblity(yAxisRightUsed, this.yAxisRight) || resized;
48370
48371 if (yAxisRightUsed == true && yAxisLeftUsed == true) {
48372 this.yAxisLeft.drawIcons = true;
48373 this.yAxisRight.drawIcons = true;
48374 } else {
48375 this.yAxisLeft.drawIcons = false;
48376 this.yAxisRight.drawIcons = false;
48377 }
48378
48379 this.yAxisRight.master = !yAxisLeftUsed;
48380 this.yAxisRight.masterAxis = this.yAxisLeft;
48381
48382 if (this.yAxisRight.master == false) {
48383 if (yAxisRightUsed == true) {
48384 this.yAxisLeft.lineOffset = this.yAxisRight.width;
48385 } else {
48386 this.yAxisLeft.lineOffset = 0;
48387 }
48388
48389 resized = this.yAxisLeft.redraw() || resized;
48390 resized = this.yAxisRight.redraw() || resized;
48391 } else {
48392 resized = this.yAxisRight.redraw() || resized;
48393 } // clean the accumulated lists
48394
48395
48396 var tempGroups = ['__barStackLeft', '__barStackRight', '__lineStackLeft', '__lineStackRight'];
48397
48398 for (i = 0; i < tempGroups.length; i++) {
48399 if (groupIds.indexOf(tempGroups[i]) != -1) {
48400 groupIds.splice(groupIds.indexOf(tempGroups[i]), 1);
48401 }
48402 }
48403
48404 return resized;
48405};
48406/**
48407 * This shows or hides the Y axis if needed. If there is a change, the changed event is emitted by the updateYAxis function
48408 *
48409 * @param {boolean} axisUsed
48410 * @param {vis.DataAxis} axis
48411 * @returns {boolean}
48412 * @private
48413 */
48414
48415
48416LineGraph.prototype._toggleAxisVisiblity = function (axisUsed, axis) {
48417 var changed = false;
48418
48419 if (axisUsed == false) {
48420 if (axis.dom.frame.parentNode && axis.hidden == false) {
48421 axis.hide();
48422 changed = true;
48423 }
48424 } else {
48425 if (!axis.dom.frame.parentNode && axis.hidden == true) {
48426 axis.show();
48427 changed = true;
48428 }
48429 }
48430
48431 return changed;
48432};
48433/**
48434 * This uses the DataAxis object to generate the correct X coordinate on the SVG window. It uses the
48435 * util function toScreen to get the x coordinate from the timestamp. It also pre-filters the data and get the minMax ranges for
48436 * the yAxis.
48437 *
48438 * @param {Array.<Object>} datapoints
48439 * @private
48440 */
48441
48442
48443LineGraph.prototype._convertXcoordinates = function (datapoints) {
48444 var toScreen = this.body.util.toScreen;
48445
48446 for (var i = 0; i < datapoints.length; i++) {
48447 datapoints[i].screen_x = toScreen(datapoints[i].x) + this.props.width;
48448 datapoints[i].screen_y = datapoints[i].y; //starting point for range calculations
48449
48450 if (datapoints[i].end != undefined) {
48451 datapoints[i].screen_end = toScreen(datapoints[i].end) + this.props.width;
48452 } else {
48453 datapoints[i].screen_end = undefined;
48454 }
48455 }
48456};
48457/**
48458 * This uses the DataAxis object to generate the correct X coordinate on the SVG window. It uses the
48459 * util function toScreen to get the x coordinate from the timestamp. It also pre-filters the data and get the minMax ranges for
48460 * the yAxis.
48461 *
48462 * @param {Array.<Object>} datapoints
48463 * @param {vis.GraphGroup} group
48464 * @private
48465 */
48466
48467
48468LineGraph.prototype._convertYcoordinates = function (datapoints, group) {
48469 var axis = this.yAxisLeft;
48470 var svgHeight = Number(this.svg.style.height.replace('px', ''));
48471
48472 if (group.options.yAxisOrientation == 'right') {
48473 axis = this.yAxisRight;
48474 }
48475
48476 for (var i = 0; i < datapoints.length; i++) {
48477 datapoints[i].screen_y = Math.round(axis.convertValue(datapoints[i].y));
48478 }
48479
48480 group.setZeroPosition(Math.min(svgHeight, axis.convertValue(0)));
48481};
48482
48483/**
48484 * This object contains all possible options. It will check if the types are correct, if required if the option is one
48485 * of the allowed values.
48486 *
48487 * __any__ means that the name of the property does not matter.
48488 * __type__ is a required field for all objects and contains the allowed types of all objects
48489 */
48490var string$1 = 'string';
48491var bool$1 = 'boolean';
48492var number$1 = 'number';
48493var array$1 = 'array';
48494var date$1 = 'date';
48495var object$1 = 'object'; // should only be in a __type__ property
48496
48497var dom$1 = 'dom';
48498var moment$5 = 'moment';
48499var any$1 = 'any';
48500var allOptions$2 = {
48501 configure: {
48502 enabled: {
48503 'boolean': bool$1
48504 },
48505 filter: {
48506 'boolean': bool$1,
48507 'function': 'function'
48508 },
48509 container: {
48510 dom: dom$1
48511 },
48512 __type__: {
48513 object: object$1,
48514 'boolean': bool$1,
48515 'function': 'function'
48516 }
48517 },
48518 //globals :
48519 alignCurrentTime: {
48520 string: string$1,
48521 'undefined': 'undefined'
48522 },
48523 yAxisOrientation: {
48524 string: ['left', 'right']
48525 },
48526 defaultGroup: {
48527 string: string$1
48528 },
48529 sort: {
48530 'boolean': bool$1
48531 },
48532 sampling: {
48533 'boolean': bool$1
48534 },
48535 stack: {
48536 'boolean': bool$1
48537 },
48538 graphHeight: {
48539 string: string$1,
48540 number: number$1
48541 },
48542 shaded: {
48543 enabled: {
48544 'boolean': bool$1
48545 },
48546 orientation: {
48547 string: ['bottom', 'top', 'zero', 'group']
48548 },
48549 // top, bottom, zero, group
48550 groupId: {
48551 object: object$1
48552 },
48553 __type__: {
48554 'boolean': bool$1,
48555 object: object$1
48556 }
48557 },
48558 style: {
48559 string: ['line', 'bar', 'points']
48560 },
48561 // line, bar
48562 barChart: {
48563 width: {
48564 number: number$1
48565 },
48566 minWidth: {
48567 number: number$1
48568 },
48569 sideBySide: {
48570 'boolean': bool$1
48571 },
48572 align: {
48573 string: ['left', 'center', 'right']
48574 },
48575 __type__: {
48576 object: object$1
48577 }
48578 },
48579 interpolation: {
48580 enabled: {
48581 'boolean': bool$1
48582 },
48583 parametrization: {
48584 string: ['centripetal', 'chordal', 'uniform']
48585 },
48586 // uniform (alpha = 0.0), chordal (alpha = 1.0), centripetal (alpha = 0.5)
48587 alpha: {
48588 number: number$1
48589 },
48590 __type__: {
48591 object: object$1,
48592 'boolean': bool$1
48593 }
48594 },
48595 drawPoints: {
48596 enabled: {
48597 'boolean': bool$1
48598 },
48599 onRender: {
48600 'function': 'function'
48601 },
48602 size: {
48603 number: number$1
48604 },
48605 style: {
48606 string: ['square', 'circle']
48607 },
48608 // square, circle
48609 __type__: {
48610 object: object$1,
48611 'boolean': bool$1,
48612 'function': 'function'
48613 }
48614 },
48615 dataAxis: {
48616 showMinorLabels: {
48617 'boolean': bool$1
48618 },
48619 showMajorLabels: {
48620 'boolean': bool$1
48621 },
48622 icons: {
48623 'boolean': bool$1
48624 },
48625 width: {
48626 string: string$1,
48627 number: number$1
48628 },
48629 visible: {
48630 'boolean': bool$1
48631 },
48632 alignZeros: {
48633 'boolean': bool$1
48634 },
48635 left: {
48636 range: {
48637 min: {
48638 number: number$1,
48639 'undefined': 'undefined'
48640 },
48641 max: {
48642 number: number$1,
48643 'undefined': 'undefined'
48644 },
48645 __type__: {
48646 object: object$1
48647 }
48648 },
48649 format: {
48650 'function': 'function'
48651 },
48652 title: {
48653 text: {
48654 string: string$1,
48655 number: number$1,
48656 'undefined': 'undefined'
48657 },
48658 style: {
48659 string: string$1,
48660 'undefined': 'undefined'
48661 },
48662 __type__: {
48663 object: object$1
48664 }
48665 },
48666 __type__: {
48667 object: object$1
48668 }
48669 },
48670 right: {
48671 range: {
48672 min: {
48673 number: number$1,
48674 'undefined': 'undefined'
48675 },
48676 max: {
48677 number: number$1,
48678 'undefined': 'undefined'
48679 },
48680 __type__: {
48681 object: object$1
48682 }
48683 },
48684 format: {
48685 'function': 'function'
48686 },
48687 title: {
48688 text: {
48689 string: string$1,
48690 number: number$1,
48691 'undefined': 'undefined'
48692 },
48693 style: {
48694 string: string$1,
48695 'undefined': 'undefined'
48696 },
48697 __type__: {
48698 object: object$1
48699 }
48700 },
48701 __type__: {
48702 object: object$1
48703 }
48704 },
48705 __type__: {
48706 object: object$1
48707 }
48708 },
48709 legend: {
48710 enabled: {
48711 'boolean': bool$1
48712 },
48713 icons: {
48714 'boolean': bool$1
48715 },
48716 left: {
48717 visible: {
48718 'boolean': bool$1
48719 },
48720 position: {
48721 string: ['top-right', 'bottom-right', 'top-left', 'bottom-left']
48722 },
48723 __type__: {
48724 object: object$1
48725 }
48726 },
48727 right: {
48728 visible: {
48729 'boolean': bool$1
48730 },
48731 position: {
48732 string: ['top-right', 'bottom-right', 'top-left', 'bottom-left']
48733 },
48734 __type__: {
48735 object: object$1
48736 }
48737 },
48738 __type__: {
48739 object: object$1,
48740 'boolean': bool$1
48741 }
48742 },
48743 groups: {
48744 visibility: {
48745 any: any$1
48746 },
48747 __type__: {
48748 object: object$1
48749 }
48750 },
48751 autoResize: {
48752 'boolean': bool$1
48753 },
48754 throttleRedraw: {
48755 number: number$1
48756 },
48757 // TODO: DEPRICATED see https://github.com/almende/vis/issues/2511
48758 clickToUse: {
48759 'boolean': bool$1
48760 },
48761 end: {
48762 number: number$1,
48763 date: date$1,
48764 string: string$1,
48765 moment: moment$5
48766 },
48767 format: {
48768 minorLabels: {
48769 millisecond: {
48770 string: string$1,
48771 'undefined': 'undefined'
48772 },
48773 second: {
48774 string: string$1,
48775 'undefined': 'undefined'
48776 },
48777 minute: {
48778 string: string$1,
48779 'undefined': 'undefined'
48780 },
48781 hour: {
48782 string: string$1,
48783 'undefined': 'undefined'
48784 },
48785 weekday: {
48786 string: string$1,
48787 'undefined': 'undefined'
48788 },
48789 day: {
48790 string: string$1,
48791 'undefined': 'undefined'
48792 },
48793 month: {
48794 string: string$1,
48795 'undefined': 'undefined'
48796 },
48797 quarter: {
48798 string: string$1,
48799 'undefined': 'undefined'
48800 },
48801 year: {
48802 string: string$1,
48803 'undefined': 'undefined'
48804 },
48805 __type__: {
48806 object: object$1
48807 }
48808 },
48809 majorLabels: {
48810 millisecond: {
48811 string: string$1,
48812 'undefined': 'undefined'
48813 },
48814 second: {
48815 string: string$1,
48816 'undefined': 'undefined'
48817 },
48818 minute: {
48819 string: string$1,
48820 'undefined': 'undefined'
48821 },
48822 hour: {
48823 string: string$1,
48824 'undefined': 'undefined'
48825 },
48826 weekday: {
48827 string: string$1,
48828 'undefined': 'undefined'
48829 },
48830 day: {
48831 string: string$1,
48832 'undefined': 'undefined'
48833 },
48834 month: {
48835 string: string$1,
48836 'undefined': 'undefined'
48837 },
48838 quarter: {
48839 string: string$1,
48840 'undefined': 'undefined'
48841 },
48842 year: {
48843 string: string$1,
48844 'undefined': 'undefined'
48845 },
48846 __type__: {
48847 object: object$1
48848 }
48849 },
48850 __type__: {
48851 object: object$1
48852 }
48853 },
48854 moment: {
48855 'function': 'function'
48856 },
48857 height: {
48858 string: string$1,
48859 number: number$1
48860 },
48861 hiddenDates: {
48862 start: {
48863 date: date$1,
48864 number: number$1,
48865 string: string$1,
48866 moment: moment$5
48867 },
48868 end: {
48869 date: date$1,
48870 number: number$1,
48871 string: string$1,
48872 moment: moment$5
48873 },
48874 repeat: {
48875 string: string$1
48876 },
48877 __type__: {
48878 object: object$1,
48879 array: array$1
48880 }
48881 },
48882 locale: {
48883 string: string$1
48884 },
48885 locales: {
48886 __any__: {
48887 any: any$1
48888 },
48889 __type__: {
48890 object: object$1
48891 }
48892 },
48893 max: {
48894 date: date$1,
48895 number: number$1,
48896 string: string$1,
48897 moment: moment$5
48898 },
48899 maxHeight: {
48900 number: number$1,
48901 string: string$1
48902 },
48903 maxMinorChars: {
48904 number: number$1
48905 },
48906 min: {
48907 date: date$1,
48908 number: number$1,
48909 string: string$1,
48910 moment: moment$5
48911 },
48912 minHeight: {
48913 number: number$1,
48914 string: string$1
48915 },
48916 moveable: {
48917 'boolean': bool$1
48918 },
48919 multiselect: {
48920 'boolean': bool$1
48921 },
48922 orientation: {
48923 string: string$1
48924 },
48925 showCurrentTime: {
48926 'boolean': bool$1
48927 },
48928 showMajorLabels: {
48929 'boolean': bool$1
48930 },
48931 showMinorLabels: {
48932 'boolean': bool$1
48933 },
48934 start: {
48935 date: date$1,
48936 number: number$1,
48937 string: string$1,
48938 moment: moment$5
48939 },
48940 timeAxis: {
48941 scale: {
48942 string: string$1,
48943 'undefined': 'undefined'
48944 },
48945 step: {
48946 number: number$1,
48947 'undefined': 'undefined'
48948 },
48949 __type__: {
48950 object: object$1
48951 }
48952 },
48953 width: {
48954 string: string$1,
48955 number: number$1
48956 },
48957 zoomable: {
48958 'boolean': bool$1
48959 },
48960 zoomKey: {
48961 string: ['ctrlKey', 'altKey', 'metaKey', '']
48962 },
48963 zoomMax: {
48964 number: number$1
48965 },
48966 zoomMin: {
48967 number: number$1
48968 },
48969 zIndex: {
48970 number: number$1
48971 },
48972 __type__: {
48973 object: object$1
48974 }
48975};
48976var configureOptions$1 = {
48977 global: {
48978 alignCurrentTime: ['none', 'year', 'month', 'quarter', 'week', 'isoWeek', 'day', 'date', 'hour', 'minute', 'second'],
48979 //yAxisOrientation: ['left','right'], // TDOO: enable as soon as Grahp2d doesn't crash when changing this on the fly
48980 sort: true,
48981 sampling: true,
48982 stack: false,
48983 shaded: {
48984 enabled: false,
48985 orientation: ['zero', 'top', 'bottom', 'group'] // zero, top, bottom
48986
48987 },
48988 style: ['line', 'bar', 'points'],
48989 // line, bar
48990 barChart: {
48991 width: [50, 5, 100, 5],
48992 minWidth: [50, 5, 100, 5],
48993 sideBySide: false,
48994 align: ['left', 'center', 'right'] // left, center, right
48995
48996 },
48997 interpolation: {
48998 enabled: true,
48999 parametrization: ['centripetal', 'chordal', 'uniform'] // uniform (alpha = 0.0), chordal (alpha = 1.0), centripetal (alpha = 0.5)
49000
49001 },
49002 drawPoints: {
49003 enabled: true,
49004 size: [6, 2, 30, 1],
49005 style: ['square', 'circle'] // square, circle
49006
49007 },
49008 dataAxis: {
49009 showMinorLabels: true,
49010 showMajorLabels: true,
49011 icons: false,
49012 width: [40, 0, 200, 1],
49013 visible: true,
49014 alignZeros: true,
49015 left: {
49016 //range: {min:'undefined': 'undefined'ined,max:'undefined': 'undefined'ined},
49017 //format: function (value) {return value;},
49018 title: {
49019 text: '',
49020 style: ''
49021 }
49022 },
49023 right: {
49024 //range: {min:'undefined': 'undefined'ined,max:'undefined': 'undefined'ined},
49025 //format: function (value) {return value;},
49026 title: {
49027 text: '',
49028 style: ''
49029 }
49030 }
49031 },
49032 legend: {
49033 enabled: false,
49034 icons: true,
49035 left: {
49036 visible: true,
49037 position: ['top-right', 'bottom-right', 'top-left', 'bottom-left'] // top/bottom - left,right
49038
49039 },
49040 right: {
49041 visible: true,
49042 position: ['top-right', 'bottom-right', 'top-left', 'bottom-left'] // top/bottom - left,right
49043
49044 }
49045 },
49046 autoResize: true,
49047 clickToUse: false,
49048 end: '',
49049 format: {
49050 minorLabels: {
49051 millisecond: 'SSS',
49052 second: 's',
49053 minute: 'HH:mm',
49054 hour: 'HH:mm',
49055 weekday: 'ddd D',
49056 day: 'D',
49057 month: 'MMM',
49058 quarter: '[Q]Q',
49059 year: 'YYYY'
49060 },
49061 majorLabels: {
49062 millisecond: 'HH:mm:ss',
49063 second: 'D MMMM HH:mm',
49064 minute: 'ddd D MMMM',
49065 hour: 'ddd D MMMM',
49066 weekday: 'MMMM YYYY',
49067 day: 'MMMM YYYY',
49068 month: 'YYYY',
49069 quarter: 'YYYY',
49070 year: ''
49071 }
49072 },
49073 height: '',
49074 locale: '',
49075 max: '',
49076 maxHeight: '',
49077 maxMinorChars: [7, 0, 20, 1],
49078 min: '',
49079 minHeight: '',
49080 moveable: true,
49081 orientation: ['both', 'bottom', 'top'],
49082 showCurrentTime: false,
49083 showMajorLabels: true,
49084 showMinorLabels: true,
49085 start: '',
49086 width: '100%',
49087 zoomable: true,
49088 zoomKey: ['ctrlKey', 'altKey', 'metaKey', ''],
49089 zoomMax: [315360000000000, 10, 315360000000000, 1],
49090 zoomMin: [10, 10, 315360000000000, 1],
49091 zIndex: 0
49092 }
49093};
49094
49095/**
49096 * Create a timeline visualization
49097 * @param {HTMLElement} container
49098 * @param {vis.DataSet | Array} [items]
49099 * @param {vis.DataSet | Array | vis.DataView | Object} [groups]
49100 * @param {Object} [options] See Graph2d.setOptions for the available options.
49101 * @constructor Graph2d
49102 * @extends Core
49103 */
49104
49105function Graph2d(container, items, groups, options) {
49106 // if the third element is options, the forth is groups (optionally);
49107 if (!(Array.isArray(groups) || groups instanceof DataSet || groups instanceof DataView$2) && groups instanceof Object) {
49108 var forthArgument = options;
49109 options = groups;
49110 groups = forthArgument;
49111 } // TODO: REMOVE THIS in the next MAJOR release
49112 // see https://github.com/almende/vis/issues/2511
49113
49114
49115 if (options && options.throttleRedraw) {
49116 console.warn("Graph2d option \"throttleRedraw\" is DEPRICATED and no longer supported. It will be removed in the next MAJOR release.");
49117 }
49118
49119 var me = this;
49120 this.defaultOptions = {
49121 start: null,
49122 end: null,
49123 autoResize: true,
49124 orientation: {
49125 axis: 'bottom',
49126 // axis orientation: 'bottom', 'top', or 'both'
49127 item: 'bottom' // not relevant for Graph2d
49128
49129 },
49130 moment: moment$3,
49131 width: null,
49132 height: null,
49133 maxHeight: null,
49134 minHeight: null
49135 };
49136 this.options = util.deepExtend({}, this.defaultOptions); // Create the DOM, props, and emitter
49137
49138 this._create(container); // all components listed here will be repainted automatically
49139
49140
49141 this.components = [];
49142 this.body = {
49143 dom: this.dom,
49144 domProps: this.props,
49145 emitter: {
49146 on: this.on.bind(this),
49147 off: this.off.bind(this),
49148 emit: this.emit.bind(this)
49149 },
49150 hiddenDates: [],
49151 util: {
49152 toScreen: me._toScreen.bind(me),
49153 toGlobalScreen: me._toGlobalScreen.bind(me),
49154 // this refers to the root.width
49155 toTime: me._toTime.bind(me),
49156 toGlobalTime: me._toGlobalTime.bind(me)
49157 }
49158 }; // range
49159
49160 this.range = new Range(this.body);
49161 this.components.push(this.range);
49162 this.body.range = this.range; // time axis
49163
49164 this.timeAxis = new TimeAxis(this.body);
49165 this.components.push(this.timeAxis); //this.body.util.snap = this.timeAxis.snap.bind(this.timeAxis);
49166 // current time bar
49167
49168 this.currentTime = new CurrentTime(this.body);
49169 this.components.push(this.currentTime); // item set
49170
49171 this.linegraph = new LineGraph(this.body);
49172 this.components.push(this.linegraph);
49173 this.itemsData = null; // DataSet
49174
49175 this.groupsData = null; // DataSet
49176
49177 this.on('tap', function (event) {
49178 me.emit('click', me.getEventProperties(event));
49179 });
49180 this.on('doubletap', function (event) {
49181 me.emit('doubleClick', me.getEventProperties(event));
49182 });
49183
49184 this.dom.root.oncontextmenu = function (event) {
49185 me.emit('contextmenu', me.getEventProperties(event));
49186 }; //Single time autoscale/fit
49187
49188
49189 this.initialFitDone = false;
49190 this.on('changed', function () {
49191 if (me.itemsData == null) return;
49192
49193 if (!me.initialFitDone && !me.options.rollingMode) {
49194 me.initialFitDone = true;
49195
49196 if (me.options.start != undefined || me.options.end != undefined) {
49197 if (me.options.start == undefined || me.options.end == undefined) {
49198 var range = me.getItemRange();
49199 }
49200
49201 var start = me.options.start != undefined ? me.options.start : range.min;
49202 var end = me.options.end != undefined ? me.options.end : range.max;
49203 me.setWindow(start, end, {
49204 animation: false
49205 });
49206 } else {
49207 me.fit({
49208 animation: false
49209 });
49210 }
49211 }
49212
49213 if (!me.initialDrawDone && (me.initialRangeChangeDone || !me.options.start && !me.options.end || me.options.rollingMode)) {
49214 me.initialDrawDone = true;
49215 me.dom.root.style.visibility = 'visible';
49216 me.dom.loadingScreen.parentNode.removeChild(me.dom.loadingScreen);
49217
49218 if (me.options.onInitialDrawComplete) {
49219 setTimeout(function () {
49220 return me.options.onInitialDrawComplete();
49221 }, 0);
49222 }
49223 }
49224 }); // apply options
49225
49226 if (options) {
49227 this.setOptions(options);
49228 } // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS!
49229
49230
49231 if (groups) {
49232 this.setGroups(groups);
49233 } // create itemset
49234
49235
49236 if (items) {
49237 this.setItems(items);
49238 } // draw for the first time
49239
49240
49241 this._redraw();
49242} // Extend the functionality from Core
49243
49244
49245Graph2d.prototype = new Core();
49246
49247Graph2d.prototype.setOptions = function (options) {
49248 // validate options
49249 var errorFound = Validator.validate(options, allOptions$2);
49250
49251 if (errorFound === true) {
49252 console.log('%cErrors have been found in the supplied options object.', printStyle);
49253 }
49254
49255 Core.prototype.setOptions.call(this, options);
49256};
49257/**
49258 * Set items
49259 * @param {vis.DataSet | Array | null} items
49260 */
49261
49262
49263Graph2d.prototype.setItems = function (items) {
49264 var initialLoad = this.itemsData == null; // convert to type DataSet when needed
49265
49266 var newDataSet;
49267
49268 if (!items) {
49269 newDataSet = null;
49270 } else if (items instanceof DataSet || items instanceof DataView$2) {
49271 newDataSet = items;
49272 } else {
49273 // turn an array into a dataset
49274 newDataSet = new DataSet(items, {
49275 type: {
49276 start: 'Date',
49277 end: 'Date'
49278 }
49279 });
49280 } // set items
49281
49282
49283 this.itemsData = newDataSet;
49284 this.linegraph && this.linegraph.setItems(newDataSet);
49285
49286 if (initialLoad) {
49287 if (this.options.start != undefined || this.options.end != undefined) {
49288 var start = this.options.start != undefined ? this.options.start : null;
49289 var end = this.options.end != undefined ? this.options.end : null;
49290 this.setWindow(start, end, {
49291 animation: false
49292 });
49293 } else {
49294 this.fit({
49295 animation: false
49296 });
49297 }
49298 }
49299};
49300/**
49301 * Set groups
49302 * @param {vis.DataSet | Array} groups
49303 */
49304
49305
49306Graph2d.prototype.setGroups = function (groups) {
49307 // convert to type DataSet when needed
49308 var newDataSet;
49309
49310 if (!groups) {
49311 newDataSet = null;
49312 } else if (groups instanceof DataSet || groups instanceof DataView$2) {
49313 newDataSet = groups;
49314 } else {
49315 // turn an array into a dataset
49316 newDataSet = new DataSet(groups);
49317 }
49318
49319 this.groupsData = newDataSet;
49320 this.linegraph.setGroups(newDataSet);
49321};
49322/**
49323 * Returns an object containing an SVG element with the icon of the group (size determined by iconWidth and iconHeight), the label of the group (content) and the yAxisOrientation of the group (left or right).
49324 * @param {vis.GraphGroup.id} groupId
49325 * @param {number} width
49326 * @param {number} height
49327 * @returns {{icon: SVGElement, label: string, orientation: string}|string}
49328 */
49329
49330
49331Graph2d.prototype.getLegend = function (groupId, width, height) {
49332 if (width === undefined) {
49333 width = 15;
49334 }
49335
49336 if (height === undefined) {
49337 height = 15;
49338 }
49339
49340 if (this.linegraph.groups[groupId] !== undefined) {
49341 return this.linegraph.groups[groupId].getLegend(width, height);
49342 } else {
49343 return "cannot find group:'" + groupId + "'";
49344 }
49345};
49346/**
49347 * This checks if the visible option of the supplied group (by ID) is true or false.
49348 * @param {vis.GraphGroup.id} groupId
49349 * @returns {boolean}
49350 */
49351
49352
49353Graph2d.prototype.isGroupVisible = function (groupId) {
49354 if (this.linegraph.groups[groupId] !== undefined) {
49355 return this.linegraph.groups[groupId].visible && (this.linegraph.options.groups.visibility[groupId] === undefined || this.linegraph.options.groups.visibility[groupId] == true);
49356 } else {
49357 return false;
49358 }
49359};
49360/**
49361 * Get the data range of the item set.
49362 * @returns {{min: Date, max: Date}} range A range with a start and end Date.
49363 * When no minimum is found, min==null
49364 * When no maximum is found, max==null
49365 */
49366
49367
49368Graph2d.prototype.getDataRange = function () {
49369 var min = null;
49370 var max = null; // calculate min from start filed
49371
49372 for (var groupId in this.linegraph.groups) {
49373 if (this.linegraph.groups.hasOwnProperty(groupId)) {
49374 if (this.linegraph.groups[groupId].visible == true) {
49375 for (var i = 0; i < this.linegraph.groups[groupId].itemsData.length; i++) {
49376 var item = this.linegraph.groups[groupId].itemsData[i];
49377 var value = util.convert(item.x, 'Date').valueOf();
49378 min = min == null ? value : min > value ? value : min;
49379 max = max == null ? value : max < value ? value : max;
49380 }
49381 }
49382 }
49383 }
49384
49385 return {
49386 min: min != null ? new Date(min) : null,
49387 max: max != null ? new Date(max) : null
49388 };
49389};
49390/**
49391 * Generate Timeline related information from an event
49392 * @param {Event} event
49393 * @return {Object} An object with related information, like on which area
49394 * The event happened, whether clicked on an item, etc.
49395 */
49396
49397
49398Graph2d.prototype.getEventProperties = function (event) {
49399 var clientX = event.center ? event.center.x : event.clientX;
49400 var clientY = event.center ? event.center.y : event.clientY;
49401 var x = clientX - util.getAbsoluteLeft(this.dom.centerContainer);
49402 var y = clientY - util.getAbsoluteTop(this.dom.centerContainer);
49403
49404 var time = this._toTime(x);
49405
49406 var customTime = CustomTime.customTimeFromTarget(event);
49407 var element = util.getTarget(event);
49408 var what = null;
49409
49410 if (util.hasParent(element, this.timeAxis.dom.foreground)) {
49411 what = 'axis';
49412 } else if (this.timeAxis2 && util.hasParent(element, this.timeAxis2.dom.foreground)) {
49413 what = 'axis';
49414 } else if (util.hasParent(element, this.linegraph.yAxisLeft.dom.frame)) {
49415 what = 'data-axis';
49416 } else if (util.hasParent(element, this.linegraph.yAxisRight.dom.frame)) {
49417 what = 'data-axis';
49418 } else if (util.hasParent(element, this.linegraph.legendLeft.dom.frame)) {
49419 what = 'legend';
49420 } else if (util.hasParent(element, this.linegraph.legendRight.dom.frame)) {
49421 what = 'legend';
49422 } else if (customTime != null) {
49423 what = 'custom-time';
49424 } else if (util.hasParent(element, this.currentTime.bar)) {
49425 what = 'current-time';
49426 } else if (util.hasParent(element, this.dom.center)) {
49427 what = 'background';
49428 }
49429
49430 var value = [];
49431 var yAxisLeft = this.linegraph.yAxisLeft;
49432 var yAxisRight = this.linegraph.yAxisRight;
49433
49434 if (!yAxisLeft.hidden && this.itemsData.length > 0) {
49435 value.push(yAxisLeft.screenToValue(y));
49436 }
49437
49438 if (!yAxisRight.hidden && this.itemsData.length > 0) {
49439 value.push(yAxisRight.screenToValue(y));
49440 }
49441
49442 return {
49443 event: event,
49444 customTime: customTime ? customTime.options.id : null,
49445 what: what,
49446 pageX: event.srcEvent ? event.srcEvent.pageX : event.pageX,
49447 pageY: event.srcEvent ? event.srcEvent.pageY : event.pageY,
49448 x: x,
49449 y: y,
49450 time: time,
49451 value: value
49452 };
49453};
49454/**
49455 * Load a configurator
49456 * @return {Object}
49457 * @private
49458 */
49459
49460
49461Graph2d.prototype._createConfigurator = function () {
49462 return new Configurator(this, this.dom.container, configureOptions$1);
49463};
49464
49465// utils
49466moment$3.locale('en');
49467var timeline = {
49468 Core: Core,
49469 DateUtil: DateUtil,
49470 Range: Range,
49471 stack: stack$1,
49472 TimeStep: TimeStep,
49473 components: {
49474 items: {
49475 Item: Item,
49476 BackgroundItem: BackgroundItem,
49477 BoxItem: BoxItem,
49478 PointItem: PointItem,
49479 RangeItem: RangeItem
49480 },
49481 BackgroundGroup: BackgroundGroup,
49482 Component: Component,
49483 CurrentTime: CurrentTime,
49484 CustomTime: CustomTime,
49485 DataAxis: DataAxis,
49486 DataScale: DataScale,
49487 GraphGroup: GraphGroup,
49488 Group: Group,
49489 ItemSet: ItemSet,
49490 Legend: Legend,
49491 LineGraph: LineGraph,
49492 TimeAxis: TimeAxis
49493 }
49494};
49495var index$1 = {
49496 util: util,
49497 DOMutil: DOMutil,
49498 DataSet: DataSet,
49499 DataView: DataView$2,
49500 Queue: Queue,
49501 Timeline: Timeline,
49502 Graph2d: Graph2d,
49503 timeline: timeline,
49504 moment: moment$3,
49505 Hammer: Hammer$1,
49506 keycharm: keycharm
49507};
49508
49509export default index$1;
49510export { DOMutil, DataSet, DataView$2 as DataView, Graph2d, Hammer$1 as Hammer, Queue, Timeline, keycharm, moment$3 as moment, timeline, util };
49511//# sourceMappingURL=vis-timeline-graph2d.esm.js.map