UNPKG

900 kBJavaScriptView Raw
1/**
2 * vis-graph3d - data
3 * http://visjs.org/
4 *
5 * Create interactive, animated 3d graphs. Surfaces, lines, dots and block styling out of the box.
6 *
7 * @version 5.0.1
8 * @date 2019-08-18T19:50:50Z
9 *
10 * @copyright (c) 2011-2017 Almende B.V, http://almende.com
11 * @copyright (c) 2018-2019 visjs contributors, https://github.com/visjs
12 *
13 * @license
14 * vis.js is dual licensed under both
15 *
16 * 1. The Apache 2.0 License
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * and
20 *
21 * 2. The MIT License
22 * http://opensource.org/licenses/MIT
23 *
24 * vis.js may be distributed under either license.
25 */
26
27var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
28
29function commonjsRequire() {
30 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
31}
32
33function createCommonjsModule(fn, module) {
34 return module = {
35 exports: {}
36 }, fn(module, module.exports), module.exports;
37}
38
39var _global = createCommonjsModule(function (module) {
40 // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
41 var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self // eslint-disable-next-line no-new-func
42 : Function('return this')();
43 if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
44});
45
46var _core = createCommonjsModule(function (module) {
47 var core = module.exports = {
48 version: '2.6.9'
49 };
50 if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
51});
52
53var _core_1 = _core.version;
54var _library = false;
55
56var _shared = createCommonjsModule(function (module) {
57 var SHARED = '__core-js_shared__';
58 var store = _global[SHARED] || (_global[SHARED] = {});
59 (module.exports = function (key, value) {
60 return store[key] || (store[key] = value !== undefined ? value : {});
61 })('versions', []).push({
62 version: _core.version,
63 mode: 'global',
64 copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
65 });
66});
67
68var id = 0;
69var px = Math.random();
70
71var _uid = function (key) {
72 return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
73};
74
75var _wks = createCommonjsModule(function (module) {
76 var store = _shared('wks');
77
78 var Symbol = _global.Symbol;
79 var USE_SYMBOL = typeof Symbol == 'function';
80
81 var $exports = module.exports = function (name) {
82 return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name));
83 };
84
85 $exports.store = store;
86});
87
88var f = _wks;
89var _wksExt = {
90 f: f
91};
92
93var _isObject = function (it) {
94 return typeof it === 'object' ? it !== null : typeof it === 'function';
95};
96
97var _anObject = function (it) {
98 if (!_isObject(it)) throw TypeError(it + ' is not an object!');
99 return it;
100};
101
102var _fails = function (exec) {
103 try {
104 return !!exec();
105 } catch (e) {
106 return true;
107 }
108};
109
110var _descriptors = !_fails(function () {
111 return Object.defineProperty({}, 'a', {
112 get: function () {
113 return 7;
114 }
115 }).a != 7;
116});
117
118var document$1 = _global.document; // typeof document.createElement is 'object' in old IE
119
120var is = _isObject(document$1) && _isObject(document$1.createElement);
121
122var _domCreate = function (it) {
123 return is ? document$1.createElement(it) : {};
124};
125
126var _ie8DomDefine = !_descriptors && !_fails(function () {
127 return Object.defineProperty(_domCreate('div'), 'a', {
128 get: function () {
129 return 7;
130 }
131 }).a != 7;
132}); // instead of the ES6 spec version, we didn't implement @@toPrimitive case
133// and the second argument - flag - preferred type is a string
134
135
136var _toPrimitive = function (it, S) {
137 if (!_isObject(it)) return it;
138 var fn, val;
139 if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
140 if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
141 if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
142 throw TypeError("Can't convert object to primitive value");
143};
144
145var dP = Object.defineProperty;
146var f$1 = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
147 _anObject(O);
148
149 P = _toPrimitive(P, true);
150
151 _anObject(Attributes);
152
153 if (_ie8DomDefine) try {
154 return dP(O, P, Attributes);
155 } catch (e) {
156 /* empty */
157 }
158 if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
159 if ('value' in Attributes) O[P] = Attributes.value;
160 return O;
161};
162var _objectDp = {
163 f: f$1
164};
165var defineProperty = _objectDp.f;
166
167var _wksDefine = function (name) {
168 var $Symbol = _core.Symbol || (_core.Symbol = _global.Symbol || {});
169 if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, {
170 value: _wksExt.f(name)
171 });
172};
173
174_wksDefine('asyncIterator');
175
176var hasOwnProperty = {}.hasOwnProperty;
177
178var _has = function (it, key) {
179 return hasOwnProperty.call(it, key);
180};
181
182var _propertyDesc = function (bitmap, value) {
183 return {
184 enumerable: !(bitmap & 1),
185 configurable: !(bitmap & 2),
186 writable: !(bitmap & 4),
187 value: value
188 };
189};
190
191var _hide = _descriptors ? function (object, key, value) {
192 return _objectDp.f(object, key, _propertyDesc(1, value));
193} : function (object, key, value) {
194 object[key] = value;
195 return object;
196};
197
198var _functionToString = _shared('native-function-to-string', Function.toString);
199
200var _redefine = createCommonjsModule(function (module) {
201 var SRC = _uid('src');
202
203 var TO_STRING = 'toString';
204
205 var TPL = ('' + _functionToString).split(TO_STRING);
206
207 _core.inspectSource = function (it) {
208 return _functionToString.call(it);
209 };
210
211 (module.exports = function (O, key, val, safe) {
212 var isFunction = typeof val == 'function';
213 if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
214 if (O[key] === val) return;
215 if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
216
217 if (O === _global) {
218 O[key] = val;
219 } else if (!safe) {
220 delete O[key];
221
222 _hide(O, key, val);
223 } else if (O[key]) {
224 O[key] = val;
225 } else {
226 _hide(O, key, val);
227 } // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
228
229 })(Function.prototype, TO_STRING, function toString() {
230 return typeof this == 'function' && this[SRC] || _functionToString.call(this);
231 });
232});
233
234var _aFunction = function (it) {
235 if (typeof it != 'function') throw TypeError(it + ' is not a function!');
236 return it;
237};
238
239var _ctx = function (fn, that, length) {
240 _aFunction(fn);
241
242 if (that === undefined) return fn;
243
244 switch (length) {
245 case 1:
246 return function (a) {
247 return fn.call(that, a);
248 };
249
250 case 2:
251 return function (a, b) {
252 return fn.call(that, a, b);
253 };
254
255 case 3:
256 return function (a, b, c) {
257 return fn.call(that, a, b, c);
258 };
259 }
260
261 return function ()
262 /* ...args */
263 {
264 return fn.apply(that, arguments);
265 };
266};
267
268var PROTOTYPE = 'prototype';
269
270var $export = function (type, name, source) {
271 var IS_FORCED = type & $export.F;
272 var IS_GLOBAL = type & $export.G;
273 var IS_STATIC = type & $export.S;
274 var IS_PROTO = type & $export.P;
275 var IS_BIND = type & $export.B;
276 var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
277 var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
278 var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
279 var key, own, out, exp;
280 if (IS_GLOBAL) source = name;
281
282 for (key in source) {
283 // contains in native
284 own = !IS_FORCED && target && target[key] !== undefined; // export native or passed
285
286 out = (own ? target : source)[key]; // bind timers to global for call from export context
287
288 exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; // extend global
289
290 if (target) _redefine(target, key, out, type & $export.U); // export
291
292 if (exports[key] != out) _hide(exports, key, exp);
293 if (IS_PROTO && expProto[key] != out) expProto[key] = out;
294 }
295};
296
297_global.core = _core; // type bitmap
298
299$export.F = 1; // forced
300
301$export.G = 2; // global
302
303$export.S = 4; // static
304
305$export.P = 8; // proto
306
307$export.B = 16; // bind
308
309$export.W = 32; // wrap
310
311$export.U = 64; // safe
312
313$export.R = 128; // real proto method for `library`
314
315var _export = $export;
316
317var _meta = createCommonjsModule(function (module) {
318 var META = _uid('meta');
319
320 var setDesc = _objectDp.f;
321 var id = 0;
322
323 var isExtensible = Object.isExtensible || function () {
324 return true;
325 };
326
327 var FREEZE = !_fails(function () {
328 return isExtensible(Object.preventExtensions({}));
329 });
330
331 var setMeta = function (it) {
332 setDesc(it, META, {
333 value: {
334 i: 'O' + ++id,
335 // object ID
336 w: {} // weak collections IDs
337
338 }
339 });
340 };
341
342 var fastKey = function (it, create) {
343 // return primitive with prefix
344 if (!_isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
345
346 if (!_has(it, META)) {
347 // can't set metadata to uncaught frozen object
348 if (!isExtensible(it)) return 'F'; // not necessary to add metadata
349
350 if (!create) return 'E'; // add missing metadata
351
352 setMeta(it); // return object ID
353 }
354
355 return it[META].i;
356 };
357
358 var getWeak = function (it, create) {
359 if (!_has(it, META)) {
360 // can't set metadata to uncaught frozen object
361 if (!isExtensible(it)) return true; // not necessary to add metadata
362
363 if (!create) return false; // add missing metadata
364
365 setMeta(it); // return hash weak collections IDs
366 }
367
368 return it[META].w;
369 }; // add metadata on freeze-family methods calling
370
371
372 var onFreeze = function (it) {
373 if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it);
374 return it;
375 };
376
377 var meta = module.exports = {
378 KEY: META,
379 NEED: false,
380 fastKey: fastKey,
381 getWeak: getWeak,
382 onFreeze: onFreeze
383 };
384});
385
386var _meta_1 = _meta.KEY;
387var _meta_2 = _meta.NEED;
388var _meta_3 = _meta.fastKey;
389var _meta_4 = _meta.getWeak;
390var _meta_5 = _meta.onFreeze;
391var def = _objectDp.f;
392
393var TAG = _wks('toStringTag');
394
395var _setToStringTag = function (it, tag, stat) {
396 if (it && !_has(it = stat ? it : it.prototype, TAG)) def(it, TAG, {
397 configurable: true,
398 value: tag
399 });
400};
401
402var toString = {}.toString;
403
404var _cof = function (it) {
405 return toString.call(it).slice(8, -1);
406}; // eslint-disable-next-line no-prototype-builtins
407
408
409var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
410 return _cof(it) == 'String' ? it.split('') : Object(it);
411}; // 7.2.1 RequireObjectCoercible(argument)
412
413
414var _defined = function (it) {
415 if (it == undefined) throw TypeError("Can't call method on " + it);
416 return it;
417};
418
419var _toIobject = function (it) {
420 return _iobject(_defined(it));
421}; // 7.1.4 ToInteger
422
423
424var ceil = Math.ceil;
425var floor = Math.floor;
426
427var _toInteger = function (it) {
428 return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
429};
430
431var min = Math.min;
432
433var _toLength = function (it) {
434 return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
435};
436
437var max = Math.max;
438var min$1 = Math.min;
439
440var _toAbsoluteIndex = function (index, length) {
441 index = _toInteger(index);
442 return index < 0 ? max(index + length, 0) : min$1(index, length);
443}; // true -> Array#includes
444
445
446var _arrayIncludes = function (IS_INCLUDES) {
447 return function ($this, el, fromIndex) {
448 var O = _toIobject($this);
449
450 var length = _toLength(O.length);
451
452 var index = _toAbsoluteIndex(fromIndex, length);
453
454 var value; // Array#includes uses SameValueZero equality algorithm
455 // eslint-disable-next-line no-self-compare
456
457 if (IS_INCLUDES && el != el) while (length > index) {
458 value = O[index++]; // eslint-disable-next-line no-self-compare
459
460 if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not
461 } else for (; length > index; index++) if (IS_INCLUDES || index in O) {
462 if (O[index] === el) return IS_INCLUDES || index || 0;
463 }
464 return !IS_INCLUDES && -1;
465 };
466};
467
468var shared = _shared('keys');
469
470var _sharedKey = function (key) {
471 return shared[key] || (shared[key] = _uid(key));
472};
473
474var arrayIndexOf = _arrayIncludes(false);
475
476var IE_PROTO = _sharedKey('IE_PROTO');
477
478var _objectKeysInternal = function (object, names) {
479 var O = _toIobject(object);
480
481 var i = 0;
482 var result = [];
483 var key;
484
485 for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key); // Don't enum bug & hidden keys
486
487
488 while (names.length > i) if (_has(O, key = names[i++])) {
489 ~arrayIndexOf(result, key) || result.push(key);
490 }
491
492 return result;
493}; // IE 8- don't enum bug keys
494
495
496var _enumBugKeys = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(',');
497
498var _objectKeys = Object.keys || function keys(O) {
499 return _objectKeysInternal(O, _enumBugKeys);
500};
501
502var f$2 = Object.getOwnPropertySymbols;
503var _objectGops = {
504 f: f$2
505};
506var f$3 = {}.propertyIsEnumerable;
507var _objectPie = {
508 f: f$3
509};
510
511var _enumKeys = function (it) {
512 var result = _objectKeys(it);
513
514 var getSymbols = _objectGops.f;
515
516 if (getSymbols) {
517 var symbols = getSymbols(it);
518 var isEnum = _objectPie.f;
519 var i = 0;
520 var key;
521
522 while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);
523 }
524
525 return result;
526};
527
528var _isArray = Array.isArray || function isArray(arg) {
529 return _cof(arg) == 'Array';
530};
531
532var _toObject = function (it) {
533 return Object(_defined(it));
534};
535
536var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
537 _anObject(O);
538
539 var keys = _objectKeys(Properties);
540
541 var length = keys.length;
542 var i = 0;
543 var P;
544
545 while (length > i) _objectDp.f(O, P = keys[i++], Properties[P]);
546
547 return O;
548};
549
550var document$2 = _global.document;
551
552var _html = document$2 && document$2.documentElement;
553
554var IE_PROTO$1 = _sharedKey('IE_PROTO');
555
556var Empty = function () {
557 /* empty */
558};
559
560var PROTOTYPE$1 = 'prototype'; // Create object with fake `null` prototype: use iframe Object with cleared prototype
561
562var createDict = function () {
563 // Thrash, waste and sodomy: IE GC bug
564 var iframe = _domCreate('iframe');
565
566 var i = _enumBugKeys.length;
567 var lt = '<';
568 var gt = '>';
569 var iframeDocument;
570 iframe.style.display = 'none';
571
572 _html.appendChild(iframe);
573
574 iframe.src = 'javascript:'; // eslint-disable-line no-script-url
575 // createDict = iframe.contentWindow.Object;
576 // html.removeChild(iframe);
577
578 iframeDocument = iframe.contentWindow.document;
579 iframeDocument.open();
580 iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
581 iframeDocument.close();
582 createDict = iframeDocument.F;
583
584 while (i--) delete createDict[PROTOTYPE$1][_enumBugKeys[i]];
585
586 return createDict();
587};
588
589var _objectCreate = Object.create || function create(O, Properties) {
590 var result;
591
592 if (O !== null) {
593 Empty[PROTOTYPE$1] = _anObject(O);
594 result = new Empty();
595 Empty[PROTOTYPE$1] = null; // add "__proto__" for Object.getPrototypeOf polyfill
596
597 result[IE_PROTO$1] = O;
598 } else result = createDict();
599
600 return Properties === undefined ? result : _objectDps(result, Properties);
601};
602
603var hiddenKeys = _enumBugKeys.concat('length', 'prototype');
604
605var f$4 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
606 return _objectKeysInternal(O, hiddenKeys);
607};
608
609var _objectGopn = {
610 f: f$4
611};
612var gOPN = _objectGopn.f;
613var toString$1 = {}.toString;
614var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : [];
615
616var getWindowNames = function (it) {
617 try {
618 return gOPN(it);
619 } catch (e) {
620 return windowNames.slice();
621 }
622};
623
624var f$5 = function getOwnPropertyNames(it) {
625 return windowNames && toString$1.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(_toIobject(it));
626};
627
628var _objectGopnExt = {
629 f: f$5
630};
631var gOPD = Object.getOwnPropertyDescriptor;
632var f$6 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) {
633 O = _toIobject(O);
634 P = _toPrimitive(P, true);
635 if (_ie8DomDefine) try {
636 return gOPD(O, P);
637 } catch (e) {
638 /* empty */
639 }
640 if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]);
641};
642var _objectGopd = {
643 f: f$6
644};
645var META = _meta.KEY;
646var gOPD$1 = _objectGopd.f;
647var dP$1 = _objectDp.f;
648var gOPN$1 = _objectGopnExt.f;
649var $Symbol = _global.Symbol;
650var $JSON = _global.JSON;
651
652var _stringify = $JSON && $JSON.stringify;
653
654var PROTOTYPE$2 = 'prototype';
655
656var HIDDEN = _wks('_hidden');
657
658var TO_PRIMITIVE = _wks('toPrimitive');
659
660var isEnum = {}.propertyIsEnumerable;
661
662var SymbolRegistry = _shared('symbol-registry');
663
664var AllSymbols = _shared('symbols');
665
666var OPSymbols = _shared('op-symbols');
667
668var ObjectProto = Object[PROTOTYPE$2];
669var USE_NATIVE = typeof $Symbol == 'function' && !!_objectGops.f;
670var QObject = _global.QObject; // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
671
672var setter = !QObject || !QObject[PROTOTYPE$2] || !QObject[PROTOTYPE$2].findChild; // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
673
674var setSymbolDesc = _descriptors && _fails(function () {
675 return _objectCreate(dP$1({}, 'a', {
676 get: function () {
677 return dP$1(this, 'a', {
678 value: 7
679 }).a;
680 }
681 })).a != 7;
682}) ? function (it, key, D) {
683 var protoDesc = gOPD$1(ObjectProto, key);
684 if (protoDesc) delete ObjectProto[key];
685 dP$1(it, key, D);
686 if (protoDesc && it !== ObjectProto) dP$1(ObjectProto, key, protoDesc);
687} : dP$1;
688
689var wrap = function (tag) {
690 var sym = AllSymbols[tag] = _objectCreate($Symbol[PROTOTYPE$2]);
691
692 sym._k = tag;
693 return sym;
694};
695
696var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {
697 return typeof it == 'symbol';
698} : function (it) {
699 return it instanceof $Symbol;
700};
701
702var $defineProperty = function defineProperty(it, key, D) {
703 if (it === ObjectProto) $defineProperty(OPSymbols, key, D);
704
705 _anObject(it);
706
707 key = _toPrimitive(key, true);
708
709 _anObject(D);
710
711 if (_has(AllSymbols, key)) {
712 if (!D.enumerable) {
713 if (!_has(it, HIDDEN)) dP$1(it, HIDDEN, _propertyDesc(1, {}));
714 it[HIDDEN][key] = true;
715 } else {
716 if (_has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;
717 D = _objectCreate(D, {
718 enumerable: _propertyDesc(0, false)
719 });
720 }
721
722 return setSymbolDesc(it, key, D);
723 }
724
725 return dP$1(it, key, D);
726};
727
728var $defineProperties = function defineProperties(it, P) {
729 _anObject(it);
730
731 var keys = _enumKeys(P = _toIobject(P));
732
733 var i = 0;
734 var l = keys.length;
735 var key;
736
737 while (l > i) $defineProperty(it, key = keys[i++], P[key]);
738
739 return it;
740};
741
742var $create = function create(it, P) {
743 return P === undefined ? _objectCreate(it) : $defineProperties(_objectCreate(it), P);
744};
745
746var $propertyIsEnumerable = function propertyIsEnumerable(key) {
747 var E = isEnum.call(this, key = _toPrimitive(key, true));
748 if (this === ObjectProto && _has(AllSymbols, key) && !_has(OPSymbols, key)) return false;
749 return E || !_has(this, key) || !_has(AllSymbols, key) || _has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
750};
751
752var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {
753 it = _toIobject(it);
754 key = _toPrimitive(key, true);
755 if (it === ObjectProto && _has(AllSymbols, key) && !_has(OPSymbols, key)) return;
756 var D = gOPD$1(it, key);
757 if (D && _has(AllSymbols, key) && !(_has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;
758 return D;
759};
760
761var $getOwnPropertyNames = function getOwnPropertyNames(it) {
762 var names = gOPN$1(_toIobject(it));
763 var result = [];
764 var i = 0;
765 var key;
766
767 while (names.length > i) {
768 if (!_has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);
769 }
770
771 return result;
772};
773
774var $getOwnPropertySymbols = function getOwnPropertySymbols(it) {
775 var IS_OP = it === ObjectProto;
776 var names = gOPN$1(IS_OP ? OPSymbols : _toIobject(it));
777 var result = [];
778 var i = 0;
779 var key;
780
781 while (names.length > i) {
782 if (_has(AllSymbols, key = names[i++]) && (IS_OP ? _has(ObjectProto, key) : true)) result.push(AllSymbols[key]);
783 }
784
785 return result;
786}; // 19.4.1.1 Symbol([description])
787
788
789if (!USE_NATIVE) {
790 $Symbol = function Symbol() {
791 if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');
792
793 var tag = _uid(arguments.length > 0 ? arguments[0] : undefined);
794
795 var $set = function (value) {
796 if (this === ObjectProto) $set.call(OPSymbols, value);
797 if (_has(this, HIDDEN) && _has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
798 setSymbolDesc(this, tag, _propertyDesc(1, value));
799 };
800
801 if (_descriptors && setter) setSymbolDesc(ObjectProto, tag, {
802 configurable: true,
803 set: $set
804 });
805 return wrap(tag);
806 };
807
808 _redefine($Symbol[PROTOTYPE$2], 'toString', function toString() {
809 return this._k;
810 });
811
812 _objectGopd.f = $getOwnPropertyDescriptor;
813 _objectDp.f = $defineProperty;
814 _objectGopn.f = _objectGopnExt.f = $getOwnPropertyNames;
815 _objectPie.f = $propertyIsEnumerable;
816 _objectGops.f = $getOwnPropertySymbols;
817
818 if (_descriptors && !_library) {
819 _redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
820 }
821
822 _wksExt.f = function (name) {
823 return wrap(_wks(name));
824 };
825}
826
827_export(_export.G + _export.W + _export.F * !USE_NATIVE, {
828 Symbol: $Symbol
829});
830
831for (var es6Symbols = // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
832'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'.split(','), j = 0; es6Symbols.length > j;) _wks(es6Symbols[j++]);
833
834for (var wellKnownSymbols = _objectKeys(_wks.store), k = 0; wellKnownSymbols.length > k;) _wksDefine(wellKnownSymbols[k++]);
835
836_export(_export.S + _export.F * !USE_NATIVE, 'Symbol', {
837 // 19.4.2.1 Symbol.for(key)
838 'for': function (key) {
839 return _has(SymbolRegistry, key += '') ? SymbolRegistry[key] : SymbolRegistry[key] = $Symbol(key);
840 },
841 // 19.4.2.5 Symbol.keyFor(sym)
842 keyFor: function keyFor(sym) {
843 if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!');
844
845 for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;
846 },
847 useSetter: function () {
848 setter = true;
849 },
850 useSimple: function () {
851 setter = false;
852 }
853});
854
855_export(_export.S + _export.F * !USE_NATIVE, 'Object', {
856 // 19.1.2.2 Object.create(O [, Properties])
857 create: $create,
858 // 19.1.2.4 Object.defineProperty(O, P, Attributes)
859 defineProperty: $defineProperty,
860 // 19.1.2.3 Object.defineProperties(O, Properties)
861 defineProperties: $defineProperties,
862 // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
863 getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
864 // 19.1.2.7 Object.getOwnPropertyNames(O)
865 getOwnPropertyNames: $getOwnPropertyNames,
866 // 19.1.2.8 Object.getOwnPropertySymbols(O)
867 getOwnPropertySymbols: $getOwnPropertySymbols
868}); // Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
869// https://bugs.chromium.org/p/v8/issues/detail?id=3443
870
871
872var FAILS_ON_PRIMITIVES = _fails(function () {
873 _objectGops.f(1);
874});
875
876_export(_export.S + _export.F * FAILS_ON_PRIMITIVES, 'Object', {
877 getOwnPropertySymbols: function getOwnPropertySymbols(it) {
878 return _objectGops.f(_toObject(it));
879 }
880}); // 24.3.2 JSON.stringify(value [, replacer [, space]])
881
882
883$JSON && _export(_export.S + _export.F * (!USE_NATIVE || _fails(function () {
884 var S = $Symbol(); // MS Edge converts symbol values to JSON as {}
885 // WebKit converts symbol values to JSON as null
886 // V8 throws on boxed symbols
887
888 return _stringify([S]) != '[null]' || _stringify({
889 a: S
890 }) != '{}' || _stringify(Object(S)) != '{}';
891})), 'JSON', {
892 stringify: function stringify(it) {
893 var args = [it];
894 var i = 1;
895 var replacer, $replacer;
896
897 while (arguments.length > i) args.push(arguments[i++]);
898
899 $replacer = replacer = args[1];
900 if (!_isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
901
902 if (!_isArray(replacer)) replacer = function (key, value) {
903 if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
904 if (!isSymbol(value)) return value;
905 };
906 args[1] = replacer;
907 return _stringify.apply($JSON, args);
908 }
909}); // 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
910
911$Symbol[PROTOTYPE$2][TO_PRIMITIVE] || _hide($Symbol[PROTOTYPE$2], TO_PRIMITIVE, $Symbol[PROTOTYPE$2].valueOf); // 19.4.3.5 Symbol.prototype[@@toStringTag]
912
913_setToStringTag($Symbol, 'Symbol'); // 20.2.1.9 Math[@@toStringTag]
914
915
916_setToStringTag(Math, 'Math', true); // 24.3.3 JSON[@@toStringTag]
917
918
919_setToStringTag(_global.JSON, 'JSON', true);
920
921function _typeof(obj) {
922 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
923 _typeof = function (obj) {
924 return typeof obj;
925 };
926 } else {
927 _typeof = function (obj) {
928 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
929 };
930 }
931
932 return _typeof(obj);
933}
934
935function _defineProperty(obj, key, value) {
936 if (key in obj) {
937 Object.defineProperty(obj, key, {
938 value: value,
939 enumerable: true,
940 configurable: true,
941 writable: true
942 });
943 } else {
944 obj[key] = value;
945 }
946
947 return obj;
948}
949
950function ownKeys(object, enumerableOnly) {
951 var keys = Object.keys(object);
952
953 if (Object.getOwnPropertySymbols) {
954 keys.push.apply(keys, Object.getOwnPropertySymbols(object));
955 }
956
957 if (enumerableOnly) keys = keys.filter(function (sym) {
958 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
959 });
960 return keys;
961}
962
963function _objectSpread2(target) {
964 for (var i = 1; i < arguments.length; i++) {
965 var source = arguments[i] != null ? arguments[i] : {};
966
967 if (i % 2) {
968 ownKeys(source, true).forEach(function (key) {
969 _defineProperty(target, key, source[key]);
970 });
971 } else if (Object.getOwnPropertyDescriptors) {
972 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
973 } else {
974 ownKeys(source).forEach(function (key) {
975 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
976 });
977 }
978 }
979
980 return target;
981}
982
983function _toConsumableArray(arr) {
984 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
985}
986
987function _arrayWithoutHoles(arr) {
988 if (Array.isArray(arr)) {
989 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
990
991 return arr2;
992 }
993}
994
995function _iterableToArray(iter) {
996 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
997}
998
999function _nonIterableSpread() {
1000 throw new TypeError("Invalid attempt to spread non-iterable instance");
1001}
1002
1003var _objectSap = function (KEY, exec) {
1004 var fn = (_core.Object || {})[KEY] || Object[KEY];
1005 var exp = {};
1006 exp[KEY] = exec(fn);
1007
1008 _export(_export.S + _export.F * _fails(function () {
1009 fn(1);
1010 }), 'Object', exp);
1011};
1012
1013_objectSap('keys', function () {
1014 return function keys(it) {
1015 return _objectKeys(_toObject(it));
1016 };
1017});
1018
1019var _flags = function () {
1020 var that = _anObject(this);
1021
1022 var result = '';
1023 if (that.global) result += 'g';
1024 if (that.ignoreCase) result += 'i';
1025 if (that.multiline) result += 'm';
1026 if (that.unicode) result += 'u';
1027 if (that.sticky) result += 'y';
1028 return result;
1029};
1030
1031if (_descriptors && /./g.flags != 'g') _objectDp.f(RegExp.prototype, 'flags', {
1032 configurable: true,
1033 get: _flags
1034});
1035var TO_STRING = 'toString';
1036var $toString = /./[TO_STRING];
1037
1038var define = function (fn) {
1039 _redefine(RegExp.prototype, TO_STRING, fn, true);
1040}; // 21.2.5.14 RegExp.prototype.toString()
1041
1042
1043if (_fails(function () {
1044 return $toString.call({
1045 source: 'a',
1046 flags: 'b'
1047 }) != '/a/b';
1048})) {
1049 define(function toString() {
1050 var R = _anObject(this);
1051
1052 return '/'.concat(R.source, '/', 'flags' in R ? R.flags : !_descriptors && R instanceof RegExp ? _flags.call(R) : undefined);
1053 }); // FF44- RegExp#toString has a wrong name
1054} else if ($toString.name != TO_STRING) {
1055 define(function toString() {
1056 return $toString.call(this);
1057 });
1058} // false -> String#codePointAt
1059
1060
1061var _stringAt = function (TO_STRING) {
1062 return function (that, pos) {
1063 var s = String(_defined(that));
1064
1065 var i = _toInteger(pos);
1066
1067 var l = s.length;
1068 var a, b;
1069 if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
1070 a = s.charCodeAt(i);
1071 return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
1072 };
1073};
1074
1075var at = _stringAt(true); // `AdvanceStringIndex` abstract operation
1076// https://tc39.github.io/ecma262/#sec-advancestringindex
1077
1078
1079var _advanceStringIndex = function (S, index, unicode) {
1080 return index + (unicode ? at(S, index).length : 1);
1081};
1082
1083var TAG$1 = _wks('toStringTag'); // ES3 wrong here
1084
1085
1086var ARG = _cof(function () {
1087 return arguments;
1088}()) == 'Arguments'; // fallback for IE11 Script Access Denied error
1089
1090var tryGet = function (it, key) {
1091 try {
1092 return it[key];
1093 } catch (e) {
1094 /* empty */
1095 }
1096};
1097
1098var _classof = function (it) {
1099 var O, T, B;
1100 return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case
1101 : typeof (T = tryGet(O = Object(it), TAG$1)) == 'string' ? T // builtinTag case
1102 : ARG ? _cof(O) // ES3 arguments fallback
1103 : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
1104};
1105
1106var builtinExec = RegExp.prototype.exec; // `RegExpExec` abstract operation
1107// https://tc39.github.io/ecma262/#sec-regexpexec
1108
1109var _regexpExecAbstract = function (R, S) {
1110 var exec = R.exec;
1111
1112 if (typeof exec === 'function') {
1113 var result = exec.call(R, S);
1114
1115 if (typeof result !== 'object') {
1116 throw new TypeError('RegExp exec method returned something other than an Object or null');
1117 }
1118
1119 return result;
1120 }
1121
1122 if (_classof(R) !== 'RegExp') {
1123 throw new TypeError('RegExp#exec called on incompatible receiver');
1124 }
1125
1126 return builtinExec.call(R, S);
1127};
1128
1129var nativeExec = RegExp.prototype.exec; // This always refers to the native implementation, because the
1130// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
1131// which loads this file before patching the method.
1132
1133var nativeReplace = String.prototype.replace;
1134var patchedExec = nativeExec;
1135var LAST_INDEX = 'lastIndex';
1136
1137var UPDATES_LAST_INDEX_WRONG = function () {
1138 var re1 = /a/,
1139 re2 = /b*/g;
1140 nativeExec.call(re1, 'a');
1141 nativeExec.call(re2, 'a');
1142 return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;
1143}(); // nonparticipating capturing group, copied from es5-shim's String#split patch.
1144
1145
1146var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
1147var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
1148
1149if (PATCH) {
1150 patchedExec = function exec(str) {
1151 var re = this;
1152 var lastIndex, reCopy, match, i;
1153
1154 if (NPCG_INCLUDED) {
1155 reCopy = new RegExp('^' + re.source + '$(?!\\s)', _flags.call(re));
1156 }
1157
1158 if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];
1159 match = nativeExec.call(re, str);
1160
1161 if (UPDATES_LAST_INDEX_WRONG && match) {
1162 re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;
1163 }
1164
1165 if (NPCG_INCLUDED && match && match.length > 1) {
1166 // Fix browsers whose `exec` methods don't consistently return `undefined`
1167 // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
1168 // eslint-disable-next-line no-loop-func
1169 nativeReplace.call(match[0], reCopy, function () {
1170 for (i = 1; i < arguments.length - 2; i++) {
1171 if (arguments[i] === undefined) match[i] = undefined;
1172 }
1173 });
1174 }
1175
1176 return match;
1177 };
1178}
1179
1180var _regexpExec = patchedExec;
1181
1182_export({
1183 target: 'RegExp',
1184 proto: true,
1185 forced: _regexpExec !== /./.exec
1186}, {
1187 exec: _regexpExec
1188});
1189
1190var SPECIES = _wks('species');
1191
1192var REPLACE_SUPPORTS_NAMED_GROUPS = !_fails(function () {
1193 // #replace needs built-in support for named groups.
1194 // #match works fine because it just return the exec results, even if it has
1195 // a "grops" property.
1196 var re = /./;
1197
1198 re.exec = function () {
1199 var result = [];
1200 result.groups = {
1201 a: '7'
1202 };
1203 return result;
1204 };
1205
1206 return ''.replace(re, '$<a>') !== '7';
1207});
1208
1209var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = function () {
1210 // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
1211 var re = /(?:)/;
1212 var originalExec = re.exec;
1213
1214 re.exec = function () {
1215 return originalExec.apply(this, arguments);
1216 };
1217
1218 var result = 'ab'.split(re);
1219 return result.length === 2 && result[0] === 'a' && result[1] === 'b';
1220}();
1221
1222var _fixReWks = function (KEY, length, exec) {
1223 var SYMBOL = _wks(KEY);
1224
1225 var DELEGATES_TO_SYMBOL = !_fails(function () {
1226 // String methods call symbol-named RegEp methods
1227 var O = {};
1228
1229 O[SYMBOL] = function () {
1230 return 7;
1231 };
1232
1233 return ''[KEY](O) != 7;
1234 });
1235 var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !_fails(function () {
1236 // Symbol-named RegExp methods call .exec
1237 var execCalled = false;
1238 var re = /a/;
1239
1240 re.exec = function () {
1241 execCalled = true;
1242 return null;
1243 };
1244
1245 if (KEY === 'split') {
1246 // RegExp[@@split] doesn't call the regex's exec method, but first creates
1247 // a new one. We need to return the patched regex when creating the new one.
1248 re.constructor = {};
1249
1250 re.constructor[SPECIES] = function () {
1251 return re;
1252 };
1253 }
1254
1255 re[SYMBOL]('');
1256 return !execCalled;
1257 }) : undefined;
1258
1259 if (!DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS || KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC) {
1260 var nativeRegExpMethod = /./[SYMBOL];
1261 var fns = exec(_defined, SYMBOL, ''[KEY], function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {
1262 if (regexp.exec === _regexpExec) {
1263 if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
1264 // The native String method already delegates to @@method (this
1265 // polyfilled function), leasing to infinite recursion.
1266 // We avoid it by directly calling the native @@method method.
1267 return {
1268 done: true,
1269 value: nativeRegExpMethod.call(regexp, str, arg2)
1270 };
1271 }
1272
1273 return {
1274 done: true,
1275 value: nativeMethod.call(str, regexp, arg2)
1276 };
1277 }
1278
1279 return {
1280 done: false
1281 };
1282 });
1283 var strfn = fns[0];
1284 var rxfn = fns[1];
1285
1286 _redefine(String.prototype, KEY, strfn);
1287
1288 _hide(RegExp.prototype, SYMBOL, length == 2 // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
1289 // 21.2.5.11 RegExp.prototype[@@split](string, limit)
1290 ? function (string, arg) {
1291 return rxfn.call(string, this, arg);
1292 } // 21.2.5.6 RegExp.prototype[@@match](string)
1293 // 21.2.5.9 RegExp.prototype[@@search](string)
1294 : function (string) {
1295 return rxfn.call(string, this);
1296 });
1297 }
1298};
1299
1300var max$1 = Math.max;
1301var min$2 = Math.min;
1302var floor$1 = Math.floor;
1303var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g;
1304var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g;
1305
1306var maybeToString = function (it) {
1307 return it === undefined ? it : String(it);
1308}; // @@replace logic
1309
1310
1311_fixReWks('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {
1312 return [// `String.prototype.replace` method
1313 // https://tc39.github.io/ecma262/#sec-string.prototype.replace
1314 function replace(searchValue, replaceValue) {
1315 var O = defined(this);
1316 var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
1317 return fn !== undefined ? fn.call(searchValue, O, replaceValue) : $replace.call(String(O), searchValue, replaceValue);
1318 }, // `RegExp.prototype[@@replace]` method
1319 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
1320 function (regexp, replaceValue) {
1321 var res = maybeCallNative($replace, regexp, this, replaceValue);
1322 if (res.done) return res.value;
1323
1324 var rx = _anObject(regexp);
1325
1326 var S = String(this);
1327 var functionalReplace = typeof replaceValue === 'function';
1328 if (!functionalReplace) replaceValue = String(replaceValue);
1329 var global = rx.global;
1330
1331 if (global) {
1332 var fullUnicode = rx.unicode;
1333 rx.lastIndex = 0;
1334 }
1335
1336 var results = [];
1337
1338 while (true) {
1339 var result = _regexpExecAbstract(rx, S);
1340
1341 if (result === null) break;
1342 results.push(result);
1343 if (!global) break;
1344 var matchStr = String(result[0]);
1345 if (matchStr === '') rx.lastIndex = _advanceStringIndex(S, _toLength(rx.lastIndex), fullUnicode);
1346 }
1347
1348 var accumulatedResult = '';
1349 var nextSourcePosition = 0;
1350
1351 for (var i = 0; i < results.length; i++) {
1352 result = results[i];
1353 var matched = String(result[0]);
1354 var position = max$1(min$2(_toInteger(result.index), S.length), 0);
1355 var captures = []; // NOTE: This is equivalent to
1356 // captures = result.slice(1).map(maybeToString)
1357 // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
1358 // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
1359 // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
1360
1361 for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
1362
1363 var namedCaptures = result.groups;
1364
1365 if (functionalReplace) {
1366 var replacerArgs = [matched].concat(captures, position, S);
1367 if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
1368 var replacement = String(replaceValue.apply(undefined, replacerArgs));
1369 } else {
1370 replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
1371 }
1372
1373 if (position >= nextSourcePosition) {
1374 accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
1375 nextSourcePosition = position + matched.length;
1376 }
1377 }
1378
1379 return accumulatedResult + S.slice(nextSourcePosition);
1380 }]; // https://tc39.github.io/ecma262/#sec-getsubstitution
1381
1382 function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
1383 var tailPos = position + matched.length;
1384 var m = captures.length;
1385 var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
1386
1387 if (namedCaptures !== undefined) {
1388 namedCaptures = _toObject(namedCaptures);
1389 symbols = SUBSTITUTION_SYMBOLS;
1390 }
1391
1392 return $replace.call(replacement, symbols, function (match, ch) {
1393 var capture;
1394
1395 switch (ch.charAt(0)) {
1396 case '$':
1397 return '$';
1398
1399 case '&':
1400 return matched;
1401
1402 case '`':
1403 return str.slice(0, position);
1404
1405 case "'":
1406 return str.slice(tailPos);
1407
1408 case '<':
1409 capture = namedCaptures[ch.slice(1, -1)];
1410 break;
1411
1412 default:
1413 // \d\d?
1414 var n = +ch;
1415 if (n === 0) return match;
1416
1417 if (n > m) {
1418 var f = floor$1(n / 10);
1419 if (f === 0) return match;
1420 if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
1421 return match;
1422 }
1423
1424 capture = captures[n - 1];
1425 }
1426
1427 return capture === undefined ? '' : capture;
1428 });
1429 }
1430});
1431
1432var UNSCOPABLES = _wks('unscopables');
1433
1434var ArrayProto = Array.prototype;
1435if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {});
1436
1437var _addToUnscopables = function (key) {
1438 ArrayProto[UNSCOPABLES][key] = true;
1439};
1440
1441var _iterStep = function (done, value) {
1442 return {
1443 value: value,
1444 done: !!done
1445 };
1446};
1447
1448var _iterators = {};
1449var IteratorPrototype = {}; // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
1450
1451_hide(IteratorPrototype, _wks('iterator'), function () {
1452 return this;
1453});
1454
1455var _iterCreate = function (Constructor, NAME, next) {
1456 Constructor.prototype = _objectCreate(IteratorPrototype, {
1457 next: _propertyDesc(1, next)
1458 });
1459
1460 _setToStringTag(Constructor, NAME + ' Iterator');
1461};
1462
1463var IE_PROTO$2 = _sharedKey('IE_PROTO');
1464
1465var ObjectProto$1 = Object.prototype;
1466
1467var _objectGpo = Object.getPrototypeOf || function (O) {
1468 O = _toObject(O);
1469 if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2];
1470
1471 if (typeof O.constructor == 'function' && O instanceof O.constructor) {
1472 return O.constructor.prototype;
1473 }
1474
1475 return O instanceof Object ? ObjectProto$1 : null;
1476};
1477
1478var ITERATOR = _wks('iterator');
1479
1480var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
1481
1482var FF_ITERATOR = '@@iterator';
1483var KEYS = 'keys';
1484var VALUES = 'values';
1485
1486var returnThis = function () {
1487 return this;
1488};
1489
1490var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
1491 _iterCreate(Constructor, NAME, next);
1492
1493 var getMethod = function (kind) {
1494 if (!BUGGY && kind in proto) return proto[kind];
1495
1496 switch (kind) {
1497 case KEYS:
1498 return function keys() {
1499 return new Constructor(this, kind);
1500 };
1501
1502 case VALUES:
1503 return function values() {
1504 return new Constructor(this, kind);
1505 };
1506 }
1507
1508 return function entries() {
1509 return new Constructor(this, kind);
1510 };
1511 };
1512
1513 var TAG = NAME + ' Iterator';
1514 var DEF_VALUES = DEFAULT == VALUES;
1515 var VALUES_BUG = false;
1516 var proto = Base.prototype;
1517 var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
1518 var $default = $native || getMethod(DEFAULT);
1519 var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
1520 var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
1521 var methods, key, IteratorPrototype; // Fix native
1522
1523 if ($anyNative) {
1524 IteratorPrototype = _objectGpo($anyNative.call(new Base()));
1525
1526 if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
1527 // Set @@toStringTag to native iterators
1528 _setToStringTag(IteratorPrototype, TAG, true); // fix for some old engines
1529
1530
1531 if (typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis);
1532 }
1533 } // fix Array#{values, @@iterator}.name in V8 / FF
1534
1535
1536 if (DEF_VALUES && $native && $native.name !== VALUES) {
1537 VALUES_BUG = true;
1538
1539 $default = function values() {
1540 return $native.call(this);
1541 };
1542 } // Define iterator
1543
1544
1545 if (BUGGY || VALUES_BUG || !proto[ITERATOR]) {
1546 _hide(proto, ITERATOR, $default);
1547 } // Plug for library
1548
1549
1550 _iterators[NAME] = $default;
1551 _iterators[TAG] = returnThis;
1552
1553 if (DEFAULT) {
1554 methods = {
1555 values: DEF_VALUES ? $default : getMethod(VALUES),
1556 keys: IS_SET ? $default : getMethod(KEYS),
1557 entries: $entries
1558 };
1559 if (FORCED) for (key in methods) {
1560 if (!(key in proto)) _redefine(proto, key, methods[key]);
1561 } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
1562 }
1563
1564 return methods;
1565}; // 22.1.3.13 Array.prototype.keys()
1566// 22.1.3.29 Array.prototype.values()
1567// 22.1.3.30 Array.prototype[@@iterator]()
1568
1569
1570var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
1571 this._t = _toIobject(iterated); // target
1572
1573 this._i = 0; // next index
1574
1575 this._k = kind; // kind
1576 // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
1577}, function () {
1578 var O = this._t;
1579 var kind = this._k;
1580 var index = this._i++;
1581
1582 if (!O || index >= O.length) {
1583 this._t = undefined;
1584 return _iterStep(1);
1585 }
1586
1587 if (kind == 'keys') return _iterStep(0, index);
1588 if (kind == 'values') return _iterStep(0, O[index]);
1589 return _iterStep(0, [index, O[index]]);
1590}, 'values'); // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
1591
1592
1593_iterators.Arguments = _iterators.Array;
1594
1595_addToUnscopables('keys');
1596
1597_addToUnscopables('values');
1598
1599_addToUnscopables('entries');
1600
1601var ITERATOR$1 = _wks('iterator');
1602
1603var TO_STRING_TAG = _wks('toStringTag');
1604
1605var ArrayValues = _iterators.Array;
1606var DOMIterables = {
1607 CSSRuleList: true,
1608 // TODO: Not spec compliant, should be false.
1609 CSSStyleDeclaration: false,
1610 CSSValueList: false,
1611 ClientRectList: false,
1612 DOMRectList: false,
1613 DOMStringList: false,
1614 DOMTokenList: true,
1615 DataTransferItemList: false,
1616 FileList: false,
1617 HTMLAllCollection: false,
1618 HTMLCollection: false,
1619 HTMLFormElement: false,
1620 HTMLSelectElement: false,
1621 MediaList: true,
1622 // TODO: Not spec compliant, should be false.
1623 MimeTypeArray: false,
1624 NamedNodeMap: false,
1625 NodeList: true,
1626 PaintRequestList: false,
1627 Plugin: false,
1628 PluginArray: false,
1629 SVGLengthList: false,
1630 SVGNumberList: false,
1631 SVGPathSegList: false,
1632 SVGPointList: false,
1633 SVGStringList: false,
1634 SVGTransformList: false,
1635 SourceBufferList: false,
1636 StyleSheetList: true,
1637 // TODO: Not spec compliant, should be false.
1638 TextTrackCueList: false,
1639 TextTrackList: false,
1640 TouchList: false
1641};
1642
1643for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
1644 var NAME = collections[i];
1645 var explicit = DOMIterables[NAME];
1646 var Collection = _global[NAME];
1647 var proto = Collection && Collection.prototype;
1648 var key;
1649
1650 if (proto) {
1651 if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues);
1652 if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME);
1653 _iterators[NAME] = ArrayValues;
1654 if (explicit) for (key in es6_array_iterator) if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true);
1655 }
1656}
1657
1658var test = {};
1659test[_wks('toStringTag')] = 'z';
1660
1661if (test + '' != '[object z]') {
1662 _redefine(Object.prototype, 'toString', function toString() {
1663 return '[object ' + _classof(this) + ']';
1664 }, true);
1665}
1666
1667var isEnum$1 = _objectPie.f;
1668
1669var _objectToArray = function (isEntries) {
1670 return function (it) {
1671 var O = _toIobject(it);
1672
1673 var keys = _objectKeys(O);
1674
1675 var length = keys.length;
1676 var i = 0;
1677 var result = [];
1678 var key;
1679
1680 while (length > i) {
1681 key = keys[i++];
1682
1683 if (!_descriptors || isEnum$1.call(O, key)) {
1684 result.push(isEntries ? [key, O[key]] : O[key]);
1685 }
1686 }
1687
1688 return result;
1689 };
1690};
1691
1692var $values = _objectToArray(false);
1693
1694_export(_export.S, 'Object', {
1695 values: function values(it) {
1696 return $values(it);
1697 }
1698});
1699
1700var MATCH = _wks('match');
1701
1702var _isRegexp = function (it) {
1703 var isRegExp;
1704 return _isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : _cof(it) == 'RegExp');
1705};
1706
1707var SPECIES$1 = _wks('species');
1708
1709var _speciesConstructor = function (O, D) {
1710 var C = _anObject(O).constructor;
1711
1712 var S;
1713 return C === undefined || (S = _anObject(C)[SPECIES$1]) == undefined ? D : _aFunction(S);
1714};
1715
1716var $min = Math.min;
1717var $push = [].push;
1718var $SPLIT = 'split';
1719var LENGTH = 'length';
1720var LAST_INDEX$1 = 'lastIndex';
1721var MAX_UINT32 = 0xffffffff; // babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
1722
1723var SUPPORTS_Y = !_fails(function () {
1724 RegExp(MAX_UINT32, 'y');
1725}); // @@split logic
1726
1727_fixReWks('split', 2, function (defined, SPLIT, $split, maybeCallNative) {
1728 var internalSplit;
1729
1730 if ('abbc'[$SPLIT](/(b)*/)[1] == 'c' || 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 || 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 || '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 || '.'[$SPLIT](/()()/)[LENGTH] > 1 || ''[$SPLIT](/.?/)[LENGTH]) {
1731 // based on es5-shim implementation, need to rework it
1732 internalSplit = function (separator, limit) {
1733 var string = String(this);
1734 if (separator === undefined && limit === 0) return []; // If `separator` is not a regex, use native split
1735
1736 if (!_isRegexp(separator)) return $split.call(string, separator, limit);
1737 var output = [];
1738 var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + (separator.sticky ? 'y' : '');
1739 var lastLastIndex = 0;
1740 var splitLimit = limit === undefined ? MAX_UINT32 : limit >>> 0; // Make `global` and avoid `lastIndex` issues by working with a copy
1741
1742 var separatorCopy = new RegExp(separator.source, flags + 'g');
1743 var match, lastIndex, lastLength;
1744
1745 while (match = _regexpExec.call(separatorCopy, string)) {
1746 lastIndex = separatorCopy[LAST_INDEX$1];
1747
1748 if (lastIndex > lastLastIndex) {
1749 output.push(string.slice(lastLastIndex, match.index));
1750 if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));
1751 lastLength = match[0][LENGTH];
1752 lastLastIndex = lastIndex;
1753 if (output[LENGTH] >= splitLimit) break;
1754 }
1755
1756 if (separatorCopy[LAST_INDEX$1] === match.index) separatorCopy[LAST_INDEX$1]++; // Avoid an infinite loop
1757 }
1758
1759 if (lastLastIndex === string[LENGTH]) {
1760 if (lastLength || !separatorCopy.test('')) output.push('');
1761 } else output.push(string.slice(lastLastIndex));
1762
1763 return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
1764 }; // Chakra, V8
1765
1766 } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {
1767 internalSplit = function (separator, limit) {
1768 return separator === undefined && limit === 0 ? [] : $split.call(this, separator, limit);
1769 };
1770 } else {
1771 internalSplit = $split;
1772 }
1773
1774 return [// `String.prototype.split` method
1775 // https://tc39.github.io/ecma262/#sec-string.prototype.split
1776 function split(separator, limit) {
1777 var O = defined(this);
1778 var splitter = separator == undefined ? undefined : separator[SPLIT];
1779 return splitter !== undefined ? splitter.call(separator, O, limit) : internalSplit.call(String(O), separator, limit);
1780 }, // `RegExp.prototype[@@split]` method
1781 // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
1782 //
1783 // NOTE: This cannot be properly polyfilled in engines that don't support
1784 // the 'y' flag.
1785 function (regexp, limit) {
1786 var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== $split);
1787 if (res.done) return res.value;
1788
1789 var rx = _anObject(regexp);
1790
1791 var S = String(this);
1792
1793 var C = _speciesConstructor(rx, RegExp);
1794
1795 var unicodeMatching = rx.unicode;
1796 var flags = (rx.ignoreCase ? 'i' : '') + (rx.multiline ? 'm' : '') + (rx.unicode ? 'u' : '') + (SUPPORTS_Y ? 'y' : 'g'); // ^(? + rx + ) is needed, in combination with some S slicing, to
1797 // simulate the 'y' flag.
1798
1799 var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
1800 var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
1801 if (lim === 0) return [];
1802 if (S.length === 0) return _regexpExecAbstract(splitter, S) === null ? [S] : [];
1803 var p = 0;
1804 var q = 0;
1805 var A = [];
1806
1807 while (q < S.length) {
1808 splitter.lastIndex = SUPPORTS_Y ? q : 0;
1809
1810 var z = _regexpExecAbstract(splitter, SUPPORTS_Y ? S : S.slice(q));
1811
1812 var e;
1813
1814 if (z === null || (e = $min(_toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p) {
1815 q = _advanceStringIndex(S, q, unicodeMatching);
1816 } else {
1817 A.push(S.slice(p, q));
1818 if (A.length === lim) return A;
1819
1820 for (var i = 1; i <= z.length - 1; i++) {
1821 A.push(z[i]);
1822 if (A.length === lim) return A;
1823 }
1824
1825 q = p = e;
1826 }
1827 }
1828
1829 A.push(S.slice(p));
1830 return A;
1831 }];
1832});
1833
1834var $assign = Object.assign; // should work with symbols and should have deterministic property order (V8 bug)
1835
1836var _objectAssign = !$assign || _fails(function () {
1837 var A = {};
1838 var B = {}; // eslint-disable-next-line no-undef
1839
1840 var S = Symbol();
1841 var K = 'abcdefghijklmnopqrst';
1842 A[S] = 7;
1843 K.split('').forEach(function (k) {
1844 B[k] = k;
1845 });
1846 return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
1847}) ? function assign(target, source) {
1848 // eslint-disable-line no-unused-vars
1849 var T = _toObject(target);
1850
1851 var aLen = arguments.length;
1852 var index = 1;
1853 var getSymbols = _objectGops.f;
1854 var isEnum = _objectPie.f;
1855
1856 while (aLen > index) {
1857 var S = _iobject(arguments[index++]);
1858
1859 var keys = getSymbols ? _objectKeys(S).concat(getSymbols(S)) : _objectKeys(S);
1860 var length = keys.length;
1861 var j = 0;
1862 var key;
1863
1864 while (length > j) {
1865 key = keys[j++];
1866 if (!_descriptors || isEnum.call(S, key)) T[key] = S[key];
1867 }
1868 }
1869
1870 return T;
1871} : $assign;
1872
1873_export(_export.S + _export.F, 'Object', {
1874 assign: _objectAssign
1875});
1876/* eslint-disable no-proto */
1877
1878
1879var check = function (O, proto) {
1880 _anObject(O);
1881
1882 if (!_isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
1883};
1884
1885var _setProto = {
1886 set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
1887 function (test, buggy, set) {
1888 try {
1889 set = _ctx(Function.call, _objectGopd.f(Object.prototype, '__proto__').set, 2);
1890 set(test, []);
1891 buggy = !(test instanceof Array);
1892 } catch (e) {
1893 buggy = true;
1894 }
1895
1896 return function setPrototypeOf(O, proto) {
1897 check(O, proto);
1898 if (buggy) O.__proto__ = proto;else set(O, proto);
1899 return O;
1900 };
1901 }({}, false) : undefined),
1902 check: check
1903};
1904var setPrototypeOf = _setProto.set;
1905
1906var _inheritIfRequired = function (that, target, C) {
1907 var S = target.constructor;
1908 var P;
1909
1910 if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && _isObject(P) && setPrototypeOf) {
1911 setPrototypeOf(that, P);
1912 }
1913
1914 return that;
1915};
1916
1917var _stringWs = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
1918
1919var space = '[' + _stringWs + ']';
1920var non = '\u200b\u0085';
1921var ltrim = RegExp('^' + space + space + '*');
1922var rtrim = RegExp(space + space + '*$');
1923
1924var exporter = function (KEY, exec, ALIAS) {
1925 var exp = {};
1926
1927 var FORCE = _fails(function () {
1928 return !!_stringWs[KEY]() || non[KEY]() != non;
1929 });
1930
1931 var fn = exp[KEY] = FORCE ? exec(trim) : _stringWs[KEY];
1932 if (ALIAS) exp[ALIAS] = fn;
1933
1934 _export(_export.P + _export.F * FORCE, 'String', exp);
1935}; // 1 -> String#trimLeft
1936// 2 -> String#trimRight
1937// 3 -> String#trim
1938
1939
1940var trim = exporter.trim = function (string, TYPE) {
1941 string = String(_defined(string));
1942 if (TYPE & 1) string = string.replace(ltrim, '');
1943 if (TYPE & 2) string = string.replace(rtrim, '');
1944 return string;
1945};
1946
1947var _stringTrim = exporter;
1948var gOPN$2 = _objectGopn.f;
1949var gOPD$2 = _objectGopd.f;
1950var dP$2 = _objectDp.f;
1951var $trim = _stringTrim.trim;
1952var NUMBER = 'Number';
1953var $Number = _global[NUMBER];
1954var Base = $Number;
1955var proto$1 = $Number.prototype; // Opera ~12 has broken Object#toString
1956
1957var BROKEN_COF = _cof(_objectCreate(proto$1)) == NUMBER;
1958var TRIM = 'trim' in String.prototype; // 7.1.3 ToNumber(argument)
1959
1960var toNumber = function (argument) {
1961 var it = _toPrimitive(argument, false);
1962
1963 if (typeof it == 'string' && it.length > 2) {
1964 it = TRIM ? it.trim() : $trim(it, 3);
1965 var first = it.charCodeAt(0);
1966 var third, radix, maxCode;
1967
1968 if (first === 43 || first === 45) {
1969 third = it.charCodeAt(2);
1970 if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
1971 } else if (first === 48) {
1972 switch (it.charCodeAt(1)) {
1973 case 66:
1974 case 98:
1975 radix = 2;
1976 maxCode = 49;
1977 break;
1978 // fast equal /^0b[01]+$/i
1979
1980 case 79:
1981 case 111:
1982 radix = 8;
1983 maxCode = 55;
1984 break;
1985 // fast equal /^0o[0-7]+$/i
1986
1987 default:
1988 return +it;
1989 }
1990
1991 for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {
1992 code = digits.charCodeAt(i); // parseInt parses a string to a first unavailable symbol
1993 // but ToNumber should return NaN if a string contains unavailable symbols
1994
1995 if (code < 48 || code > maxCode) return NaN;
1996 }
1997
1998 return parseInt(digits, radix);
1999 }
2000 }
2001
2002 return +it;
2003};
2004
2005if (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {
2006 $Number = function Number(value) {
2007 var it = arguments.length < 1 ? 0 : value;
2008 var that = this;
2009 return that instanceof $Number // check on 1..constructor(foo) case
2010 && (BROKEN_COF ? _fails(function () {
2011 proto$1.valueOf.call(that);
2012 }) : _cof(that) != NUMBER) ? _inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);
2013 };
2014
2015 for (var keys = _descriptors ? gOPN$2(Base) : ( // ES3:
2016 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + // ES6 (in case, if modules with ES6 Number statics required before):
2017 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' + 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger').split(','), j$1 = 0, key$1; keys.length > j$1; j$1++) {
2018 if (_has(Base, key$1 = keys[j$1]) && !_has($Number, key$1)) {
2019 dP$2($Number, key$1, gOPD$2(Base, key$1));
2020 }
2021 }
2022
2023 $Number.prototype = proto$1;
2024 proto$1.constructor = $Number;
2025
2026 _redefine(_global, NUMBER, $Number);
2027}
2028
2029var moment = createCommonjsModule(function (module, exports) {
2030 (function (global, factory) {
2031 module.exports = factory();
2032 })(commonjsGlobal, function () {
2033 var hookCallback;
2034
2035 function hooks() {
2036 return hookCallback.apply(null, arguments);
2037 } // This is done to register the method called with moment()
2038 // without creating circular dependencies.
2039
2040
2041 function setHookCallback(callback) {
2042 hookCallback = callback;
2043 }
2044
2045 function isArray(input) {
2046 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
2047 }
2048
2049 function isObject(input) {
2050 // IE8 will treat undefined and null as object if it wasn't for
2051 // input != null
2052 return input != null && Object.prototype.toString.call(input) === '[object Object]';
2053 }
2054
2055 function isObjectEmpty(obj) {
2056 if (Object.getOwnPropertyNames) {
2057 return Object.getOwnPropertyNames(obj).length === 0;
2058 } else {
2059 var k;
2060
2061 for (k in obj) {
2062 if (obj.hasOwnProperty(k)) {
2063 return false;
2064 }
2065 }
2066
2067 return true;
2068 }
2069 }
2070
2071 function isUndefined(input) {
2072 return input === void 0;
2073 }
2074
2075 function isNumber(input) {
2076 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
2077 }
2078
2079 function isDate(input) {
2080 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
2081 }
2082
2083 function map(arr, fn) {
2084 var res = [],
2085 i;
2086
2087 for (i = 0; i < arr.length; ++i) {
2088 res.push(fn(arr[i], i));
2089 }
2090
2091 return res;
2092 }
2093
2094 function hasOwnProp(a, b) {
2095 return Object.prototype.hasOwnProperty.call(a, b);
2096 }
2097
2098 function extend(a, b) {
2099 for (var i in b) {
2100 if (hasOwnProp(b, i)) {
2101 a[i] = b[i];
2102 }
2103 }
2104
2105 if (hasOwnProp(b, 'toString')) {
2106 a.toString = b.toString;
2107 }
2108
2109 if (hasOwnProp(b, 'valueOf')) {
2110 a.valueOf = b.valueOf;
2111 }
2112
2113 return a;
2114 }
2115
2116 function createUTC(input, format, locale, strict) {
2117 return createLocalOrUTC(input, format, locale, strict, true).utc();
2118 }
2119
2120 function defaultParsingFlags() {
2121 // We need to deep clone this object.
2122 return {
2123 empty: false,
2124 unusedTokens: [],
2125 unusedInput: [],
2126 overflow: -2,
2127 charsLeftOver: 0,
2128 nullInput: false,
2129 invalidMonth: null,
2130 invalidFormat: false,
2131 userInvalidated: false,
2132 iso: false,
2133 parsedDateParts: [],
2134 meridiem: null,
2135 rfc2822: false,
2136 weekdayMismatch: false
2137 };
2138 }
2139
2140 function getParsingFlags(m) {
2141 if (m._pf == null) {
2142 m._pf = defaultParsingFlags();
2143 }
2144
2145 return m._pf;
2146 }
2147
2148 var some;
2149
2150 if (Array.prototype.some) {
2151 some = Array.prototype.some;
2152 } else {
2153 some = function (fun) {
2154 var t = Object(this);
2155 var len = t.length >>> 0;
2156
2157 for (var i = 0; i < len; i++) {
2158 if (i in t && fun.call(this, t[i], i, t)) {
2159 return true;
2160 }
2161 }
2162
2163 return false;
2164 };
2165 }
2166
2167 function isValid(m) {
2168 if (m._isValid == null) {
2169 var flags = getParsingFlags(m);
2170 var parsedParts = some.call(flags.parsedDateParts, function (i) {
2171 return i != null;
2172 });
2173 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);
2174
2175 if (m._strict) {
2176 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
2177 }
2178
2179 if (Object.isFrozen == null || !Object.isFrozen(m)) {
2180 m._isValid = isNowValid;
2181 } else {
2182 return isNowValid;
2183 }
2184 }
2185
2186 return m._isValid;
2187 }
2188
2189 function createInvalid(flags) {
2190 var m = createUTC(NaN);
2191
2192 if (flags != null) {
2193 extend(getParsingFlags(m), flags);
2194 } else {
2195 getParsingFlags(m).userInvalidated = true;
2196 }
2197
2198 return m;
2199 } // Plugins that add properties should also add the key here (null value),
2200 // so we can properly clone ourselves.
2201
2202
2203 var momentProperties = hooks.momentProperties = [];
2204
2205 function copyConfig(to, from) {
2206 var i, prop, val;
2207
2208 if (!isUndefined(from._isAMomentObject)) {
2209 to._isAMomentObject = from._isAMomentObject;
2210 }
2211
2212 if (!isUndefined(from._i)) {
2213 to._i = from._i;
2214 }
2215
2216 if (!isUndefined(from._f)) {
2217 to._f = from._f;
2218 }
2219
2220 if (!isUndefined(from._l)) {
2221 to._l = from._l;
2222 }
2223
2224 if (!isUndefined(from._strict)) {
2225 to._strict = from._strict;
2226 }
2227
2228 if (!isUndefined(from._tzm)) {
2229 to._tzm = from._tzm;
2230 }
2231
2232 if (!isUndefined(from._isUTC)) {
2233 to._isUTC = from._isUTC;
2234 }
2235
2236 if (!isUndefined(from._offset)) {
2237 to._offset = from._offset;
2238 }
2239
2240 if (!isUndefined(from._pf)) {
2241 to._pf = getParsingFlags(from);
2242 }
2243
2244 if (!isUndefined(from._locale)) {
2245 to._locale = from._locale;
2246 }
2247
2248 if (momentProperties.length > 0) {
2249 for (i = 0; i < momentProperties.length; i++) {
2250 prop = momentProperties[i];
2251 val = from[prop];
2252
2253 if (!isUndefined(val)) {
2254 to[prop] = val;
2255 }
2256 }
2257 }
2258
2259 return to;
2260 }
2261
2262 var updateInProgress = false; // Moment prototype object
2263
2264 function Moment(config) {
2265 copyConfig(this, config);
2266 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
2267
2268 if (!this.isValid()) {
2269 this._d = new Date(NaN);
2270 } // Prevent infinite loop in case updateOffset creates new moment
2271 // objects.
2272
2273
2274 if (updateInProgress === false) {
2275 updateInProgress = true;
2276 hooks.updateOffset(this);
2277 updateInProgress = false;
2278 }
2279 }
2280
2281 function isMoment(obj) {
2282 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
2283 }
2284
2285 function absFloor(number) {
2286 if (number < 0) {
2287 // -0 -> 0
2288 return Math.ceil(number) || 0;
2289 } else {
2290 return Math.floor(number);
2291 }
2292 }
2293
2294 function toInt(argumentForCoercion) {
2295 var coercedNumber = +argumentForCoercion,
2296 value = 0;
2297
2298 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
2299 value = absFloor(coercedNumber);
2300 }
2301
2302 return value;
2303 } // compare two arrays, return the number of differences
2304
2305
2306 function compareArrays(array1, array2, dontConvert) {
2307 var len = Math.min(array1.length, array2.length),
2308 lengthDiff = Math.abs(array1.length - array2.length),
2309 diffs = 0,
2310 i;
2311
2312 for (i = 0; i < len; i++) {
2313 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
2314 diffs++;
2315 }
2316 }
2317
2318 return diffs + lengthDiff;
2319 }
2320
2321 function warn(msg) {
2322 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
2323 console.warn('Deprecation warning: ' + msg);
2324 }
2325 }
2326
2327 function deprecate(msg, fn) {
2328 var firstTime = true;
2329 return extend(function () {
2330 if (hooks.deprecationHandler != null) {
2331 hooks.deprecationHandler(null, msg);
2332 }
2333
2334 if (firstTime) {
2335 var args = [];
2336 var arg;
2337
2338 for (var i = 0; i < arguments.length; i++) {
2339 arg = '';
2340
2341 if (typeof arguments[i] === 'object') {
2342 arg += '\n[' + i + '] ';
2343
2344 for (var key in arguments[0]) {
2345 arg += key + ': ' + arguments[0][key] + ', ';
2346 }
2347
2348 arg = arg.slice(0, -2); // Remove trailing comma and space
2349 } else {
2350 arg = arguments[i];
2351 }
2352
2353 args.push(arg);
2354 }
2355
2356 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
2357 firstTime = false;
2358 }
2359
2360 return fn.apply(this, arguments);
2361 }, fn);
2362 }
2363
2364 var deprecations = {};
2365
2366 function deprecateSimple(name, msg) {
2367 if (hooks.deprecationHandler != null) {
2368 hooks.deprecationHandler(name, msg);
2369 }
2370
2371 if (!deprecations[name]) {
2372 warn(msg);
2373 deprecations[name] = true;
2374 }
2375 }
2376
2377 hooks.suppressDeprecationWarnings = false;
2378 hooks.deprecationHandler = null;
2379
2380 function isFunction(input) {
2381 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
2382 }
2383
2384 function set(config) {
2385 var prop, i;
2386
2387 for (i in config) {
2388 prop = config[i];
2389
2390 if (isFunction(prop)) {
2391 this[i] = prop;
2392 } else {
2393 this['_' + i] = prop;
2394 }
2395 }
2396
2397 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
2398 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
2399 // TODO: Remove "ordinalParse" fallback in next major release.
2400
2401 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
2402 }
2403
2404 function mergeConfigs(parentConfig, childConfig) {
2405 var res = extend({}, parentConfig),
2406 prop;
2407
2408 for (prop in childConfig) {
2409 if (hasOwnProp(childConfig, prop)) {
2410 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
2411 res[prop] = {};
2412 extend(res[prop], parentConfig[prop]);
2413 extend(res[prop], childConfig[prop]);
2414 } else if (childConfig[prop] != null) {
2415 res[prop] = childConfig[prop];
2416 } else {
2417 delete res[prop];
2418 }
2419 }
2420 }
2421
2422 for (prop in parentConfig) {
2423 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
2424 // make sure changes to properties don't modify parent config
2425 res[prop] = extend({}, res[prop]);
2426 }
2427 }
2428
2429 return res;
2430 }
2431
2432 function Locale(config) {
2433 if (config != null) {
2434 this.set(config);
2435 }
2436 }
2437
2438 var keys;
2439
2440 if (Object.keys) {
2441 keys = Object.keys;
2442 } else {
2443 keys = function (obj) {
2444 var i,
2445 res = [];
2446
2447 for (i in obj) {
2448 if (hasOwnProp(obj, i)) {
2449 res.push(i);
2450 }
2451 }
2452
2453 return res;
2454 };
2455 }
2456
2457 var defaultCalendar = {
2458 sameDay: '[Today at] LT',
2459 nextDay: '[Tomorrow at] LT',
2460 nextWeek: 'dddd [at] LT',
2461 lastDay: '[Yesterday at] LT',
2462 lastWeek: '[Last] dddd [at] LT',
2463 sameElse: 'L'
2464 };
2465
2466 function calendar(key, mom, now) {
2467 var output = this._calendar[key] || this._calendar['sameElse'];
2468 return isFunction(output) ? output.call(mom, now) : output;
2469 }
2470
2471 var defaultLongDateFormat = {
2472 LTS: 'h:mm:ss A',
2473 LT: 'h:mm A',
2474 L: 'MM/DD/YYYY',
2475 LL: 'MMMM D, YYYY',
2476 LLL: 'MMMM D, YYYY h:mm A',
2477 LLLL: 'dddd, MMMM D, YYYY h:mm A'
2478 };
2479
2480 function longDateFormat(key) {
2481 var format = this._longDateFormat[key],
2482 formatUpper = this._longDateFormat[key.toUpperCase()];
2483
2484 if (format || !formatUpper) {
2485 return format;
2486 }
2487
2488 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
2489 return val.slice(1);
2490 });
2491 return this._longDateFormat[key];
2492 }
2493
2494 var defaultInvalidDate = 'Invalid date';
2495
2496 function invalidDate() {
2497 return this._invalidDate;
2498 }
2499
2500 var defaultOrdinal = '%d';
2501 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
2502
2503 function ordinal(number) {
2504 return this._ordinal.replace('%d', number);
2505 }
2506
2507 var defaultRelativeTime = {
2508 future: 'in %s',
2509 past: '%s ago',
2510 s: 'a few seconds',
2511 ss: '%d seconds',
2512 m: 'a minute',
2513 mm: '%d minutes',
2514 h: 'an hour',
2515 hh: '%d hours',
2516 d: 'a day',
2517 dd: '%d days',
2518 M: 'a month',
2519 MM: '%d months',
2520 y: 'a year',
2521 yy: '%d years'
2522 };
2523
2524 function relativeTime(number, withoutSuffix, string, isFuture) {
2525 var output = this._relativeTime[string];
2526 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
2527 }
2528
2529 function pastFuture(diff, output) {
2530 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
2531 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
2532 }
2533
2534 var aliases = {};
2535
2536 function addUnitAlias(unit, shorthand) {
2537 var lowerCase = unit.toLowerCase();
2538 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
2539 }
2540
2541 function normalizeUnits(units) {
2542 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
2543 }
2544
2545 function normalizeObjectUnits(inputObject) {
2546 var normalizedInput = {},
2547 normalizedProp,
2548 prop;
2549
2550 for (prop in inputObject) {
2551 if (hasOwnProp(inputObject, prop)) {
2552 normalizedProp = normalizeUnits(prop);
2553
2554 if (normalizedProp) {
2555 normalizedInput[normalizedProp] = inputObject[prop];
2556 }
2557 }
2558 }
2559
2560 return normalizedInput;
2561 }
2562
2563 var priorities = {};
2564
2565 function addUnitPriority(unit, priority) {
2566 priorities[unit] = priority;
2567 }
2568
2569 function getPrioritizedUnits(unitsObj) {
2570 var units = [];
2571
2572 for (var u in unitsObj) {
2573 units.push({
2574 unit: u,
2575 priority: priorities[u]
2576 });
2577 }
2578
2579 units.sort(function (a, b) {
2580 return a.priority - b.priority;
2581 });
2582 return units;
2583 }
2584
2585 function zeroFill(number, targetLength, forceSign) {
2586 var absNumber = '' + Math.abs(number),
2587 zerosToFill = targetLength - absNumber.length,
2588 sign = number >= 0;
2589 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
2590 }
2591
2592 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;
2593 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
2594 var formatFunctions = {};
2595 var formatTokenFunctions = {}; // token: 'M'
2596 // padded: ['MM', 2]
2597 // ordinal: 'Mo'
2598 // callback: function () { this.month() + 1 }
2599
2600 function addFormatToken(token, padded, ordinal, callback) {
2601 var func = callback;
2602
2603 if (typeof callback === 'string') {
2604 func = function () {
2605 return this[callback]();
2606 };
2607 }
2608
2609 if (token) {
2610 formatTokenFunctions[token] = func;
2611 }
2612
2613 if (padded) {
2614 formatTokenFunctions[padded[0]] = function () {
2615 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
2616 };
2617 }
2618
2619 if (ordinal) {
2620 formatTokenFunctions[ordinal] = function () {
2621 return this.localeData().ordinal(func.apply(this, arguments), token);
2622 };
2623 }
2624 }
2625
2626 function removeFormattingTokens(input) {
2627 if (input.match(/\[[\s\S]/)) {
2628 return input.replace(/^\[|\]$/g, '');
2629 }
2630
2631 return input.replace(/\\/g, '');
2632 }
2633
2634 function makeFormatFunction(format) {
2635 var array = format.match(formattingTokens),
2636 i,
2637 length;
2638
2639 for (i = 0, length = array.length; i < length; i++) {
2640 if (formatTokenFunctions[array[i]]) {
2641 array[i] = formatTokenFunctions[array[i]];
2642 } else {
2643 array[i] = removeFormattingTokens(array[i]);
2644 }
2645 }
2646
2647 return function (mom) {
2648 var output = '',
2649 i;
2650
2651 for (i = 0; i < length; i++) {
2652 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
2653 }
2654
2655 return output;
2656 };
2657 } // format date using native date object
2658
2659
2660 function formatMoment(m, format) {
2661 if (!m.isValid()) {
2662 return m.localeData().invalidDate();
2663 }
2664
2665 format = expandFormat(format, m.localeData());
2666 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
2667 return formatFunctions[format](m);
2668 }
2669
2670 function expandFormat(format, locale) {
2671 var i = 5;
2672
2673 function replaceLongDateFormatTokens(input) {
2674 return locale.longDateFormat(input) || input;
2675 }
2676
2677 localFormattingTokens.lastIndex = 0;
2678
2679 while (i >= 0 && localFormattingTokens.test(format)) {
2680 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
2681 localFormattingTokens.lastIndex = 0;
2682 i -= 1;
2683 }
2684
2685 return format;
2686 }
2687
2688 var match1 = /\d/; // 0 - 9
2689
2690 var match2 = /\d\d/; // 00 - 99
2691
2692 var match3 = /\d{3}/; // 000 - 999
2693
2694 var match4 = /\d{4}/; // 0000 - 9999
2695
2696 var match6 = /[+-]?\d{6}/; // -999999 - 999999
2697
2698 var match1to2 = /\d\d?/; // 0 - 99
2699
2700 var match3to4 = /\d\d\d\d?/; // 999 - 9999
2701
2702 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
2703
2704 var match1to3 = /\d{1,3}/; // 0 - 999
2705
2706 var match1to4 = /\d{1,4}/; // 0 - 9999
2707
2708 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
2709
2710 var matchUnsigned = /\d+/; // 0 - inf
2711
2712 var matchSigned = /[+-]?\d+/; // -inf - inf
2713
2714 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
2715
2716 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
2717
2718 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
2719 // any word (or two) characters or numbers including two/three word month in arabic.
2720 // includes scottish gaelic two word and hyphenated months
2721
2722 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;
2723 var regexes = {};
2724
2725 function addRegexToken(token, regex, strictRegex) {
2726 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
2727 return isStrict && strictRegex ? strictRegex : regex;
2728 };
2729 }
2730
2731 function getParseRegexForToken(token, config) {
2732 if (!hasOwnProp(regexes, token)) {
2733 return new RegExp(unescapeFormat(token));
2734 }
2735
2736 return regexes[token](config._strict, config._locale);
2737 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
2738
2739
2740 function unescapeFormat(s) {
2741 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
2742 return p1 || p2 || p3 || p4;
2743 }));
2744 }
2745
2746 function regexEscape(s) {
2747 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
2748 }
2749
2750 var tokens = {};
2751
2752 function addParseToken(token, callback) {
2753 var i,
2754 func = callback;
2755
2756 if (typeof token === 'string') {
2757 token = [token];
2758 }
2759
2760 if (isNumber(callback)) {
2761 func = function (input, array) {
2762 array[callback] = toInt(input);
2763 };
2764 }
2765
2766 for (i = 0; i < token.length; i++) {
2767 tokens[token[i]] = func;
2768 }
2769 }
2770
2771 function addWeekParseToken(token, callback) {
2772 addParseToken(token, function (input, array, config, token) {
2773 config._w = config._w || {};
2774 callback(input, config._w, config, token);
2775 });
2776 }
2777
2778 function addTimeToArrayFromToken(token, input, config) {
2779 if (input != null && hasOwnProp(tokens, token)) {
2780 tokens[token](input, config._a, config, token);
2781 }
2782 }
2783
2784 var YEAR = 0;
2785 var MONTH = 1;
2786 var DATE = 2;
2787 var HOUR = 3;
2788 var MINUTE = 4;
2789 var SECOND = 5;
2790 var MILLISECOND = 6;
2791 var WEEK = 7;
2792 var WEEKDAY = 8; // FORMATTING
2793
2794 addFormatToken('Y', 0, 0, function () {
2795 var y = this.year();
2796 return y <= 9999 ? '' + y : '+' + y;
2797 });
2798 addFormatToken(0, ['YY', 2], 0, function () {
2799 return this.year() % 100;
2800 });
2801 addFormatToken(0, ['YYYY', 4], 0, 'year');
2802 addFormatToken(0, ['YYYYY', 5], 0, 'year');
2803 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
2804
2805 addUnitAlias('year', 'y'); // PRIORITIES
2806
2807 addUnitPriority('year', 1); // PARSING
2808
2809 addRegexToken('Y', matchSigned);
2810 addRegexToken('YY', match1to2, match2);
2811 addRegexToken('YYYY', match1to4, match4);
2812 addRegexToken('YYYYY', match1to6, match6);
2813 addRegexToken('YYYYYY', match1to6, match6);
2814 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
2815 addParseToken('YYYY', function (input, array) {
2816 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
2817 });
2818 addParseToken('YY', function (input, array) {
2819 array[YEAR] = hooks.parseTwoDigitYear(input);
2820 });
2821 addParseToken('Y', function (input, array) {
2822 array[YEAR] = parseInt(input, 10);
2823 }); // HELPERS
2824
2825 function daysInYear(year) {
2826 return isLeapYear(year) ? 366 : 365;
2827 }
2828
2829 function isLeapYear(year) {
2830 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
2831 } // HOOKS
2832
2833
2834 hooks.parseTwoDigitYear = function (input) {
2835 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
2836 }; // MOMENTS
2837
2838
2839 var getSetYear = makeGetSet('FullYear', true);
2840
2841 function getIsLeapYear() {
2842 return isLeapYear(this.year());
2843 }
2844
2845 function makeGetSet(unit, keepTime) {
2846 return function (value) {
2847 if (value != null) {
2848 set$1(this, unit, value);
2849 hooks.updateOffset(this, keepTime);
2850 return this;
2851 } else {
2852 return get(this, unit);
2853 }
2854 };
2855 }
2856
2857 function get(mom, unit) {
2858 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
2859 }
2860
2861 function set$1(mom, unit, value) {
2862 if (mom.isValid() && !isNaN(value)) {
2863 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
2864 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
2865 } else {
2866 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
2867 }
2868 }
2869 } // MOMENTS
2870
2871
2872 function stringGet(units) {
2873 units = normalizeUnits(units);
2874
2875 if (isFunction(this[units])) {
2876 return this[units]();
2877 }
2878
2879 return this;
2880 }
2881
2882 function stringSet(units, value) {
2883 if (typeof units === 'object') {
2884 units = normalizeObjectUnits(units);
2885 var prioritized = getPrioritizedUnits(units);
2886
2887 for (var i = 0; i < prioritized.length; i++) {
2888 this[prioritized[i].unit](units[prioritized[i].unit]);
2889 }
2890 } else {
2891 units = normalizeUnits(units);
2892
2893 if (isFunction(this[units])) {
2894 return this[units](value);
2895 }
2896 }
2897
2898 return this;
2899 }
2900
2901 function mod(n, x) {
2902 return (n % x + x) % x;
2903 }
2904
2905 var indexOf;
2906
2907 if (Array.prototype.indexOf) {
2908 indexOf = Array.prototype.indexOf;
2909 } else {
2910 indexOf = function (o) {
2911 // I know
2912 var i;
2913
2914 for (i = 0; i < this.length; ++i) {
2915 if (this[i] === o) {
2916 return i;
2917 }
2918 }
2919
2920 return -1;
2921 };
2922 }
2923
2924 function daysInMonth(year, month) {
2925 if (isNaN(year) || isNaN(month)) {
2926 return NaN;
2927 }
2928
2929 var modMonth = mod(month, 12);
2930 year += (month - modMonth) / 12;
2931 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
2932 } // FORMATTING
2933
2934
2935 addFormatToken('M', ['MM', 2], 'Mo', function () {
2936 return this.month() + 1;
2937 });
2938 addFormatToken('MMM', 0, 0, function (format) {
2939 return this.localeData().monthsShort(this, format);
2940 });
2941 addFormatToken('MMMM', 0, 0, function (format) {
2942 return this.localeData().months(this, format);
2943 }); // ALIASES
2944
2945 addUnitAlias('month', 'M'); // PRIORITY
2946
2947 addUnitPriority('month', 8); // PARSING
2948
2949 addRegexToken('M', match1to2);
2950 addRegexToken('MM', match1to2, match2);
2951 addRegexToken('MMM', function (isStrict, locale) {
2952 return locale.monthsShortRegex(isStrict);
2953 });
2954 addRegexToken('MMMM', function (isStrict, locale) {
2955 return locale.monthsRegex(isStrict);
2956 });
2957 addParseToken(['M', 'MM'], function (input, array) {
2958 array[MONTH] = toInt(input) - 1;
2959 });
2960 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
2961 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
2962
2963
2964 if (month != null) {
2965 array[MONTH] = month;
2966 } else {
2967 getParsingFlags(config).invalidMonth = input;
2968 }
2969 }); // LOCALES
2970
2971 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
2972 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
2973
2974 function localeMonths(m, format) {
2975 if (!m) {
2976 return isArray(this._months) ? this._months : this._months['standalone'];
2977 }
2978
2979 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
2980 }
2981
2982 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
2983
2984 function localeMonthsShort(m, format) {
2985 if (!m) {
2986 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
2987 }
2988
2989 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
2990 }
2991
2992 function handleStrictParse(monthName, format, strict) {
2993 var i,
2994 ii,
2995 mom,
2996 llc = monthName.toLocaleLowerCase();
2997
2998 if (!this._monthsParse) {
2999 // this is not used
3000 this._monthsParse = [];
3001 this._longMonthsParse = [];
3002 this._shortMonthsParse = [];
3003
3004 for (i = 0; i < 12; ++i) {
3005 mom = createUTC([2000, i]);
3006 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
3007 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
3008 }
3009 }
3010
3011 if (strict) {
3012 if (format === 'MMM') {
3013 ii = indexOf.call(this._shortMonthsParse, llc);
3014 return ii !== -1 ? ii : null;
3015 } else {
3016 ii = indexOf.call(this._longMonthsParse, llc);
3017 return ii !== -1 ? ii : null;
3018 }
3019 } else {
3020 if (format === 'MMM') {
3021 ii = indexOf.call(this._shortMonthsParse, llc);
3022
3023 if (ii !== -1) {
3024 return ii;
3025 }
3026
3027 ii = indexOf.call(this._longMonthsParse, llc);
3028 return ii !== -1 ? ii : null;
3029 } else {
3030 ii = indexOf.call(this._longMonthsParse, llc);
3031
3032 if (ii !== -1) {
3033 return ii;
3034 }
3035
3036 ii = indexOf.call(this._shortMonthsParse, llc);
3037 return ii !== -1 ? ii : null;
3038 }
3039 }
3040 }
3041
3042 function localeMonthsParse(monthName, format, strict) {
3043 var i, mom, regex;
3044
3045 if (this._monthsParseExact) {
3046 return handleStrictParse.call(this, monthName, format, strict);
3047 }
3048
3049 if (!this._monthsParse) {
3050 this._monthsParse = [];
3051 this._longMonthsParse = [];
3052 this._shortMonthsParse = [];
3053 } // TODO: add sorting
3054 // Sorting makes sure if one month (or abbr) is a prefix of another
3055 // see sorting in computeMonthsParse
3056
3057
3058 for (i = 0; i < 12; i++) {
3059 // make the regex if we don't have it already
3060 mom = createUTC([2000, i]);
3061
3062 if (strict && !this._longMonthsParse[i]) {
3063 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
3064 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
3065 }
3066
3067 if (!strict && !this._monthsParse[i]) {
3068 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
3069 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
3070 } // test the regex
3071
3072
3073 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
3074 return i;
3075 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
3076 return i;
3077 } else if (!strict && this._monthsParse[i].test(monthName)) {
3078 return i;
3079 }
3080 }
3081 } // MOMENTS
3082
3083
3084 function setMonth(mom, value) {
3085 var dayOfMonth;
3086
3087 if (!mom.isValid()) {
3088 // No op
3089 return mom;
3090 }
3091
3092 if (typeof value === 'string') {
3093 if (/^\d+$/.test(value)) {
3094 value = toInt(value);
3095 } else {
3096 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
3097
3098 if (!isNumber(value)) {
3099 return mom;
3100 }
3101 }
3102 }
3103
3104 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
3105
3106 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
3107
3108 return mom;
3109 }
3110
3111 function getSetMonth(value) {
3112 if (value != null) {
3113 setMonth(this, value);
3114 hooks.updateOffset(this, true);
3115 return this;
3116 } else {
3117 return get(this, 'Month');
3118 }
3119 }
3120
3121 function getDaysInMonth() {
3122 return daysInMonth(this.year(), this.month());
3123 }
3124
3125 var defaultMonthsShortRegex = matchWord;
3126
3127 function monthsShortRegex(isStrict) {
3128 if (this._monthsParseExact) {
3129 if (!hasOwnProp(this, '_monthsRegex')) {
3130 computeMonthsParse.call(this);
3131 }
3132
3133 if (isStrict) {
3134 return this._monthsShortStrictRegex;
3135 } else {
3136 return this._monthsShortRegex;
3137 }
3138 } else {
3139 if (!hasOwnProp(this, '_monthsShortRegex')) {
3140 this._monthsShortRegex = defaultMonthsShortRegex;
3141 }
3142
3143 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
3144 }
3145 }
3146
3147 var defaultMonthsRegex = matchWord;
3148
3149 function monthsRegex(isStrict) {
3150 if (this._monthsParseExact) {
3151 if (!hasOwnProp(this, '_monthsRegex')) {
3152 computeMonthsParse.call(this);
3153 }
3154
3155 if (isStrict) {
3156 return this._monthsStrictRegex;
3157 } else {
3158 return this._monthsRegex;
3159 }
3160 } else {
3161 if (!hasOwnProp(this, '_monthsRegex')) {
3162 this._monthsRegex = defaultMonthsRegex;
3163 }
3164
3165 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
3166 }
3167 }
3168
3169 function computeMonthsParse() {
3170 function cmpLenRev(a, b) {
3171 return b.length - a.length;
3172 }
3173
3174 var shortPieces = [],
3175 longPieces = [],
3176 mixedPieces = [],
3177 i,
3178 mom;
3179
3180 for (i = 0; i < 12; i++) {
3181 // make the regex if we don't have it already
3182 mom = createUTC([2000, i]);
3183 shortPieces.push(this.monthsShort(mom, ''));
3184 longPieces.push(this.months(mom, ''));
3185 mixedPieces.push(this.months(mom, ''));
3186 mixedPieces.push(this.monthsShort(mom, ''));
3187 } // Sorting makes sure if one month (or abbr) is a prefix of another it
3188 // will match the longer piece.
3189
3190
3191 shortPieces.sort(cmpLenRev);
3192 longPieces.sort(cmpLenRev);
3193 mixedPieces.sort(cmpLenRev);
3194
3195 for (i = 0; i < 12; i++) {
3196 shortPieces[i] = regexEscape(shortPieces[i]);
3197 longPieces[i] = regexEscape(longPieces[i]);
3198 }
3199
3200 for (i = 0; i < 24; i++) {
3201 mixedPieces[i] = regexEscape(mixedPieces[i]);
3202 }
3203
3204 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
3205 this._monthsShortRegex = this._monthsRegex;
3206 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
3207 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
3208 }
3209
3210 function createDate(y, m, d, h, M, s, ms) {
3211 // can't just apply() to create a date:
3212 // https://stackoverflow.com/q/181348
3213 var date; // the date constructor remaps years 0-99 to 1900-1999
3214
3215 if (y < 100 && y >= 0) {
3216 // preserve leap years using a full 400 year cycle, then reset
3217 date = new Date(y + 400, m, d, h, M, s, ms);
3218
3219 if (isFinite(date.getFullYear())) {
3220 date.setFullYear(y);
3221 }
3222 } else {
3223 date = new Date(y, m, d, h, M, s, ms);
3224 }
3225
3226 return date;
3227 }
3228
3229 function createUTCDate(y) {
3230 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
3231
3232 if (y < 100 && y >= 0) {
3233 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
3234
3235 args[0] = y + 400;
3236 date = new Date(Date.UTC.apply(null, args));
3237
3238 if (isFinite(date.getUTCFullYear())) {
3239 date.setUTCFullYear(y);
3240 }
3241 } else {
3242 date = new Date(Date.UTC.apply(null, arguments));
3243 }
3244
3245 return date;
3246 } // start-of-first-week - start-of-year
3247
3248
3249 function firstWeekOffset(year, dow, doy) {
3250 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
3251 fwd = 7 + dow - doy,
3252 // first-week day local weekday -- which local weekday is fwd
3253 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
3254 return -fwdlw + fwd - 1;
3255 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
3256
3257
3258 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
3259 var localWeekday = (7 + weekday - dow) % 7,
3260 weekOffset = firstWeekOffset(year, dow, doy),
3261 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
3262 resYear,
3263 resDayOfYear;
3264
3265 if (dayOfYear <= 0) {
3266 resYear = year - 1;
3267 resDayOfYear = daysInYear(resYear) + dayOfYear;
3268 } else if (dayOfYear > daysInYear(year)) {
3269 resYear = year + 1;
3270 resDayOfYear = dayOfYear - daysInYear(year);
3271 } else {
3272 resYear = year;
3273 resDayOfYear = dayOfYear;
3274 }
3275
3276 return {
3277 year: resYear,
3278 dayOfYear: resDayOfYear
3279 };
3280 }
3281
3282 function weekOfYear(mom, dow, doy) {
3283 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
3284 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
3285 resWeek,
3286 resYear;
3287
3288 if (week < 1) {
3289 resYear = mom.year() - 1;
3290 resWeek = week + weeksInYear(resYear, dow, doy);
3291 } else if (week > weeksInYear(mom.year(), dow, doy)) {
3292 resWeek = week - weeksInYear(mom.year(), dow, doy);
3293 resYear = mom.year() + 1;
3294 } else {
3295 resYear = mom.year();
3296 resWeek = week;
3297 }
3298
3299 return {
3300 week: resWeek,
3301 year: resYear
3302 };
3303 }
3304
3305 function weeksInYear(year, dow, doy) {
3306 var weekOffset = firstWeekOffset(year, dow, doy),
3307 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
3308 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
3309 } // FORMATTING
3310
3311
3312 addFormatToken('w', ['ww', 2], 'wo', 'week');
3313 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
3314
3315 addUnitAlias('week', 'w');
3316 addUnitAlias('isoWeek', 'W'); // PRIORITIES
3317
3318 addUnitPriority('week', 5);
3319 addUnitPriority('isoWeek', 5); // PARSING
3320
3321 addRegexToken('w', match1to2);
3322 addRegexToken('ww', match1to2, match2);
3323 addRegexToken('W', match1to2);
3324 addRegexToken('WW', match1to2, match2);
3325 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
3326 week[token.substr(0, 1)] = toInt(input);
3327 }); // HELPERS
3328 // LOCALES
3329
3330 function localeWeek(mom) {
3331 return weekOfYear(mom, this._week.dow, this._week.doy).week;
3332 }
3333
3334 var defaultLocaleWeek = {
3335 dow: 0,
3336 // Sunday is the first day of the week.
3337 doy: 6 // The week that contains Jan 6th is the first week of the year.
3338
3339 };
3340
3341 function localeFirstDayOfWeek() {
3342 return this._week.dow;
3343 }
3344
3345 function localeFirstDayOfYear() {
3346 return this._week.doy;
3347 } // MOMENTS
3348
3349
3350 function getSetWeek(input) {
3351 var week = this.localeData().week(this);
3352 return input == null ? week : this.add((input - week) * 7, 'd');
3353 }
3354
3355 function getSetISOWeek(input) {
3356 var week = weekOfYear(this, 1, 4).week;
3357 return input == null ? week : this.add((input - week) * 7, 'd');
3358 } // FORMATTING
3359
3360
3361 addFormatToken('d', 0, 'do', 'day');
3362 addFormatToken('dd', 0, 0, function (format) {
3363 return this.localeData().weekdaysMin(this, format);
3364 });
3365 addFormatToken('ddd', 0, 0, function (format) {
3366 return this.localeData().weekdaysShort(this, format);
3367 });
3368 addFormatToken('dddd', 0, 0, function (format) {
3369 return this.localeData().weekdays(this, format);
3370 });
3371 addFormatToken('e', 0, 0, 'weekday');
3372 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
3373
3374 addUnitAlias('day', 'd');
3375 addUnitAlias('weekday', 'e');
3376 addUnitAlias('isoWeekday', 'E'); // PRIORITY
3377
3378 addUnitPriority('day', 11);
3379 addUnitPriority('weekday', 11);
3380 addUnitPriority('isoWeekday', 11); // PARSING
3381
3382 addRegexToken('d', match1to2);
3383 addRegexToken('e', match1to2);
3384 addRegexToken('E', match1to2);
3385 addRegexToken('dd', function (isStrict, locale) {
3386 return locale.weekdaysMinRegex(isStrict);
3387 });
3388 addRegexToken('ddd', function (isStrict, locale) {
3389 return locale.weekdaysShortRegex(isStrict);
3390 });
3391 addRegexToken('dddd', function (isStrict, locale) {
3392 return locale.weekdaysRegex(isStrict);
3393 });
3394 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
3395 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
3396
3397
3398 if (weekday != null) {
3399 week.d = weekday;
3400 } else {
3401 getParsingFlags(config).invalidWeekday = input;
3402 }
3403 });
3404 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
3405 week[token] = toInt(input);
3406 }); // HELPERS
3407
3408 function parseWeekday(input, locale) {
3409 if (typeof input !== 'string') {
3410 return input;
3411 }
3412
3413 if (!isNaN(input)) {
3414 return parseInt(input, 10);
3415 }
3416
3417 input = locale.weekdaysParse(input);
3418
3419 if (typeof input === 'number') {
3420 return input;
3421 }
3422
3423 return null;
3424 }
3425
3426 function parseIsoWeekday(input, locale) {
3427 if (typeof input === 'string') {
3428 return locale.weekdaysParse(input) % 7 || 7;
3429 }
3430
3431 return isNaN(input) ? null : input;
3432 } // LOCALES
3433
3434
3435 function shiftWeekdays(ws, n) {
3436 return ws.slice(n, 7).concat(ws.slice(0, n));
3437 }
3438
3439 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
3440
3441 function localeWeekdays(m, format) {
3442 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
3443 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
3444 }
3445
3446 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
3447
3448 function localeWeekdaysShort(m) {
3449 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
3450 }
3451
3452 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
3453
3454 function localeWeekdaysMin(m) {
3455 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
3456 }
3457
3458 function handleStrictParse$1(weekdayName, format, strict) {
3459 var i,
3460 ii,
3461 mom,
3462 llc = weekdayName.toLocaleLowerCase();
3463
3464 if (!this._weekdaysParse) {
3465 this._weekdaysParse = [];
3466 this._shortWeekdaysParse = [];
3467 this._minWeekdaysParse = [];
3468
3469 for (i = 0; i < 7; ++i) {
3470 mom = createUTC([2000, 1]).day(i);
3471 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
3472 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
3473 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
3474 }
3475 }
3476
3477 if (strict) {
3478 if (format === 'dddd') {
3479 ii = indexOf.call(this._weekdaysParse, llc);
3480 return ii !== -1 ? ii : null;
3481 } else if (format === 'ddd') {
3482 ii = indexOf.call(this._shortWeekdaysParse, llc);
3483 return ii !== -1 ? ii : null;
3484 } else {
3485 ii = indexOf.call(this._minWeekdaysParse, llc);
3486 return ii !== -1 ? ii : null;
3487 }
3488 } else {
3489 if (format === 'dddd') {
3490 ii = indexOf.call(this._weekdaysParse, llc);
3491
3492 if (ii !== -1) {
3493 return ii;
3494 }
3495
3496 ii = indexOf.call(this._shortWeekdaysParse, llc);
3497
3498 if (ii !== -1) {
3499 return ii;
3500 }
3501
3502 ii = indexOf.call(this._minWeekdaysParse, llc);
3503 return ii !== -1 ? ii : null;
3504 } else if (format === 'ddd') {
3505 ii = indexOf.call(this._shortWeekdaysParse, llc);
3506
3507 if (ii !== -1) {
3508 return ii;
3509 }
3510
3511 ii = indexOf.call(this._weekdaysParse, llc);
3512
3513 if (ii !== -1) {
3514 return ii;
3515 }
3516
3517 ii = indexOf.call(this._minWeekdaysParse, llc);
3518 return ii !== -1 ? ii : null;
3519 } else {
3520 ii = indexOf.call(this._minWeekdaysParse, llc);
3521
3522 if (ii !== -1) {
3523 return ii;
3524 }
3525
3526 ii = indexOf.call(this._weekdaysParse, llc);
3527
3528 if (ii !== -1) {
3529 return ii;
3530 }
3531
3532 ii = indexOf.call(this._shortWeekdaysParse, llc);
3533 return ii !== -1 ? ii : null;
3534 }
3535 }
3536 }
3537
3538 function localeWeekdaysParse(weekdayName, format, strict) {
3539 var i, mom, regex;
3540
3541 if (this._weekdaysParseExact) {
3542 return handleStrictParse$1.call(this, weekdayName, format, strict);
3543 }
3544
3545 if (!this._weekdaysParse) {
3546 this._weekdaysParse = [];
3547 this._minWeekdaysParse = [];
3548 this._shortWeekdaysParse = [];
3549 this._fullWeekdaysParse = [];
3550 }
3551
3552 for (i = 0; i < 7; i++) {
3553 // make the regex if we don't have it already
3554 mom = createUTC([2000, 1]).day(i);
3555
3556 if (strict && !this._fullWeekdaysParse[i]) {
3557 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
3558 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
3559 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
3560 }
3561
3562 if (!this._weekdaysParse[i]) {
3563 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
3564 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
3565 } // test the regex
3566
3567
3568 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
3569 return i;
3570 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
3571 return i;
3572 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
3573 return i;
3574 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
3575 return i;
3576 }
3577 }
3578 } // MOMENTS
3579
3580
3581 function getSetDayOfWeek(input) {
3582 if (!this.isValid()) {
3583 return input != null ? this : NaN;
3584 }
3585
3586 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
3587
3588 if (input != null) {
3589 input = parseWeekday(input, this.localeData());
3590 return this.add(input - day, 'd');
3591 } else {
3592 return day;
3593 }
3594 }
3595
3596 function getSetLocaleDayOfWeek(input) {
3597 if (!this.isValid()) {
3598 return input != null ? this : NaN;
3599 }
3600
3601 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
3602 return input == null ? weekday : this.add(input - weekday, 'd');
3603 }
3604
3605 function getSetISODayOfWeek(input) {
3606 if (!this.isValid()) {
3607 return input != null ? this : NaN;
3608 } // behaves the same as moment#day except
3609 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
3610 // as a setter, sunday should belong to the previous week.
3611
3612
3613 if (input != null) {
3614 var weekday = parseIsoWeekday(input, this.localeData());
3615 return this.day(this.day() % 7 ? weekday : weekday - 7);
3616 } else {
3617 return this.day() || 7;
3618 }
3619 }
3620
3621 var defaultWeekdaysRegex = matchWord;
3622
3623 function weekdaysRegex(isStrict) {
3624 if (this._weekdaysParseExact) {
3625 if (!hasOwnProp(this, '_weekdaysRegex')) {
3626 computeWeekdaysParse.call(this);
3627 }
3628
3629 if (isStrict) {
3630 return this._weekdaysStrictRegex;
3631 } else {
3632 return this._weekdaysRegex;
3633 }
3634 } else {
3635 if (!hasOwnProp(this, '_weekdaysRegex')) {
3636 this._weekdaysRegex = defaultWeekdaysRegex;
3637 }
3638
3639 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
3640 }
3641 }
3642
3643 var defaultWeekdaysShortRegex = matchWord;
3644
3645 function weekdaysShortRegex(isStrict) {
3646 if (this._weekdaysParseExact) {
3647 if (!hasOwnProp(this, '_weekdaysRegex')) {
3648 computeWeekdaysParse.call(this);
3649 }
3650
3651 if (isStrict) {
3652 return this._weekdaysShortStrictRegex;
3653 } else {
3654 return this._weekdaysShortRegex;
3655 }
3656 } else {
3657 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
3658 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
3659 }
3660
3661 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
3662 }
3663 }
3664
3665 var defaultWeekdaysMinRegex = matchWord;
3666
3667 function weekdaysMinRegex(isStrict) {
3668 if (this._weekdaysParseExact) {
3669 if (!hasOwnProp(this, '_weekdaysRegex')) {
3670 computeWeekdaysParse.call(this);
3671 }
3672
3673 if (isStrict) {
3674 return this._weekdaysMinStrictRegex;
3675 } else {
3676 return this._weekdaysMinRegex;
3677 }
3678 } else {
3679 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
3680 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
3681 }
3682
3683 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
3684 }
3685 }
3686
3687 function computeWeekdaysParse() {
3688 function cmpLenRev(a, b) {
3689 return b.length - a.length;
3690 }
3691
3692 var minPieces = [],
3693 shortPieces = [],
3694 longPieces = [],
3695 mixedPieces = [],
3696 i,
3697 mom,
3698 minp,
3699 shortp,
3700 longp;
3701
3702 for (i = 0; i < 7; i++) {
3703 // make the regex if we don't have it already
3704 mom = createUTC([2000, 1]).day(i);
3705 minp = this.weekdaysMin(mom, '');
3706 shortp = this.weekdaysShort(mom, '');
3707 longp = this.weekdays(mom, '');
3708 minPieces.push(minp);
3709 shortPieces.push(shortp);
3710 longPieces.push(longp);
3711 mixedPieces.push(minp);
3712 mixedPieces.push(shortp);
3713 mixedPieces.push(longp);
3714 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
3715 // will match the longer piece.
3716
3717
3718 minPieces.sort(cmpLenRev);
3719 shortPieces.sort(cmpLenRev);
3720 longPieces.sort(cmpLenRev);
3721 mixedPieces.sort(cmpLenRev);
3722
3723 for (i = 0; i < 7; i++) {
3724 shortPieces[i] = regexEscape(shortPieces[i]);
3725 longPieces[i] = regexEscape(longPieces[i]);
3726 mixedPieces[i] = regexEscape(mixedPieces[i]);
3727 }
3728
3729 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
3730 this._weekdaysShortRegex = this._weekdaysRegex;
3731 this._weekdaysMinRegex = this._weekdaysRegex;
3732 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
3733 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
3734 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
3735 } // FORMATTING
3736
3737
3738 function hFormat() {
3739 return this.hours() % 12 || 12;
3740 }
3741
3742 function kFormat() {
3743 return this.hours() || 24;
3744 }
3745
3746 addFormatToken('H', ['HH', 2], 0, 'hour');
3747 addFormatToken('h', ['hh', 2], 0, hFormat);
3748 addFormatToken('k', ['kk', 2], 0, kFormat);
3749 addFormatToken('hmm', 0, 0, function () {
3750 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
3751 });
3752 addFormatToken('hmmss', 0, 0, function () {
3753 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
3754 });
3755 addFormatToken('Hmm', 0, 0, function () {
3756 return '' + this.hours() + zeroFill(this.minutes(), 2);
3757 });
3758 addFormatToken('Hmmss', 0, 0, function () {
3759 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
3760 });
3761
3762 function meridiem(token, lowercase) {
3763 addFormatToken(token, 0, 0, function () {
3764 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
3765 });
3766 }
3767
3768 meridiem('a', true);
3769 meridiem('A', false); // ALIASES
3770
3771 addUnitAlias('hour', 'h'); // PRIORITY
3772
3773 addUnitPriority('hour', 13); // PARSING
3774
3775 function matchMeridiem(isStrict, locale) {
3776 return locale._meridiemParse;
3777 }
3778
3779 addRegexToken('a', matchMeridiem);
3780 addRegexToken('A', matchMeridiem);
3781 addRegexToken('H', match1to2);
3782 addRegexToken('h', match1to2);
3783 addRegexToken('k', match1to2);
3784 addRegexToken('HH', match1to2, match2);
3785 addRegexToken('hh', match1to2, match2);
3786 addRegexToken('kk', match1to2, match2);
3787 addRegexToken('hmm', match3to4);
3788 addRegexToken('hmmss', match5to6);
3789 addRegexToken('Hmm', match3to4);
3790 addRegexToken('Hmmss', match5to6);
3791 addParseToken(['H', 'HH'], HOUR);
3792 addParseToken(['k', 'kk'], function (input, array, config) {
3793 var kInput = toInt(input);
3794 array[HOUR] = kInput === 24 ? 0 : kInput;
3795 });
3796 addParseToken(['a', 'A'], function (input, array, config) {
3797 config._isPm = config._locale.isPM(input);
3798 config._meridiem = input;
3799 });
3800 addParseToken(['h', 'hh'], function (input, array, config) {
3801 array[HOUR] = toInt(input);
3802 getParsingFlags(config).bigHour = true;
3803 });
3804 addParseToken('hmm', function (input, array, config) {
3805 var pos = input.length - 2;
3806 array[HOUR] = toInt(input.substr(0, pos));
3807 array[MINUTE] = toInt(input.substr(pos));
3808 getParsingFlags(config).bigHour = true;
3809 });
3810 addParseToken('hmmss', function (input, array, config) {
3811 var pos1 = input.length - 4;
3812 var pos2 = input.length - 2;
3813 array[HOUR] = toInt(input.substr(0, pos1));
3814 array[MINUTE] = toInt(input.substr(pos1, 2));
3815 array[SECOND] = toInt(input.substr(pos2));
3816 getParsingFlags(config).bigHour = true;
3817 });
3818 addParseToken('Hmm', function (input, array, config) {
3819 var pos = input.length - 2;
3820 array[HOUR] = toInt(input.substr(0, pos));
3821 array[MINUTE] = toInt(input.substr(pos));
3822 });
3823 addParseToken('Hmmss', function (input, array, config) {
3824 var pos1 = input.length - 4;
3825 var pos2 = input.length - 2;
3826 array[HOUR] = toInt(input.substr(0, pos1));
3827 array[MINUTE] = toInt(input.substr(pos1, 2));
3828 array[SECOND] = toInt(input.substr(pos2));
3829 }); // LOCALES
3830
3831 function localeIsPM(input) {
3832 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
3833 // Using charAt should be more compatible.
3834 return (input + '').toLowerCase().charAt(0) === 'p';
3835 }
3836
3837 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
3838
3839 function localeMeridiem(hours, minutes, isLower) {
3840 if (hours > 11) {
3841 return isLower ? 'pm' : 'PM';
3842 } else {
3843 return isLower ? 'am' : 'AM';
3844 }
3845 } // MOMENTS
3846 // Setting the hour should keep the time, because the user explicitly
3847 // specified which hour they want. So trying to maintain the same hour (in
3848 // a new timezone) makes sense. Adding/subtracting hours does not follow
3849 // this rule.
3850
3851
3852 var getSetHour = makeGetSet('Hours', true);
3853 var baseConfig = {
3854 calendar: defaultCalendar,
3855 longDateFormat: defaultLongDateFormat,
3856 invalidDate: defaultInvalidDate,
3857 ordinal: defaultOrdinal,
3858 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
3859 relativeTime: defaultRelativeTime,
3860 months: defaultLocaleMonths,
3861 monthsShort: defaultLocaleMonthsShort,
3862 week: defaultLocaleWeek,
3863 weekdays: defaultLocaleWeekdays,
3864 weekdaysMin: defaultLocaleWeekdaysMin,
3865 weekdaysShort: defaultLocaleWeekdaysShort,
3866 meridiemParse: defaultLocaleMeridiemParse
3867 }; // internal storage for locale config files
3868
3869 var locales = {};
3870 var localeFamilies = {};
3871 var globalLocale;
3872
3873 function normalizeLocale(key) {
3874 return key ? key.toLowerCase().replace('_', '-') : key;
3875 } // pick the locale from the array
3876 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
3877 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
3878
3879
3880 function chooseLocale(names) {
3881 var i = 0,
3882 j,
3883 next,
3884 locale,
3885 split;
3886
3887 while (i < names.length) {
3888 split = normalizeLocale(names[i]).split('-');
3889 j = split.length;
3890 next = normalizeLocale(names[i + 1]);
3891 next = next ? next.split('-') : null;
3892
3893 while (j > 0) {
3894 locale = loadLocale(split.slice(0, j).join('-'));
3895
3896 if (locale) {
3897 return locale;
3898 }
3899
3900 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
3901 //the next array item is better than a shallower substring of this one
3902 break;
3903 }
3904
3905 j--;
3906 }
3907
3908 i++;
3909 }
3910
3911 return globalLocale;
3912 }
3913
3914 function loadLocale(name) {
3915 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
3916
3917 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
3918 try {
3919 oldLocale = globalLocale._abbr;
3920 var aliasedRequire = commonjsRequire;
3921 aliasedRequire('./locale/' + name);
3922 getSetGlobalLocale(oldLocale);
3923 } catch (e) {}
3924 }
3925
3926 return locales[name];
3927 } // This function will load locale and then set the global locale. If
3928 // no arguments are passed in, it will simply return the current global
3929 // locale key.
3930
3931
3932 function getSetGlobalLocale(key, values) {
3933 var data;
3934
3935 if (key) {
3936 if (isUndefined(values)) {
3937 data = getLocale(key);
3938 } else {
3939 data = defineLocale(key, values);
3940 }
3941
3942 if (data) {
3943 // moment.duration._locale = moment._locale = data;
3944 globalLocale = data;
3945 } else {
3946 if (typeof console !== 'undefined' && console.warn) {
3947 //warn user if arguments are passed but the locale could not be set
3948 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
3949 }
3950 }
3951 }
3952
3953 return globalLocale._abbr;
3954 }
3955
3956 function defineLocale(name, config) {
3957 if (config !== null) {
3958 var locale,
3959 parentConfig = baseConfig;
3960 config.abbr = name;
3961
3962 if (locales[name] != null) {
3963 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.');
3964 parentConfig = locales[name]._config;
3965 } else if (config.parentLocale != null) {
3966 if (locales[config.parentLocale] != null) {
3967 parentConfig = locales[config.parentLocale]._config;
3968 } else {
3969 locale = loadLocale(config.parentLocale);
3970
3971 if (locale != null) {
3972 parentConfig = locale._config;
3973 } else {
3974 if (!localeFamilies[config.parentLocale]) {
3975 localeFamilies[config.parentLocale] = [];
3976 }
3977
3978 localeFamilies[config.parentLocale].push({
3979 name: name,
3980 config: config
3981 });
3982 return null;
3983 }
3984 }
3985 }
3986
3987 locales[name] = new Locale(mergeConfigs(parentConfig, config));
3988
3989 if (localeFamilies[name]) {
3990 localeFamilies[name].forEach(function (x) {
3991 defineLocale(x.name, x.config);
3992 });
3993 } // backwards compat for now: also set the locale
3994 // make sure we set the locale AFTER all child locales have been
3995 // created, so we won't end up with the child locale set.
3996
3997
3998 getSetGlobalLocale(name);
3999 return locales[name];
4000 } else {
4001 // useful for testing
4002 delete locales[name];
4003 return null;
4004 }
4005 }
4006
4007 function updateLocale(name, config) {
4008 if (config != null) {
4009 var locale,
4010 tmpLocale,
4011 parentConfig = baseConfig; // MERGE
4012
4013 tmpLocale = loadLocale(name);
4014
4015 if (tmpLocale != null) {
4016 parentConfig = tmpLocale._config;
4017 }
4018
4019 config = mergeConfigs(parentConfig, config);
4020 locale = new Locale(config);
4021 locale.parentLocale = locales[name];
4022 locales[name] = locale; // backwards compat for now: also set the locale
4023
4024 getSetGlobalLocale(name);
4025 } else {
4026 // pass null for config to unupdate, useful for tests
4027 if (locales[name] != null) {
4028 if (locales[name].parentLocale != null) {
4029 locales[name] = locales[name].parentLocale;
4030 } else if (locales[name] != null) {
4031 delete locales[name];
4032 }
4033 }
4034 }
4035
4036 return locales[name];
4037 } // returns locale data
4038
4039
4040 function getLocale(key) {
4041 var locale;
4042
4043 if (key && key._locale && key._locale._abbr) {
4044 key = key._locale._abbr;
4045 }
4046
4047 if (!key) {
4048 return globalLocale;
4049 }
4050
4051 if (!isArray(key)) {
4052 //short-circuit everything else
4053 locale = loadLocale(key);
4054
4055 if (locale) {
4056 return locale;
4057 }
4058
4059 key = [key];
4060 }
4061
4062 return chooseLocale(key);
4063 }
4064
4065 function listLocales() {
4066 return keys(locales);
4067 }
4068
4069 function checkOverflow(m) {
4070 var overflow;
4071 var a = m._a;
4072
4073 if (a && getParsingFlags(m).overflow === -2) {
4074 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;
4075
4076 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
4077 overflow = DATE;
4078 }
4079
4080 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
4081 overflow = WEEK;
4082 }
4083
4084 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
4085 overflow = WEEKDAY;
4086 }
4087
4088 getParsingFlags(m).overflow = overflow;
4089 }
4090
4091 return m;
4092 } // Pick the first defined of two or three arguments.
4093
4094
4095 function defaults(a, b, c) {
4096 if (a != null) {
4097 return a;
4098 }
4099
4100 if (b != null) {
4101 return b;
4102 }
4103
4104 return c;
4105 }
4106
4107 function currentDateArray(config) {
4108 // hooks is actually the exported moment object
4109 var nowValue = new Date(hooks.now());
4110
4111 if (config._useUTC) {
4112 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
4113 }
4114
4115 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
4116 } // convert an array to a date.
4117 // the array should mirror the parameters below
4118 // note: all values past the year are optional and will default to the lowest possible value.
4119 // [year, month, day , hour, minute, second, millisecond]
4120
4121
4122 function configFromArray(config) {
4123 var i,
4124 date,
4125 input = [],
4126 currentDate,
4127 expectedWeekday,
4128 yearToUse;
4129
4130 if (config._d) {
4131 return;
4132 }
4133
4134 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
4135
4136 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
4137 dayOfYearFromWeekInfo(config);
4138 } //if the day of the year is set, figure out what it is
4139
4140
4141 if (config._dayOfYear != null) {
4142 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
4143
4144 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
4145 getParsingFlags(config)._overflowDayOfYear = true;
4146 }
4147
4148 date = createUTCDate(yearToUse, 0, config._dayOfYear);
4149 config._a[MONTH] = date.getUTCMonth();
4150 config._a[DATE] = date.getUTCDate();
4151 } // Default to current date.
4152 // * if no year, month, day of month are given, default to today
4153 // * if day of month is given, default month and year
4154 // * if month is given, default only year
4155 // * if year is given, don't default anything
4156
4157
4158 for (i = 0; i < 3 && config._a[i] == null; ++i) {
4159 config._a[i] = input[i] = currentDate[i];
4160 } // Zero out whatever was not defaulted, including time
4161
4162
4163 for (; i < 7; i++) {
4164 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
4165 } // Check for 24:00:00.000
4166
4167
4168 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
4169 config._nextDay = true;
4170 config._a[HOUR] = 0;
4171 }
4172
4173 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
4174 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
4175 // with parseZone.
4176
4177 if (config._tzm != null) {
4178 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
4179 }
4180
4181 if (config._nextDay) {
4182 config._a[HOUR] = 24;
4183 } // check for mismatching day of week
4184
4185
4186 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
4187 getParsingFlags(config).weekdayMismatch = true;
4188 }
4189 }
4190
4191 function dayOfYearFromWeekInfo(config) {
4192 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
4193 w = config._w;
4194
4195 if (w.GG != null || w.W != null || w.E != null) {
4196 dow = 1;
4197 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
4198 // how we interpret now (local, utc, fixed offset). So create
4199 // a now version of current config (take local/utc/offset flags, and
4200 // create now).
4201
4202 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
4203 week = defaults(w.W, 1);
4204 weekday = defaults(w.E, 1);
4205
4206 if (weekday < 1 || weekday > 7) {
4207 weekdayOverflow = true;
4208 }
4209 } else {
4210 dow = config._locale._week.dow;
4211 doy = config._locale._week.doy;
4212 var curWeek = weekOfYear(createLocal(), dow, doy);
4213 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
4214
4215 week = defaults(w.w, curWeek.week);
4216
4217 if (w.d != null) {
4218 // weekday -- low day numbers are considered next week
4219 weekday = w.d;
4220
4221 if (weekday < 0 || weekday > 6) {
4222 weekdayOverflow = true;
4223 }
4224 } else if (w.e != null) {
4225 // local weekday -- counting starts from beginning of week
4226 weekday = w.e + dow;
4227
4228 if (w.e < 0 || w.e > 6) {
4229 weekdayOverflow = true;
4230 }
4231 } else {
4232 // default to beginning of week
4233 weekday = dow;
4234 }
4235 }
4236
4237 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
4238 getParsingFlags(config)._overflowWeeks = true;
4239 } else if (weekdayOverflow != null) {
4240 getParsingFlags(config)._overflowWeekday = true;
4241 } else {
4242 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
4243 config._a[YEAR] = temp.year;
4244 config._dayOfYear = temp.dayOfYear;
4245 }
4246 } // iso 8601 regex
4247 // 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)
4248
4249
4250 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)?)?$/;
4251 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)?)?$/;
4252 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
4253 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
4254 ['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
4255
4256 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/]];
4257 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
4258
4259 function configFromISO(config) {
4260 var i,
4261 l,
4262 string = config._i,
4263 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
4264 allowTime,
4265 dateFormat,
4266 timeFormat,
4267 tzFormat;
4268
4269 if (match) {
4270 getParsingFlags(config).iso = true;
4271
4272 for (i = 0, l = isoDates.length; i < l; i++) {
4273 if (isoDates[i][1].exec(match[1])) {
4274 dateFormat = isoDates[i][0];
4275 allowTime = isoDates[i][2] !== false;
4276 break;
4277 }
4278 }
4279
4280 if (dateFormat == null) {
4281 config._isValid = false;
4282 return;
4283 }
4284
4285 if (match[3]) {
4286 for (i = 0, l = isoTimes.length; i < l; i++) {
4287 if (isoTimes[i][1].exec(match[3])) {
4288 // match[2] should be 'T' or space
4289 timeFormat = (match[2] || ' ') + isoTimes[i][0];
4290 break;
4291 }
4292 }
4293
4294 if (timeFormat == null) {
4295 config._isValid = false;
4296 return;
4297 }
4298 }
4299
4300 if (!allowTime && timeFormat != null) {
4301 config._isValid = false;
4302 return;
4303 }
4304
4305 if (match[4]) {
4306 if (tzRegex.exec(match[4])) {
4307 tzFormat = 'Z';
4308 } else {
4309 config._isValid = false;
4310 return;
4311 }
4312 }
4313
4314 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
4315 configFromStringAndFormat(config);
4316 } else {
4317 config._isValid = false;
4318 }
4319 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
4320
4321
4322 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}))$/;
4323
4324 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
4325 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
4326
4327 if (secondStr) {
4328 result.push(parseInt(secondStr, 10));
4329 }
4330
4331 return result;
4332 }
4333
4334 function untruncateYear(yearStr) {
4335 var year = parseInt(yearStr, 10);
4336
4337 if (year <= 49) {
4338 return 2000 + year;
4339 } else if (year <= 999) {
4340 return 1900 + year;
4341 }
4342
4343 return year;
4344 }
4345
4346 function preprocessRFC2822(s) {
4347 // Remove comments and folding whitespace and replace multiple-spaces with a single space
4348 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
4349 }
4350
4351 function checkWeekday(weekdayStr, parsedInput, config) {
4352 if (weekdayStr) {
4353 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
4354 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
4355 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
4356
4357 if (weekdayProvided !== weekdayActual) {
4358 getParsingFlags(config).weekdayMismatch = true;
4359 config._isValid = false;
4360 return false;
4361 }
4362 }
4363
4364 return true;
4365 }
4366
4367 var obsOffsets = {
4368 UT: 0,
4369 GMT: 0,
4370 EDT: -4 * 60,
4371 EST: -5 * 60,
4372 CDT: -5 * 60,
4373 CST: -6 * 60,
4374 MDT: -6 * 60,
4375 MST: -7 * 60,
4376 PDT: -7 * 60,
4377 PST: -8 * 60
4378 };
4379
4380 function calculateOffset(obsOffset, militaryOffset, numOffset) {
4381 if (obsOffset) {
4382 return obsOffsets[obsOffset];
4383 } else if (militaryOffset) {
4384 // the only allowed military tz is Z
4385 return 0;
4386 } else {
4387 var hm = parseInt(numOffset, 10);
4388 var m = hm % 100,
4389 h = (hm - m) / 100;
4390 return h * 60 + m;
4391 }
4392 } // date and time from ref 2822 format
4393
4394
4395 function configFromRFC2822(config) {
4396 var match = rfc2822.exec(preprocessRFC2822(config._i));
4397
4398 if (match) {
4399 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
4400
4401 if (!checkWeekday(match[1], parsedArray, config)) {
4402 return;
4403 }
4404
4405 config._a = parsedArray;
4406 config._tzm = calculateOffset(match[8], match[9], match[10]);
4407 config._d = createUTCDate.apply(null, config._a);
4408
4409 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
4410
4411 getParsingFlags(config).rfc2822 = true;
4412 } else {
4413 config._isValid = false;
4414 }
4415 } // date from iso format or fallback
4416
4417
4418 function configFromString(config) {
4419 var matched = aspNetJsonRegex.exec(config._i);
4420
4421 if (matched !== null) {
4422 config._d = new Date(+matched[1]);
4423 return;
4424 }
4425
4426 configFromISO(config);
4427
4428 if (config._isValid === false) {
4429 delete config._isValid;
4430 } else {
4431 return;
4432 }
4433
4434 configFromRFC2822(config);
4435
4436 if (config._isValid === false) {
4437 delete config._isValid;
4438 } else {
4439 return;
4440 } // Final attempt, use Input Fallback
4441
4442
4443 hooks.createFromInputFallback(config);
4444 }
4445
4446 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) {
4447 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
4448 }); // constant that refers to the ISO standard
4449
4450 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
4451
4452
4453 hooks.RFC_2822 = function () {}; // date from string and format string
4454
4455
4456 function configFromStringAndFormat(config) {
4457 // TODO: Move this to another part of the creation flow to prevent circular deps
4458 if (config._f === hooks.ISO_8601) {
4459 configFromISO(config);
4460 return;
4461 }
4462
4463 if (config._f === hooks.RFC_2822) {
4464 configFromRFC2822(config);
4465 return;
4466 }
4467
4468 config._a = [];
4469 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
4470
4471 var string = '' + config._i,
4472 i,
4473 parsedInput,
4474 tokens,
4475 token,
4476 skipped,
4477 stringLength = string.length,
4478 totalParsedInputLength = 0;
4479 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
4480
4481 for (i = 0; i < tokens.length; i++) {
4482 token = tokens[i];
4483 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
4484 // 'regex', getParseRegexForToken(token, config));
4485
4486 if (parsedInput) {
4487 skipped = string.substr(0, string.indexOf(parsedInput));
4488
4489 if (skipped.length > 0) {
4490 getParsingFlags(config).unusedInput.push(skipped);
4491 }
4492
4493 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
4494 totalParsedInputLength += parsedInput.length;
4495 } // don't parse if it's not a known token
4496
4497
4498 if (formatTokenFunctions[token]) {
4499 if (parsedInput) {
4500 getParsingFlags(config).empty = false;
4501 } else {
4502 getParsingFlags(config).unusedTokens.push(token);
4503 }
4504
4505 addTimeToArrayFromToken(token, parsedInput, config);
4506 } else if (config._strict && !parsedInput) {
4507 getParsingFlags(config).unusedTokens.push(token);
4508 }
4509 } // add remaining unparsed input length to the string
4510
4511
4512 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
4513
4514 if (string.length > 0) {
4515 getParsingFlags(config).unusedInput.push(string);
4516 } // clear _12h flag if hour is <= 12
4517
4518
4519 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
4520 getParsingFlags(config).bigHour = undefined;
4521 }
4522
4523 getParsingFlags(config).parsedDateParts = config._a.slice(0);
4524 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
4525
4526 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
4527 configFromArray(config);
4528 checkOverflow(config);
4529 }
4530
4531 function meridiemFixWrap(locale, hour, meridiem) {
4532 var isPm;
4533
4534 if (meridiem == null) {
4535 // nothing to do
4536 return hour;
4537 }
4538
4539 if (locale.meridiemHour != null) {
4540 return locale.meridiemHour(hour, meridiem);
4541 } else if (locale.isPM != null) {
4542 // Fallback
4543 isPm = locale.isPM(meridiem);
4544
4545 if (isPm && hour < 12) {
4546 hour += 12;
4547 }
4548
4549 if (!isPm && hour === 12) {
4550 hour = 0;
4551 }
4552
4553 return hour;
4554 } else {
4555 // this is not supposed to happen
4556 return hour;
4557 }
4558 } // date from string and array of format strings
4559
4560
4561 function configFromStringAndArray(config) {
4562 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
4563
4564 if (config._f.length === 0) {
4565 getParsingFlags(config).invalidFormat = true;
4566 config._d = new Date(NaN);
4567 return;
4568 }
4569
4570 for (i = 0; i < config._f.length; i++) {
4571 currentScore = 0;
4572 tempConfig = copyConfig({}, config);
4573
4574 if (config._useUTC != null) {
4575 tempConfig._useUTC = config._useUTC;
4576 }
4577
4578 tempConfig._f = config._f[i];
4579 configFromStringAndFormat(tempConfig);
4580
4581 if (!isValid(tempConfig)) {
4582 continue;
4583 } // if there is any input that was not parsed add a penalty for that format
4584
4585
4586 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
4587
4588 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
4589 getParsingFlags(tempConfig).score = currentScore;
4590
4591 if (scoreToBeat == null || currentScore < scoreToBeat) {
4592 scoreToBeat = currentScore;
4593 bestMoment = tempConfig;
4594 }
4595 }
4596
4597 extend(config, bestMoment || tempConfig);
4598 }
4599
4600 function configFromObject(config) {
4601 if (config._d) {
4602 return;
4603 }
4604
4605 var i = normalizeObjectUnits(config._i);
4606 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
4607 return obj && parseInt(obj, 10);
4608 });
4609 configFromArray(config);
4610 }
4611
4612 function createFromConfig(config) {
4613 var res = new Moment(checkOverflow(prepareConfig(config)));
4614
4615 if (res._nextDay) {
4616 // Adding is smart enough around DST
4617 res.add(1, 'd');
4618 res._nextDay = undefined;
4619 }
4620
4621 return res;
4622 }
4623
4624 function prepareConfig(config) {
4625 var input = config._i,
4626 format = config._f;
4627 config._locale = config._locale || getLocale(config._l);
4628
4629 if (input === null || format === undefined && input === '') {
4630 return createInvalid({
4631 nullInput: true
4632 });
4633 }
4634
4635 if (typeof input === 'string') {
4636 config._i = input = config._locale.preparse(input);
4637 }
4638
4639 if (isMoment(input)) {
4640 return new Moment(checkOverflow(input));
4641 } else if (isDate(input)) {
4642 config._d = input;
4643 } else if (isArray(format)) {
4644 configFromStringAndArray(config);
4645 } else if (format) {
4646 configFromStringAndFormat(config);
4647 } else {
4648 configFromInput(config);
4649 }
4650
4651 if (!isValid(config)) {
4652 config._d = null;
4653 }
4654
4655 return config;
4656 }
4657
4658 function configFromInput(config) {
4659 var input = config._i;
4660
4661 if (isUndefined(input)) {
4662 config._d = new Date(hooks.now());
4663 } else if (isDate(input)) {
4664 config._d = new Date(input.valueOf());
4665 } else if (typeof input === 'string') {
4666 configFromString(config);
4667 } else if (isArray(input)) {
4668 config._a = map(input.slice(0), function (obj) {
4669 return parseInt(obj, 10);
4670 });
4671 configFromArray(config);
4672 } else if (isObject(input)) {
4673 configFromObject(config);
4674 } else if (isNumber(input)) {
4675 // from milliseconds
4676 config._d = new Date(input);
4677 } else {
4678 hooks.createFromInputFallback(config);
4679 }
4680 }
4681
4682 function createLocalOrUTC(input, format, locale, strict, isUTC) {
4683 var c = {};
4684
4685 if (locale === true || locale === false) {
4686 strict = locale;
4687 locale = undefined;
4688 }
4689
4690 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
4691 input = undefined;
4692 } // object construction must be done this way.
4693 // https://github.com/moment/moment/issues/1423
4694
4695
4696 c._isAMomentObject = true;
4697 c._useUTC = c._isUTC = isUTC;
4698 c._l = locale;
4699 c._i = input;
4700 c._f = format;
4701 c._strict = strict;
4702 return createFromConfig(c);
4703 }
4704
4705 function createLocal(input, format, locale, strict) {
4706 return createLocalOrUTC(input, format, locale, strict, false);
4707 }
4708
4709 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
4710 var other = createLocal.apply(null, arguments);
4711
4712 if (this.isValid() && other.isValid()) {
4713 return other < this ? this : other;
4714 } else {
4715 return createInvalid();
4716 }
4717 });
4718 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
4719 var other = createLocal.apply(null, arguments);
4720
4721 if (this.isValid() && other.isValid()) {
4722 return other > this ? this : other;
4723 } else {
4724 return createInvalid();
4725 }
4726 }); // Pick a moment m from moments so that m[fn](other) is true for all
4727 // other. This relies on the function fn to be transitive.
4728 //
4729 // moments should either be an array of moment objects or an array, whose
4730 // first element is an array of moment objects.
4731
4732 function pickBy(fn, moments) {
4733 var res, i;
4734
4735 if (moments.length === 1 && isArray(moments[0])) {
4736 moments = moments[0];
4737 }
4738
4739 if (!moments.length) {
4740 return createLocal();
4741 }
4742
4743 res = moments[0];
4744
4745 for (i = 1; i < moments.length; ++i) {
4746 if (!moments[i].isValid() || moments[i][fn](res)) {
4747 res = moments[i];
4748 }
4749 }
4750
4751 return res;
4752 } // TODO: Use [].sort instead?
4753
4754
4755 function min() {
4756 var args = [].slice.call(arguments, 0);
4757 return pickBy('isBefore', args);
4758 }
4759
4760 function max() {
4761 var args = [].slice.call(arguments, 0);
4762 return pickBy('isAfter', args);
4763 }
4764
4765 var now = function () {
4766 return Date.now ? Date.now() : +new Date();
4767 };
4768
4769 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
4770
4771 function isDurationValid(m) {
4772 for (var key in m) {
4773 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
4774 return false;
4775 }
4776 }
4777
4778 var unitHasDecimal = false;
4779
4780 for (var i = 0; i < ordering.length; ++i) {
4781 if (m[ordering[i]]) {
4782 if (unitHasDecimal) {
4783 return false; // only allow non-integers for smallest unit
4784 }
4785
4786 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
4787 unitHasDecimal = true;
4788 }
4789 }
4790 }
4791
4792 return true;
4793 }
4794
4795 function isValid$1() {
4796 return this._isValid;
4797 }
4798
4799 function createInvalid$1() {
4800 return createDuration(NaN);
4801 }
4802
4803 function Duration(duration) {
4804 var normalizedInput = normalizeObjectUnits(duration),
4805 years = normalizedInput.year || 0,
4806 quarters = normalizedInput.quarter || 0,
4807 months = normalizedInput.month || 0,
4808 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
4809 days = normalizedInput.day || 0,
4810 hours = normalizedInput.hour || 0,
4811 minutes = normalizedInput.minute || 0,
4812 seconds = normalizedInput.second || 0,
4813 milliseconds = normalizedInput.millisecond || 0;
4814 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
4815
4816 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
4817 minutes * 6e4 + // 1000 * 60
4818 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
4819 // Because of dateAddRemove treats 24 hours as different from a
4820 // day when working around DST, we need to store them separately
4821
4822 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
4823 // which months you are are talking about, so we have to store
4824 // it separately.
4825
4826 this._months = +months + quarters * 3 + years * 12;
4827 this._data = {};
4828 this._locale = getLocale();
4829
4830 this._bubble();
4831 }
4832
4833 function isDuration(obj) {
4834 return obj instanceof Duration;
4835 }
4836
4837 function absRound(number) {
4838 if (number < 0) {
4839 return Math.round(-1 * number) * -1;
4840 } else {
4841 return Math.round(number);
4842 }
4843 } // FORMATTING
4844
4845
4846 function offset(token, separator) {
4847 addFormatToken(token, 0, 0, function () {
4848 var offset = this.utcOffset();
4849 var sign = '+';
4850
4851 if (offset < 0) {
4852 offset = -offset;
4853 sign = '-';
4854 }
4855
4856 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
4857 });
4858 }
4859
4860 offset('Z', ':');
4861 offset('ZZ', ''); // PARSING
4862
4863 addRegexToken('Z', matchShortOffset);
4864 addRegexToken('ZZ', matchShortOffset);
4865 addParseToken(['Z', 'ZZ'], function (input, array, config) {
4866 config._useUTC = true;
4867 config._tzm = offsetFromString(matchShortOffset, input);
4868 }); // HELPERS
4869 // timezone chunker
4870 // '+10:00' > ['10', '00']
4871 // '-1530' > ['-15', '30']
4872
4873 var chunkOffset = /([\+\-]|\d\d)/gi;
4874
4875 function offsetFromString(matcher, string) {
4876 var matches = (string || '').match(matcher);
4877
4878 if (matches === null) {
4879 return null;
4880 }
4881
4882 var chunk = matches[matches.length - 1] || [];
4883 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
4884 var minutes = +(parts[1] * 60) + toInt(parts[2]);
4885 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
4886 } // Return a moment from input, that is local/utc/zone equivalent to model.
4887
4888
4889 function cloneWithOffset(input, model) {
4890 var res, diff;
4891
4892 if (model._isUTC) {
4893 res = model.clone();
4894 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
4895
4896 res._d.setTime(res._d.valueOf() + diff);
4897
4898 hooks.updateOffset(res, false);
4899 return res;
4900 } else {
4901 return createLocal(input).local();
4902 }
4903 }
4904
4905 function getDateOffset(m) {
4906 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
4907 // https://github.com/moment/moment/pull/1871
4908 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
4909 } // HOOKS
4910 // This function will be called whenever a moment is mutated.
4911 // It is intended to keep the offset in sync with the timezone.
4912
4913
4914 hooks.updateOffset = function () {}; // MOMENTS
4915 // keepLocalTime = true means only change the timezone, without
4916 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
4917 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
4918 // +0200, so we adjust the time as needed, to be valid.
4919 //
4920 // Keeping the time actually adds/subtracts (one hour)
4921 // from the actual represented time. That is why we call updateOffset
4922 // a second time. In case it wants us to change the offset again
4923 // _changeInProgress == true case, then we have to adjust, because
4924 // there is no such time in the given timezone.
4925
4926
4927 function getSetOffset(input, keepLocalTime, keepMinutes) {
4928 var offset = this._offset || 0,
4929 localAdjust;
4930
4931 if (!this.isValid()) {
4932 return input != null ? this : NaN;
4933 }
4934
4935 if (input != null) {
4936 if (typeof input === 'string') {
4937 input = offsetFromString(matchShortOffset, input);
4938
4939 if (input === null) {
4940 return this;
4941 }
4942 } else if (Math.abs(input) < 16 && !keepMinutes) {
4943 input = input * 60;
4944 }
4945
4946 if (!this._isUTC && keepLocalTime) {
4947 localAdjust = getDateOffset(this);
4948 }
4949
4950 this._offset = input;
4951 this._isUTC = true;
4952
4953 if (localAdjust != null) {
4954 this.add(localAdjust, 'm');
4955 }
4956
4957 if (offset !== input) {
4958 if (!keepLocalTime || this._changeInProgress) {
4959 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
4960 } else if (!this._changeInProgress) {
4961 this._changeInProgress = true;
4962 hooks.updateOffset(this, true);
4963 this._changeInProgress = null;
4964 }
4965 }
4966
4967 return this;
4968 } else {
4969 return this._isUTC ? offset : getDateOffset(this);
4970 }
4971 }
4972
4973 function getSetZone(input, keepLocalTime) {
4974 if (input != null) {
4975 if (typeof input !== 'string') {
4976 input = -input;
4977 }
4978
4979 this.utcOffset(input, keepLocalTime);
4980 return this;
4981 } else {
4982 return -this.utcOffset();
4983 }
4984 }
4985
4986 function setOffsetToUTC(keepLocalTime) {
4987 return this.utcOffset(0, keepLocalTime);
4988 }
4989
4990 function setOffsetToLocal(keepLocalTime) {
4991 if (this._isUTC) {
4992 this.utcOffset(0, keepLocalTime);
4993 this._isUTC = false;
4994
4995 if (keepLocalTime) {
4996 this.subtract(getDateOffset(this), 'm');
4997 }
4998 }
4999
5000 return this;
5001 }
5002
5003 function setOffsetToParsedOffset() {
5004 if (this._tzm != null) {
5005 this.utcOffset(this._tzm, false, true);
5006 } else if (typeof this._i === 'string') {
5007 var tZone = offsetFromString(matchOffset, this._i);
5008
5009 if (tZone != null) {
5010 this.utcOffset(tZone);
5011 } else {
5012 this.utcOffset(0, true);
5013 }
5014 }
5015
5016 return this;
5017 }
5018
5019 function hasAlignedHourOffset(input) {
5020 if (!this.isValid()) {
5021 return false;
5022 }
5023
5024 input = input ? createLocal(input).utcOffset() : 0;
5025 return (this.utcOffset() - input) % 60 === 0;
5026 }
5027
5028 function isDaylightSavingTime() {
5029 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
5030 }
5031
5032 function isDaylightSavingTimeShifted() {
5033 if (!isUndefined(this._isDSTShifted)) {
5034 return this._isDSTShifted;
5035 }
5036
5037 var c = {};
5038 copyConfig(c, this);
5039 c = prepareConfig(c);
5040
5041 if (c._a) {
5042 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
5043 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
5044 } else {
5045 this._isDSTShifted = false;
5046 }
5047
5048 return this._isDSTShifted;
5049 }
5050
5051 function isLocal() {
5052 return this.isValid() ? !this._isUTC : false;
5053 }
5054
5055 function isUtcOffset() {
5056 return this.isValid() ? this._isUTC : false;
5057 }
5058
5059 function isUtc() {
5060 return this.isValid() ? this._isUTC && this._offset === 0 : false;
5061 } // ASP.NET json date format regex
5062
5063
5064 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
5065 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
5066 // and further modified to allow for strings containing both week and day
5067
5068 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)?)?$/;
5069
5070 function createDuration(input, key) {
5071 var duration = input,
5072 // matching against regexp is expensive, do it on demand
5073 match = null,
5074 sign,
5075 ret,
5076 diffRes;
5077
5078 if (isDuration(input)) {
5079 duration = {
5080 ms: input._milliseconds,
5081 d: input._days,
5082 M: input._months
5083 };
5084 } else if (isNumber(input)) {
5085 duration = {};
5086
5087 if (key) {
5088 duration[key] = input;
5089 } else {
5090 duration.milliseconds = input;
5091 }
5092 } else if (!!(match = aspNetRegex.exec(input))) {
5093 sign = match[1] === '-' ? -1 : 1;
5094 duration = {
5095 y: 0,
5096 d: toInt(match[DATE]) * sign,
5097 h: toInt(match[HOUR]) * sign,
5098 m: toInt(match[MINUTE]) * sign,
5099 s: toInt(match[SECOND]) * sign,
5100 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
5101
5102 };
5103 } else if (!!(match = isoRegex.exec(input))) {
5104 sign = match[1] === '-' ? -1 : 1;
5105 duration = {
5106 y: parseIso(match[2], sign),
5107 M: parseIso(match[3], sign),
5108 w: parseIso(match[4], sign),
5109 d: parseIso(match[5], sign),
5110 h: parseIso(match[6], sign),
5111 m: parseIso(match[7], sign),
5112 s: parseIso(match[8], sign)
5113 };
5114 } else if (duration == null) {
5115 // checks for null or undefined
5116 duration = {};
5117 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
5118 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
5119 duration = {};
5120 duration.ms = diffRes.milliseconds;
5121 duration.M = diffRes.months;
5122 }
5123
5124 ret = new Duration(duration);
5125
5126 if (isDuration(input) && hasOwnProp(input, '_locale')) {
5127 ret._locale = input._locale;
5128 }
5129
5130 return ret;
5131 }
5132
5133 createDuration.fn = Duration.prototype;
5134 createDuration.invalid = createInvalid$1;
5135
5136 function parseIso(inp, sign) {
5137 // We'd normally use ~~inp for this, but unfortunately it also
5138 // converts floats to ints.
5139 // inp may be undefined, so careful calling replace on it.
5140 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
5141
5142 return (isNaN(res) ? 0 : res) * sign;
5143 }
5144
5145 function positiveMomentsDifference(base, other) {
5146 var res = {};
5147 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
5148
5149 if (base.clone().add(res.months, 'M').isAfter(other)) {
5150 --res.months;
5151 }
5152
5153 res.milliseconds = +other - +base.clone().add(res.months, 'M');
5154 return res;
5155 }
5156
5157 function momentsDifference(base, other) {
5158 var res;
5159
5160 if (!(base.isValid() && other.isValid())) {
5161 return {
5162 milliseconds: 0,
5163 months: 0
5164 };
5165 }
5166
5167 other = cloneWithOffset(other, base);
5168
5169 if (base.isBefore(other)) {
5170 res = positiveMomentsDifference(base, other);
5171 } else {
5172 res = positiveMomentsDifference(other, base);
5173 res.milliseconds = -res.milliseconds;
5174 res.months = -res.months;
5175 }
5176
5177 return res;
5178 } // TODO: remove 'name' arg after deprecation is removed
5179
5180
5181 function createAdder(direction, name) {
5182 return function (val, period) {
5183 var dur, tmp; //invert the arguments, but complain about it
5184
5185 if (period !== null && !isNaN(+period)) {
5186 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.');
5187 tmp = val;
5188 val = period;
5189 period = tmp;
5190 }
5191
5192 val = typeof val === 'string' ? +val : val;
5193 dur = createDuration(val, period);
5194 addSubtract(this, dur, direction);
5195 return this;
5196 };
5197 }
5198
5199 function addSubtract(mom, duration, isAdding, updateOffset) {
5200 var milliseconds = duration._milliseconds,
5201 days = absRound(duration._days),
5202 months = absRound(duration._months);
5203
5204 if (!mom.isValid()) {
5205 // No op
5206 return;
5207 }
5208
5209 updateOffset = updateOffset == null ? true : updateOffset;
5210
5211 if (months) {
5212 setMonth(mom, get(mom, 'Month') + months * isAdding);
5213 }
5214
5215 if (days) {
5216 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
5217 }
5218
5219 if (milliseconds) {
5220 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
5221 }
5222
5223 if (updateOffset) {
5224 hooks.updateOffset(mom, days || months);
5225 }
5226 }
5227
5228 var add = createAdder(1, 'add');
5229 var subtract = createAdder(-1, 'subtract');
5230
5231 function getCalendarFormat(myMoment, now) {
5232 var diff = myMoment.diff(now, 'days', true);
5233 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
5234 }
5235
5236 function calendar$1(time, formats) {
5237 // We want to compare the start of today, vs this.
5238 // Getting start-of-today depends on whether we're local/utc/offset or not.
5239 var now = time || createLocal(),
5240 sod = cloneWithOffset(now, this).startOf('day'),
5241 format = hooks.calendarFormat(this, sod) || 'sameElse';
5242 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
5243 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
5244 }
5245
5246 function clone() {
5247 return new Moment(this);
5248 }
5249
5250 function isAfter(input, units) {
5251 var localInput = isMoment(input) ? input : createLocal(input);
5252
5253 if (!(this.isValid() && localInput.isValid())) {
5254 return false;
5255 }
5256
5257 units = normalizeUnits(units) || 'millisecond';
5258
5259 if (units === 'millisecond') {
5260 return this.valueOf() > localInput.valueOf();
5261 } else {
5262 return localInput.valueOf() < this.clone().startOf(units).valueOf();
5263 }
5264 }
5265
5266 function isBefore(input, units) {
5267 var localInput = isMoment(input) ? input : createLocal(input);
5268
5269 if (!(this.isValid() && localInput.isValid())) {
5270 return false;
5271 }
5272
5273 units = normalizeUnits(units) || 'millisecond';
5274
5275 if (units === 'millisecond') {
5276 return this.valueOf() < localInput.valueOf();
5277 } else {
5278 return this.clone().endOf(units).valueOf() < localInput.valueOf();
5279 }
5280 }
5281
5282 function isBetween(from, to, units, inclusivity) {
5283 var localFrom = isMoment(from) ? from : createLocal(from),
5284 localTo = isMoment(to) ? to : createLocal(to);
5285
5286 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
5287 return false;
5288 }
5289
5290 inclusivity = inclusivity || '()';
5291 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
5292 }
5293
5294 function isSame(input, units) {
5295 var localInput = isMoment(input) ? input : createLocal(input),
5296 inputMs;
5297
5298 if (!(this.isValid() && localInput.isValid())) {
5299 return false;
5300 }
5301
5302 units = normalizeUnits(units) || 'millisecond';
5303
5304 if (units === 'millisecond') {
5305 return this.valueOf() === localInput.valueOf();
5306 } else {
5307 inputMs = localInput.valueOf();
5308 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
5309 }
5310 }
5311
5312 function isSameOrAfter(input, units) {
5313 return this.isSame(input, units) || this.isAfter(input, units);
5314 }
5315
5316 function isSameOrBefore(input, units) {
5317 return this.isSame(input, units) || this.isBefore(input, units);
5318 }
5319
5320 function diff(input, units, asFloat) {
5321 var that, zoneDelta, output;
5322
5323 if (!this.isValid()) {
5324 return NaN;
5325 }
5326
5327 that = cloneWithOffset(input, this);
5328
5329 if (!that.isValid()) {
5330 return NaN;
5331 }
5332
5333 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
5334 units = normalizeUnits(units);
5335
5336 switch (units) {
5337 case 'year':
5338 output = monthDiff(this, that) / 12;
5339 break;
5340
5341 case 'month':
5342 output = monthDiff(this, that);
5343 break;
5344
5345 case 'quarter':
5346 output = monthDiff(this, that) / 3;
5347 break;
5348
5349 case 'second':
5350 output = (this - that) / 1e3;
5351 break;
5352 // 1000
5353
5354 case 'minute':
5355 output = (this - that) / 6e4;
5356 break;
5357 // 1000 * 60
5358
5359 case 'hour':
5360 output = (this - that) / 36e5;
5361 break;
5362 // 1000 * 60 * 60
5363
5364 case 'day':
5365 output = (this - that - zoneDelta) / 864e5;
5366 break;
5367 // 1000 * 60 * 60 * 24, negate dst
5368
5369 case 'week':
5370 output = (this - that - zoneDelta) / 6048e5;
5371 break;
5372 // 1000 * 60 * 60 * 24 * 7, negate dst
5373
5374 default:
5375 output = this - that;
5376 }
5377
5378 return asFloat ? output : absFloor(output);
5379 }
5380
5381 function monthDiff(a, b) {
5382 // difference in months
5383 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
5384 // b is in (anchor - 1 month, anchor + 1 month)
5385 anchor = a.clone().add(wholeMonthDiff, 'months'),
5386 anchor2,
5387 adjust;
5388
5389 if (b - anchor < 0) {
5390 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
5391
5392 adjust = (b - anchor) / (anchor - anchor2);
5393 } else {
5394 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
5395
5396 adjust = (b - anchor) / (anchor2 - anchor);
5397 } //check for negative zero, return zero if negative zero
5398
5399
5400 return -(wholeMonthDiff + adjust) || 0;
5401 }
5402
5403 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
5404 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
5405
5406 function toString() {
5407 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
5408 }
5409
5410 function toISOString(keepOffset) {
5411 if (!this.isValid()) {
5412 return null;
5413 }
5414
5415 var utc = keepOffset !== true;
5416 var m = utc ? this.clone().utc() : this;
5417
5418 if (m.year() < 0 || m.year() > 9999) {
5419 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
5420 }
5421
5422 if (isFunction(Date.prototype.toISOString)) {
5423 // native implementation is ~50x faster, use it when we can
5424 if (utc) {
5425 return this.toDate().toISOString();
5426 } else {
5427 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
5428 }
5429 }
5430
5431 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
5432 }
5433 /**
5434 * Return a human readable representation of a moment that can
5435 * also be evaluated to get a new moment which is the same
5436 *
5437 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
5438 */
5439
5440
5441 function inspect() {
5442 if (!this.isValid()) {
5443 return 'moment.invalid(/* ' + this._i + ' */)';
5444 }
5445
5446 var func = 'moment';
5447 var zone = '';
5448
5449 if (!this.isLocal()) {
5450 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
5451 zone = 'Z';
5452 }
5453
5454 var prefix = '[' + func + '("]';
5455 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
5456 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
5457 var suffix = zone + '[")]';
5458 return this.format(prefix + year + datetime + suffix);
5459 }
5460
5461 function format(inputString) {
5462 if (!inputString) {
5463 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
5464 }
5465
5466 var output = formatMoment(this, inputString);
5467 return this.localeData().postformat(output);
5468 }
5469
5470 function from(time, withoutSuffix) {
5471 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
5472 return createDuration({
5473 to: this,
5474 from: time
5475 }).locale(this.locale()).humanize(!withoutSuffix);
5476 } else {
5477 return this.localeData().invalidDate();
5478 }
5479 }
5480
5481 function fromNow(withoutSuffix) {
5482 return this.from(createLocal(), withoutSuffix);
5483 }
5484
5485 function to(time, withoutSuffix) {
5486 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
5487 return createDuration({
5488 from: this,
5489 to: time
5490 }).locale(this.locale()).humanize(!withoutSuffix);
5491 } else {
5492 return this.localeData().invalidDate();
5493 }
5494 }
5495
5496 function toNow(withoutSuffix) {
5497 return this.to(createLocal(), withoutSuffix);
5498 } // If passed a locale key, it will set the locale for this
5499 // instance. Otherwise, it will return the locale configuration
5500 // variables for this instance.
5501
5502
5503 function locale(key) {
5504 var newLocaleData;
5505
5506 if (key === undefined) {
5507 return this._locale._abbr;
5508 } else {
5509 newLocaleData = getLocale(key);
5510
5511 if (newLocaleData != null) {
5512 this._locale = newLocaleData;
5513 }
5514
5515 return this;
5516 }
5517 }
5518
5519 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
5520 if (key === undefined) {
5521 return this.localeData();
5522 } else {
5523 return this.locale(key);
5524 }
5525 });
5526
5527 function localeData() {
5528 return this._locale;
5529 }
5530
5531 var MS_PER_SECOND = 1000;
5532 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
5533 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
5534 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
5535
5536 function mod$1(dividend, divisor) {
5537 return (dividend % divisor + divisor) % divisor;
5538 }
5539
5540 function localStartOfDate(y, m, d) {
5541 // the date constructor remaps years 0-99 to 1900-1999
5542 if (y < 100 && y >= 0) {
5543 // preserve leap years using a full 400 year cycle, then reset
5544 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
5545 } else {
5546 return new Date(y, m, d).valueOf();
5547 }
5548 }
5549
5550 function utcStartOfDate(y, m, d) {
5551 // Date.UTC remaps years 0-99 to 1900-1999
5552 if (y < 100 && y >= 0) {
5553 // preserve leap years using a full 400 year cycle, then reset
5554 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
5555 } else {
5556 return Date.UTC(y, m, d);
5557 }
5558 }
5559
5560 function startOf(units) {
5561 var time;
5562 units = normalizeUnits(units);
5563
5564 if (units === undefined || units === 'millisecond' || !this.isValid()) {
5565 return this;
5566 }
5567
5568 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
5569
5570 switch (units) {
5571 case 'year':
5572 time = startOfDate(this.year(), 0, 1);
5573 break;
5574
5575 case 'quarter':
5576 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
5577 break;
5578
5579 case 'month':
5580 time = startOfDate(this.year(), this.month(), 1);
5581 break;
5582
5583 case 'week':
5584 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
5585 break;
5586
5587 case 'isoWeek':
5588 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
5589 break;
5590
5591 case 'day':
5592 case 'date':
5593 time = startOfDate(this.year(), this.month(), this.date());
5594 break;
5595
5596 case 'hour':
5597 time = this._d.valueOf();
5598 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
5599 break;
5600
5601 case 'minute':
5602 time = this._d.valueOf();
5603 time -= mod$1(time, MS_PER_MINUTE);
5604 break;
5605
5606 case 'second':
5607 time = this._d.valueOf();
5608 time -= mod$1(time, MS_PER_SECOND);
5609 break;
5610 }
5611
5612 this._d.setTime(time);
5613
5614 hooks.updateOffset(this, true);
5615 return this;
5616 }
5617
5618 function endOf(units) {
5619 var time;
5620 units = normalizeUnits(units);
5621
5622 if (units === undefined || units === 'millisecond' || !this.isValid()) {
5623 return this;
5624 }
5625
5626 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
5627
5628 switch (units) {
5629 case 'year':
5630 time = startOfDate(this.year() + 1, 0, 1) - 1;
5631 break;
5632
5633 case 'quarter':
5634 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
5635 break;
5636
5637 case 'month':
5638 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
5639 break;
5640
5641 case 'week':
5642 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
5643 break;
5644
5645 case 'isoWeek':
5646 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
5647 break;
5648
5649 case 'day':
5650 case 'date':
5651 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
5652 break;
5653
5654 case 'hour':
5655 time = this._d.valueOf();
5656 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
5657 break;
5658
5659 case 'minute':
5660 time = this._d.valueOf();
5661 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
5662 break;
5663
5664 case 'second':
5665 time = this._d.valueOf();
5666 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
5667 break;
5668 }
5669
5670 this._d.setTime(time);
5671
5672 hooks.updateOffset(this, true);
5673 return this;
5674 }
5675
5676 function valueOf() {
5677 return this._d.valueOf() - (this._offset || 0) * 60000;
5678 }
5679
5680 function unix() {
5681 return Math.floor(this.valueOf() / 1000);
5682 }
5683
5684 function toDate() {
5685 return new Date(this.valueOf());
5686 }
5687
5688 function toArray() {
5689 var m = this;
5690 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
5691 }
5692
5693 function toObject() {
5694 var m = this;
5695 return {
5696 years: m.year(),
5697 months: m.month(),
5698 date: m.date(),
5699 hours: m.hours(),
5700 minutes: m.minutes(),
5701 seconds: m.seconds(),
5702 milliseconds: m.milliseconds()
5703 };
5704 }
5705
5706 function toJSON() {
5707 // new Date(NaN).toJSON() === null
5708 return this.isValid() ? this.toISOString() : null;
5709 }
5710
5711 function isValid$2() {
5712 return isValid(this);
5713 }
5714
5715 function parsingFlags() {
5716 return extend({}, getParsingFlags(this));
5717 }
5718
5719 function invalidAt() {
5720 return getParsingFlags(this).overflow;
5721 }
5722
5723 function creationData() {
5724 return {
5725 input: this._i,
5726 format: this._f,
5727 locale: this._locale,
5728 isUTC: this._isUTC,
5729 strict: this._strict
5730 };
5731 } // FORMATTING
5732
5733
5734 addFormatToken(0, ['gg', 2], 0, function () {
5735 return this.weekYear() % 100;
5736 });
5737 addFormatToken(0, ['GG', 2], 0, function () {
5738 return this.isoWeekYear() % 100;
5739 });
5740
5741 function addWeekYearFormatToken(token, getter) {
5742 addFormatToken(0, [token, token.length], 0, getter);
5743 }
5744
5745 addWeekYearFormatToken('gggg', 'weekYear');
5746 addWeekYearFormatToken('ggggg', 'weekYear');
5747 addWeekYearFormatToken('GGGG', 'isoWeekYear');
5748 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
5749
5750 addUnitAlias('weekYear', 'gg');
5751 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
5752
5753 addUnitPriority('weekYear', 1);
5754 addUnitPriority('isoWeekYear', 1); // PARSING
5755
5756 addRegexToken('G', matchSigned);
5757 addRegexToken('g', matchSigned);
5758 addRegexToken('GG', match1to2, match2);
5759 addRegexToken('gg', match1to2, match2);
5760 addRegexToken('GGGG', match1to4, match4);
5761 addRegexToken('gggg', match1to4, match4);
5762 addRegexToken('GGGGG', match1to6, match6);
5763 addRegexToken('ggggg', match1to6, match6);
5764 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
5765 week[token.substr(0, 2)] = toInt(input);
5766 });
5767 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
5768 week[token] = hooks.parseTwoDigitYear(input);
5769 }); // MOMENTS
5770
5771 function getSetWeekYear(input) {
5772 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
5773 }
5774
5775 function getSetISOWeekYear(input) {
5776 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
5777 }
5778
5779 function getISOWeeksInYear() {
5780 return weeksInYear(this.year(), 1, 4);
5781 }
5782
5783 function getWeeksInYear() {
5784 var weekInfo = this.localeData()._week;
5785
5786 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
5787 }
5788
5789 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
5790 var weeksTarget;
5791
5792 if (input == null) {
5793 return weekOfYear(this, dow, doy).year;
5794 } else {
5795 weeksTarget = weeksInYear(input, dow, doy);
5796
5797 if (week > weeksTarget) {
5798 week = weeksTarget;
5799 }
5800
5801 return setWeekAll.call(this, input, week, weekday, dow, doy);
5802 }
5803 }
5804
5805 function setWeekAll(weekYear, week, weekday, dow, doy) {
5806 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
5807 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
5808 this.year(date.getUTCFullYear());
5809 this.month(date.getUTCMonth());
5810 this.date(date.getUTCDate());
5811 return this;
5812 } // FORMATTING
5813
5814
5815 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
5816
5817 addUnitAlias('quarter', 'Q'); // PRIORITY
5818
5819 addUnitPriority('quarter', 7); // PARSING
5820
5821 addRegexToken('Q', match1);
5822 addParseToken('Q', function (input, array) {
5823 array[MONTH] = (toInt(input) - 1) * 3;
5824 }); // MOMENTS
5825
5826 function getSetQuarter(input) {
5827 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
5828 } // FORMATTING
5829
5830
5831 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
5832
5833 addUnitAlias('date', 'D'); // PRIORITY
5834
5835 addUnitPriority('date', 9); // PARSING
5836
5837 addRegexToken('D', match1to2);
5838 addRegexToken('DD', match1to2, match2);
5839 addRegexToken('Do', function (isStrict, locale) {
5840 // TODO: Remove "ordinalParse" fallback in next major release.
5841 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
5842 });
5843 addParseToken(['D', 'DD'], DATE);
5844 addParseToken('Do', function (input, array) {
5845 array[DATE] = toInt(input.match(match1to2)[0]);
5846 }); // MOMENTS
5847
5848 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
5849
5850 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
5851
5852 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
5853
5854 addUnitPriority('dayOfYear', 4); // PARSING
5855
5856 addRegexToken('DDD', match1to3);
5857 addRegexToken('DDDD', match3);
5858 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
5859 config._dayOfYear = toInt(input);
5860 }); // HELPERS
5861 // MOMENTS
5862
5863 function getSetDayOfYear(input) {
5864 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
5865 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
5866 } // FORMATTING
5867
5868
5869 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
5870
5871 addUnitAlias('minute', 'm'); // PRIORITY
5872
5873 addUnitPriority('minute', 14); // PARSING
5874
5875 addRegexToken('m', match1to2);
5876 addRegexToken('mm', match1to2, match2);
5877 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
5878
5879 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
5880
5881 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
5882
5883 addUnitAlias('second', 's'); // PRIORITY
5884
5885 addUnitPriority('second', 15); // PARSING
5886
5887 addRegexToken('s', match1to2);
5888 addRegexToken('ss', match1to2, match2);
5889 addParseToken(['s', 'ss'], SECOND); // MOMENTS
5890
5891 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
5892
5893 addFormatToken('S', 0, 0, function () {
5894 return ~~(this.millisecond() / 100);
5895 });
5896 addFormatToken(0, ['SS', 2], 0, function () {
5897 return ~~(this.millisecond() / 10);
5898 });
5899 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
5900 addFormatToken(0, ['SSSS', 4], 0, function () {
5901 return this.millisecond() * 10;
5902 });
5903 addFormatToken(0, ['SSSSS', 5], 0, function () {
5904 return this.millisecond() * 100;
5905 });
5906 addFormatToken(0, ['SSSSSS', 6], 0, function () {
5907 return this.millisecond() * 1000;
5908 });
5909 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
5910 return this.millisecond() * 10000;
5911 });
5912 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
5913 return this.millisecond() * 100000;
5914 });
5915 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
5916 return this.millisecond() * 1000000;
5917 }); // ALIASES
5918
5919 addUnitAlias('millisecond', 'ms'); // PRIORITY
5920
5921 addUnitPriority('millisecond', 16); // PARSING
5922
5923 addRegexToken('S', match1to3, match1);
5924 addRegexToken('SS', match1to3, match2);
5925 addRegexToken('SSS', match1to3, match3);
5926 var token;
5927
5928 for (token = 'SSSS'; token.length <= 9; token += 'S') {
5929 addRegexToken(token, matchUnsigned);
5930 }
5931
5932 function parseMs(input, array) {
5933 array[MILLISECOND] = toInt(('0.' + input) * 1000);
5934 }
5935
5936 for (token = 'S'; token.length <= 9; token += 'S') {
5937 addParseToken(token, parseMs);
5938 } // MOMENTS
5939
5940
5941 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
5942
5943 addFormatToken('z', 0, 0, 'zoneAbbr');
5944 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
5945
5946 function getZoneAbbr() {
5947 return this._isUTC ? 'UTC' : '';
5948 }
5949
5950 function getZoneName() {
5951 return this._isUTC ? 'Coordinated Universal Time' : '';
5952 }
5953
5954 var proto = Moment.prototype;
5955 proto.add = add;
5956 proto.calendar = calendar$1;
5957 proto.clone = clone;
5958 proto.diff = diff;
5959 proto.endOf = endOf;
5960 proto.format = format;
5961 proto.from = from;
5962 proto.fromNow = fromNow;
5963 proto.to = to;
5964 proto.toNow = toNow;
5965 proto.get = stringGet;
5966 proto.invalidAt = invalidAt;
5967 proto.isAfter = isAfter;
5968 proto.isBefore = isBefore;
5969 proto.isBetween = isBetween;
5970 proto.isSame = isSame;
5971 proto.isSameOrAfter = isSameOrAfter;
5972 proto.isSameOrBefore = isSameOrBefore;
5973 proto.isValid = isValid$2;
5974 proto.lang = lang;
5975 proto.locale = locale;
5976 proto.localeData = localeData;
5977 proto.max = prototypeMax;
5978 proto.min = prototypeMin;
5979 proto.parsingFlags = parsingFlags;
5980 proto.set = stringSet;
5981 proto.startOf = startOf;
5982 proto.subtract = subtract;
5983 proto.toArray = toArray;
5984 proto.toObject = toObject;
5985 proto.toDate = toDate;
5986 proto.toISOString = toISOString;
5987 proto.inspect = inspect;
5988 proto.toJSON = toJSON;
5989 proto.toString = toString;
5990 proto.unix = unix;
5991 proto.valueOf = valueOf;
5992 proto.creationData = creationData;
5993 proto.year = getSetYear;
5994 proto.isLeapYear = getIsLeapYear;
5995 proto.weekYear = getSetWeekYear;
5996 proto.isoWeekYear = getSetISOWeekYear;
5997 proto.quarter = proto.quarters = getSetQuarter;
5998 proto.month = getSetMonth;
5999 proto.daysInMonth = getDaysInMonth;
6000 proto.week = proto.weeks = getSetWeek;
6001 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
6002 proto.weeksInYear = getWeeksInYear;
6003 proto.isoWeeksInYear = getISOWeeksInYear;
6004 proto.date = getSetDayOfMonth;
6005 proto.day = proto.days = getSetDayOfWeek;
6006 proto.weekday = getSetLocaleDayOfWeek;
6007 proto.isoWeekday = getSetISODayOfWeek;
6008 proto.dayOfYear = getSetDayOfYear;
6009 proto.hour = proto.hours = getSetHour;
6010 proto.minute = proto.minutes = getSetMinute;
6011 proto.second = proto.seconds = getSetSecond;
6012 proto.millisecond = proto.milliseconds = getSetMillisecond;
6013 proto.utcOffset = getSetOffset;
6014 proto.utc = setOffsetToUTC;
6015 proto.local = setOffsetToLocal;
6016 proto.parseZone = setOffsetToParsedOffset;
6017 proto.hasAlignedHourOffset = hasAlignedHourOffset;
6018 proto.isDST = isDaylightSavingTime;
6019 proto.isLocal = isLocal;
6020 proto.isUtcOffset = isUtcOffset;
6021 proto.isUtc = isUtc;
6022 proto.isUTC = isUtc;
6023 proto.zoneAbbr = getZoneAbbr;
6024 proto.zoneName = getZoneName;
6025 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
6026 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
6027 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
6028 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
6029 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
6030
6031 function createUnix(input) {
6032 return createLocal(input * 1000);
6033 }
6034
6035 function createInZone() {
6036 return createLocal.apply(null, arguments).parseZone();
6037 }
6038
6039 function preParsePostFormat(string) {
6040 return string;
6041 }
6042
6043 var proto$1 = Locale.prototype;
6044 proto$1.calendar = calendar;
6045 proto$1.longDateFormat = longDateFormat;
6046 proto$1.invalidDate = invalidDate;
6047 proto$1.ordinal = ordinal;
6048 proto$1.preparse = preParsePostFormat;
6049 proto$1.postformat = preParsePostFormat;
6050 proto$1.relativeTime = relativeTime;
6051 proto$1.pastFuture = pastFuture;
6052 proto$1.set = set;
6053 proto$1.months = localeMonths;
6054 proto$1.monthsShort = localeMonthsShort;
6055 proto$1.monthsParse = localeMonthsParse;
6056 proto$1.monthsRegex = monthsRegex;
6057 proto$1.monthsShortRegex = monthsShortRegex;
6058 proto$1.week = localeWeek;
6059 proto$1.firstDayOfYear = localeFirstDayOfYear;
6060 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
6061 proto$1.weekdays = localeWeekdays;
6062 proto$1.weekdaysMin = localeWeekdaysMin;
6063 proto$1.weekdaysShort = localeWeekdaysShort;
6064 proto$1.weekdaysParse = localeWeekdaysParse;
6065 proto$1.weekdaysRegex = weekdaysRegex;
6066 proto$1.weekdaysShortRegex = weekdaysShortRegex;
6067 proto$1.weekdaysMinRegex = weekdaysMinRegex;
6068 proto$1.isPM = localeIsPM;
6069 proto$1.meridiem = localeMeridiem;
6070
6071 function get$1(format, index, field, setter) {
6072 var locale = getLocale();
6073 var utc = createUTC().set(setter, index);
6074 return locale[field](utc, format);
6075 }
6076
6077 function listMonthsImpl(format, index, field) {
6078 if (isNumber(format)) {
6079 index = format;
6080 format = undefined;
6081 }
6082
6083 format = format || '';
6084
6085 if (index != null) {
6086 return get$1(format, index, field, 'month');
6087 }
6088
6089 var i;
6090 var out = [];
6091
6092 for (i = 0; i < 12; i++) {
6093 out[i] = get$1(format, i, field, 'month');
6094 }
6095
6096 return out;
6097 } // ()
6098 // (5)
6099 // (fmt, 5)
6100 // (fmt)
6101 // (true)
6102 // (true, 5)
6103 // (true, fmt, 5)
6104 // (true, fmt)
6105
6106
6107 function listWeekdaysImpl(localeSorted, format, index, field) {
6108 if (typeof localeSorted === 'boolean') {
6109 if (isNumber(format)) {
6110 index = format;
6111 format = undefined;
6112 }
6113
6114 format = format || '';
6115 } else {
6116 format = localeSorted;
6117 index = format;
6118 localeSorted = false;
6119
6120 if (isNumber(format)) {
6121 index = format;
6122 format = undefined;
6123 }
6124
6125 format = format || '';
6126 }
6127
6128 var locale = getLocale(),
6129 shift = localeSorted ? locale._week.dow : 0;
6130
6131 if (index != null) {
6132 return get$1(format, (index + shift) % 7, field, 'day');
6133 }
6134
6135 var i;
6136 var out = [];
6137
6138 for (i = 0; i < 7; i++) {
6139 out[i] = get$1(format, (i + shift) % 7, field, 'day');
6140 }
6141
6142 return out;
6143 }
6144
6145 function listMonths(format, index) {
6146 return listMonthsImpl(format, index, 'months');
6147 }
6148
6149 function listMonthsShort(format, index) {
6150 return listMonthsImpl(format, index, 'monthsShort');
6151 }
6152
6153 function listWeekdays(localeSorted, format, index) {
6154 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
6155 }
6156
6157 function listWeekdaysShort(localeSorted, format, index) {
6158 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
6159 }
6160
6161 function listWeekdaysMin(localeSorted, format, index) {
6162 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
6163 }
6164
6165 getSetGlobalLocale('en', {
6166 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
6167 ordinal: function (number) {
6168 var b = number % 10,
6169 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
6170 return number + output;
6171 }
6172 }); // Side effect imports
6173
6174 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
6175 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
6176 var mathAbs = Math.abs;
6177
6178 function abs() {
6179 var data = this._data;
6180 this._milliseconds = mathAbs(this._milliseconds);
6181 this._days = mathAbs(this._days);
6182 this._months = mathAbs(this._months);
6183 data.milliseconds = mathAbs(data.milliseconds);
6184 data.seconds = mathAbs(data.seconds);
6185 data.minutes = mathAbs(data.minutes);
6186 data.hours = mathAbs(data.hours);
6187 data.months = mathAbs(data.months);
6188 data.years = mathAbs(data.years);
6189 return this;
6190 }
6191
6192 function addSubtract$1(duration, input, value, direction) {
6193 var other = createDuration(input, value);
6194 duration._milliseconds += direction * other._milliseconds;
6195 duration._days += direction * other._days;
6196 duration._months += direction * other._months;
6197 return duration._bubble();
6198 } // supports only 2.0-style add(1, 's') or add(duration)
6199
6200
6201 function add$1(input, value) {
6202 return addSubtract$1(this, input, value, 1);
6203 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
6204
6205
6206 function subtract$1(input, value) {
6207 return addSubtract$1(this, input, value, -1);
6208 }
6209
6210 function absCeil(number) {
6211 if (number < 0) {
6212 return Math.floor(number);
6213 } else {
6214 return Math.ceil(number);
6215 }
6216 }
6217
6218 function bubble() {
6219 var milliseconds = this._milliseconds;
6220 var days = this._days;
6221 var months = this._months;
6222 var data = this._data;
6223 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
6224 // check: https://github.com/moment/moment/issues/2166
6225
6226 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
6227 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
6228 days = 0;
6229 months = 0;
6230 } // The following code bubbles up values, see the tests for
6231 // examples of what that means.
6232
6233
6234 data.milliseconds = milliseconds % 1000;
6235 seconds = absFloor(milliseconds / 1000);
6236 data.seconds = seconds % 60;
6237 minutes = absFloor(seconds / 60);
6238 data.minutes = minutes % 60;
6239 hours = absFloor(minutes / 60);
6240 data.hours = hours % 24;
6241 days += absFloor(hours / 24); // convert days to months
6242
6243 monthsFromDays = absFloor(daysToMonths(days));
6244 months += monthsFromDays;
6245 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
6246
6247 years = absFloor(months / 12);
6248 months %= 12;
6249 data.days = days;
6250 data.months = months;
6251 data.years = years;
6252 return this;
6253 }
6254
6255 function daysToMonths(days) {
6256 // 400 years have 146097 days (taking into account leap year rules)
6257 // 400 years have 12 months === 4800
6258 return days * 4800 / 146097;
6259 }
6260
6261 function monthsToDays(months) {
6262 // the reverse of daysToMonths
6263 return months * 146097 / 4800;
6264 }
6265
6266 function as(units) {
6267 if (!this.isValid()) {
6268 return NaN;
6269 }
6270
6271 var days;
6272 var months;
6273 var milliseconds = this._milliseconds;
6274 units = normalizeUnits(units);
6275
6276 if (units === 'month' || units === 'quarter' || units === 'year') {
6277 days = this._days + milliseconds / 864e5;
6278 months = this._months + daysToMonths(days);
6279
6280 switch (units) {
6281 case 'month':
6282 return months;
6283
6284 case 'quarter':
6285 return months / 3;
6286
6287 case 'year':
6288 return months / 12;
6289 }
6290 } else {
6291 // handle milliseconds separately because of floating point math errors (issue #1867)
6292 days = this._days + Math.round(monthsToDays(this._months));
6293
6294 switch (units) {
6295 case 'week':
6296 return days / 7 + milliseconds / 6048e5;
6297
6298 case 'day':
6299 return days + milliseconds / 864e5;
6300
6301 case 'hour':
6302 return days * 24 + milliseconds / 36e5;
6303
6304 case 'minute':
6305 return days * 1440 + milliseconds / 6e4;
6306
6307 case 'second':
6308 return days * 86400 + milliseconds / 1000;
6309 // Math.floor prevents floating point math errors here
6310
6311 case 'millisecond':
6312 return Math.floor(days * 864e5) + milliseconds;
6313
6314 default:
6315 throw new Error('Unknown unit ' + units);
6316 }
6317 }
6318 } // TODO: Use this.as('ms')?
6319
6320
6321 function valueOf$1() {
6322 if (!this.isValid()) {
6323 return NaN;
6324 }
6325
6326 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
6327 }
6328
6329 function makeAs(alias) {
6330 return function () {
6331 return this.as(alias);
6332 };
6333 }
6334
6335 var asMilliseconds = makeAs('ms');
6336 var asSeconds = makeAs('s');
6337 var asMinutes = makeAs('m');
6338 var asHours = makeAs('h');
6339 var asDays = makeAs('d');
6340 var asWeeks = makeAs('w');
6341 var asMonths = makeAs('M');
6342 var asQuarters = makeAs('Q');
6343 var asYears = makeAs('y');
6344
6345 function clone$1() {
6346 return createDuration(this);
6347 }
6348
6349 function get$2(units) {
6350 units = normalizeUnits(units);
6351 return this.isValid() ? this[units + 's']() : NaN;
6352 }
6353
6354 function makeGetter(name) {
6355 return function () {
6356 return this.isValid() ? this._data[name] : NaN;
6357 };
6358 }
6359
6360 var milliseconds = makeGetter('milliseconds');
6361 var seconds = makeGetter('seconds');
6362 var minutes = makeGetter('minutes');
6363 var hours = makeGetter('hours');
6364 var days = makeGetter('days');
6365 var months = makeGetter('months');
6366 var years = makeGetter('years');
6367
6368 function weeks() {
6369 return absFloor(this.days() / 7);
6370 }
6371
6372 var round = Math.round;
6373 var thresholds = {
6374 ss: 44,
6375 // a few seconds to seconds
6376 s: 45,
6377 // seconds to minute
6378 m: 45,
6379 // minutes to hour
6380 h: 22,
6381 // hours to day
6382 d: 26,
6383 // days to month
6384 M: 11 // months to year
6385
6386 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
6387
6388 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
6389 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
6390 }
6391
6392 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
6393 var duration = createDuration(posNegDuration).abs();
6394 var seconds = round(duration.as('s'));
6395 var minutes = round(duration.as('m'));
6396 var hours = round(duration.as('h'));
6397 var days = round(duration.as('d'));
6398 var months = round(duration.as('M'));
6399 var years = round(duration.as('y'));
6400 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];
6401 a[2] = withoutSuffix;
6402 a[3] = +posNegDuration > 0;
6403 a[4] = locale;
6404 return substituteTimeAgo.apply(null, a);
6405 } // This function allows you to set the rounding function for relative time strings
6406
6407
6408 function getSetRelativeTimeRounding(roundingFunction) {
6409 if (roundingFunction === undefined) {
6410 return round;
6411 }
6412
6413 if (typeof roundingFunction === 'function') {
6414 round = roundingFunction;
6415 return true;
6416 }
6417
6418 return false;
6419 } // This function allows you to set a threshold for relative time strings
6420
6421
6422 function getSetRelativeTimeThreshold(threshold, limit) {
6423 if (thresholds[threshold] === undefined) {
6424 return false;
6425 }
6426
6427 if (limit === undefined) {
6428 return thresholds[threshold];
6429 }
6430
6431 thresholds[threshold] = limit;
6432
6433 if (threshold === 's') {
6434 thresholds.ss = limit - 1;
6435 }
6436
6437 return true;
6438 }
6439
6440 function humanize(withSuffix) {
6441 if (!this.isValid()) {
6442 return this.localeData().invalidDate();
6443 }
6444
6445 var locale = this.localeData();
6446 var output = relativeTime$1(this, !withSuffix, locale);
6447
6448 if (withSuffix) {
6449 output = locale.pastFuture(+this, output);
6450 }
6451
6452 return locale.postformat(output);
6453 }
6454
6455 var abs$1 = Math.abs;
6456
6457 function sign(x) {
6458 return (x > 0) - (x < 0) || +x;
6459 }
6460
6461 function toISOString$1() {
6462 // for ISO strings we do not use the normal bubbling rules:
6463 // * milliseconds bubble up until they become hours
6464 // * days do not bubble at all
6465 // * months bubble up until they become years
6466 // This is because there is no context-free conversion between hours and days
6467 // (think of clock changes)
6468 // and also not between days and months (28-31 days per month)
6469 if (!this.isValid()) {
6470 return this.localeData().invalidDate();
6471 }
6472
6473 var seconds = abs$1(this._milliseconds) / 1000;
6474 var days = abs$1(this._days);
6475 var months = abs$1(this._months);
6476 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
6477
6478 minutes = absFloor(seconds / 60);
6479 hours = absFloor(minutes / 60);
6480 seconds %= 60;
6481 minutes %= 60; // 12 months -> 1 year
6482
6483 years = absFloor(months / 12);
6484 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
6485
6486 var Y = years;
6487 var M = months;
6488 var D = days;
6489 var h = hours;
6490 var m = minutes;
6491 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
6492 var total = this.asSeconds();
6493
6494 if (!total) {
6495 // this is the same as C#'s (Noda) and python (isodate)...
6496 // but not other JS (goog.date)
6497 return 'P0D';
6498 }
6499
6500 var totalSign = total < 0 ? '-' : '';
6501 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
6502 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
6503 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
6504 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' : '');
6505 }
6506
6507 var proto$2 = Duration.prototype;
6508 proto$2.isValid = isValid$1;
6509 proto$2.abs = abs;
6510 proto$2.add = add$1;
6511 proto$2.subtract = subtract$1;
6512 proto$2.as = as;
6513 proto$2.asMilliseconds = asMilliseconds;
6514 proto$2.asSeconds = asSeconds;
6515 proto$2.asMinutes = asMinutes;
6516 proto$2.asHours = asHours;
6517 proto$2.asDays = asDays;
6518 proto$2.asWeeks = asWeeks;
6519 proto$2.asMonths = asMonths;
6520 proto$2.asQuarters = asQuarters;
6521 proto$2.asYears = asYears;
6522 proto$2.valueOf = valueOf$1;
6523 proto$2._bubble = bubble;
6524 proto$2.clone = clone$1;
6525 proto$2.get = get$2;
6526 proto$2.milliseconds = milliseconds;
6527 proto$2.seconds = seconds;
6528 proto$2.minutes = minutes;
6529 proto$2.hours = hours;
6530 proto$2.days = days;
6531 proto$2.weeks = weeks;
6532 proto$2.months = months;
6533 proto$2.years = years;
6534 proto$2.humanize = humanize;
6535 proto$2.toISOString = toISOString$1;
6536 proto$2.toString = toISOString$1;
6537 proto$2.toJSON = toISOString$1;
6538 proto$2.locale = locale;
6539 proto$2.localeData = localeData;
6540 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
6541 proto$2.lang = lang; // Side effect imports
6542 // FORMATTING
6543
6544 addFormatToken('X', 0, 0, 'unix');
6545 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
6546
6547 addRegexToken('x', matchSigned);
6548 addRegexToken('X', matchTimestamp);
6549 addParseToken('X', function (input, array, config) {
6550 config._d = new Date(parseFloat(input, 10) * 1000);
6551 });
6552 addParseToken('x', function (input, array, config) {
6553 config._d = new Date(toInt(input));
6554 }); // Side effect imports
6555
6556 hooks.version = '2.24.0';
6557 setHookCallback(createLocal);
6558 hooks.fn = proto;
6559 hooks.min = min;
6560 hooks.max = max;
6561 hooks.now = now;
6562 hooks.utc = createUTC;
6563 hooks.unix = createUnix;
6564 hooks.months = listMonths;
6565 hooks.isDate = isDate;
6566 hooks.locale = getSetGlobalLocale;
6567 hooks.invalid = createInvalid;
6568 hooks.duration = createDuration;
6569 hooks.isMoment = isMoment;
6570 hooks.weekdays = listWeekdays;
6571 hooks.parseZone = createInZone;
6572 hooks.localeData = getLocale;
6573 hooks.isDuration = isDuration;
6574 hooks.monthsShort = listMonthsShort;
6575 hooks.weekdaysMin = listWeekdaysMin;
6576 hooks.defineLocale = defineLocale;
6577 hooks.updateLocale = updateLocale;
6578 hooks.locales = listLocales;
6579 hooks.weekdaysShort = listWeekdaysShort;
6580 hooks.normalizeUnits = normalizeUnits;
6581 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
6582 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
6583 hooks.calendarFormat = getCalendarFormat;
6584 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
6585
6586 hooks.HTML5_FMT = {
6587 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
6588 // <input type="datetime-local" />
6589 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
6590 // <input type="datetime-local" step="1" />
6591 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
6592 // <input type="datetime-local" step="0.001" />
6593 DATE: 'YYYY-MM-DD',
6594 // <input type="date" />
6595 TIME: 'HH:mm',
6596 // <input type="time" />
6597 TIME_SECONDS: 'HH:mm:ss',
6598 // <input type="time" step="1" />
6599 TIME_MS: 'HH:mm:ss.SSS',
6600 // <input type="time" step="0.001" />
6601 WEEK: 'GGGG-[W]WW',
6602 // <input type="week" />
6603 MONTH: 'YYYY-MM' // <input type="month" />
6604
6605 };
6606 return hooks;
6607 });
6608}); // Maps for number <-> hex string conversion
6609
6610var byteToHex = [];
6611
6612for (var i$1 = 0; i$1 < 256; i$1++) {
6613 byteToHex[i$1] = (i$1 + 0x100).toString(16).substr(1);
6614}
6615/**
6616 * Represent binary UUID into it's string representation.
6617 *
6618 * @param buf - Buffer containing UUID bytes.
6619 * @param offset - Offset from the start of the buffer where the UUID is saved (not needed if the buffer starts with the UUID).
6620 *
6621 * @returns String representation of the UUID.
6622 */
6623
6624
6625function stringifyUUID(buf, offset) {
6626 var i = offset || 0;
6627 var bth = byteToHex;
6628 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++]];
6629}
6630/**
6631 * Generate 16 random bytes to be used as a base for UUID.
6632 *
6633 * @ignore
6634 */
6635
6636
6637var random = function () {
6638 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
6639 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
6640 // Moderately fast, high quality
6641 var _rnds8 = new Uint8Array(16);
6642
6643 return function whatwgRNG() {
6644 crypto.getRandomValues(_rnds8);
6645 return _rnds8;
6646 };
6647 } // Math.random()-based (RNG)
6648 //
6649 // If all else fails, use Math.random().
6650 // It's fast, but is of unspecified quality.
6651
6652
6653 var _rnds = new Array(16);
6654
6655 return function () {
6656 for (var i = 0, r; i < 16; i++) {
6657 if ((i & 0x03) === 0) {
6658 r = Math.random() * 0x100000000;
6659 }
6660
6661 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
6662 }
6663
6664 return _rnds;
6665 }; // uuid.js
6666 //
6667 // Copyright (c) 2010-2012 Robert Kieffer
6668 // MIT License - http://opensource.org/licenses/mit-license.php
6669 // Unique ID creation requires a high quality random # generator. We feature
6670 // detect to determine the best RNG source, normalizing to a function that
6671 // returns 128-bits of randomness, since that's what's usually required
6672 // return require('./rng');
6673}();
6674
6675var byteToHex$1 = [];
6676
6677for (var i$1$1 = 0; i$1$1 < 256; i$1$1++) {
6678 byteToHex$1[i$1$1] = (i$1$1 + 0x100).toString(16).substr(1);
6679} // **`v1()` - Generate time-based UUID**
6680//
6681// Inspired by https://github.com/LiosK/UUID.js
6682// and http://docs.python.org/library/uuid.html
6683// random #'s we need to init node and clockseq
6684
6685
6686var seedBytes = random(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
6687
6688var defaultNodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; // Per 4.2.2, randomize (14 bit) clockseq
6689
6690var defaultClockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; // Previous uuid creation time
6691
6692/**
6693 * UUIDv4 options.
6694 */
6695
6696/**
6697 * Generate UUIDv4
6698 *
6699 * @param options - Options to be used instead of default generated values.
6700 * String 'binary' is a shorthand for uuid4({}, new Array(16)).
6701 * @param buf - If present the buffer will be filled with the generated UUID.
6702 * @param offset - Offset of the UUID from the start of the buffer.
6703 *
6704 * @returns UUIDv4
6705 */
6706
6707function uuid4() {
6708 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6709 var buf = arguments.length > 1 ? arguments[1] : undefined;
6710 var offset = arguments.length > 2 ? arguments[2] : undefined; // Deprecated - 'format' argument, as supported in v1.2
6711
6712 var i = buf && offset || 0;
6713
6714 if (typeof options === 'string') {
6715 buf = options === 'binary' ? new Array(16) : undefined;
6716 options = {};
6717 }
6718
6719 var rnds = options.random || (options.rng || random)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
6720
6721 rnds[6] = rnds[6] & 0x0f | 0x40;
6722 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
6723
6724 if (buf) {
6725 for (var ii = 0; ii < 16; ii++) {
6726 buf[i + ii] = rnds[ii];
6727 }
6728 }
6729
6730 return buf || stringifyUUID(rnds);
6731} // Rollup will complain about mixing default and named exports in UMD build,
6732// for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
6733// code from http://momentjs.com/
6734
6735
6736var ASPDateRegex = /^\/?Date\((-?\d+)/i; // Color REs
6737
6738var fullHexRE = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
6739var shortHexRE = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
6740var rgbRE = /^rgb\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *\)$/i;
6741var rgbaRE = /^rgba\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *([01]|0?\.\d+) *\)$/i;
6742/**
6743 * Hue, Saturation, Value.
6744 */
6745
6746/**
6747 * Test whether given object is a number
6748 *
6749 * @param value - Input value of unknown type.
6750 *
6751 * @returns True if number, false otherwise.
6752 */
6753
6754function isNumber(value) {
6755 return value instanceof Number || typeof value === "number";
6756}
6757/**
6758 * Remove everything in the DOM object
6759 *
6760 * @param DOMobject - Node whose child nodes will be recursively deleted.
6761 */
6762
6763
6764function recursiveDOMDelete(DOMobject) {
6765 if (DOMobject) {
6766 while (DOMobject.hasChildNodes() === true) {
6767 var child = DOMobject.firstChild;
6768
6769 if (child) {
6770 recursiveDOMDelete(child);
6771 DOMobject.removeChild(child);
6772 }
6773 }
6774 }
6775}
6776/**
6777 * Test whether given object is a string
6778 *
6779 * @param value - Input value of unknown type.
6780 *
6781 * @returns True if string, false otherwise.
6782 */
6783
6784
6785function isString(value) {
6786 return value instanceof String || typeof value === "string";
6787}
6788/**
6789 * Test whether given object is a object (not primitive or null).
6790 *
6791 * @param value - Input value of unknown type.
6792 *
6793 * @returns True if not null object, false otherwise.
6794 */
6795
6796
6797function isObject(value) {
6798 return _typeof(value) === "object" && value !== null;
6799}
6800/**
6801 * Test whether given object is a Date, or a String containing a Date
6802 *
6803 * @param value - Input value of unknown type.
6804 *
6805 * @returns True if Date instance or string date representation, false otherwise.
6806 */
6807
6808
6809function isDate(value) {
6810 if (value instanceof Date) {
6811 return true;
6812 } else if (isString(value)) {
6813 // test whether this string contains a date
6814 var match = ASPDateRegex.exec(value);
6815
6816 if (match) {
6817 return true;
6818 } else if (!isNaN(Date.parse(value))) {
6819 return true;
6820 }
6821 }
6822
6823 return false;
6824}
6825/**
6826 * Test whether given object is a Moment date.
6827 * @TODO: This is basically a workaround, if Moment was imported property it wouldn't necessary as moment.isMoment is a TS type guard.
6828 *
6829 * @param value - Input value of unknown type.
6830 *
6831 * @returns True if Moment instance, false otherwise.
6832 */
6833
6834
6835function isMoment(value) {
6836 return moment.isMoment(value);
6837}
6838/**
6839 * Copy property from b to a if property present in a.
6840 * If property in b explicitly set to null, delete it if `allowDeletion` set.
6841 *
6842 * Internal helper routine, should not be exported. Not added to `exports` for that reason.
6843 *
6844 * @param a - Target object.
6845 * @param b - Source object.
6846 * @param prop - Name of property to copy from b to a.
6847 * @param allowDeletion if true, delete property in a if explicitly set to null in b
6848 */
6849
6850
6851function copyOrDelete(a, b, prop, allowDeletion) {
6852 var doDeletion = false;
6853
6854 if (allowDeletion === true) {
6855 doDeletion = b[prop] === null && a[prop] !== undefined;
6856 }
6857
6858 if (doDeletion) {
6859 delete a[prop];
6860 } else {
6861 a[prop] = b[prop]; // Remember, this is a reference copy!
6862 }
6863}
6864/**
6865 * Fill an object with a possibly partially defined other object.
6866 *
6867 * Only copies values for the properties already present in a.
6868 * That means an object is not created on a property if only the b object has it.
6869 *
6870 * @param a - The object that will have it's properties updated.
6871 * @param b - The object with property updates.
6872 * @param allowDeletion - if true, delete properties in a that are explicitly set to null in b
6873 */
6874
6875
6876function fillIfDefined(a, b) {
6877 var allowDeletion = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; // NOTE: iteration of properties of a
6878 // NOTE: prototype properties iterated over as well
6879
6880 for (var prop in a) {
6881 if (b[prop] !== undefined) {
6882 if (b[prop] === null || _typeof(b[prop]) !== "object") {
6883 // Note: typeof null === 'object'
6884 copyOrDelete(a, b, prop, allowDeletion);
6885 } else {
6886 var aProp = a[prop];
6887 var bProp = b[prop];
6888
6889 if (isObject(aProp) && isObject(bProp)) {
6890 fillIfDefined(aProp, bProp, allowDeletion);
6891 }
6892 }
6893 }
6894 }
6895}
6896/**
6897 * Copy the values of all of the enumerable own properties from one or more source objects to a
6898 * target object. Returns the target object.
6899 *
6900 * @param target - The target object to copy to.
6901 * @param source - The source object from which to copy properties.
6902 *
6903 * @return The target object.
6904 */
6905
6906
6907var extend = Object.assign;
6908/**
6909 * Extend object a with selected properties of object b or a series of objects
6910 * Only properties with defined values are copied
6911 *
6912 * @param props - Properties to be copied to a.
6913 * @param a - The target.
6914 * @param others - The sources.
6915 *
6916 * @returns Argument a.
6917 */
6918
6919function selectiveExtend(props, a) {
6920 if (!Array.isArray(props)) {
6921 throw new Error("Array with property names expected as first argument");
6922 }
6923
6924 for (var _len = arguments.length, others = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
6925 others[_key - 2] = arguments[_key];
6926 }
6927
6928 for (var _i = 0, _others = others; _i < _others.length; _i++) {
6929 var other = _others[_i];
6930
6931 for (var p = 0; p < props.length; p++) {
6932 var prop = props[p];
6933
6934 if (other && Object.prototype.hasOwnProperty.call(other, prop)) {
6935 a[prop] = other[prop];
6936 }
6937 }
6938 }
6939
6940 return a;
6941}
6942/**
6943 * Extend object a with selected properties of object b.
6944 * Only properties with defined values are copied.
6945 *
6946 * **Note:** Previous version of this routine implied that multiple source objects
6947 * could be used; however, the implementation was **wrong**.
6948 * Since multiple (>1) sources weren't used anywhere in the `vis.js` code,
6949 * this has been removed
6950 *
6951 * @param props - Names of first-level properties to copy over.
6952 * @param a - Target object.
6953 * @param b - Source object.
6954 * @param allowDeletion - If true, delete property in a if explicitly set to null in b.
6955 *
6956 * @returns Argument a.
6957 */
6958
6959
6960function selectiveDeepExtend(props, a, b) {
6961 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TODO: add support for Arrays to deepExtend
6962
6963 if (Array.isArray(b)) {
6964 throw new TypeError("Arrays are not supported by deepExtend");
6965 }
6966
6967 for (var p = 0; p < props.length; p++) {
6968 var prop = props[p];
6969
6970 if (Object.prototype.hasOwnProperty.call(b, prop)) {
6971 if (b[prop] && b[prop].constructor === Object) {
6972 if (a[prop] === undefined) {
6973 a[prop] = {};
6974 }
6975
6976 if (a[prop].constructor === Object) {
6977 deepExtend(a[prop], b[prop], false, allowDeletion);
6978 } else {
6979 copyOrDelete(a, b, prop, allowDeletion);
6980 }
6981 } else if (Array.isArray(b[prop])) {
6982 throw new TypeError("Arrays are not supported by deepExtend");
6983 } else {
6984 copyOrDelete(a, b, prop, allowDeletion);
6985 }
6986 }
6987 }
6988
6989 return a;
6990}
6991/**
6992 * Extend object `a` with properties of object `b`, ignoring properties which are explicitly
6993 * specified to be excluded.
6994 *
6995 * The properties of `b` are considered for copying.
6996 * Properties which are themselves objects are are also extended.
6997 * Only properties with defined values are copied
6998 *
6999 * @param propsToExclude - Names of properties which should *not* be copied.
7000 * @param a - Object to extend.
7001 * @param b - Object to take properties from for extension.
7002 * @param allowDeletion - If true, delete properties in a that are explicitly set to null in b.
7003 *
7004 * @returns Argument a.
7005 */
7006
7007
7008function selectiveNotDeepExtend(propsToExclude, a, b) {
7009 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TODO: add support for Arrays to deepExtend
7010 // NOTE: array properties have an else-below; apparently, there is a problem here.
7011
7012 if (Array.isArray(b)) {
7013 throw new TypeError("Arrays are not supported by deepExtend");
7014 }
7015
7016 for (var prop in b) {
7017 if (!Object.prototype.hasOwnProperty.call(b, prop)) {
7018 continue;
7019 } // Handle local properties only
7020
7021
7022 if (propsToExclude.indexOf(prop) !== -1) {
7023 continue;
7024 } // In exclusion list, skip
7025
7026
7027 if (b[prop] && b[prop].constructor === Object) {
7028 if (a[prop] === undefined) {
7029 a[prop] = {};
7030 }
7031
7032 if (a[prop].constructor === Object) {
7033 deepExtend(a[prop], b[prop]); // NOTE: allowDeletion not propagated!
7034 } else {
7035 copyOrDelete(a, b, prop, allowDeletion);
7036 }
7037 } else if (Array.isArray(b[prop])) {
7038 a[prop] = [];
7039
7040 for (var i = 0; i < b[prop].length; i++) {
7041 a[prop].push(b[prop][i]);
7042 }
7043 } else {
7044 copyOrDelete(a, b, prop, allowDeletion);
7045 }
7046 }
7047
7048 return a;
7049}
7050/**
7051 * Deep extend an object a with the properties of object b
7052 *
7053 * @param a - Target object.
7054 * @param b - Source object.
7055 * @param protoExtend - If true, the prototype values will also be extended
7056 * (ie. the options objects that inherit from others will also get the inherited options).
7057 * @param allowDeletion - If true, the values of fields that are null will be deleted.
7058 *
7059 * @returns Argument a.
7060 */
7061
7062
7063function deepExtend(a, b) {
7064 var protoExtend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7065 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
7066
7067 for (var prop in b) {
7068 if (Object.prototype.hasOwnProperty.call(b, prop) || protoExtend === true) {
7069 if (b[prop] && Object.getPrototypeOf(b[prop]) === Object.prototype) {
7070 if (a[prop] === undefined) {
7071 a[prop] = deepExtend({}, b[prop], protoExtend); // NOTE: allowDeletion not propagated!
7072 } else if (a[prop] && Object.getPrototypeOf(a[prop]) === Object.prototype) {
7073 deepExtend(a[prop], b[prop], protoExtend); // NOTE: allowDeletion not propagated!
7074 } else {
7075 copyOrDelete(a, b, prop, allowDeletion);
7076 }
7077 } else if (Array.isArray(b[prop])) {
7078 a[prop] = b[prop].slice();
7079 } else {
7080 copyOrDelete(a, b, prop, allowDeletion);
7081 }
7082 }
7083 }
7084
7085 return a;
7086}
7087/**
7088 * Test whether all elements in two arrays are equal.
7089 *
7090 * @param a - First array.
7091 * @param b - Second array.
7092 *
7093 * @returns True if both arrays have the same length and same elements (1 = '1').
7094 */
7095
7096
7097function equalArray(a, b) {
7098 if (a.length !== b.length) {
7099 return false;
7100 }
7101
7102 for (var i = 0, len = a.length; i < len; i++) {
7103 if (a[i] != b[i]) {
7104 return false;
7105 }
7106 }
7107
7108 return true;
7109}
7110/**
7111 * Convert an object into another type
7112 *
7113 * @param object - Value of unknown type.
7114 * @param type - Name of the desired type.
7115 *
7116 * @returns Object in the desired type.
7117 * @throws Error
7118 */
7119
7120
7121function convert(object, type) {
7122 var match;
7123
7124 if (object === undefined) {
7125 return undefined;
7126 }
7127
7128 if (object === null) {
7129 return null;
7130 }
7131
7132 if (!type) {
7133 return object;
7134 }
7135
7136 if (!(typeof type === "string") && !(type instanceof String)) {
7137 throw new Error("Type must be a string");
7138 } //noinspection FallthroughInSwitchStatementJS
7139
7140
7141 switch (type) {
7142 case "boolean":
7143 case "Boolean":
7144 return Boolean(object);
7145
7146 case "number":
7147 case "Number":
7148 if (isString(object) && !isNaN(Date.parse(object))) {
7149 return moment(object).valueOf();
7150 } else {
7151 // @TODO: I don't think that Number and String constructors are a good idea.
7152 // This could also fail if the object doesn't have valueOf method or if it's redefined.
7153 // For example: Object.create(null) or { valueOf: 7 }.
7154 return Number(object.valueOf());
7155 }
7156
7157 case "string":
7158 case "String":
7159 return String(object);
7160
7161 case "Date":
7162 if (isNumber(object)) {
7163 return new Date(object);
7164 }
7165
7166 if (object instanceof Date) {
7167 return new Date(object.valueOf());
7168 } else if (isMoment(object)) {
7169 return new Date(object.valueOf());
7170 }
7171
7172 if (isString(object)) {
7173 match = ASPDateRegex.exec(object);
7174
7175 if (match) {
7176 // object is an ASP date
7177 return new Date(Number(match[1])); // parse number
7178 } else {
7179 return moment(new Date(object)).toDate(); // parse string
7180 }
7181 } else {
7182 throw new Error("Cannot convert object of type " + getType(object) + " to type Date");
7183 }
7184
7185 case "Moment":
7186 if (isNumber(object)) {
7187 return moment(object);
7188 }
7189
7190 if (object instanceof Date) {
7191 return moment(object.valueOf());
7192 } else if (isMoment(object)) {
7193 return moment(object);
7194 }
7195
7196 if (isString(object)) {
7197 match = ASPDateRegex.exec(object);
7198
7199 if (match) {
7200 // object is an ASP date
7201 return moment(Number(match[1])); // parse number
7202 } else {
7203 return moment(object); // parse string
7204 }
7205 } else {
7206 throw new Error("Cannot convert object of type " + getType(object) + " to type Date");
7207 }
7208
7209 case "ISODate":
7210 if (isNumber(object)) {
7211 return new Date(object);
7212 } else if (object instanceof Date) {
7213 return object.toISOString();
7214 } else if (isMoment(object)) {
7215 return object.toDate().toISOString();
7216 } else if (isString(object)) {
7217 match = ASPDateRegex.exec(object);
7218
7219 if (match) {
7220 // object is an ASP date
7221 return new Date(Number(match[1])).toISOString(); // parse number
7222 } else {
7223 return moment(object).format(); // ISO 8601
7224 }
7225 } else {
7226 throw new Error("Cannot convert object of type " + getType(object) + " to type ISODate");
7227 }
7228
7229 case "ASPDate":
7230 if (isNumber(object)) {
7231 return "/Date(" + object + ")/";
7232 } else if (object instanceof Date || isMoment(object)) {
7233 return "/Date(" + object.valueOf() + ")/";
7234 } else if (isString(object)) {
7235 match = ASPDateRegex.exec(object);
7236
7237 var _value;
7238
7239 if (match) {
7240 // object is an ASP date
7241 _value = new Date(Number(match[1])).valueOf(); // parse number
7242 } else {
7243 _value = new Date(object).valueOf(); // parse string
7244 }
7245
7246 return "/Date(" + _value + ")/";
7247 } else {
7248 throw new Error("Cannot convert object of type " + getType(object) + " to type ASPDate");
7249 }
7250
7251 default:
7252 var never = type;
7253 throw new Error("Unknown type ".concat(never));
7254 }
7255}
7256/**
7257 * Get the type of an object, for example exports.getType([]) returns 'Array'
7258 *
7259 * @param object - Input value of unknown type.
7260 *
7261 * @returns Detected type.
7262 */
7263
7264
7265function getType(object) {
7266 var type = _typeof(object);
7267
7268 if (type === "object") {
7269 if (object === null) {
7270 return "null";
7271 }
7272
7273 if (object instanceof Boolean) {
7274 return "Boolean";
7275 }
7276
7277 if (object instanceof Number) {
7278 return "Number";
7279 }
7280
7281 if (object instanceof String) {
7282 return "String";
7283 }
7284
7285 if (Array.isArray(object)) {
7286 return "Array";
7287 }
7288
7289 if (object instanceof Date) {
7290 return "Date";
7291 }
7292
7293 return "Object";
7294 }
7295
7296 if (type === "number") {
7297 return "Number";
7298 }
7299
7300 if (type === "boolean") {
7301 return "Boolean";
7302 }
7303
7304 if (type === "string") {
7305 return "String";
7306 }
7307
7308 if (type === undefined) {
7309 return "undefined";
7310 }
7311
7312 return type;
7313}
7314/**
7315 * Used to extend an array and copy it. This is used to propagate paths recursively.
7316 *
7317 * @param arr - First part.
7318 * @param newValue - The value to be aadded into the array.
7319 *
7320 * @returns A new array with all items from arr and newValue (which is last).
7321 */
7322
7323
7324function copyAndExtendArray(arr, newValue) {
7325 return [].concat(_toConsumableArray(arr), [newValue]);
7326}
7327/**
7328 * Used to extend an array and copy it. This is used to propagate paths recursively.
7329 *
7330 * @param arr - The array to be copied.
7331 *
7332 * @returns Shallow copy of arr.
7333 */
7334
7335
7336function copyArray(arr) {
7337 return arr.slice();
7338}
7339/**
7340 * Retrieve the absolute left value of a DOM element
7341 *
7342 * @param elem - A dom element, for example a div.
7343 *
7344 * @returns The absolute left position of this element in the browser page.
7345 */
7346
7347
7348function getAbsoluteLeft(elem) {
7349 return elem.getBoundingClientRect().left;
7350}
7351/**
7352 * Retrieve the absolute right value of a DOM element
7353 *
7354 * @param elem - A dom element, for example a div.
7355 *
7356 * @returns The absolute right position of this element in the browser page.
7357 */
7358
7359
7360function getAbsoluteRight(elem) {
7361 return elem.getBoundingClientRect().right;
7362}
7363/**
7364 * Retrieve the absolute top value of a DOM element
7365 *
7366 * @param elem - A dom element, for example a div.
7367 *
7368 * @returns The absolute top position of this element in the browser page.
7369 */
7370
7371
7372function getAbsoluteTop(elem) {
7373 return elem.getBoundingClientRect().top;
7374}
7375/**
7376 * Add a className to the given elements style.
7377 *
7378 * @param elem - The element to which the classes will be added.
7379 * @param classNames - Space separated list of classes.
7380 */
7381
7382
7383function addClassName(elem, classNames) {
7384 var classes = elem.className.split(" ");
7385 var newClasses = classNames.split(" ");
7386 classes = classes.concat(newClasses.filter(function (className) {
7387 return classes.indexOf(className) < 0;
7388 }));
7389 elem.className = classes.join(" ");
7390}
7391/**
7392 * Remove a className from the given elements style.
7393 *
7394 * @param elem - The element from which the classes will be removed.
7395 * @param classNames - Space separated list of classes.
7396 */
7397
7398
7399function removeClassName(elem, classNames) {
7400 var classes = elem.className.split(" ");
7401 var oldClasses = classNames.split(" ");
7402 classes = classes.filter(function (className) {
7403 return oldClasses.indexOf(className) < 0;
7404 });
7405 elem.className = classes.join(" ");
7406}
7407/**
7408 * For each method for both arrays and objects.
7409 * In case of an array, the built-in Array.forEach() is applied (**No, it's not!**).
7410 * In case of an Object, the method loops over all properties of the object.
7411 *
7412 * @param object - An Object or Array to be iterated over.
7413 * @param callback - Array.forEach-like callback.
7414 */
7415
7416
7417function forEach(object, callback) {
7418 if (Array.isArray(object)) {
7419 // array
7420 var len = object.length;
7421
7422 for (var i = 0; i < len; i++) {
7423 callback(object[i], i, object);
7424 }
7425 } else {
7426 // object
7427 for (var _key2 in object) {
7428 if (Object.prototype.hasOwnProperty.call(object, _key2)) {
7429 callback(object[_key2], _key2, object);
7430 }
7431 }
7432 }
7433}
7434/**
7435 * Convert an object into an array: all objects properties are put into the array. The resulting array is unordered.
7436 *
7437 * @param o - Object that contains the properties and methods.
7438 *
7439 * @returns An array of unordered values.
7440 */
7441
7442
7443var toArray = Object.values;
7444/**
7445 * Update a property in an object
7446 *
7447 * @param object - The object whose property will be updated.
7448 * @param key - Name of the property to be updated.
7449 * @param value - The new value to be assigned.
7450 *
7451 * @returns Whether the value was updated (true) or already strictly the same in the original object (false).
7452 */
7453
7454function updateProperty(object, key, value) {
7455 if (object[key] !== value) {
7456 object[key] = value;
7457 return true;
7458 } else {
7459 return false;
7460 }
7461}
7462/**
7463 * Throttle the given function to be only executed once per animation frame.
7464 *
7465 * @param fn - The original function.
7466 *
7467 * @returns The throttled function.
7468 */
7469
7470
7471function throttle(fn) {
7472 var scheduled = false;
7473 return function () {
7474 if (!scheduled) {
7475 scheduled = true;
7476 requestAnimationFrame(function () {
7477 scheduled = false;
7478 fn();
7479 });
7480 }
7481 };
7482}
7483/**
7484 * Add and event listener. Works for all browsers.
7485 *
7486 * @param element - The element to bind the event listener to.
7487 * @param action - Same as Element.addEventListener(action, —, —).
7488 * @param listener - Same as Element.addEventListener(—, listener, —).
7489 * @param useCapture - Same as Element.addEventListener(—, —, useCapture).
7490 */
7491
7492
7493function addEventListener(element, action, listener, useCapture) {
7494 if (element.addEventListener) {
7495 if (useCapture === undefined) {
7496 useCapture = false;
7497 }
7498
7499 if (action === "mousewheel" && navigator.userAgent.indexOf("Firefox") >= 0) {
7500 action = "DOMMouseScroll"; // For Firefox
7501 }
7502
7503 element.addEventListener(action, listener, useCapture);
7504 } else {
7505 // @TODO: IE types? Does anyone care?
7506 element.attachEvent("on" + action, listener); // IE browsers
7507 }
7508}
7509/**
7510 * Remove an event listener from an element
7511 *
7512 * @param element - The element to bind the event listener to.
7513 * @param action - Same as Element.removeEventListener(action, —, —).
7514 * @param listener - Same as Element.removeEventListener(—, listener, —).
7515 * @param useCapture - Same as Element.removeEventListener(—, —, useCapture).
7516 */
7517
7518
7519function removeEventListener(element, action, listener, useCapture) {
7520 if (element.removeEventListener) {
7521 // non-IE browsers
7522 if (useCapture === undefined) {
7523 useCapture = false;
7524 }
7525
7526 if (action === "mousewheel" && navigator.userAgent.indexOf("Firefox") >= 0) {
7527 action = "DOMMouseScroll"; // For Firefox
7528 }
7529
7530 element.removeEventListener(action, listener, useCapture);
7531 } else {
7532 // @TODO: IE types? Does anyone care?
7533 element.detachEvent("on" + action, listener); // IE browsers
7534 }
7535}
7536/**
7537 * Cancels the event's default action if it is cancelable, without stopping further propagation of the event.
7538 *
7539 * @param event - The event whose default action should be prevented.
7540 */
7541
7542
7543function preventDefault(event) {
7544 if (!event) {
7545 event = window.event;
7546 }
7547
7548 if (!event) ;else if (event.preventDefault) {
7549 event.preventDefault(); // non-IE browsers
7550 } else {
7551 // @TODO: IE types? Does anyone care?
7552 event.returnValue = false; // IE browsers
7553 }
7554}
7555/**
7556 * Get HTML element which is the target of the event.
7557 *
7558 * @param event - The event.
7559 *
7560 * @returns The element or null if not obtainable.
7561 */
7562
7563
7564function getTarget() {
7565 var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.event; // code from http://www.quirksmode.org/js/events_properties.html
7566 // @TODO: EventTarget can be almost anything, is it okay to return only Elements?
7567
7568 var target = null;
7569 if (!event) ;else if (event.target) {
7570 target = event.target;
7571 } else if (event.srcElement) {
7572 target = event.srcElement;
7573 }
7574
7575 if (!(target instanceof Element)) {
7576 return null;
7577 }
7578
7579 if (target.nodeType != null && target.nodeType == 3) {
7580 // defeat Safari bug
7581 target = target.parentNode;
7582
7583 if (!(target instanceof Element)) {
7584 return null;
7585 }
7586 }
7587
7588 return target;
7589}
7590/**
7591 * Check if given element contains given parent somewhere in the DOM tree
7592 *
7593 * @param element - The element to be tested.
7594 * @param parent - The ancestor (not necessarily parent) of the element.
7595 *
7596 * @returns True if parent is an ancestor of the element, false otherwise.
7597 */
7598
7599
7600function hasParent(element, parent) {
7601 var elem = element;
7602
7603 while (elem) {
7604 if (elem === parent) {
7605 return true;
7606 } else if (elem.parentNode) {
7607 elem = elem.parentNode;
7608 } else {
7609 return false;
7610 }
7611 }
7612
7613 return false;
7614}
7615
7616var option = {
7617 /**
7618 * Convert a value into a boolean.
7619 *
7620 * @param value - Value to be converted intoboolean, a function will be executed as (() => unknown).
7621 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
7622 *
7623 * @returns Corresponding boolean value, if none then the default value, if none then null.
7624 */
7625 asBoolean: function asBoolean(value, defaultValue) {
7626 if (typeof value == "function") {
7627 value = value();
7628 }
7629
7630 if (value != null) {
7631 return value != false;
7632 }
7633
7634 return defaultValue || null;
7635 },
7636
7637 /**
7638 * Convert a value into a number.
7639 *
7640 * @param value - Value to be converted intonumber, a function will be executed as (() => unknown).
7641 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
7642 *
7643 * @returns Corresponding **boxed** number value, if none then the default value, if none then null.
7644 */
7645 asNumber: function asNumber(value, defaultValue) {
7646 if (typeof value == "function") {
7647 value = value();
7648 }
7649
7650 if (value != null) {
7651 return Number(value) || defaultValue || null;
7652 }
7653
7654 return defaultValue || null;
7655 },
7656
7657 /**
7658 * Convert a value into a string.
7659 *
7660 * @param value - Value to be converted intostring, a function will be executed as (() => unknown).
7661 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
7662 *
7663 * @returns Corresponding **boxed** string value, if none then the default value, if none then null.
7664 */
7665 asString: function asString(value, defaultValue) {
7666 if (typeof value == "function") {
7667 value = value();
7668 }
7669
7670 if (value != null) {
7671 return String(value);
7672 }
7673
7674 return defaultValue || null;
7675 },
7676
7677 /**
7678 * Convert a value into a size.
7679 *
7680 * @param value - Value to be converted intosize, a function will be executed as (() => unknown).
7681 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
7682 *
7683 * @returns Corresponding string value (number + 'px'), if none then the default value, if none then null.
7684 */
7685 asSize: function asSize(value, defaultValue) {
7686 if (typeof value == "function") {
7687 value = value();
7688 }
7689
7690 if (isString(value)) {
7691 return value;
7692 } else if (isNumber(value)) {
7693 return value + "px";
7694 } else {
7695 return defaultValue || null;
7696 }
7697 },
7698
7699 /**
7700 * Convert a value into a DOM Element.
7701 *
7702 * @param value - Value to be converted into DOM Element, a function will be executed as (() => unknown).
7703 * @param defaultValue - If the value or the return value of the function == null then this will be returned.
7704 *
7705 * @returns The DOM Element, if none then the default value, if none then null.
7706 */
7707 asElement: function asElement(value, defaultValue) {
7708 if (typeof value == "function") {
7709 value = value();
7710 }
7711
7712 return value || defaultValue || null;
7713 }
7714};
7715/**
7716 * Convert hex color string into RGB color object.
7717 * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
7718 *
7719 * @param hex - Hex color string (3 or 6 digits, with or without #).
7720 *
7721 * @returns RGB color object.
7722 */
7723
7724function hexToRGB(hex) {
7725 var result;
7726
7727 switch (hex.length) {
7728 case 3:
7729 case 4:
7730 result = shortHexRE.exec(hex);
7731 return result ? {
7732 r: parseInt(result[1] + result[1], 16),
7733 g: parseInt(result[2] + result[2], 16),
7734 b: parseInt(result[3] + result[3], 16)
7735 } : null;
7736
7737 case 6:
7738 case 7:
7739 result = fullHexRE.exec(hex);
7740 return result ? {
7741 r: parseInt(result[1], 16),
7742 g: parseInt(result[2], 16),
7743 b: parseInt(result[3], 16)
7744 } : null;
7745
7746 default:
7747 return null;
7748 }
7749}
7750/**
7751 * This function takes string color in hex or RGB format and adds the opacity, RGBA is passed through unchanged.
7752 *
7753 * @param color - The color string (hex, RGB, RGBA).
7754 * @param opacity - The new opacity.
7755 *
7756 * @returns RGBA string, for example 'rgba(255, 0, 127, 0.3)'.
7757 */
7758
7759
7760function overrideOpacity(color, opacity) {
7761 if (color.indexOf("rgba") !== -1) {
7762 return color;
7763 } else if (color.indexOf("rgb") !== -1) {
7764 var rgb = color.substr(color.indexOf("(") + 1).replace(")", "").split(",");
7765 return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + opacity + ")";
7766 } else {
7767 var _rgb = hexToRGB(color);
7768
7769 if (_rgb == null) {
7770 return color;
7771 } else {
7772 return "rgba(" + _rgb.r + "," + _rgb.g + "," + _rgb.b + "," + opacity + ")";
7773 }
7774 }
7775}
7776/**
7777 * Convert RGB <0, 255> into hex color string.
7778 *
7779 * @param red - Red channel.
7780 * @param green - Green channel.
7781 * @param blue - Blue channel.
7782 *
7783 * @returns Hex color string (for example: '#0acdc0').
7784 */
7785
7786
7787function RGBToHex(red, green, blue) {
7788 return "#" + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1);
7789}
7790/**
7791 * Parse a color property into an object with border, background, and highlight colors
7792 *
7793 * @param inputColor - Shorthand color string or input color object.
7794 * @param defaultColor - Full color object to fill in missing values in inputColor.
7795 *
7796 * @returns Color object.
7797 */
7798
7799
7800function parseColor(inputColor, defaultColor) {
7801 if (isString(inputColor)) {
7802 var colorStr = inputColor;
7803
7804 if (isValidRGB(colorStr)) {
7805 var rgb = colorStr.substr(4).substr(0, colorStr.length - 5).split(",").map(function (value) {
7806 return parseInt(value);
7807 });
7808 colorStr = RGBToHex(rgb[0], rgb[1], rgb[2]);
7809 }
7810
7811 if (isValidHex(colorStr) === true) {
7812 var hsv = hexToHSV(colorStr);
7813 var lighterColorHSV = {
7814 h: hsv.h,
7815 s: hsv.s * 0.8,
7816 v: Math.min(1, hsv.v * 1.02)
7817 };
7818 var darkerColorHSV = {
7819 h: hsv.h,
7820 s: Math.min(1, hsv.s * 1.25),
7821 v: hsv.v * 0.8
7822 };
7823 var darkerColorHex = HSVToHex(darkerColorHSV.h, darkerColorHSV.s, darkerColorHSV.v);
7824 var lighterColorHex = HSVToHex(lighterColorHSV.h, lighterColorHSV.s, lighterColorHSV.v);
7825 return {
7826 background: colorStr,
7827 border: darkerColorHex,
7828 highlight: {
7829 background: lighterColorHex,
7830 border: darkerColorHex
7831 },
7832 hover: {
7833 background: lighterColorHex,
7834 border: darkerColorHex
7835 }
7836 };
7837 } else {
7838 return {
7839 background: colorStr,
7840 border: colorStr,
7841 highlight: {
7842 background: colorStr,
7843 border: colorStr
7844 },
7845 hover: {
7846 background: colorStr,
7847 border: colorStr
7848 }
7849 };
7850 }
7851 } else {
7852 if (defaultColor) {
7853 var color = {
7854 background: inputColor.background || defaultColor.background,
7855 border: inputColor.border || defaultColor.border,
7856 highlight: isString(inputColor.highlight) ? {
7857 border: inputColor.highlight,
7858 background: inputColor.highlight
7859 } : {
7860 background: inputColor.highlight && inputColor.highlight.background || defaultColor.highlight.background,
7861 border: inputColor.highlight && inputColor.highlight.border || defaultColor.highlight.border
7862 },
7863 hover: isString(inputColor.hover) ? {
7864 border: inputColor.hover,
7865 background: inputColor.hover
7866 } : {
7867 border: inputColor.hover && inputColor.hover.border || defaultColor.hover.border,
7868 background: inputColor.hover && inputColor.hover.background || defaultColor.hover.background
7869 }
7870 };
7871 return color;
7872 } else {
7873 var _color = {
7874 background: inputColor.background || undefined,
7875 border: inputColor.border || undefined,
7876 highlight: isString(inputColor.highlight) ? {
7877 border: inputColor.highlight,
7878 background: inputColor.highlight
7879 } : {
7880 background: inputColor.highlight && inputColor.highlight.background || undefined,
7881 border: inputColor.highlight && inputColor.highlight.border || undefined
7882 },
7883 hover: isString(inputColor.hover) ? {
7884 border: inputColor.hover,
7885 background: inputColor.hover
7886 } : {
7887 border: inputColor.hover && inputColor.hover.border || undefined,
7888 background: inputColor.hover && inputColor.hover.background || undefined
7889 }
7890 };
7891 return _color;
7892 }
7893 }
7894}
7895/**
7896 * Convert RGB <0, 255> into HSV object.
7897 * http://www.javascripter.net/faq/rgb2hsv.htm
7898 *
7899 * @param red - Red channel.
7900 * @param green - Green channel.
7901 * @param blue - Blue channel.
7902 *
7903 * @returns HSV color object.
7904 */
7905
7906
7907function RGBToHSV(red, green, blue) {
7908 red = red / 255;
7909 green = green / 255;
7910 blue = blue / 255;
7911 var minRGB = Math.min(red, Math.min(green, blue));
7912 var maxRGB = Math.max(red, Math.max(green, blue)); // Black-gray-white
7913
7914 if (minRGB === maxRGB) {
7915 return {
7916 h: 0,
7917 s: 0,
7918 v: minRGB
7919 };
7920 } // Colors other than black-gray-white:
7921
7922
7923 var d = red === minRGB ? green - blue : blue === minRGB ? red - green : blue - red;
7924 var h = red === minRGB ? 3 : blue === minRGB ? 1 : 5;
7925 var hue = 60 * (h - d / (maxRGB - minRGB)) / 360;
7926 var saturation = (maxRGB - minRGB) / maxRGB;
7927 var value = maxRGB;
7928 return {
7929 h: hue,
7930 s: saturation,
7931 v: value
7932 };
7933}
7934
7935var cssUtil = {
7936 // split a string with css styles into an object with key/values
7937 split: function split(cssText) {
7938 var styles = {};
7939 cssText.split(";").forEach(function (style) {
7940 if (style.trim() != "") {
7941 var parts = style.split(":");
7942
7943 var _key3 = parts[0].trim();
7944
7945 var _value2 = parts[1].trim();
7946
7947 styles[_key3] = _value2;
7948 }
7949 });
7950 return styles;
7951 },
7952 // build a css text string from an object with key/values
7953 join: function join(styles) {
7954 return Object.keys(styles).map(function (key) {
7955 return key + ": " + styles[key];
7956 }).join("; ");
7957 }
7958};
7959/**
7960 * Append a string with css styles to an element
7961 *
7962 * @param element - The element that will receive new styles.
7963 * @param cssText - The styles to be appended.
7964 */
7965
7966function addCssText(element, cssText) {
7967 var currentStyles = cssUtil.split(element.style.cssText);
7968 var newStyles = cssUtil.split(cssText);
7969
7970 var styles = _objectSpread2({}, currentStyles, {}, newStyles);
7971
7972 element.style.cssText = cssUtil.join(styles);
7973}
7974/**
7975 * Remove a string with css styles from an element
7976 *
7977 * @param element - The element from which styles should be removed.
7978 * @param cssText - The styles to be removed.
7979 */
7980
7981
7982function removeCssText(element, cssText) {
7983 var styles = cssUtil.split(element.style.cssText);
7984 var removeStyles = cssUtil.split(cssText);
7985
7986 for (var _key4 in removeStyles) {
7987 if (Object.prototype.hasOwnProperty.call(removeStyles, _key4)) {
7988 delete styles[_key4];
7989 }
7990 }
7991
7992 element.style.cssText = cssUtil.join(styles);
7993}
7994/**
7995 * Convert HSV <0, 1> into RGB color object.
7996 * https://gist.github.com/mjijackson/5311256
7997 *
7998 * @param h - Hue
7999 * @param s - Saturation
8000 * @param v - Value
8001 *
8002 * @returns RGB color object.
8003 */
8004
8005
8006function HSVToRGB(h, s, v) {
8007 var r;
8008 var g;
8009 var b;
8010 var i = Math.floor(h * 6);
8011 var f = h * 6 - i;
8012 var p = v * (1 - s);
8013 var q = v * (1 - f * s);
8014 var t = v * (1 - (1 - f) * s);
8015
8016 switch (i % 6) {
8017 case 0:
8018 r = v, g = t, b = p;
8019 break;
8020
8021 case 1:
8022 r = q, g = v, b = p;
8023 break;
8024
8025 case 2:
8026 r = p, g = v, b = t;
8027 break;
8028
8029 case 3:
8030 r = p, g = q, b = v;
8031 break;
8032
8033 case 4:
8034 r = t, g = p, b = v;
8035 break;
8036
8037 case 5:
8038 r = v, g = p, b = q;
8039 break;
8040 }
8041
8042 return {
8043 r: Math.floor(r * 255),
8044 g: Math.floor(g * 255),
8045 b: Math.floor(b * 255)
8046 };
8047}
8048/**
8049 * Convert HSV <0, 1> into hex color string.
8050 *
8051 * @param h - Hue
8052 * @param s - Saturation
8053 * @param v - Value
8054 *
8055 * @returns Hex color string.
8056 */
8057
8058
8059function HSVToHex(h, s, v) {
8060 var rgb = HSVToRGB(h, s, v);
8061 return RGBToHex(rgb.r, rgb.g, rgb.b);
8062}
8063/**
8064 * Convert hex color string into HSV <0, 1>.
8065 *
8066 * @param hex - Hex color string.
8067 *
8068 * @returns HSV color object.
8069 */
8070
8071
8072function hexToHSV(hex) {
8073 var rgb = hexToRGB(hex);
8074
8075 if (!rgb) {
8076 throw new TypeError("'".concat(hex, "' is not a valid color."));
8077 }
8078
8079 return RGBToHSV(rgb.r, rgb.g, rgb.b);
8080}
8081/**
8082 * Validate hex color string.
8083 *
8084 * @param hex - Unknown string that may contain a color.
8085 *
8086 * @returns True if the string is valid, false otherwise.
8087 */
8088
8089
8090function isValidHex(hex) {
8091 var isOk = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex);
8092 return isOk;
8093}
8094/**
8095 * Validate RGB color string.
8096 *
8097 * @param rgb - Unknown string that may contain a color.
8098 *
8099 * @returns True if the string is valid, false otherwise.
8100 */
8101
8102
8103function isValidRGB(rgb) {
8104 return rgbRE.test(rgb);
8105}
8106/**
8107 * Validate RGBA color string.
8108 *
8109 * @param rgba - Unknown string that may contain a color.
8110 *
8111 * @returns True if the string is valid, false otherwise.
8112 */
8113
8114
8115function isValidRGBA(rgba) {
8116 return rgbaRE.test(rgba);
8117}
8118/**
8119 * This recursively redirects the prototype of JSON objects to the referenceObject.
8120 * This is used for default options.
8121 *
8122 * @param fields - Names of properties to be bridged.
8123 * @param referenceObject - The original object.
8124 *
8125 * @returns A new object inheriting from the referenceObject.
8126 */
8127
8128
8129function selectiveBridgeObject(fields, referenceObject) {
8130 if (referenceObject !== null && _typeof(referenceObject) === "object") {
8131 // !!! typeof null === 'object'
8132 var objectTo = Object.create(referenceObject);
8133
8134 for (var i = 0; i < fields.length; i++) {
8135 if (Object.prototype.hasOwnProperty.call(referenceObject, fields[i])) {
8136 if (_typeof(referenceObject[fields[i]]) == "object") {
8137 objectTo[fields[i]] = bridgeObject(referenceObject[fields[i]]);
8138 }
8139 }
8140 }
8141
8142 return objectTo;
8143 } else {
8144 return null;
8145 }
8146}
8147/**
8148 * This recursively redirects the prototype of JSON objects to the referenceObject.
8149 * This is used for default options.
8150 *
8151 * @param referenceObject - The original object.
8152 *
8153 * @returns The Element if the referenceObject is an Element, or a new object inheriting from the referenceObject.
8154 */
8155
8156
8157function bridgeObject(referenceObject) {
8158 if (referenceObject === null || _typeof(referenceObject) !== "object") {
8159 return null;
8160 }
8161
8162 if (referenceObject instanceof Element) {
8163 // Avoid bridging DOM objects
8164 return referenceObject;
8165 }
8166
8167 var objectTo = Object.create(referenceObject);
8168
8169 for (var i in referenceObject) {
8170 if (Object.prototype.hasOwnProperty.call(referenceObject, i)) {
8171 if (_typeof(referenceObject[i]) == "object") {
8172 objectTo[i] = bridgeObject(referenceObject[i]);
8173 }
8174 }
8175 }
8176
8177 return objectTo;
8178}
8179/**
8180 * This method provides a stable sort implementation, very fast for presorted data.
8181 *
8182 * @param a - The array to be sorted (in-place).
8183 * @param compare - An order comparator.
8184 *
8185 * @returns The argument a.
8186 */
8187
8188
8189function insertSort(a, compare) {
8190 for (var i = 0; i < a.length; i++) {
8191 var k = a[i];
8192 var j = void 0;
8193
8194 for (j = i; j > 0 && compare(k, a[j - 1]) < 0; j--) {
8195 a[j] = a[j - 1];
8196 }
8197
8198 a[j] = k;
8199 }
8200
8201 return a;
8202}
8203/**
8204 * This is used to set the options of subobjects in the options object.
8205 *
8206 * A requirement of these subobjects is that they have an 'enabled' element
8207 * which is optional for the user but mandatory for the program.
8208 *
8209 * The added value here of the merge is that option 'enabled' is set as required.
8210 *
8211 * @param mergeTarget - Either this.options or the options used for the groups.
8212 * @param options - Options.
8213 * @param option - Option key in the options argument.
8214 * @param globalOptions - Global options, passed in to determine value of option 'enabled'.
8215 */
8216
8217
8218function mergeOptions(mergeTarget, options, option) {
8219 var globalOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; // Local helpers
8220
8221 var isPresent = function isPresent(obj) {
8222 return obj !== null && obj !== undefined;
8223 };
8224
8225 var isObject = function isObject(obj) {
8226 return obj !== null && _typeof(obj) === "object";
8227 }; // https://stackoverflow.com/a/34491287/1223531
8228
8229
8230 var isEmpty = function isEmpty(obj) {
8231 for (var x in obj) {
8232 if (Object.prototype.hasOwnProperty.call(obj, x)) {
8233 return false;
8234 }
8235 }
8236
8237 return true;
8238 }; // Guards
8239
8240
8241 if (!isObject(mergeTarget)) {
8242 throw new Error("Parameter mergeTarget must be an object");
8243 }
8244
8245 if (!isObject(options)) {
8246 throw new Error("Parameter options must be an object");
8247 }
8248
8249 if (!isPresent(option)) {
8250 throw new Error("Parameter option must have a value");
8251 }
8252
8253 if (!isObject(globalOptions)) {
8254 throw new Error("Parameter globalOptions must be an object");
8255 } //
8256 // Actual merge routine, separated from main logic
8257 // Only a single level of options is merged. Deeper levels are ref'd. This may actually be an issue.
8258 //
8259
8260
8261 var doMerge = function doMerge(target, options, option) {
8262 if (!isObject(target[option])) {
8263 target[option] = {};
8264 }
8265
8266 var src = options[option];
8267 var dst = target[option];
8268
8269 for (var prop in src) {
8270 if (Object.prototype.hasOwnProperty.call(src, prop)) {
8271 dst[prop] = src[prop];
8272 }
8273 }
8274 }; // Local initialization
8275
8276
8277 var srcOption = options[option];
8278 var globalPassed = isObject(globalOptions) && !isEmpty(globalOptions);
8279 var globalOption = globalPassed ? globalOptions[option] : undefined;
8280 var globalEnabled = globalOption ? globalOption.enabled : undefined; /////////////////////////////////////////
8281 // Main routine
8282 /////////////////////////////////////////
8283
8284 if (srcOption === undefined) {
8285 return; // Nothing to do
8286 }
8287
8288 if (typeof srcOption === "boolean") {
8289 if (!isObject(mergeTarget[option])) {
8290 mergeTarget[option] = {};
8291 }
8292
8293 mergeTarget[option].enabled = srcOption;
8294 return;
8295 }
8296
8297 if (srcOption === null && !isObject(mergeTarget[option])) {
8298 // If possible, explicit copy from globals
8299 if (isPresent(globalOption)) {
8300 mergeTarget[option] = Object.create(globalOption);
8301 } else {
8302 return; // Nothing to do
8303 }
8304 }
8305
8306 if (!isObject(srcOption)) {
8307 return;
8308 } //
8309 // Ensure that 'enabled' is properly set. It is required internally
8310 // Note that the value from options will always overwrite the existing value
8311 //
8312
8313
8314 var enabled = true; // default value
8315
8316 if (srcOption.enabled !== undefined) {
8317 enabled = srcOption.enabled;
8318 } else {
8319 // Take from globals, if present
8320 if (globalEnabled !== undefined) {
8321 enabled = globalOption.enabled;
8322 }
8323 }
8324
8325 doMerge(mergeTarget, options, option);
8326 mergeTarget[option].enabled = enabled;
8327}
8328/**
8329 * This function does a binary search for a visible item in a sorted list. If we find a visible item, the code that uses
8330 * this function will then iterate in both directions over this sorted list to find all visible items.
8331 *
8332 * @param orderedItems - Items ordered by start
8333 * @param comparator - -1 is lower, 0 is equal, 1 is higher
8334 * @param field - Property name on an item (i.e. item[field]).
8335 * @param field2 - Second property name on an item (i.e. item[field][field2]).
8336 *
8337 * @returns Index of the found item or -1 if nothing was found.
8338 */
8339
8340
8341function binarySearchCustom(orderedItems, comparator, field, field2) {
8342 var maxIterations = 10000;
8343 var iteration = 0;
8344 var low = 0;
8345 var high = orderedItems.length - 1;
8346
8347 while (low <= high && iteration < maxIterations) {
8348 var middle = Math.floor((low + high) / 2);
8349 var item = orderedItems[middle];
8350
8351 var _value3 = field2 === undefined ? item[field] : item[field][field2];
8352
8353 var searchResult = comparator(_value3);
8354
8355 if (searchResult == 0) {
8356 // jihaa, found a visible item!
8357 return middle;
8358 } else if (searchResult == -1) {
8359 // it is too small --> increase low
8360 low = middle + 1;
8361 } else {
8362 // it is too big --> decrease high
8363 high = middle - 1;
8364 }
8365
8366 iteration++;
8367 }
8368
8369 return -1;
8370}
8371/**
8372 * This function does a binary search for a specific value in a sorted array. If it does not exist but is in between of
8373 * two values, we return either the one before or the one after, depending on user input
8374 * If it is found, we return the index, else -1.
8375 *
8376 * @param orderedItems - Sorted array.
8377 * @param target - The searched value.
8378 * @param field - Name of the property in items to be searched.
8379 * @param sidePreference - If the target is between two values, should the index of the before or the after be returned?
8380 * @param comparator - An optional comparator, returning -1, 0, 1 for <, ===, >.
8381 *
8382 * @returns The index of found value or -1 if nothing was found.
8383 */
8384
8385
8386function binarySearchValue(orderedItems, target, field, sidePreference, comparator) {
8387 var maxIterations = 10000;
8388 var iteration = 0;
8389 var low = 0;
8390 var high = orderedItems.length - 1;
8391 var prevValue;
8392 var value;
8393 var nextValue;
8394 var middle;
8395 comparator = comparator != undefined ? comparator : function (a, b) {
8396 return a == b ? 0 : a < b ? -1 : 1;
8397 };
8398
8399 while (low <= high && iteration < maxIterations) {
8400 // get a new guess
8401 middle = Math.floor(0.5 * (high + low));
8402 prevValue = orderedItems[Math.max(0, middle - 1)][field];
8403 value = orderedItems[middle][field];
8404 nextValue = orderedItems[Math.min(orderedItems.length - 1, middle + 1)][field];
8405
8406 if (comparator(value, target) == 0) {
8407 // we found the target
8408 return middle;
8409 } else if (comparator(prevValue, target) < 0 && comparator(value, target) > 0) {
8410 // target is in between of the previous and the current
8411 return sidePreference == "before" ? Math.max(0, middle - 1) : middle;
8412 } else if (comparator(value, target) < 0 && comparator(nextValue, target) > 0) {
8413 // target is in between of the current and the next
8414 return sidePreference == "before" ? middle : Math.min(orderedItems.length - 1, middle + 1);
8415 } else {
8416 // didnt find the target, we need to change our boundaries.
8417 if (comparator(value, target) < 0) {
8418 // it is too small --> increase low
8419 low = middle + 1;
8420 } else {
8421 // it is too big --> decrease high
8422 high = middle - 1;
8423 }
8424 }
8425
8426 iteration++;
8427 } // didnt find anything. Return -1.
8428
8429
8430 return -1;
8431}
8432/*
8433 * Easing Functions.
8434 * Only considering the t value for the range [0, 1] => [0, 1].
8435 *
8436 * Inspiration: from http://gizma.com/easing/
8437 * https://gist.github.com/gre/1650294
8438 */
8439
8440
8441var easingFunctions = {
8442 /**
8443 * no easing, no acceleration
8444 *
8445 * @param t - Time.
8446 *
8447 * @returns Value at time t.
8448 */
8449 linear: function linear(t) {
8450 return t;
8451 },
8452
8453 /**
8454 * accelerating from zero velocity
8455 *
8456 * @param t - Time.
8457 *
8458 * @returns Value at time t.
8459 */
8460 easeInQuad: function easeInQuad(t) {
8461 return t * t;
8462 },
8463
8464 /**
8465 * decelerating to zero velocity
8466 *
8467 * @param t - Time.
8468 *
8469 * @returns Value at time t.
8470 */
8471 easeOutQuad: function easeOutQuad(t) {
8472 return t * (2 - t);
8473 },
8474
8475 /**
8476 * acceleration until halfway, then deceleration
8477 *
8478 * @param t - Time.
8479 *
8480 * @returns Value at time t.
8481 */
8482 easeInOutQuad: function easeInOutQuad(t) {
8483 return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
8484 },
8485
8486 /**
8487 * accelerating from zero velocity
8488 *
8489 * @param t - Time.
8490 *
8491 * @returns Value at time t.
8492 */
8493 easeInCubic: function easeInCubic(t) {
8494 return t * t * t;
8495 },
8496
8497 /**
8498 * decelerating to zero velocity
8499 *
8500 * @param t - Time.
8501 *
8502 * @returns Value at time t.
8503 */
8504 easeOutCubic: function easeOutCubic(t) {
8505 return --t * t * t + 1;
8506 },
8507
8508 /**
8509 * acceleration until halfway, then deceleration
8510 *
8511 * @param t - Time.
8512 *
8513 * @returns Value at time t.
8514 */
8515 easeInOutCubic: function easeInOutCubic(t) {
8516 return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
8517 },
8518
8519 /**
8520 * accelerating from zero velocity
8521 *
8522 * @param t - Time.
8523 *
8524 * @returns Value at time t.
8525 */
8526 easeInQuart: function easeInQuart(t) {
8527 return t * t * t * t;
8528 },
8529
8530 /**
8531 * decelerating to zero velocity
8532 *
8533 * @param t - Time.
8534 *
8535 * @returns Value at time t.
8536 */
8537 easeOutQuart: function easeOutQuart(t) {
8538 return 1 - --t * t * t * t;
8539 },
8540
8541 /**
8542 * acceleration until halfway, then deceleration
8543 *
8544 * @param t - Time.
8545 *
8546 * @returns Value at time t.
8547 */
8548 easeInOutQuart: function easeInOutQuart(t) {
8549 return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
8550 },
8551
8552 /**
8553 * accelerating from zero velocity
8554 *
8555 * @param t - Time.
8556 *
8557 * @returns Value at time t.
8558 */
8559 easeInQuint: function easeInQuint(t) {
8560 return t * t * t * t * t;
8561 },
8562
8563 /**
8564 * decelerating to zero velocity
8565 *
8566 * @param t - Time.
8567 *
8568 * @returns Value at time t.
8569 */
8570 easeOutQuint: function easeOutQuint(t) {
8571 return 1 + --t * t * t * t * t;
8572 },
8573
8574 /**
8575 * acceleration until halfway, then deceleration
8576 *
8577 * @param t - Time.
8578 *
8579 * @returns Value at time t.
8580 */
8581 easeInOutQuint: function easeInOutQuint(t) {
8582 return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
8583 }
8584};
8585/**
8586 * Experimentaly compute the width of the scrollbar for this browser.
8587 *
8588 * @returns The width in pixels.
8589 */
8590
8591function getScrollBarWidth() {
8592 var inner = document.createElement("p");
8593 inner.style.width = "100%";
8594 inner.style.height = "200px";
8595 var outer = document.createElement("div");
8596 outer.style.position = "absolute";
8597 outer.style.top = "0px";
8598 outer.style.left = "0px";
8599 outer.style.visibility = "hidden";
8600 outer.style.width = "200px";
8601 outer.style.height = "150px";
8602 outer.style.overflow = "hidden";
8603 outer.appendChild(inner);
8604 document.body.appendChild(outer);
8605 var w1 = inner.offsetWidth;
8606 outer.style.overflow = "scroll";
8607 var w2 = inner.offsetWidth;
8608
8609 if (w1 == w2) {
8610 w2 = outer.clientWidth;
8611 }
8612
8613 document.body.removeChild(outer);
8614 return w1 - w2;
8615} // @TODO: This doesn't work properly.
8616// It works only for single property objects,
8617// otherwise it combines all of the types in a union.
8618// export function topMost<K1 extends string, V1> (
8619// pile: Record<K1, undefined | V1>[],
8620// accessors: K1 | [K1]
8621// ): undefined | V1
8622// export function topMost<K1 extends string, K2 extends string, V1, V2> (
8623// pile: Record<K1, undefined | V1 | Record<K2, undefined | V2>>[],
8624// accessors: [K1, K2]
8625// ): undefined | V1 | V2
8626// export function topMost<K1 extends string, K2 extends string, K3 extends string, V1, V2, V3> (
8627// pile: Record<K1, undefined | V1 | Record<K2, undefined | V2 | Record<K3, undefined | V3>>>[],
8628// accessors: [K1, K2, K3]
8629// ): undefined | V1 | V2 | V3
8630
8631/**
8632 * Get the top most property value from a pile of objects.
8633 *
8634 * @param pile - Array of objects, no required format.
8635 * @param accessors - Array of property names (e.g. object['foo']['bar'] → ['foo', 'bar']).
8636 *
8637 * @returns Value of the property with given accessors path from the first pile item where it's not undefined.
8638 */
8639
8640
8641function topMost(pile, accessors) {
8642 var candidate;
8643
8644 if (!Array.isArray(accessors)) {
8645 accessors = [accessors];
8646 }
8647
8648 var _iteratorNormalCompletion = true;
8649 var _didIteratorError = false;
8650 var _iteratorError = undefined;
8651
8652 try {
8653 for (var _iterator = pile[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
8654 var member = _step.value;
8655
8656 if (member) {
8657 candidate = member[accessors[0]];
8658
8659 for (var i = 1; i < accessors.length; i++) {
8660 if (candidate) {
8661 candidate = candidate[accessors[i]];
8662 }
8663 }
8664
8665 if (typeof candidate !== "undefined") {
8666 break;
8667 }
8668 }
8669 }
8670 } catch (err) {
8671 _didIteratorError = true;
8672 _iteratorError = err;
8673 } finally {
8674 try {
8675 if (!_iteratorNormalCompletion && _iterator.return != null) {
8676 _iterator.return();
8677 }
8678 } finally {
8679 if (_didIteratorError) {
8680 throw _iteratorError;
8681 }
8682 }
8683 }
8684
8685 return candidate;
8686}
8687
8688var util =
8689/*#__PURE__*/
8690Object.freeze({
8691 isNumber: isNumber,
8692 recursiveDOMDelete: recursiveDOMDelete,
8693 isString: isString,
8694 isObject: isObject,
8695 isDate: isDate,
8696 isMoment: isMoment,
8697 fillIfDefined: fillIfDefined,
8698 extend: extend,
8699 selectiveExtend: selectiveExtend,
8700 selectiveDeepExtend: selectiveDeepExtend,
8701 selectiveNotDeepExtend: selectiveNotDeepExtend,
8702 deepExtend: deepExtend,
8703 equalArray: equalArray,
8704 convert: convert,
8705 getType: getType,
8706 copyAndExtendArray: copyAndExtendArray,
8707 copyArray: copyArray,
8708 getAbsoluteLeft: getAbsoluteLeft,
8709 getAbsoluteRight: getAbsoluteRight,
8710 getAbsoluteTop: getAbsoluteTop,
8711 addClassName: addClassName,
8712 removeClassName: removeClassName,
8713 forEach: forEach,
8714 toArray: toArray,
8715 updateProperty: updateProperty,
8716 throttle: throttle,
8717 addEventListener: addEventListener,
8718 removeEventListener: removeEventListener,
8719 preventDefault: preventDefault,
8720 getTarget: getTarget,
8721 hasParent: hasParent,
8722 option: option,
8723 hexToRGB: hexToRGB,
8724 overrideOpacity: overrideOpacity,
8725 RGBToHex: RGBToHex,
8726 parseColor: parseColor,
8727 RGBToHSV: RGBToHSV,
8728 addCssText: addCssText,
8729 removeCssText: removeCssText,
8730 HSVToRGB: HSVToRGB,
8731 HSVToHex: HSVToHex,
8732 hexToHSV: hexToHSV,
8733 isValidHex: isValidHex,
8734 isValidRGB: isValidRGB,
8735 isValidRGBA: isValidRGBA,
8736 selectiveBridgeObject: selectiveBridgeObject,
8737 bridgeObject: bridgeObject,
8738 insertSort: insertSort,
8739 mergeOptions: mergeOptions,
8740 binarySearchCustom: binarySearchCustom,
8741 binarySearchValue: binarySearchValue,
8742 easingFunctions: easingFunctions,
8743 getScrollBarWidth: getScrollBarWidth,
8744 topMost: topMost,
8745 randomUUID: uuid4
8746}); // New API (tree shakeable).
8747
8748var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8749
8750function commonjsRequire$1 () {
8751 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
8752}
8753
8754function createCommonjsModule$1(fn, module) {
8755 return module = { exports: {} }, fn(module, module.exports), module.exports;
8756}
8757
8758var DOMutil = createCommonjsModule$1(function (module, exports) {
8759 // DOM utility methods
8760
8761 /**
8762 * this prepares the JSON container for allocating SVG elements
8763 * @param {Object} JSONcontainer
8764 * @private
8765 */
8766 exports.prepareElements = function (JSONcontainer) {
8767 // cleanup the redundant svgElements;
8768 for (var elementType in JSONcontainer) {
8769 if (JSONcontainer.hasOwnProperty(elementType)) {
8770 JSONcontainer[elementType].redundant = JSONcontainer[elementType].used;
8771 JSONcontainer[elementType].used = [];
8772 }
8773 }
8774 };
8775 /**
8776 * this cleans up all the unused SVG elements. By asking for the parentNode, we only need to supply the JSON container from
8777 * which to remove the redundant elements.
8778 *
8779 * @param {Object} JSONcontainer
8780 * @private
8781 */
8782
8783
8784 exports.cleanupElements = function (JSONcontainer) {
8785 // cleanup the redundant svgElements;
8786 for (var elementType in JSONcontainer) {
8787 if (JSONcontainer.hasOwnProperty(elementType)) {
8788 if (JSONcontainer[elementType].redundant) {
8789 for (var i = 0; i < JSONcontainer[elementType].redundant.length; i++) {
8790 JSONcontainer[elementType].redundant[i].parentNode.removeChild(JSONcontainer[elementType].redundant[i]);
8791 }
8792
8793 JSONcontainer[elementType].redundant = [];
8794 }
8795 }
8796 }
8797 };
8798 /**
8799 * Ensures that all elements are removed first up so they can be recreated cleanly
8800 * @param {Object} JSONcontainer
8801 */
8802
8803
8804 exports.resetElements = function (JSONcontainer) {
8805 exports.prepareElements(JSONcontainer);
8806 exports.cleanupElements(JSONcontainer);
8807 exports.prepareElements(JSONcontainer);
8808 };
8809 /**
8810 * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer
8811 * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this.
8812 *
8813 * @param {string} elementType
8814 * @param {Object} JSONcontainer
8815 * @param {Object} svgContainer
8816 * @returns {Element}
8817 * @private
8818 */
8819
8820
8821 exports.getSVGElement = function (elementType, JSONcontainer, svgContainer) {
8822 var element; // allocate SVG element, if it doesnt yet exist, create one.
8823
8824 if (JSONcontainer.hasOwnProperty(elementType)) {
8825 // this element has been created before
8826 // check if there is an redundant element
8827 if (JSONcontainer[elementType].redundant.length > 0) {
8828 element = JSONcontainer[elementType].redundant[0];
8829 JSONcontainer[elementType].redundant.shift();
8830 } else {
8831 // create a new element and add it to the SVG
8832 element = document.createElementNS('http://www.w3.org/2000/svg', elementType);
8833 svgContainer.appendChild(element);
8834 }
8835 } else {
8836 // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it.
8837 element = document.createElementNS('http://www.w3.org/2000/svg', elementType);
8838 JSONcontainer[elementType] = {
8839 used: [],
8840 redundant: []
8841 };
8842 svgContainer.appendChild(element);
8843 }
8844
8845 JSONcontainer[elementType].used.push(element);
8846 return element;
8847 };
8848 /**
8849 * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer
8850 * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this.
8851 *
8852 * @param {string} elementType
8853 * @param {Object} JSONcontainer
8854 * @param {Element} DOMContainer
8855 * @param {Element} insertBefore
8856 * @returns {*}
8857 */
8858
8859
8860 exports.getDOMElement = function (elementType, JSONcontainer, DOMContainer, insertBefore) {
8861 var element; // allocate DOM element, if it doesnt yet exist, create one.
8862
8863 if (JSONcontainer.hasOwnProperty(elementType)) {
8864 // this element has been created before
8865 // check if there is an redundant element
8866 if (JSONcontainer[elementType].redundant.length > 0) {
8867 element = JSONcontainer[elementType].redundant[0];
8868 JSONcontainer[elementType].redundant.shift();
8869 } else {
8870 // create a new element and add it to the SVG
8871 element = document.createElement(elementType);
8872
8873 if (insertBefore !== undefined) {
8874 DOMContainer.insertBefore(element, insertBefore);
8875 } else {
8876 DOMContainer.appendChild(element);
8877 }
8878 }
8879 } else {
8880 // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it.
8881 element = document.createElement(elementType);
8882 JSONcontainer[elementType] = {
8883 used: [],
8884 redundant: []
8885 };
8886
8887 if (insertBefore !== undefined) {
8888 DOMContainer.insertBefore(element, insertBefore);
8889 } else {
8890 DOMContainer.appendChild(element);
8891 }
8892 }
8893
8894 JSONcontainer[elementType].used.push(element);
8895 return element;
8896 };
8897 /**
8898 * Draw a point object. This is a separate function because it can also be called by the legend.
8899 * The reason the JSONcontainer and the target SVG svgContainer have to be supplied is so the legend can use these functions
8900 * as well.
8901 *
8902 * @param {number} x
8903 * @param {number} y
8904 * @param {Object} groupTemplate: A template containing the necessary information to draw the datapoint e.g., {style: 'circle', size: 5, className: 'className' }
8905 * @param {Object} JSONcontainer
8906 * @param {Object} svgContainer
8907 * @param {Object} labelObj
8908 * @returns {vis.PointItem}
8909 */
8910
8911
8912 exports.drawPoint = function (x, y, groupTemplate, JSONcontainer, svgContainer, labelObj) {
8913 var point;
8914
8915 if (groupTemplate.style == 'circle') {
8916 point = exports.getSVGElement('circle', JSONcontainer, svgContainer);
8917 point.setAttributeNS(null, "cx", x);
8918 point.setAttributeNS(null, "cy", y);
8919 point.setAttributeNS(null, "r", 0.5 * groupTemplate.size);
8920 } else {
8921 point = exports.getSVGElement('rect', JSONcontainer, svgContainer);
8922 point.setAttributeNS(null, "x", x - 0.5 * groupTemplate.size);
8923 point.setAttributeNS(null, "y", y - 0.5 * groupTemplate.size);
8924 point.setAttributeNS(null, "width", groupTemplate.size);
8925 point.setAttributeNS(null, "height", groupTemplate.size);
8926 }
8927
8928 if (groupTemplate.styles !== undefined) {
8929 point.setAttributeNS(null, "style", groupTemplate.styles);
8930 }
8931
8932 point.setAttributeNS(null, "class", groupTemplate.className + " vis-point"); //handle label
8933
8934 if (labelObj) {
8935 var label = exports.getSVGElement('text', JSONcontainer, svgContainer);
8936
8937 if (labelObj.xOffset) {
8938 x = x + labelObj.xOffset;
8939 }
8940
8941 if (labelObj.yOffset) {
8942 y = y + labelObj.yOffset;
8943 }
8944
8945 if (labelObj.content) {
8946 label.textContent = labelObj.content;
8947 }
8948
8949 if (labelObj.className) {
8950 label.setAttributeNS(null, "class", labelObj.className + " vis-label");
8951 }
8952
8953 label.setAttributeNS(null, "x", x);
8954 label.setAttributeNS(null, "y", y);
8955 }
8956
8957 return point;
8958 };
8959 /**
8960 * draw a bar SVG element centered on the X coordinate
8961 *
8962 * @param {number} x
8963 * @param {number} y
8964 * @param {number} width
8965 * @param {number} height
8966 * @param {string} className
8967 * @param {Object} JSONcontainer
8968 * @param {Object} svgContainer
8969 * @param {string} style
8970 */
8971
8972
8973 exports.drawBar = function (x, y, width, height, className, JSONcontainer, svgContainer, style) {
8974 if (height != 0) {
8975 if (height < 0) {
8976 height *= -1;
8977 y -= height;
8978 }
8979
8980 var rect = exports.getSVGElement('rect', JSONcontainer, svgContainer);
8981 rect.setAttributeNS(null, "x", x - 0.5 * width);
8982 rect.setAttributeNS(null, "y", y);
8983 rect.setAttributeNS(null, "width", width);
8984 rect.setAttributeNS(null, "height", height);
8985 rect.setAttributeNS(null, "class", className);
8986
8987 if (style) {
8988 rect.setAttributeNS(null, "style", style);
8989 }
8990 }
8991 };
8992});
8993var DOMutil_1 = DOMutil.prepareElements;
8994var DOMutil_2 = DOMutil.cleanupElements;
8995var DOMutil_3 = DOMutil.resetElements;
8996var DOMutil_4 = DOMutil.getSVGElement;
8997var DOMutil_5 = DOMutil.getDOMElement;
8998var DOMutil_6 = DOMutil.drawPoint;
8999var DOMutil_7 = DOMutil.drawBar;
9000
9001/**
9002 * vis-data - data
9003 * http://visjs.org/
9004 *
9005 * Manage unstructured data using DataSet. Add, update, and remove data, and listen for changes in the data.
9006 *
9007 * @version 6.2.0
9008 * @date 2019-08-14T22:18:56Z
9009 *
9010 * @copyright (c) 2011-2017 Almende B.V, http://almende.com
9011 * @copyright (c) 2018-2019 visjs contributors, https://github.com/visjs
9012 *
9013 * @license
9014 * vis.js is dual licensed under both
9015 *
9016 * 1. The Apache 2.0 License
9017 * http://www.apache.org/licenses/LICENSE-2.0
9018 *
9019 * and
9020 *
9021 * 2. The MIT License
9022 * http://opensource.org/licenses/MIT
9023 *
9024 * vis.js may be distributed under either license.
9025 */
9026function createCommonjsModule$2(fn, module) {
9027 return module = {
9028 exports: {}
9029 }, fn(module, module.exports), module.exports;
9030}
9031
9032var runtime_1 = createCommonjsModule$2(function (module) {
9033 /**
9034 * Copyright (c) 2014-present, Facebook, Inc.
9035 *
9036 * This source code is licensed under the MIT license found in the
9037 * LICENSE file in the root directory of this source tree.
9038 */
9039 var runtime = function (exports) {
9040 var Op = Object.prototype;
9041 var hasOwn = Op.hasOwnProperty;
9042 var undefined$1; // More compressible than void 0.
9043
9044 var $Symbol = typeof Symbol === "function" ? Symbol : {};
9045 var iteratorSymbol = $Symbol.iterator || "@@iterator";
9046 var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
9047 var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
9048
9049 function wrap(innerFn, outerFn, self, tryLocsList) {
9050 // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
9051 var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
9052 var generator = Object.create(protoGenerator.prototype);
9053 var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
9054 // .throw, and .return methods.
9055
9056 generator._invoke = makeInvokeMethod(innerFn, self, context);
9057 return generator;
9058 }
9059
9060 exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
9061 // record like context.tryEntries[i].completion. This interface could
9062 // have been (and was previously) designed to take a closure to be
9063 // invoked without arguments, but in all the cases we care about we
9064 // already have an existing method we want to call, so there's no need
9065 // to create a new function object. We can even get away with assuming
9066 // the method takes exactly one argument, since that happens to be true
9067 // in every case, so we don't have to touch the arguments object. The
9068 // only additional allocation required is the completion record, which
9069 // has a stable shape and so hopefully should be cheap to allocate.
9070
9071 function tryCatch(fn, obj, arg) {
9072 try {
9073 return {
9074 type: "normal",
9075 arg: fn.call(obj, arg)
9076 };
9077 } catch (err) {
9078 return {
9079 type: "throw",
9080 arg: err
9081 };
9082 }
9083 }
9084
9085 var GenStateSuspendedStart = "suspendedStart";
9086 var GenStateSuspendedYield = "suspendedYield";
9087 var GenStateExecuting = "executing";
9088 var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
9089 // breaking out of the dispatch switch statement.
9090
9091 var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
9092 // .constructor.prototype properties for functions that return Generator
9093 // objects. For full spec compliance, you may wish to configure your
9094 // minifier not to mangle the names of these two functions.
9095
9096 function Generator() {}
9097
9098 function GeneratorFunction() {}
9099
9100 function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
9101 // don't natively support it.
9102
9103
9104 var IteratorPrototype = {};
9105
9106 IteratorPrototype[iteratorSymbol] = function () {
9107 return this;
9108 };
9109
9110 var getProto = Object.getPrototypeOf;
9111 var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
9112
9113 if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
9114 // This environment has a native %IteratorPrototype%; use it instead
9115 // of the polyfill.
9116 IteratorPrototype = NativeIteratorPrototype;
9117 }
9118
9119 var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
9120 GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
9121 GeneratorFunctionPrototype.constructor = GeneratorFunction;
9122 GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; // Helper for defining the .next, .throw, and .return methods of the
9123 // Iterator interface in terms of a single ._invoke method.
9124
9125 function defineIteratorMethods(prototype) {
9126 ["next", "throw", "return"].forEach(function (method) {
9127 prototype[method] = function (arg) {
9128 return this._invoke(method, arg);
9129 };
9130 });
9131 }
9132
9133 exports.isGeneratorFunction = function (genFun) {
9134 var ctor = typeof genFun === "function" && genFun.constructor;
9135 return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
9136 // do is to check its .name property.
9137 (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
9138 };
9139
9140 exports.mark = function (genFun) {
9141 if (Object.setPrototypeOf) {
9142 Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
9143 } else {
9144 genFun.__proto__ = GeneratorFunctionPrototype;
9145
9146 if (!(toStringTagSymbol in genFun)) {
9147 genFun[toStringTagSymbol] = "GeneratorFunction";
9148 }
9149 }
9150
9151 genFun.prototype = Object.create(Gp);
9152 return genFun;
9153 }; // Within the body of any async function, `await x` is transformed to
9154 // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
9155 // `hasOwn.call(value, "__await")` to determine if the yielded value is
9156 // meant to be awaited.
9157
9158
9159 exports.awrap = function (arg) {
9160 return {
9161 __await: arg
9162 };
9163 };
9164
9165 function AsyncIterator(generator) {
9166 function invoke(method, arg, resolve, reject) {
9167 var record = tryCatch(generator[method], generator, arg);
9168
9169 if (record.type === "throw") {
9170 reject(record.arg);
9171 } else {
9172 var result = record.arg;
9173 var value = result.value;
9174
9175 if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
9176 return Promise.resolve(value.__await).then(function (value) {
9177 invoke("next", value, resolve, reject);
9178 }, function (err) {
9179 invoke("throw", err, resolve, reject);
9180 });
9181 }
9182
9183 return Promise.resolve(value).then(function (unwrapped) {
9184 // When a yielded Promise is resolved, its final value becomes
9185 // the .value of the Promise<{value,done}> result for the
9186 // current iteration.
9187 result.value = unwrapped;
9188 resolve(result);
9189 }, function (error) {
9190 // If a rejected Promise was yielded, throw the rejection back
9191 // into the async generator function so it can be handled there.
9192 return invoke("throw", error, resolve, reject);
9193 });
9194 }
9195 }
9196
9197 var previousPromise;
9198
9199 function enqueue(method, arg) {
9200 function callInvokeWithMethodAndArg() {
9201 return new Promise(function (resolve, reject) {
9202 invoke(method, arg, resolve, reject);
9203 });
9204 }
9205
9206 return previousPromise = // If enqueue has been called before, then we want to wait until
9207 // all previous Promises have been resolved before calling invoke,
9208 // so that results are always delivered in the correct order. If
9209 // enqueue has not been called before, then it is important to
9210 // call invoke immediately, without waiting on a callback to fire,
9211 // so that the async generator function has the opportunity to do
9212 // any necessary setup in a predictable way. This predictability
9213 // is why the Promise constructor synchronously invokes its
9214 // executor callback, and why async functions synchronously
9215 // execute code before the first await. Since we implement simple
9216 // async functions in terms of async generators, it is especially
9217 // important to get this right, even though it requires care.
9218 previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
9219 // invocations of the iterator.
9220 callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
9221 } // Define the unified helper method that is used to implement .next,
9222 // .throw, and .return (see defineIteratorMethods).
9223
9224
9225 this._invoke = enqueue;
9226 }
9227
9228 defineIteratorMethods(AsyncIterator.prototype);
9229
9230 AsyncIterator.prototype[asyncIteratorSymbol] = function () {
9231 return this;
9232 };
9233
9234 exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
9235 // AsyncIterator objects; they just return a Promise for the value of
9236 // the final result produced by the iterator.
9237
9238 exports.async = function (innerFn, outerFn, self, tryLocsList) {
9239 var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList));
9240 return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
9241 : iter.next().then(function (result) {
9242 return result.done ? result.value : iter.next();
9243 });
9244 };
9245
9246 function makeInvokeMethod(innerFn, self, context) {
9247 var state = GenStateSuspendedStart;
9248 return function invoke(method, arg) {
9249 if (state === GenStateExecuting) {
9250 throw new Error("Generator is already running");
9251 }
9252
9253 if (state === GenStateCompleted) {
9254 if (method === "throw") {
9255 throw arg;
9256 } // Be forgiving, per 25.3.3.3.3 of the spec:
9257 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
9258
9259
9260 return doneResult();
9261 }
9262
9263 context.method = method;
9264 context.arg = arg;
9265
9266 while (true) {
9267 var delegate = context.delegate;
9268
9269 if (delegate) {
9270 var delegateResult = maybeInvokeDelegate(delegate, context);
9271
9272 if (delegateResult) {
9273 if (delegateResult === ContinueSentinel) continue;
9274 return delegateResult;
9275 }
9276 }
9277
9278 if (context.method === "next") {
9279 // Setting context._sent for legacy support of Babel's
9280 // function.sent implementation.
9281 context.sent = context._sent = context.arg;
9282 } else if (context.method === "throw") {
9283 if (state === GenStateSuspendedStart) {
9284 state = GenStateCompleted;
9285 throw context.arg;
9286 }
9287
9288 context.dispatchException(context.arg);
9289 } else if (context.method === "return") {
9290 context.abrupt("return", context.arg);
9291 }
9292
9293 state = GenStateExecuting;
9294 var record = tryCatch(innerFn, self, context);
9295
9296 if (record.type === "normal") {
9297 // If an exception is thrown from innerFn, we leave state ===
9298 // GenStateExecuting and loop back for another invocation.
9299 state = context.done ? GenStateCompleted : GenStateSuspendedYield;
9300
9301 if (record.arg === ContinueSentinel) {
9302 continue;
9303 }
9304
9305 return {
9306 value: record.arg,
9307 done: context.done
9308 };
9309 } else if (record.type === "throw") {
9310 state = GenStateCompleted; // Dispatch the exception by looping back around to the
9311 // context.dispatchException(context.arg) call above.
9312
9313 context.method = "throw";
9314 context.arg = record.arg;
9315 }
9316 }
9317 };
9318 } // Call delegate.iterator[context.method](context.arg) and handle the
9319 // result, either by returning a { value, done } result from the
9320 // delegate iterator, or by modifying context.method and context.arg,
9321 // setting context.delegate to null, and returning the ContinueSentinel.
9322
9323
9324 function maybeInvokeDelegate(delegate, context) {
9325 var method = delegate.iterator[context.method];
9326
9327 if (method === undefined$1) {
9328 // A .throw or .return when the delegate iterator has no .throw
9329 // method always terminates the yield* loop.
9330 context.delegate = null;
9331
9332 if (context.method === "throw") {
9333 // Note: ["return"] must be used for ES3 parsing compatibility.
9334 if (delegate.iterator["return"]) {
9335 // If the delegate iterator has a return method, give it a
9336 // chance to clean up.
9337 context.method = "return";
9338 context.arg = undefined$1;
9339 maybeInvokeDelegate(delegate, context);
9340
9341 if (context.method === "throw") {
9342 // If maybeInvokeDelegate(context) changed context.method from
9343 // "return" to "throw", let that override the TypeError below.
9344 return ContinueSentinel;
9345 }
9346 }
9347
9348 context.method = "throw";
9349 context.arg = new TypeError("The iterator does not provide a 'throw' method");
9350 }
9351
9352 return ContinueSentinel;
9353 }
9354
9355 var record = tryCatch(method, delegate.iterator, context.arg);
9356
9357 if (record.type === "throw") {
9358 context.method = "throw";
9359 context.arg = record.arg;
9360 context.delegate = null;
9361 return ContinueSentinel;
9362 }
9363
9364 var info = record.arg;
9365
9366 if (!info) {
9367 context.method = "throw";
9368 context.arg = new TypeError("iterator result is not an object");
9369 context.delegate = null;
9370 return ContinueSentinel;
9371 }
9372
9373 if (info.done) {
9374 // Assign the result of the finished delegate to the temporary
9375 // variable specified by delegate.resultName (see delegateYield).
9376 context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
9377
9378 context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
9379 // exception, let the outer generator proceed normally. If
9380 // context.method was "next", forget context.arg since it has been
9381 // "consumed" by the delegate iterator. If context.method was
9382 // "return", allow the original .return call to continue in the
9383 // outer generator.
9384
9385 if (context.method !== "return") {
9386 context.method = "next";
9387 context.arg = undefined$1;
9388 }
9389 } else {
9390 // Re-yield the result returned by the delegate method.
9391 return info;
9392 } // The delegate iterator is finished, so forget it and continue with
9393 // the outer generator.
9394
9395
9396 context.delegate = null;
9397 return ContinueSentinel;
9398 } // Define Generator.prototype.{next,throw,return} in terms of the
9399 // unified ._invoke helper method.
9400
9401
9402 defineIteratorMethods(Gp);
9403 Gp[toStringTagSymbol] = "Generator"; // A Generator should always return itself as the iterator object when the
9404 // @@iterator function is called on it. Some browsers' implementations of the
9405 // iterator prototype chain incorrectly implement this, causing the Generator
9406 // object to not be returned from this call. This ensures that doesn't happen.
9407 // See https://github.com/facebook/regenerator/issues/274 for more details.
9408
9409 Gp[iteratorSymbol] = function () {
9410 return this;
9411 };
9412
9413 Gp.toString = function () {
9414 return "[object Generator]";
9415 };
9416
9417 function pushTryEntry(locs) {
9418 var entry = {
9419 tryLoc: locs[0]
9420 };
9421
9422 if (1 in locs) {
9423 entry.catchLoc = locs[1];
9424 }
9425
9426 if (2 in locs) {
9427 entry.finallyLoc = locs[2];
9428 entry.afterLoc = locs[3];
9429 }
9430
9431 this.tryEntries.push(entry);
9432 }
9433
9434 function resetTryEntry(entry) {
9435 var record = entry.completion || {};
9436 record.type = "normal";
9437 delete record.arg;
9438 entry.completion = record;
9439 }
9440
9441 function Context(tryLocsList) {
9442 // The root entry object (effectively a try statement without a catch
9443 // or a finally block) gives us a place to store values thrown from
9444 // locations where there is no enclosing try statement.
9445 this.tryEntries = [{
9446 tryLoc: "root"
9447 }];
9448 tryLocsList.forEach(pushTryEntry, this);
9449 this.reset(true);
9450 }
9451
9452 exports.keys = function (object) {
9453 var keys = [];
9454
9455 for (var key in object) {
9456 keys.push(key);
9457 }
9458
9459 keys.reverse(); // Rather than returning an object with a next method, we keep
9460 // things simple and return the next function itself.
9461
9462 return function next() {
9463 while (keys.length) {
9464 var key = keys.pop();
9465
9466 if (key in object) {
9467 next.value = key;
9468 next.done = false;
9469 return next;
9470 }
9471 } // To avoid creating an additional object, we just hang the .value
9472 // and .done properties off the next function object itself. This
9473 // also ensures that the minifier will not anonymize the function.
9474
9475
9476 next.done = true;
9477 return next;
9478 };
9479 };
9480
9481 function values(iterable) {
9482 if (iterable) {
9483 var iteratorMethod = iterable[iteratorSymbol];
9484
9485 if (iteratorMethod) {
9486 return iteratorMethod.call(iterable);
9487 }
9488
9489 if (typeof iterable.next === "function") {
9490 return iterable;
9491 }
9492
9493 if (!isNaN(iterable.length)) {
9494 var i = -1,
9495 next = function next() {
9496 while (++i < iterable.length) {
9497 if (hasOwn.call(iterable, i)) {
9498 next.value = iterable[i];
9499 next.done = false;
9500 return next;
9501 }
9502 }
9503
9504 next.value = undefined$1;
9505 next.done = true;
9506 return next;
9507 };
9508
9509 return next.next = next;
9510 }
9511 } // Return an iterator with no values.
9512
9513
9514 return {
9515 next: doneResult
9516 };
9517 }
9518
9519 exports.values = values;
9520
9521 function doneResult() {
9522 return {
9523 value: undefined$1,
9524 done: true
9525 };
9526 }
9527
9528 Context.prototype = {
9529 constructor: Context,
9530 reset: function (skipTempReset) {
9531 this.prev = 0;
9532 this.next = 0; // Resetting context._sent for legacy support of Babel's
9533 // function.sent implementation.
9534
9535 this.sent = this._sent = undefined$1;
9536 this.done = false;
9537 this.delegate = null;
9538 this.method = "next";
9539 this.arg = undefined$1;
9540 this.tryEntries.forEach(resetTryEntry);
9541
9542 if (!skipTempReset) {
9543 for (var name in this) {
9544 // Not sure about the optimal order of these conditions:
9545 if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
9546 this[name] = undefined$1;
9547 }
9548 }
9549 }
9550 },
9551 stop: function () {
9552 this.done = true;
9553 var rootEntry = this.tryEntries[0];
9554 var rootRecord = rootEntry.completion;
9555
9556 if (rootRecord.type === "throw") {
9557 throw rootRecord.arg;
9558 }
9559
9560 return this.rval;
9561 },
9562 dispatchException: function (exception) {
9563 if (this.done) {
9564 throw exception;
9565 }
9566
9567 var context = this;
9568
9569 function handle(loc, caught) {
9570 record.type = "throw";
9571 record.arg = exception;
9572 context.next = loc;
9573
9574 if (caught) {
9575 // If the dispatched exception was caught by a catch block,
9576 // then let that catch block handle the exception normally.
9577 context.method = "next";
9578 context.arg = undefined$1;
9579 }
9580
9581 return !!caught;
9582 }
9583
9584 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
9585 var entry = this.tryEntries[i];
9586 var record = entry.completion;
9587
9588 if (entry.tryLoc === "root") {
9589 // Exception thrown outside of any try block that could handle
9590 // it, so set the completion value of the entire function to
9591 // throw the exception.
9592 return handle("end");
9593 }
9594
9595 if (entry.tryLoc <= this.prev) {
9596 var hasCatch = hasOwn.call(entry, "catchLoc");
9597 var hasFinally = hasOwn.call(entry, "finallyLoc");
9598
9599 if (hasCatch && hasFinally) {
9600 if (this.prev < entry.catchLoc) {
9601 return handle(entry.catchLoc, true);
9602 } else if (this.prev < entry.finallyLoc) {
9603 return handle(entry.finallyLoc);
9604 }
9605 } else if (hasCatch) {
9606 if (this.prev < entry.catchLoc) {
9607 return handle(entry.catchLoc, true);
9608 }
9609 } else if (hasFinally) {
9610 if (this.prev < entry.finallyLoc) {
9611 return handle(entry.finallyLoc);
9612 }
9613 } else {
9614 throw new Error("try statement without catch or finally");
9615 }
9616 }
9617 }
9618 },
9619 abrupt: function (type, arg) {
9620 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
9621 var entry = this.tryEntries[i];
9622
9623 if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
9624 var finallyEntry = entry;
9625 break;
9626 }
9627 }
9628
9629 if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
9630 // Ignore the finally entry if control is not jumping to a
9631 // location outside the try/catch block.
9632 finallyEntry = null;
9633 }
9634
9635 var record = finallyEntry ? finallyEntry.completion : {};
9636 record.type = type;
9637 record.arg = arg;
9638
9639 if (finallyEntry) {
9640 this.method = "next";
9641 this.next = finallyEntry.finallyLoc;
9642 return ContinueSentinel;
9643 }
9644
9645 return this.complete(record);
9646 },
9647 complete: function (record, afterLoc) {
9648 if (record.type === "throw") {
9649 throw record.arg;
9650 }
9651
9652 if (record.type === "break" || record.type === "continue") {
9653 this.next = record.arg;
9654 } else if (record.type === "return") {
9655 this.rval = this.arg = record.arg;
9656 this.method = "return";
9657 this.next = "end";
9658 } else if (record.type === "normal" && afterLoc) {
9659 this.next = afterLoc;
9660 }
9661
9662 return ContinueSentinel;
9663 },
9664 finish: function (finallyLoc) {
9665 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
9666 var entry = this.tryEntries[i];
9667
9668 if (entry.finallyLoc === finallyLoc) {
9669 this.complete(entry.completion, entry.afterLoc);
9670 resetTryEntry(entry);
9671 return ContinueSentinel;
9672 }
9673 }
9674 },
9675 "catch": function (tryLoc) {
9676 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
9677 var entry = this.tryEntries[i];
9678
9679 if (entry.tryLoc === tryLoc) {
9680 var record = entry.completion;
9681
9682 if (record.type === "throw") {
9683 var thrown = record.arg;
9684 resetTryEntry(entry);
9685 }
9686
9687 return thrown;
9688 }
9689 } // The context.catch method must only be called with a location
9690 // argument that corresponds to a known catch block.
9691
9692
9693 throw new Error("illegal catch attempt");
9694 },
9695 delegateYield: function (iterable, resultName, nextLoc) {
9696 this.delegate = {
9697 iterator: values(iterable),
9698 resultName: resultName,
9699 nextLoc: nextLoc
9700 };
9701
9702 if (this.method === "next") {
9703 // Deliberately forget the last sent value so that we don't
9704 // accidentally pass it on to the delegate.
9705 this.arg = undefined$1;
9706 }
9707
9708 return ContinueSentinel;
9709 }
9710 }; // Regardless of whether this script is executing as a CommonJS module
9711 // or not, return the runtime object so that we can declare the variable
9712 // regeneratorRuntime in the outer scope, which allows this module to be
9713 // injected easily by `bin/regenerator --include-runtime script.js`.
9714
9715 return exports;
9716 }( // If this script is executing as a CommonJS module, use module.exports
9717 // as the regeneratorRuntime namespace. Otherwise create a new empty
9718 // object. Either way, the resulting object will be used to initialize
9719 // the regeneratorRuntime variable at the top of this file.
9720 module.exports);
9721
9722 try {
9723 regeneratorRuntime = runtime;
9724 } catch (accidentalStrictMode) {
9725 // This module should not be running in strict mode, so the above
9726 // assignment should always work unless something is misconfigured. Just
9727 // in case runtime.js accidentally runs in strict mode, we can escape
9728 // strict mode using a global Function call. This could conceivably fail
9729 // if a Content Security Policy forbids using Function, but in that case
9730 // the proper solution is to fix the accidental strict mode problem. If
9731 // you've misconfigured your bundler to force strict mode and applied a
9732 // CSP to forbid Function, and you're not willing to fix either of those
9733 // problems, please detail your unique predicament in a GitHub issue.
9734 Function("r", "regeneratorRuntime = r")(runtime);
9735 }
9736});
9737var regenerator = runtime_1;
9738
9739function _defineProperty$1(obj, key, value) {
9740 if (key in obj) {
9741 Object.defineProperty(obj, key, {
9742 value: value,
9743 enumerable: true,
9744 configurable: true,
9745 writable: true
9746 });
9747 } else {
9748 obj[key] = value;
9749 }
9750
9751 return obj;
9752}
9753
9754var defineProperty$1 = _defineProperty$1;
9755
9756function _arrayWithoutHoles$1(arr) {
9757 if (Array.isArray(arr)) {
9758 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
9759 arr2[i] = arr[i];
9760 }
9761
9762 return arr2;
9763 }
9764}
9765
9766var arrayWithoutHoles = _arrayWithoutHoles$1;
9767
9768function _iterableToArray$1(iter) {
9769 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
9770}
9771
9772var iterableToArray = _iterableToArray$1;
9773
9774function _nonIterableSpread$1() {
9775 throw new TypeError("Invalid attempt to spread non-iterable instance");
9776}
9777
9778var nonIterableSpread = _nonIterableSpread$1;
9779
9780function _toConsumableArray$1(arr) {
9781 return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
9782}
9783
9784var toConsumableArray = _toConsumableArray$1;
9785
9786var _typeof_1 = createCommonjsModule$2(function (module) {
9787 function _typeof2(obj) {
9788 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
9789 _typeof2 = function _typeof2(obj) {
9790 return typeof obj;
9791 };
9792 } else {
9793 _typeof2 = function _typeof2(obj) {
9794 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
9795 };
9796 }
9797
9798 return _typeof2(obj);
9799 }
9800
9801 function _typeof(obj) {
9802 if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
9803 module.exports = _typeof = function _typeof(obj) {
9804 return _typeof2(obj);
9805 };
9806 } else {
9807 module.exports = _typeof = function _typeof(obj) {
9808 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
9809 };
9810 }
9811
9812 return _typeof(obj);
9813 }
9814
9815 module.exports = _typeof;
9816});
9817
9818function _classCallCheck(instance, Constructor) {
9819 if (!(instance instanceof Constructor)) {
9820 throw new TypeError("Cannot call a class as a function");
9821 }
9822}
9823
9824var classCallCheck = _classCallCheck;
9825
9826function _defineProperties(target, props) {
9827 for (var i = 0; i < props.length; i++) {
9828 var descriptor = props[i];
9829 descriptor.enumerable = descriptor.enumerable || false;
9830 descriptor.configurable = true;
9831 if ("value" in descriptor) descriptor.writable = true;
9832 Object.defineProperty(target, descriptor.key, descriptor);
9833 }
9834}
9835
9836function _createClass(Constructor, protoProps, staticProps) {
9837 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
9838 if (staticProps) _defineProperties(Constructor, staticProps);
9839 return Constructor;
9840}
9841
9842var createClass = _createClass;
9843
9844function _assertThisInitialized(self) {
9845 if (self === void 0) {
9846 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
9847 }
9848
9849 return self;
9850}
9851
9852var assertThisInitialized = _assertThisInitialized;
9853
9854function _possibleConstructorReturn(self, call) {
9855 if (call && (_typeof_1(call) === "object" || typeof call === "function")) {
9856 return call;
9857 }
9858
9859 return assertThisInitialized(self);
9860}
9861
9862var possibleConstructorReturn = _possibleConstructorReturn;
9863var getPrototypeOf = createCommonjsModule$2(function (module) {
9864 function _getPrototypeOf(o) {
9865 module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
9866 return o.__proto__ || Object.getPrototypeOf(o);
9867 };
9868 return _getPrototypeOf(o);
9869 }
9870
9871 module.exports = _getPrototypeOf;
9872});
9873var setPrototypeOf$1 = createCommonjsModule$2(function (module) {
9874 function _setPrototypeOf(o, p) {
9875 module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
9876 o.__proto__ = p;
9877 return o;
9878 };
9879
9880 return _setPrototypeOf(o, p);
9881 }
9882
9883 module.exports = _setPrototypeOf;
9884});
9885
9886function _inherits(subClass, superClass) {
9887 if (typeof superClass !== "function" && superClass !== null) {
9888 throw new TypeError("Super expression must either be null or a function");
9889 }
9890
9891 subClass.prototype = Object.create(superClass && superClass.prototype, {
9892 constructor: {
9893 value: subClass,
9894 writable: true,
9895 configurable: true
9896 }
9897 });
9898 if (superClass) setPrototypeOf$1(subClass, superClass);
9899}
9900
9901var inherits = _inherits; // Maps for number <-> hex string conversion
9902
9903var byteToHex$2 = [];
9904
9905for (var i$2 = 0; i$2 < 256; i$2++) {
9906 byteToHex$2[i$2] = (i$2 + 0x100).toString(16).substr(1);
9907}
9908/**
9909 * Represent binary UUID into it's string representation.
9910 *
9911 * @param buf - Buffer containing UUID bytes.
9912 * @param offset - Offset from the start of the buffer where the UUID is saved (not needed if the buffer starts with the UUID).
9913 *
9914 * @returns String representation of the UUID.
9915 */
9916
9917
9918function stringifyUUID$1(buf, offset) {
9919 var i = offset || 0;
9920 var bth = byteToHex$2;
9921 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++]];
9922}
9923/**
9924 * Generate 16 random bytes to be used as a base for UUID.
9925 *
9926 * @ignore
9927 */
9928
9929
9930var random$1 = function () {
9931 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
9932 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
9933 // Moderately fast, high quality
9934 var _rnds8 = new Uint8Array(16);
9935
9936 return function whatwgRNG() {
9937 crypto.getRandomValues(_rnds8);
9938 return _rnds8;
9939 };
9940 } // Math.random()-based (RNG)
9941 //
9942 // If all else fails, use Math.random().
9943 // It's fast, but is of unspecified quality.
9944
9945
9946 var _rnds = new Array(16);
9947
9948 return function () {
9949 for (var i = 0, r; i < 16; i++) {
9950 if ((i & 0x03) === 0) {
9951 r = Math.random() * 0x100000000;
9952 }
9953
9954 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
9955 }
9956
9957 return _rnds;
9958 }; // uuid.js
9959 //
9960 // Copyright (c) 2010-2012 Robert Kieffer
9961 // MIT License - http://opensource.org/licenses/mit-license.php
9962 // Unique ID creation requires a high quality random # generator. We feature
9963 // detect to determine the best RNG source, normalizing to a function that
9964 // returns 128-bits of randomness, since that's what's usually required
9965 // return require('./rng');
9966}();
9967
9968var byteToHex$1$1 = [];
9969
9970for (var i$1$2 = 0; i$1$2 < 256; i$1$2++) {
9971 byteToHex$1$1[i$1$2] = (i$1$2 + 0x100).toString(16).substr(1);
9972} // **`v1()` - Generate time-based UUID**
9973//
9974// Inspired by https://github.com/LiosK/UUID.js
9975// and http://docs.python.org/library/uuid.html
9976// random #'s we need to init node and clockseq
9977
9978
9979var seedBytes$1 = random$1(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
9980
9981var 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
9982
9983var defaultClockseq$1 = (seedBytes$1[6] << 8 | seedBytes$1[7]) & 0x3fff; // Previous uuid creation time
9984
9985/**
9986 * UUIDv4 options.
9987 */
9988
9989/**
9990 * Generate UUIDv4
9991 *
9992 * @param options - Options to be used instead of default generated values.
9993 * String 'binary' is a shorthand for uuid4({}, new Array(16)).
9994 * @param buf - If present the buffer will be filled with the generated UUID.
9995 * @param offset - Offset of the UUID from the start of the buffer.
9996 *
9997 * @returns UUIDv4
9998 */
9999
10000function uuid4$1() {
10001 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10002 var buf = arguments.length > 1 ? arguments[1] : undefined;
10003 var offset = arguments.length > 2 ? arguments[2] : undefined; // Deprecated - 'format' argument, as supported in v1.2
10004
10005 var i = buf && offset || 0;
10006
10007 if (typeof options === 'string') {
10008 buf = options === 'binary' ? new Array(16) : undefined;
10009 options = {};
10010 }
10011
10012 var rnds = options.random || (options.rng || random$1)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
10013
10014 rnds[6] = rnds[6] & 0x0f | 0x40;
10015 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
10016
10017 if (buf) {
10018 for (var ii = 0; ii < 16; ii++) {
10019 buf[i + ii] = rnds[ii];
10020 }
10021 }
10022
10023 return buf || stringifyUUID$1(rnds);
10024} // Rollup will complain about mixing default and named exports in UMD build,
10025
10026
10027function _typeof$1(obj) {
10028 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
10029 _typeof$1 = function (obj) {
10030 return typeof obj;
10031 };
10032 } else {
10033 _typeof$1 = function (obj) {
10034 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
10035 };
10036 }
10037
10038 return _typeof$1(obj);
10039}
10040
10041var commonjsGlobal$2 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
10042
10043function commonjsRequire$2() {
10044 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
10045}
10046
10047function createCommonjsModule$1$1(fn, module) {
10048 return module = {
10049 exports: {}
10050 }, fn(module, module.exports), module.exports;
10051}
10052
10053var moment$1 = createCommonjsModule$1$1(function (module, exports) {
10054 (function (global, factory) {
10055 module.exports = factory();
10056 })(commonjsGlobal$2, function () {
10057 var hookCallback;
10058
10059 function hooks() {
10060 return hookCallback.apply(null, arguments);
10061 } // This is done to register the method called with moment()
10062 // without creating circular dependencies.
10063
10064
10065 function setHookCallback(callback) {
10066 hookCallback = callback;
10067 }
10068
10069 function isArray(input) {
10070 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
10071 }
10072
10073 function isObject(input) {
10074 // IE8 will treat undefined and null as object if it wasn't for
10075 // input != null
10076 return input != null && Object.prototype.toString.call(input) === '[object Object]';
10077 }
10078
10079 function isObjectEmpty(obj) {
10080 if (Object.getOwnPropertyNames) {
10081 return Object.getOwnPropertyNames(obj).length === 0;
10082 } else {
10083 var k;
10084
10085 for (k in obj) {
10086 if (obj.hasOwnProperty(k)) {
10087 return false;
10088 }
10089 }
10090
10091 return true;
10092 }
10093 }
10094
10095 function isUndefined(input) {
10096 return input === void 0;
10097 }
10098
10099 function isNumber(input) {
10100 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
10101 }
10102
10103 function isDate(input) {
10104 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
10105 }
10106
10107 function map(arr, fn) {
10108 var res = [],
10109 i;
10110
10111 for (i = 0; i < arr.length; ++i) {
10112 res.push(fn(arr[i], i));
10113 }
10114
10115 return res;
10116 }
10117
10118 function hasOwnProp(a, b) {
10119 return Object.prototype.hasOwnProperty.call(a, b);
10120 }
10121
10122 function extend(a, b) {
10123 for (var i in b) {
10124 if (hasOwnProp(b, i)) {
10125 a[i] = b[i];
10126 }
10127 }
10128
10129 if (hasOwnProp(b, 'toString')) {
10130 a.toString = b.toString;
10131 }
10132
10133 if (hasOwnProp(b, 'valueOf')) {
10134 a.valueOf = b.valueOf;
10135 }
10136
10137 return a;
10138 }
10139
10140 function createUTC(input, format, locale, strict) {
10141 return createLocalOrUTC(input, format, locale, strict, true).utc();
10142 }
10143
10144 function defaultParsingFlags() {
10145 // We need to deep clone this object.
10146 return {
10147 empty: false,
10148 unusedTokens: [],
10149 unusedInput: [],
10150 overflow: -2,
10151 charsLeftOver: 0,
10152 nullInput: false,
10153 invalidMonth: null,
10154 invalidFormat: false,
10155 userInvalidated: false,
10156 iso: false,
10157 parsedDateParts: [],
10158 meridiem: null,
10159 rfc2822: false,
10160 weekdayMismatch: false
10161 };
10162 }
10163
10164 function getParsingFlags(m) {
10165 if (m._pf == null) {
10166 m._pf = defaultParsingFlags();
10167 }
10168
10169 return m._pf;
10170 }
10171
10172 var some;
10173
10174 if (Array.prototype.some) {
10175 some = Array.prototype.some;
10176 } else {
10177 some = function (fun) {
10178 var t = Object(this);
10179 var len = t.length >>> 0;
10180
10181 for (var i = 0; i < len; i++) {
10182 if (i in t && fun.call(this, t[i], i, t)) {
10183 return true;
10184 }
10185 }
10186
10187 return false;
10188 };
10189 }
10190
10191 function isValid(m) {
10192 if (m._isValid == null) {
10193 var flags = getParsingFlags(m);
10194 var parsedParts = some.call(flags.parsedDateParts, function (i) {
10195 return i != null;
10196 });
10197 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);
10198
10199 if (m._strict) {
10200 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
10201 }
10202
10203 if (Object.isFrozen == null || !Object.isFrozen(m)) {
10204 m._isValid = isNowValid;
10205 } else {
10206 return isNowValid;
10207 }
10208 }
10209
10210 return m._isValid;
10211 }
10212
10213 function createInvalid(flags) {
10214 var m = createUTC(NaN);
10215
10216 if (flags != null) {
10217 extend(getParsingFlags(m), flags);
10218 } else {
10219 getParsingFlags(m).userInvalidated = true;
10220 }
10221
10222 return m;
10223 } // Plugins that add properties should also add the key here (null value),
10224 // so we can properly clone ourselves.
10225
10226
10227 var momentProperties = hooks.momentProperties = [];
10228
10229 function copyConfig(to, from) {
10230 var i, prop, val;
10231
10232 if (!isUndefined(from._isAMomentObject)) {
10233 to._isAMomentObject = from._isAMomentObject;
10234 }
10235
10236 if (!isUndefined(from._i)) {
10237 to._i = from._i;
10238 }
10239
10240 if (!isUndefined(from._f)) {
10241 to._f = from._f;
10242 }
10243
10244 if (!isUndefined(from._l)) {
10245 to._l = from._l;
10246 }
10247
10248 if (!isUndefined(from._strict)) {
10249 to._strict = from._strict;
10250 }
10251
10252 if (!isUndefined(from._tzm)) {
10253 to._tzm = from._tzm;
10254 }
10255
10256 if (!isUndefined(from._isUTC)) {
10257 to._isUTC = from._isUTC;
10258 }
10259
10260 if (!isUndefined(from._offset)) {
10261 to._offset = from._offset;
10262 }
10263
10264 if (!isUndefined(from._pf)) {
10265 to._pf = getParsingFlags(from);
10266 }
10267
10268 if (!isUndefined(from._locale)) {
10269 to._locale = from._locale;
10270 }
10271
10272 if (momentProperties.length > 0) {
10273 for (i = 0; i < momentProperties.length; i++) {
10274 prop = momentProperties[i];
10275 val = from[prop];
10276
10277 if (!isUndefined(val)) {
10278 to[prop] = val;
10279 }
10280 }
10281 }
10282
10283 return to;
10284 }
10285
10286 var updateInProgress = false; // Moment prototype object
10287
10288 function Moment(config) {
10289 copyConfig(this, config);
10290 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
10291
10292 if (!this.isValid()) {
10293 this._d = new Date(NaN);
10294 } // Prevent infinite loop in case updateOffset creates new moment
10295 // objects.
10296
10297
10298 if (updateInProgress === false) {
10299 updateInProgress = true;
10300 hooks.updateOffset(this);
10301 updateInProgress = false;
10302 }
10303 }
10304
10305 function isMoment(obj) {
10306 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
10307 }
10308
10309 function absFloor(number) {
10310 if (number < 0) {
10311 // -0 -> 0
10312 return Math.ceil(number) || 0;
10313 } else {
10314 return Math.floor(number);
10315 }
10316 }
10317
10318 function toInt(argumentForCoercion) {
10319 var coercedNumber = +argumentForCoercion,
10320 value = 0;
10321
10322 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
10323 value = absFloor(coercedNumber);
10324 }
10325
10326 return value;
10327 } // compare two arrays, return the number of differences
10328
10329
10330 function compareArrays(array1, array2, dontConvert) {
10331 var len = Math.min(array1.length, array2.length),
10332 lengthDiff = Math.abs(array1.length - array2.length),
10333 diffs = 0,
10334 i;
10335
10336 for (i = 0; i < len; i++) {
10337 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
10338 diffs++;
10339 }
10340 }
10341
10342 return diffs + lengthDiff;
10343 }
10344
10345 function warn(msg) {
10346 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
10347 console.warn('Deprecation warning: ' + msg);
10348 }
10349 }
10350
10351 function deprecate(msg, fn) {
10352 var firstTime = true;
10353 return extend(function () {
10354 if (hooks.deprecationHandler != null) {
10355 hooks.deprecationHandler(null, msg);
10356 }
10357
10358 if (firstTime) {
10359 var args = [];
10360 var arg;
10361
10362 for (var i = 0; i < arguments.length; i++) {
10363 arg = '';
10364
10365 if (typeof arguments[i] === 'object') {
10366 arg += '\n[' + i + '] ';
10367
10368 for (var key in arguments[0]) {
10369 arg += key + ': ' + arguments[0][key] + ', ';
10370 }
10371
10372 arg = arg.slice(0, -2); // Remove trailing comma and space
10373 } else {
10374 arg = arguments[i];
10375 }
10376
10377 args.push(arg);
10378 }
10379
10380 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
10381 firstTime = false;
10382 }
10383
10384 return fn.apply(this, arguments);
10385 }, fn);
10386 }
10387
10388 var deprecations = {};
10389
10390 function deprecateSimple(name, msg) {
10391 if (hooks.deprecationHandler != null) {
10392 hooks.deprecationHandler(name, msg);
10393 }
10394
10395 if (!deprecations[name]) {
10396 warn(msg);
10397 deprecations[name] = true;
10398 }
10399 }
10400
10401 hooks.suppressDeprecationWarnings = false;
10402 hooks.deprecationHandler = null;
10403
10404 function isFunction(input) {
10405 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
10406 }
10407
10408 function set(config) {
10409 var prop, i;
10410
10411 for (i in config) {
10412 prop = config[i];
10413
10414 if (isFunction(prop)) {
10415 this[i] = prop;
10416 } else {
10417 this['_' + i] = prop;
10418 }
10419 }
10420
10421 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
10422 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
10423 // TODO: Remove "ordinalParse" fallback in next major release.
10424
10425 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
10426 }
10427
10428 function mergeConfigs(parentConfig, childConfig) {
10429 var res = extend({}, parentConfig),
10430 prop;
10431
10432 for (prop in childConfig) {
10433 if (hasOwnProp(childConfig, prop)) {
10434 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
10435 res[prop] = {};
10436 extend(res[prop], parentConfig[prop]);
10437 extend(res[prop], childConfig[prop]);
10438 } else if (childConfig[prop] != null) {
10439 res[prop] = childConfig[prop];
10440 } else {
10441 delete res[prop];
10442 }
10443 }
10444 }
10445
10446 for (prop in parentConfig) {
10447 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
10448 // make sure changes to properties don't modify parent config
10449 res[prop] = extend({}, res[prop]);
10450 }
10451 }
10452
10453 return res;
10454 }
10455
10456 function Locale(config) {
10457 if (config != null) {
10458 this.set(config);
10459 }
10460 }
10461
10462 var keys;
10463
10464 if (Object.keys) {
10465 keys = Object.keys;
10466 } else {
10467 keys = function (obj) {
10468 var i,
10469 res = [];
10470
10471 for (i in obj) {
10472 if (hasOwnProp(obj, i)) {
10473 res.push(i);
10474 }
10475 }
10476
10477 return res;
10478 };
10479 }
10480
10481 var defaultCalendar = {
10482 sameDay: '[Today at] LT',
10483 nextDay: '[Tomorrow at] LT',
10484 nextWeek: 'dddd [at] LT',
10485 lastDay: '[Yesterday at] LT',
10486 lastWeek: '[Last] dddd [at] LT',
10487 sameElse: 'L'
10488 };
10489
10490 function calendar(key, mom, now) {
10491 var output = this._calendar[key] || this._calendar['sameElse'];
10492 return isFunction(output) ? output.call(mom, now) : output;
10493 }
10494
10495 var defaultLongDateFormat = {
10496 LTS: 'h:mm:ss A',
10497 LT: 'h:mm A',
10498 L: 'MM/DD/YYYY',
10499 LL: 'MMMM D, YYYY',
10500 LLL: 'MMMM D, YYYY h:mm A',
10501 LLLL: 'dddd, MMMM D, YYYY h:mm A'
10502 };
10503
10504 function longDateFormat(key) {
10505 var format = this._longDateFormat[key],
10506 formatUpper = this._longDateFormat[key.toUpperCase()];
10507
10508 if (format || !formatUpper) {
10509 return format;
10510 }
10511
10512 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
10513 return val.slice(1);
10514 });
10515 return this._longDateFormat[key];
10516 }
10517
10518 var defaultInvalidDate = 'Invalid date';
10519
10520 function invalidDate() {
10521 return this._invalidDate;
10522 }
10523
10524 var defaultOrdinal = '%d';
10525 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
10526
10527 function ordinal(number) {
10528 return this._ordinal.replace('%d', number);
10529 }
10530
10531 var defaultRelativeTime = {
10532 future: 'in %s',
10533 past: '%s ago',
10534 s: 'a few seconds',
10535 ss: '%d seconds',
10536 m: 'a minute',
10537 mm: '%d minutes',
10538 h: 'an hour',
10539 hh: '%d hours',
10540 d: 'a day',
10541 dd: '%d days',
10542 M: 'a month',
10543 MM: '%d months',
10544 y: 'a year',
10545 yy: '%d years'
10546 };
10547
10548 function relativeTime(number, withoutSuffix, string, isFuture) {
10549 var output = this._relativeTime[string];
10550 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
10551 }
10552
10553 function pastFuture(diff, output) {
10554 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
10555 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
10556 }
10557
10558 var aliases = {};
10559
10560 function addUnitAlias(unit, shorthand) {
10561 var lowerCase = unit.toLowerCase();
10562 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
10563 }
10564
10565 function normalizeUnits(units) {
10566 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
10567 }
10568
10569 function normalizeObjectUnits(inputObject) {
10570 var normalizedInput = {},
10571 normalizedProp,
10572 prop;
10573
10574 for (prop in inputObject) {
10575 if (hasOwnProp(inputObject, prop)) {
10576 normalizedProp = normalizeUnits(prop);
10577
10578 if (normalizedProp) {
10579 normalizedInput[normalizedProp] = inputObject[prop];
10580 }
10581 }
10582 }
10583
10584 return normalizedInput;
10585 }
10586
10587 var priorities = {};
10588
10589 function addUnitPriority(unit, priority) {
10590 priorities[unit] = priority;
10591 }
10592
10593 function getPrioritizedUnits(unitsObj) {
10594 var units = [];
10595
10596 for (var u in unitsObj) {
10597 units.push({
10598 unit: u,
10599 priority: priorities[u]
10600 });
10601 }
10602
10603 units.sort(function (a, b) {
10604 return a.priority - b.priority;
10605 });
10606 return units;
10607 }
10608
10609 function zeroFill(number, targetLength, forceSign) {
10610 var absNumber = '' + Math.abs(number),
10611 zerosToFill = targetLength - absNumber.length,
10612 sign = number >= 0;
10613 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
10614 }
10615
10616 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;
10617 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
10618 var formatFunctions = {};
10619 var formatTokenFunctions = {}; // token: 'M'
10620 // padded: ['MM', 2]
10621 // ordinal: 'Mo'
10622 // callback: function () { this.month() + 1 }
10623
10624 function addFormatToken(token, padded, ordinal, callback) {
10625 var func = callback;
10626
10627 if (typeof callback === 'string') {
10628 func = function () {
10629 return this[callback]();
10630 };
10631 }
10632
10633 if (token) {
10634 formatTokenFunctions[token] = func;
10635 }
10636
10637 if (padded) {
10638 formatTokenFunctions[padded[0]] = function () {
10639 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
10640 };
10641 }
10642
10643 if (ordinal) {
10644 formatTokenFunctions[ordinal] = function () {
10645 return this.localeData().ordinal(func.apply(this, arguments), token);
10646 };
10647 }
10648 }
10649
10650 function removeFormattingTokens(input) {
10651 if (input.match(/\[[\s\S]/)) {
10652 return input.replace(/^\[|\]$/g, '');
10653 }
10654
10655 return input.replace(/\\/g, '');
10656 }
10657
10658 function makeFormatFunction(format) {
10659 var array = format.match(formattingTokens),
10660 i,
10661 length;
10662
10663 for (i = 0, length = array.length; i < length; i++) {
10664 if (formatTokenFunctions[array[i]]) {
10665 array[i] = formatTokenFunctions[array[i]];
10666 } else {
10667 array[i] = removeFormattingTokens(array[i]);
10668 }
10669 }
10670
10671 return function (mom) {
10672 var output = '',
10673 i;
10674
10675 for (i = 0; i < length; i++) {
10676 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
10677 }
10678
10679 return output;
10680 };
10681 } // format date using native date object
10682
10683
10684 function formatMoment(m, format) {
10685 if (!m.isValid()) {
10686 return m.localeData().invalidDate();
10687 }
10688
10689 format = expandFormat(format, m.localeData());
10690 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
10691 return formatFunctions[format](m);
10692 }
10693
10694 function expandFormat(format, locale) {
10695 var i = 5;
10696
10697 function replaceLongDateFormatTokens(input) {
10698 return locale.longDateFormat(input) || input;
10699 }
10700
10701 localFormattingTokens.lastIndex = 0;
10702
10703 while (i >= 0 && localFormattingTokens.test(format)) {
10704 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
10705 localFormattingTokens.lastIndex = 0;
10706 i -= 1;
10707 }
10708
10709 return format;
10710 }
10711
10712 var match1 = /\d/; // 0 - 9
10713
10714 var match2 = /\d\d/; // 00 - 99
10715
10716 var match3 = /\d{3}/; // 000 - 999
10717
10718 var match4 = /\d{4}/; // 0000 - 9999
10719
10720 var match6 = /[+-]?\d{6}/; // -999999 - 999999
10721
10722 var match1to2 = /\d\d?/; // 0 - 99
10723
10724 var match3to4 = /\d\d\d\d?/; // 999 - 9999
10725
10726 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
10727
10728 var match1to3 = /\d{1,3}/; // 0 - 999
10729
10730 var match1to4 = /\d{1,4}/; // 0 - 9999
10731
10732 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
10733
10734 var matchUnsigned = /\d+/; // 0 - inf
10735
10736 var matchSigned = /[+-]?\d+/; // -inf - inf
10737
10738 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
10739
10740 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
10741
10742 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
10743 // any word (or two) characters or numbers including two/three word month in arabic.
10744 // includes scottish gaelic two word and hyphenated months
10745
10746 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;
10747 var regexes = {};
10748
10749 function addRegexToken(token, regex, strictRegex) {
10750 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
10751 return isStrict && strictRegex ? strictRegex : regex;
10752 };
10753 }
10754
10755 function getParseRegexForToken(token, config) {
10756 if (!hasOwnProp(regexes, token)) {
10757 return new RegExp(unescapeFormat(token));
10758 }
10759
10760 return regexes[token](config._strict, config._locale);
10761 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
10762
10763
10764 function unescapeFormat(s) {
10765 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
10766 return p1 || p2 || p3 || p4;
10767 }));
10768 }
10769
10770 function regexEscape(s) {
10771 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
10772 }
10773
10774 var tokens = {};
10775
10776 function addParseToken(token, callback) {
10777 var i,
10778 func = callback;
10779
10780 if (typeof token === 'string') {
10781 token = [token];
10782 }
10783
10784 if (isNumber(callback)) {
10785 func = function (input, array) {
10786 array[callback] = toInt(input);
10787 };
10788 }
10789
10790 for (i = 0; i < token.length; i++) {
10791 tokens[token[i]] = func;
10792 }
10793 }
10794
10795 function addWeekParseToken(token, callback) {
10796 addParseToken(token, function (input, array, config, token) {
10797 config._w = config._w || {};
10798 callback(input, config._w, config, token);
10799 });
10800 }
10801
10802 function addTimeToArrayFromToken(token, input, config) {
10803 if (input != null && hasOwnProp(tokens, token)) {
10804 tokens[token](input, config._a, config, token);
10805 }
10806 }
10807
10808 var YEAR = 0;
10809 var MONTH = 1;
10810 var DATE = 2;
10811 var HOUR = 3;
10812 var MINUTE = 4;
10813 var SECOND = 5;
10814 var MILLISECOND = 6;
10815 var WEEK = 7;
10816 var WEEKDAY = 8; // FORMATTING
10817
10818 addFormatToken('Y', 0, 0, function () {
10819 var y = this.year();
10820 return y <= 9999 ? '' + y : '+' + y;
10821 });
10822 addFormatToken(0, ['YY', 2], 0, function () {
10823 return this.year() % 100;
10824 });
10825 addFormatToken(0, ['YYYY', 4], 0, 'year');
10826 addFormatToken(0, ['YYYYY', 5], 0, 'year');
10827 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
10828
10829 addUnitAlias('year', 'y'); // PRIORITIES
10830
10831 addUnitPriority('year', 1); // PARSING
10832
10833 addRegexToken('Y', matchSigned);
10834 addRegexToken('YY', match1to2, match2);
10835 addRegexToken('YYYY', match1to4, match4);
10836 addRegexToken('YYYYY', match1to6, match6);
10837 addRegexToken('YYYYYY', match1to6, match6);
10838 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
10839 addParseToken('YYYY', function (input, array) {
10840 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
10841 });
10842 addParseToken('YY', function (input, array) {
10843 array[YEAR] = hooks.parseTwoDigitYear(input);
10844 });
10845 addParseToken('Y', function (input, array) {
10846 array[YEAR] = parseInt(input, 10);
10847 }); // HELPERS
10848
10849 function daysInYear(year) {
10850 return isLeapYear(year) ? 366 : 365;
10851 }
10852
10853 function isLeapYear(year) {
10854 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
10855 } // HOOKS
10856
10857
10858 hooks.parseTwoDigitYear = function (input) {
10859 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
10860 }; // MOMENTS
10861
10862
10863 var getSetYear = makeGetSet('FullYear', true);
10864
10865 function getIsLeapYear() {
10866 return isLeapYear(this.year());
10867 }
10868
10869 function makeGetSet(unit, keepTime) {
10870 return function (value) {
10871 if (value != null) {
10872 set$1(this, unit, value);
10873 hooks.updateOffset(this, keepTime);
10874 return this;
10875 } else {
10876 return get(this, unit);
10877 }
10878 };
10879 }
10880
10881 function get(mom, unit) {
10882 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
10883 }
10884
10885 function set$1(mom, unit, value) {
10886 if (mom.isValid() && !isNaN(value)) {
10887 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
10888 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
10889 } else {
10890 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
10891 }
10892 }
10893 } // MOMENTS
10894
10895
10896 function stringGet(units) {
10897 units = normalizeUnits(units);
10898
10899 if (isFunction(this[units])) {
10900 return this[units]();
10901 }
10902
10903 return this;
10904 }
10905
10906 function stringSet(units, value) {
10907 if (typeof units === 'object') {
10908 units = normalizeObjectUnits(units);
10909 var prioritized = getPrioritizedUnits(units);
10910
10911 for (var i = 0; i < prioritized.length; i++) {
10912 this[prioritized[i].unit](units[prioritized[i].unit]);
10913 }
10914 } else {
10915 units = normalizeUnits(units);
10916
10917 if (isFunction(this[units])) {
10918 return this[units](value);
10919 }
10920 }
10921
10922 return this;
10923 }
10924
10925 function mod(n, x) {
10926 return (n % x + x) % x;
10927 }
10928
10929 var indexOf;
10930
10931 if (Array.prototype.indexOf) {
10932 indexOf = Array.prototype.indexOf;
10933 } else {
10934 indexOf = function (o) {
10935 // I know
10936 var i;
10937
10938 for (i = 0; i < this.length; ++i) {
10939 if (this[i] === o) {
10940 return i;
10941 }
10942 }
10943
10944 return -1;
10945 };
10946 }
10947
10948 function daysInMonth(year, month) {
10949 if (isNaN(year) || isNaN(month)) {
10950 return NaN;
10951 }
10952
10953 var modMonth = mod(month, 12);
10954 year += (month - modMonth) / 12;
10955 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
10956 } // FORMATTING
10957
10958
10959 addFormatToken('M', ['MM', 2], 'Mo', function () {
10960 return this.month() + 1;
10961 });
10962 addFormatToken('MMM', 0, 0, function (format) {
10963 return this.localeData().monthsShort(this, format);
10964 });
10965 addFormatToken('MMMM', 0, 0, function (format) {
10966 return this.localeData().months(this, format);
10967 }); // ALIASES
10968
10969 addUnitAlias('month', 'M'); // PRIORITY
10970
10971 addUnitPriority('month', 8); // PARSING
10972
10973 addRegexToken('M', match1to2);
10974 addRegexToken('MM', match1to2, match2);
10975 addRegexToken('MMM', function (isStrict, locale) {
10976 return locale.monthsShortRegex(isStrict);
10977 });
10978 addRegexToken('MMMM', function (isStrict, locale) {
10979 return locale.monthsRegex(isStrict);
10980 });
10981 addParseToken(['M', 'MM'], function (input, array) {
10982 array[MONTH] = toInt(input) - 1;
10983 });
10984 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
10985 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
10986
10987
10988 if (month != null) {
10989 array[MONTH] = month;
10990 } else {
10991 getParsingFlags(config).invalidMonth = input;
10992 }
10993 }); // LOCALES
10994
10995 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
10996 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
10997
10998 function localeMonths(m, format) {
10999 if (!m) {
11000 return isArray(this._months) ? this._months : this._months['standalone'];
11001 }
11002
11003 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
11004 }
11005
11006 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
11007
11008 function localeMonthsShort(m, format) {
11009 if (!m) {
11010 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
11011 }
11012
11013 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
11014 }
11015
11016 function handleStrictParse(monthName, format, strict) {
11017 var i,
11018 ii,
11019 mom,
11020 llc = monthName.toLocaleLowerCase();
11021
11022 if (!this._monthsParse) {
11023 // this is not used
11024 this._monthsParse = [];
11025 this._longMonthsParse = [];
11026 this._shortMonthsParse = [];
11027
11028 for (i = 0; i < 12; ++i) {
11029 mom = createUTC([2000, i]);
11030 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
11031 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
11032 }
11033 }
11034
11035 if (strict) {
11036 if (format === 'MMM') {
11037 ii = indexOf.call(this._shortMonthsParse, llc);
11038 return ii !== -1 ? ii : null;
11039 } else {
11040 ii = indexOf.call(this._longMonthsParse, llc);
11041 return ii !== -1 ? ii : null;
11042 }
11043 } else {
11044 if (format === 'MMM') {
11045 ii = indexOf.call(this._shortMonthsParse, llc);
11046
11047 if (ii !== -1) {
11048 return ii;
11049 }
11050
11051 ii = indexOf.call(this._longMonthsParse, llc);
11052 return ii !== -1 ? ii : null;
11053 } else {
11054 ii = indexOf.call(this._longMonthsParse, llc);
11055
11056 if (ii !== -1) {
11057 return ii;
11058 }
11059
11060 ii = indexOf.call(this._shortMonthsParse, llc);
11061 return ii !== -1 ? ii : null;
11062 }
11063 }
11064 }
11065
11066 function localeMonthsParse(monthName, format, strict) {
11067 var i, mom, regex;
11068
11069 if (this._monthsParseExact) {
11070 return handleStrictParse.call(this, monthName, format, strict);
11071 }
11072
11073 if (!this._monthsParse) {
11074 this._monthsParse = [];
11075 this._longMonthsParse = [];
11076 this._shortMonthsParse = [];
11077 } // TODO: add sorting
11078 // Sorting makes sure if one month (or abbr) is a prefix of another
11079 // see sorting in computeMonthsParse
11080
11081
11082 for (i = 0; i < 12; i++) {
11083 // make the regex if we don't have it already
11084 mom = createUTC([2000, i]);
11085
11086 if (strict && !this._longMonthsParse[i]) {
11087 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
11088 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
11089 }
11090
11091 if (!strict && !this._monthsParse[i]) {
11092 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
11093 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
11094 } // test the regex
11095
11096
11097 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
11098 return i;
11099 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
11100 return i;
11101 } else if (!strict && this._monthsParse[i].test(monthName)) {
11102 return i;
11103 }
11104 }
11105 } // MOMENTS
11106
11107
11108 function setMonth(mom, value) {
11109 var dayOfMonth;
11110
11111 if (!mom.isValid()) {
11112 // No op
11113 return mom;
11114 }
11115
11116 if (typeof value === 'string') {
11117 if (/^\d+$/.test(value)) {
11118 value = toInt(value);
11119 } else {
11120 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
11121
11122 if (!isNumber(value)) {
11123 return mom;
11124 }
11125 }
11126 }
11127
11128 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
11129
11130 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
11131
11132 return mom;
11133 }
11134
11135 function getSetMonth(value) {
11136 if (value != null) {
11137 setMonth(this, value);
11138 hooks.updateOffset(this, true);
11139 return this;
11140 } else {
11141 return get(this, 'Month');
11142 }
11143 }
11144
11145 function getDaysInMonth() {
11146 return daysInMonth(this.year(), this.month());
11147 }
11148
11149 var defaultMonthsShortRegex = matchWord;
11150
11151 function monthsShortRegex(isStrict) {
11152 if (this._monthsParseExact) {
11153 if (!hasOwnProp(this, '_monthsRegex')) {
11154 computeMonthsParse.call(this);
11155 }
11156
11157 if (isStrict) {
11158 return this._monthsShortStrictRegex;
11159 } else {
11160 return this._monthsShortRegex;
11161 }
11162 } else {
11163 if (!hasOwnProp(this, '_monthsShortRegex')) {
11164 this._monthsShortRegex = defaultMonthsShortRegex;
11165 }
11166
11167 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
11168 }
11169 }
11170
11171 var defaultMonthsRegex = matchWord;
11172
11173 function monthsRegex(isStrict) {
11174 if (this._monthsParseExact) {
11175 if (!hasOwnProp(this, '_monthsRegex')) {
11176 computeMonthsParse.call(this);
11177 }
11178
11179 if (isStrict) {
11180 return this._monthsStrictRegex;
11181 } else {
11182 return this._monthsRegex;
11183 }
11184 } else {
11185 if (!hasOwnProp(this, '_monthsRegex')) {
11186 this._monthsRegex = defaultMonthsRegex;
11187 }
11188
11189 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
11190 }
11191 }
11192
11193 function computeMonthsParse() {
11194 function cmpLenRev(a, b) {
11195 return b.length - a.length;
11196 }
11197
11198 var shortPieces = [],
11199 longPieces = [],
11200 mixedPieces = [],
11201 i,
11202 mom;
11203
11204 for (i = 0; i < 12; i++) {
11205 // make the regex if we don't have it already
11206 mom = createUTC([2000, i]);
11207 shortPieces.push(this.monthsShort(mom, ''));
11208 longPieces.push(this.months(mom, ''));
11209 mixedPieces.push(this.months(mom, ''));
11210 mixedPieces.push(this.monthsShort(mom, ''));
11211 } // Sorting makes sure if one month (or abbr) is a prefix of another it
11212 // will match the longer piece.
11213
11214
11215 shortPieces.sort(cmpLenRev);
11216 longPieces.sort(cmpLenRev);
11217 mixedPieces.sort(cmpLenRev);
11218
11219 for (i = 0; i < 12; i++) {
11220 shortPieces[i] = regexEscape(shortPieces[i]);
11221 longPieces[i] = regexEscape(longPieces[i]);
11222 }
11223
11224 for (i = 0; i < 24; i++) {
11225 mixedPieces[i] = regexEscape(mixedPieces[i]);
11226 }
11227
11228 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
11229 this._monthsShortRegex = this._monthsRegex;
11230 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
11231 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
11232 }
11233
11234 function createDate(y, m, d, h, M, s, ms) {
11235 // can't just apply() to create a date:
11236 // https://stackoverflow.com/q/181348
11237 var date; // the date constructor remaps years 0-99 to 1900-1999
11238
11239 if (y < 100 && y >= 0) {
11240 // preserve leap years using a full 400 year cycle, then reset
11241 date = new Date(y + 400, m, d, h, M, s, ms);
11242
11243 if (isFinite(date.getFullYear())) {
11244 date.setFullYear(y);
11245 }
11246 } else {
11247 date = new Date(y, m, d, h, M, s, ms);
11248 }
11249
11250 return date;
11251 }
11252
11253 function createUTCDate(y) {
11254 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
11255
11256 if (y < 100 && y >= 0) {
11257 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
11258
11259 args[0] = y + 400;
11260 date = new Date(Date.UTC.apply(null, args));
11261
11262 if (isFinite(date.getUTCFullYear())) {
11263 date.setUTCFullYear(y);
11264 }
11265 } else {
11266 date = new Date(Date.UTC.apply(null, arguments));
11267 }
11268
11269 return date;
11270 } // start-of-first-week - start-of-year
11271
11272
11273 function firstWeekOffset(year, dow, doy) {
11274 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
11275 fwd = 7 + dow - doy,
11276 // first-week day local weekday -- which local weekday is fwd
11277 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
11278 return -fwdlw + fwd - 1;
11279 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
11280
11281
11282 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
11283 var localWeekday = (7 + weekday - dow) % 7,
11284 weekOffset = firstWeekOffset(year, dow, doy),
11285 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
11286 resYear,
11287 resDayOfYear;
11288
11289 if (dayOfYear <= 0) {
11290 resYear = year - 1;
11291 resDayOfYear = daysInYear(resYear) + dayOfYear;
11292 } else if (dayOfYear > daysInYear(year)) {
11293 resYear = year + 1;
11294 resDayOfYear = dayOfYear - daysInYear(year);
11295 } else {
11296 resYear = year;
11297 resDayOfYear = dayOfYear;
11298 }
11299
11300 return {
11301 year: resYear,
11302 dayOfYear: resDayOfYear
11303 };
11304 }
11305
11306 function weekOfYear(mom, dow, doy) {
11307 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
11308 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
11309 resWeek,
11310 resYear;
11311
11312 if (week < 1) {
11313 resYear = mom.year() - 1;
11314 resWeek = week + weeksInYear(resYear, dow, doy);
11315 } else if (week > weeksInYear(mom.year(), dow, doy)) {
11316 resWeek = week - weeksInYear(mom.year(), dow, doy);
11317 resYear = mom.year() + 1;
11318 } else {
11319 resYear = mom.year();
11320 resWeek = week;
11321 }
11322
11323 return {
11324 week: resWeek,
11325 year: resYear
11326 };
11327 }
11328
11329 function weeksInYear(year, dow, doy) {
11330 var weekOffset = firstWeekOffset(year, dow, doy),
11331 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
11332 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
11333 } // FORMATTING
11334
11335
11336 addFormatToken('w', ['ww', 2], 'wo', 'week');
11337 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
11338
11339 addUnitAlias('week', 'w');
11340 addUnitAlias('isoWeek', 'W'); // PRIORITIES
11341
11342 addUnitPriority('week', 5);
11343 addUnitPriority('isoWeek', 5); // PARSING
11344
11345 addRegexToken('w', match1to2);
11346 addRegexToken('ww', match1to2, match2);
11347 addRegexToken('W', match1to2);
11348 addRegexToken('WW', match1to2, match2);
11349 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
11350 week[token.substr(0, 1)] = toInt(input);
11351 }); // HELPERS
11352 // LOCALES
11353
11354 function localeWeek(mom) {
11355 return weekOfYear(mom, this._week.dow, this._week.doy).week;
11356 }
11357
11358 var defaultLocaleWeek = {
11359 dow: 0,
11360 // Sunday is the first day of the week.
11361 doy: 6 // The week that contains Jan 6th is the first week of the year.
11362
11363 };
11364
11365 function localeFirstDayOfWeek() {
11366 return this._week.dow;
11367 }
11368
11369 function localeFirstDayOfYear() {
11370 return this._week.doy;
11371 } // MOMENTS
11372
11373
11374 function getSetWeek(input) {
11375 var week = this.localeData().week(this);
11376 return input == null ? week : this.add((input - week) * 7, 'd');
11377 }
11378
11379 function getSetISOWeek(input) {
11380 var week = weekOfYear(this, 1, 4).week;
11381 return input == null ? week : this.add((input - week) * 7, 'd');
11382 } // FORMATTING
11383
11384
11385 addFormatToken('d', 0, 'do', 'day');
11386 addFormatToken('dd', 0, 0, function (format) {
11387 return this.localeData().weekdaysMin(this, format);
11388 });
11389 addFormatToken('ddd', 0, 0, function (format) {
11390 return this.localeData().weekdaysShort(this, format);
11391 });
11392 addFormatToken('dddd', 0, 0, function (format) {
11393 return this.localeData().weekdays(this, format);
11394 });
11395 addFormatToken('e', 0, 0, 'weekday');
11396 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
11397
11398 addUnitAlias('day', 'd');
11399 addUnitAlias('weekday', 'e');
11400 addUnitAlias('isoWeekday', 'E'); // PRIORITY
11401
11402 addUnitPriority('day', 11);
11403 addUnitPriority('weekday', 11);
11404 addUnitPriority('isoWeekday', 11); // PARSING
11405
11406 addRegexToken('d', match1to2);
11407 addRegexToken('e', match1to2);
11408 addRegexToken('E', match1to2);
11409 addRegexToken('dd', function (isStrict, locale) {
11410 return locale.weekdaysMinRegex(isStrict);
11411 });
11412 addRegexToken('ddd', function (isStrict, locale) {
11413 return locale.weekdaysShortRegex(isStrict);
11414 });
11415 addRegexToken('dddd', function (isStrict, locale) {
11416 return locale.weekdaysRegex(isStrict);
11417 });
11418 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
11419 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
11420
11421
11422 if (weekday != null) {
11423 week.d = weekday;
11424 } else {
11425 getParsingFlags(config).invalidWeekday = input;
11426 }
11427 });
11428 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
11429 week[token] = toInt(input);
11430 }); // HELPERS
11431
11432 function parseWeekday(input, locale) {
11433 if (typeof input !== 'string') {
11434 return input;
11435 }
11436
11437 if (!isNaN(input)) {
11438 return parseInt(input, 10);
11439 }
11440
11441 input = locale.weekdaysParse(input);
11442
11443 if (typeof input === 'number') {
11444 return input;
11445 }
11446
11447 return null;
11448 }
11449
11450 function parseIsoWeekday(input, locale) {
11451 if (typeof input === 'string') {
11452 return locale.weekdaysParse(input) % 7 || 7;
11453 }
11454
11455 return isNaN(input) ? null : input;
11456 } // LOCALES
11457
11458
11459 function shiftWeekdays(ws, n) {
11460 return ws.slice(n, 7).concat(ws.slice(0, n));
11461 }
11462
11463 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
11464
11465 function localeWeekdays(m, format) {
11466 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
11467 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
11468 }
11469
11470 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
11471
11472 function localeWeekdaysShort(m) {
11473 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
11474 }
11475
11476 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
11477
11478 function localeWeekdaysMin(m) {
11479 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
11480 }
11481
11482 function handleStrictParse$1(weekdayName, format, strict) {
11483 var i,
11484 ii,
11485 mom,
11486 llc = weekdayName.toLocaleLowerCase();
11487
11488 if (!this._weekdaysParse) {
11489 this._weekdaysParse = [];
11490 this._shortWeekdaysParse = [];
11491 this._minWeekdaysParse = [];
11492
11493 for (i = 0; i < 7; ++i) {
11494 mom = createUTC([2000, 1]).day(i);
11495 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
11496 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
11497 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
11498 }
11499 }
11500
11501 if (strict) {
11502 if (format === 'dddd') {
11503 ii = indexOf.call(this._weekdaysParse, llc);
11504 return ii !== -1 ? ii : null;
11505 } else if (format === 'ddd') {
11506 ii = indexOf.call(this._shortWeekdaysParse, llc);
11507 return ii !== -1 ? ii : null;
11508 } else {
11509 ii = indexOf.call(this._minWeekdaysParse, llc);
11510 return ii !== -1 ? ii : null;
11511 }
11512 } else {
11513 if (format === 'dddd') {
11514 ii = indexOf.call(this._weekdaysParse, llc);
11515
11516 if (ii !== -1) {
11517 return ii;
11518 }
11519
11520 ii = indexOf.call(this._shortWeekdaysParse, llc);
11521
11522 if (ii !== -1) {
11523 return ii;
11524 }
11525
11526 ii = indexOf.call(this._minWeekdaysParse, llc);
11527 return ii !== -1 ? ii : null;
11528 } else if (format === 'ddd') {
11529 ii = indexOf.call(this._shortWeekdaysParse, llc);
11530
11531 if (ii !== -1) {
11532 return ii;
11533 }
11534
11535 ii = indexOf.call(this._weekdaysParse, llc);
11536
11537 if (ii !== -1) {
11538 return ii;
11539 }
11540
11541 ii = indexOf.call(this._minWeekdaysParse, llc);
11542 return ii !== -1 ? ii : null;
11543 } else {
11544 ii = indexOf.call(this._minWeekdaysParse, llc);
11545
11546 if (ii !== -1) {
11547 return ii;
11548 }
11549
11550 ii = indexOf.call(this._weekdaysParse, llc);
11551
11552 if (ii !== -1) {
11553 return ii;
11554 }
11555
11556 ii = indexOf.call(this._shortWeekdaysParse, llc);
11557 return ii !== -1 ? ii : null;
11558 }
11559 }
11560 }
11561
11562 function localeWeekdaysParse(weekdayName, format, strict) {
11563 var i, mom, regex;
11564
11565 if (this._weekdaysParseExact) {
11566 return handleStrictParse$1.call(this, weekdayName, format, strict);
11567 }
11568
11569 if (!this._weekdaysParse) {
11570 this._weekdaysParse = [];
11571 this._minWeekdaysParse = [];
11572 this._shortWeekdaysParse = [];
11573 this._fullWeekdaysParse = [];
11574 }
11575
11576 for (i = 0; i < 7; i++) {
11577 // make the regex if we don't have it already
11578 mom = createUTC([2000, 1]).day(i);
11579
11580 if (strict && !this._fullWeekdaysParse[i]) {
11581 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
11582 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
11583 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
11584 }
11585
11586 if (!this._weekdaysParse[i]) {
11587 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
11588 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
11589 } // test the regex
11590
11591
11592 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
11593 return i;
11594 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
11595 return i;
11596 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
11597 return i;
11598 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
11599 return i;
11600 }
11601 }
11602 } // MOMENTS
11603
11604
11605 function getSetDayOfWeek(input) {
11606 if (!this.isValid()) {
11607 return input != null ? this : NaN;
11608 }
11609
11610 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
11611
11612 if (input != null) {
11613 input = parseWeekday(input, this.localeData());
11614 return this.add(input - day, 'd');
11615 } else {
11616 return day;
11617 }
11618 }
11619
11620 function getSetLocaleDayOfWeek(input) {
11621 if (!this.isValid()) {
11622 return input != null ? this : NaN;
11623 }
11624
11625 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
11626 return input == null ? weekday : this.add(input - weekday, 'd');
11627 }
11628
11629 function getSetISODayOfWeek(input) {
11630 if (!this.isValid()) {
11631 return input != null ? this : NaN;
11632 } // behaves the same as moment#day except
11633 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
11634 // as a setter, sunday should belong to the previous week.
11635
11636
11637 if (input != null) {
11638 var weekday = parseIsoWeekday(input, this.localeData());
11639 return this.day(this.day() % 7 ? weekday : weekday - 7);
11640 } else {
11641 return this.day() || 7;
11642 }
11643 }
11644
11645 var defaultWeekdaysRegex = matchWord;
11646
11647 function weekdaysRegex(isStrict) {
11648 if (this._weekdaysParseExact) {
11649 if (!hasOwnProp(this, '_weekdaysRegex')) {
11650 computeWeekdaysParse.call(this);
11651 }
11652
11653 if (isStrict) {
11654 return this._weekdaysStrictRegex;
11655 } else {
11656 return this._weekdaysRegex;
11657 }
11658 } else {
11659 if (!hasOwnProp(this, '_weekdaysRegex')) {
11660 this._weekdaysRegex = defaultWeekdaysRegex;
11661 }
11662
11663 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
11664 }
11665 }
11666
11667 var defaultWeekdaysShortRegex = matchWord;
11668
11669 function weekdaysShortRegex(isStrict) {
11670 if (this._weekdaysParseExact) {
11671 if (!hasOwnProp(this, '_weekdaysRegex')) {
11672 computeWeekdaysParse.call(this);
11673 }
11674
11675 if (isStrict) {
11676 return this._weekdaysShortStrictRegex;
11677 } else {
11678 return this._weekdaysShortRegex;
11679 }
11680 } else {
11681 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
11682 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
11683 }
11684
11685 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
11686 }
11687 }
11688
11689 var defaultWeekdaysMinRegex = matchWord;
11690
11691 function weekdaysMinRegex(isStrict) {
11692 if (this._weekdaysParseExact) {
11693 if (!hasOwnProp(this, '_weekdaysRegex')) {
11694 computeWeekdaysParse.call(this);
11695 }
11696
11697 if (isStrict) {
11698 return this._weekdaysMinStrictRegex;
11699 } else {
11700 return this._weekdaysMinRegex;
11701 }
11702 } else {
11703 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
11704 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
11705 }
11706
11707 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
11708 }
11709 }
11710
11711 function computeWeekdaysParse() {
11712 function cmpLenRev(a, b) {
11713 return b.length - a.length;
11714 }
11715
11716 var minPieces = [],
11717 shortPieces = [],
11718 longPieces = [],
11719 mixedPieces = [],
11720 i,
11721 mom,
11722 minp,
11723 shortp,
11724 longp;
11725
11726 for (i = 0; i < 7; i++) {
11727 // make the regex if we don't have it already
11728 mom = createUTC([2000, 1]).day(i);
11729 minp = this.weekdaysMin(mom, '');
11730 shortp = this.weekdaysShort(mom, '');
11731 longp = this.weekdays(mom, '');
11732 minPieces.push(minp);
11733 shortPieces.push(shortp);
11734 longPieces.push(longp);
11735 mixedPieces.push(minp);
11736 mixedPieces.push(shortp);
11737 mixedPieces.push(longp);
11738 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
11739 // will match the longer piece.
11740
11741
11742 minPieces.sort(cmpLenRev);
11743 shortPieces.sort(cmpLenRev);
11744 longPieces.sort(cmpLenRev);
11745 mixedPieces.sort(cmpLenRev);
11746
11747 for (i = 0; i < 7; i++) {
11748 shortPieces[i] = regexEscape(shortPieces[i]);
11749 longPieces[i] = regexEscape(longPieces[i]);
11750 mixedPieces[i] = regexEscape(mixedPieces[i]);
11751 }
11752
11753 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
11754 this._weekdaysShortRegex = this._weekdaysRegex;
11755 this._weekdaysMinRegex = this._weekdaysRegex;
11756 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
11757 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
11758 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
11759 } // FORMATTING
11760
11761
11762 function hFormat() {
11763 return this.hours() % 12 || 12;
11764 }
11765
11766 function kFormat() {
11767 return this.hours() || 24;
11768 }
11769
11770 addFormatToken('H', ['HH', 2], 0, 'hour');
11771 addFormatToken('h', ['hh', 2], 0, hFormat);
11772 addFormatToken('k', ['kk', 2], 0, kFormat);
11773 addFormatToken('hmm', 0, 0, function () {
11774 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
11775 });
11776 addFormatToken('hmmss', 0, 0, function () {
11777 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
11778 });
11779 addFormatToken('Hmm', 0, 0, function () {
11780 return '' + this.hours() + zeroFill(this.minutes(), 2);
11781 });
11782 addFormatToken('Hmmss', 0, 0, function () {
11783 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
11784 });
11785
11786 function meridiem(token, lowercase) {
11787 addFormatToken(token, 0, 0, function () {
11788 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
11789 });
11790 }
11791
11792 meridiem('a', true);
11793 meridiem('A', false); // ALIASES
11794
11795 addUnitAlias('hour', 'h'); // PRIORITY
11796
11797 addUnitPriority('hour', 13); // PARSING
11798
11799 function matchMeridiem(isStrict, locale) {
11800 return locale._meridiemParse;
11801 }
11802
11803 addRegexToken('a', matchMeridiem);
11804 addRegexToken('A', matchMeridiem);
11805 addRegexToken('H', match1to2);
11806 addRegexToken('h', match1to2);
11807 addRegexToken('k', match1to2);
11808 addRegexToken('HH', match1to2, match2);
11809 addRegexToken('hh', match1to2, match2);
11810 addRegexToken('kk', match1to2, match2);
11811 addRegexToken('hmm', match3to4);
11812 addRegexToken('hmmss', match5to6);
11813 addRegexToken('Hmm', match3to4);
11814 addRegexToken('Hmmss', match5to6);
11815 addParseToken(['H', 'HH'], HOUR);
11816 addParseToken(['k', 'kk'], function (input, array, config) {
11817 var kInput = toInt(input);
11818 array[HOUR] = kInput === 24 ? 0 : kInput;
11819 });
11820 addParseToken(['a', 'A'], function (input, array, config) {
11821 config._isPm = config._locale.isPM(input);
11822 config._meridiem = input;
11823 });
11824 addParseToken(['h', 'hh'], function (input, array, config) {
11825 array[HOUR] = toInt(input);
11826 getParsingFlags(config).bigHour = true;
11827 });
11828 addParseToken('hmm', function (input, array, config) {
11829 var pos = input.length - 2;
11830 array[HOUR] = toInt(input.substr(0, pos));
11831 array[MINUTE] = toInt(input.substr(pos));
11832 getParsingFlags(config).bigHour = true;
11833 });
11834 addParseToken('hmmss', function (input, array, config) {
11835 var pos1 = input.length - 4;
11836 var pos2 = input.length - 2;
11837 array[HOUR] = toInt(input.substr(0, pos1));
11838 array[MINUTE] = toInt(input.substr(pos1, 2));
11839 array[SECOND] = toInt(input.substr(pos2));
11840 getParsingFlags(config).bigHour = true;
11841 });
11842 addParseToken('Hmm', function (input, array, config) {
11843 var pos = input.length - 2;
11844 array[HOUR] = toInt(input.substr(0, pos));
11845 array[MINUTE] = toInt(input.substr(pos));
11846 });
11847 addParseToken('Hmmss', function (input, array, config) {
11848 var pos1 = input.length - 4;
11849 var pos2 = input.length - 2;
11850 array[HOUR] = toInt(input.substr(0, pos1));
11851 array[MINUTE] = toInt(input.substr(pos1, 2));
11852 array[SECOND] = toInt(input.substr(pos2));
11853 }); // LOCALES
11854
11855 function localeIsPM(input) {
11856 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
11857 // Using charAt should be more compatible.
11858 return (input + '').toLowerCase().charAt(0) === 'p';
11859 }
11860
11861 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
11862
11863 function localeMeridiem(hours, minutes, isLower) {
11864 if (hours > 11) {
11865 return isLower ? 'pm' : 'PM';
11866 } else {
11867 return isLower ? 'am' : 'AM';
11868 }
11869 } // MOMENTS
11870 // Setting the hour should keep the time, because the user explicitly
11871 // specified which hour they want. So trying to maintain the same hour (in
11872 // a new timezone) makes sense. Adding/subtracting hours does not follow
11873 // this rule.
11874
11875
11876 var getSetHour = makeGetSet('Hours', true);
11877 var baseConfig = {
11878 calendar: defaultCalendar,
11879 longDateFormat: defaultLongDateFormat,
11880 invalidDate: defaultInvalidDate,
11881 ordinal: defaultOrdinal,
11882 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
11883 relativeTime: defaultRelativeTime,
11884 months: defaultLocaleMonths,
11885 monthsShort: defaultLocaleMonthsShort,
11886 week: defaultLocaleWeek,
11887 weekdays: defaultLocaleWeekdays,
11888 weekdaysMin: defaultLocaleWeekdaysMin,
11889 weekdaysShort: defaultLocaleWeekdaysShort,
11890 meridiemParse: defaultLocaleMeridiemParse
11891 }; // internal storage for locale config files
11892
11893 var locales = {};
11894 var localeFamilies = {};
11895 var globalLocale;
11896
11897 function normalizeLocale(key) {
11898 return key ? key.toLowerCase().replace('_', '-') : key;
11899 } // pick the locale from the array
11900 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
11901 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
11902
11903
11904 function chooseLocale(names) {
11905 var i = 0,
11906 j,
11907 next,
11908 locale,
11909 split;
11910
11911 while (i < names.length) {
11912 split = normalizeLocale(names[i]).split('-');
11913 j = split.length;
11914 next = normalizeLocale(names[i + 1]);
11915 next = next ? next.split('-') : null;
11916
11917 while (j > 0) {
11918 locale = loadLocale(split.slice(0, j).join('-'));
11919
11920 if (locale) {
11921 return locale;
11922 }
11923
11924 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
11925 //the next array item is better than a shallower substring of this one
11926 break;
11927 }
11928
11929 j--;
11930 }
11931
11932 i++;
11933 }
11934
11935 return globalLocale;
11936 }
11937
11938 function loadLocale(name) {
11939 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
11940
11941 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
11942 try {
11943 oldLocale = globalLocale._abbr;
11944 var aliasedRequire = commonjsRequire$2;
11945 aliasedRequire('./locale/' + name);
11946 getSetGlobalLocale(oldLocale);
11947 } catch (e) {}
11948 }
11949
11950 return locales[name];
11951 } // This function will load locale and then set the global locale. If
11952 // no arguments are passed in, it will simply return the current global
11953 // locale key.
11954
11955
11956 function getSetGlobalLocale(key, values) {
11957 var data;
11958
11959 if (key) {
11960 if (isUndefined(values)) {
11961 data = getLocale(key);
11962 } else {
11963 data = defineLocale(key, values);
11964 }
11965
11966 if (data) {
11967 // moment.duration._locale = moment._locale = data;
11968 globalLocale = data;
11969 } else {
11970 if (typeof console !== 'undefined' && console.warn) {
11971 //warn user if arguments are passed but the locale could not be set
11972 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
11973 }
11974 }
11975 }
11976
11977 return globalLocale._abbr;
11978 }
11979
11980 function defineLocale(name, config) {
11981 if (config !== null) {
11982 var locale,
11983 parentConfig = baseConfig;
11984 config.abbr = name;
11985
11986 if (locales[name] != null) {
11987 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.');
11988 parentConfig = locales[name]._config;
11989 } else if (config.parentLocale != null) {
11990 if (locales[config.parentLocale] != null) {
11991 parentConfig = locales[config.parentLocale]._config;
11992 } else {
11993 locale = loadLocale(config.parentLocale);
11994
11995 if (locale != null) {
11996 parentConfig = locale._config;
11997 } else {
11998 if (!localeFamilies[config.parentLocale]) {
11999 localeFamilies[config.parentLocale] = [];
12000 }
12001
12002 localeFamilies[config.parentLocale].push({
12003 name: name,
12004 config: config
12005 });
12006 return null;
12007 }
12008 }
12009 }
12010
12011 locales[name] = new Locale(mergeConfigs(parentConfig, config));
12012
12013 if (localeFamilies[name]) {
12014 localeFamilies[name].forEach(function (x) {
12015 defineLocale(x.name, x.config);
12016 });
12017 } // backwards compat for now: also set the locale
12018 // make sure we set the locale AFTER all child locales have been
12019 // created, so we won't end up with the child locale set.
12020
12021
12022 getSetGlobalLocale(name);
12023 return locales[name];
12024 } else {
12025 // useful for testing
12026 delete locales[name];
12027 return null;
12028 }
12029 }
12030
12031 function updateLocale(name, config) {
12032 if (config != null) {
12033 var locale,
12034 tmpLocale,
12035 parentConfig = baseConfig; // MERGE
12036
12037 tmpLocale = loadLocale(name);
12038
12039 if (tmpLocale != null) {
12040 parentConfig = tmpLocale._config;
12041 }
12042
12043 config = mergeConfigs(parentConfig, config);
12044 locale = new Locale(config);
12045 locale.parentLocale = locales[name];
12046 locales[name] = locale; // backwards compat for now: also set the locale
12047
12048 getSetGlobalLocale(name);
12049 } else {
12050 // pass null for config to unupdate, useful for tests
12051 if (locales[name] != null) {
12052 if (locales[name].parentLocale != null) {
12053 locales[name] = locales[name].parentLocale;
12054 } else if (locales[name] != null) {
12055 delete locales[name];
12056 }
12057 }
12058 }
12059
12060 return locales[name];
12061 } // returns locale data
12062
12063
12064 function getLocale(key) {
12065 var locale;
12066
12067 if (key && key._locale && key._locale._abbr) {
12068 key = key._locale._abbr;
12069 }
12070
12071 if (!key) {
12072 return globalLocale;
12073 }
12074
12075 if (!isArray(key)) {
12076 //short-circuit everything else
12077 locale = loadLocale(key);
12078
12079 if (locale) {
12080 return locale;
12081 }
12082
12083 key = [key];
12084 }
12085
12086 return chooseLocale(key);
12087 }
12088
12089 function listLocales() {
12090 return keys(locales);
12091 }
12092
12093 function checkOverflow(m) {
12094 var overflow;
12095 var a = m._a;
12096
12097 if (a && getParsingFlags(m).overflow === -2) {
12098 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;
12099
12100 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
12101 overflow = DATE;
12102 }
12103
12104 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
12105 overflow = WEEK;
12106 }
12107
12108 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
12109 overflow = WEEKDAY;
12110 }
12111
12112 getParsingFlags(m).overflow = overflow;
12113 }
12114
12115 return m;
12116 } // Pick the first defined of two or three arguments.
12117
12118
12119 function defaults(a, b, c) {
12120 if (a != null) {
12121 return a;
12122 }
12123
12124 if (b != null) {
12125 return b;
12126 }
12127
12128 return c;
12129 }
12130
12131 function currentDateArray(config) {
12132 // hooks is actually the exported moment object
12133 var nowValue = new Date(hooks.now());
12134
12135 if (config._useUTC) {
12136 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
12137 }
12138
12139 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
12140 } // convert an array to a date.
12141 // the array should mirror the parameters below
12142 // note: all values past the year are optional and will default to the lowest possible value.
12143 // [year, month, day , hour, minute, second, millisecond]
12144
12145
12146 function configFromArray(config) {
12147 var i,
12148 date,
12149 input = [],
12150 currentDate,
12151 expectedWeekday,
12152 yearToUse;
12153
12154 if (config._d) {
12155 return;
12156 }
12157
12158 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
12159
12160 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
12161 dayOfYearFromWeekInfo(config);
12162 } //if the day of the year is set, figure out what it is
12163
12164
12165 if (config._dayOfYear != null) {
12166 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
12167
12168 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
12169 getParsingFlags(config)._overflowDayOfYear = true;
12170 }
12171
12172 date = createUTCDate(yearToUse, 0, config._dayOfYear);
12173 config._a[MONTH] = date.getUTCMonth();
12174 config._a[DATE] = date.getUTCDate();
12175 } // Default to current date.
12176 // * if no year, month, day of month are given, default to today
12177 // * if day of month is given, default month and year
12178 // * if month is given, default only year
12179 // * if year is given, don't default anything
12180
12181
12182 for (i = 0; i < 3 && config._a[i] == null; ++i) {
12183 config._a[i] = input[i] = currentDate[i];
12184 } // Zero out whatever was not defaulted, including time
12185
12186
12187 for (; i < 7; i++) {
12188 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
12189 } // Check for 24:00:00.000
12190
12191
12192 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
12193 config._nextDay = true;
12194 config._a[HOUR] = 0;
12195 }
12196
12197 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
12198 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
12199 // with parseZone.
12200
12201 if (config._tzm != null) {
12202 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
12203 }
12204
12205 if (config._nextDay) {
12206 config._a[HOUR] = 24;
12207 } // check for mismatching day of week
12208
12209
12210 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
12211 getParsingFlags(config).weekdayMismatch = true;
12212 }
12213 }
12214
12215 function dayOfYearFromWeekInfo(config) {
12216 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
12217 w = config._w;
12218
12219 if (w.GG != null || w.W != null || w.E != null) {
12220 dow = 1;
12221 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
12222 // how we interpret now (local, utc, fixed offset). So create
12223 // a now version of current config (take local/utc/offset flags, and
12224 // create now).
12225
12226 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
12227 week = defaults(w.W, 1);
12228 weekday = defaults(w.E, 1);
12229
12230 if (weekday < 1 || weekday > 7) {
12231 weekdayOverflow = true;
12232 }
12233 } else {
12234 dow = config._locale._week.dow;
12235 doy = config._locale._week.doy;
12236 var curWeek = weekOfYear(createLocal(), dow, doy);
12237 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
12238
12239 week = defaults(w.w, curWeek.week);
12240
12241 if (w.d != null) {
12242 // weekday -- low day numbers are considered next week
12243 weekday = w.d;
12244
12245 if (weekday < 0 || weekday > 6) {
12246 weekdayOverflow = true;
12247 }
12248 } else if (w.e != null) {
12249 // local weekday -- counting starts from beginning of week
12250 weekday = w.e + dow;
12251
12252 if (w.e < 0 || w.e > 6) {
12253 weekdayOverflow = true;
12254 }
12255 } else {
12256 // default to beginning of week
12257 weekday = dow;
12258 }
12259 }
12260
12261 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
12262 getParsingFlags(config)._overflowWeeks = true;
12263 } else if (weekdayOverflow != null) {
12264 getParsingFlags(config)._overflowWeekday = true;
12265 } else {
12266 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
12267 config._a[YEAR] = temp.year;
12268 config._dayOfYear = temp.dayOfYear;
12269 }
12270 } // iso 8601 regex
12271 // 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)
12272
12273
12274 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)?)?$/;
12275 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)?)?$/;
12276 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
12277 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
12278 ['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
12279
12280 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/]];
12281 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
12282
12283 function configFromISO(config) {
12284 var i,
12285 l,
12286 string = config._i,
12287 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
12288 allowTime,
12289 dateFormat,
12290 timeFormat,
12291 tzFormat;
12292
12293 if (match) {
12294 getParsingFlags(config).iso = true;
12295
12296 for (i = 0, l = isoDates.length; i < l; i++) {
12297 if (isoDates[i][1].exec(match[1])) {
12298 dateFormat = isoDates[i][0];
12299 allowTime = isoDates[i][2] !== false;
12300 break;
12301 }
12302 }
12303
12304 if (dateFormat == null) {
12305 config._isValid = false;
12306 return;
12307 }
12308
12309 if (match[3]) {
12310 for (i = 0, l = isoTimes.length; i < l; i++) {
12311 if (isoTimes[i][1].exec(match[3])) {
12312 // match[2] should be 'T' or space
12313 timeFormat = (match[2] || ' ') + isoTimes[i][0];
12314 break;
12315 }
12316 }
12317
12318 if (timeFormat == null) {
12319 config._isValid = false;
12320 return;
12321 }
12322 }
12323
12324 if (!allowTime && timeFormat != null) {
12325 config._isValid = false;
12326 return;
12327 }
12328
12329 if (match[4]) {
12330 if (tzRegex.exec(match[4])) {
12331 tzFormat = 'Z';
12332 } else {
12333 config._isValid = false;
12334 return;
12335 }
12336 }
12337
12338 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
12339 configFromStringAndFormat(config);
12340 } else {
12341 config._isValid = false;
12342 }
12343 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
12344
12345
12346 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}))$/;
12347
12348 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
12349 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
12350
12351 if (secondStr) {
12352 result.push(parseInt(secondStr, 10));
12353 }
12354
12355 return result;
12356 }
12357
12358 function untruncateYear(yearStr) {
12359 var year = parseInt(yearStr, 10);
12360
12361 if (year <= 49) {
12362 return 2000 + year;
12363 } else if (year <= 999) {
12364 return 1900 + year;
12365 }
12366
12367 return year;
12368 }
12369
12370 function preprocessRFC2822(s) {
12371 // Remove comments and folding whitespace and replace multiple-spaces with a single space
12372 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
12373 }
12374
12375 function checkWeekday(weekdayStr, parsedInput, config) {
12376 if (weekdayStr) {
12377 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
12378 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
12379 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
12380
12381 if (weekdayProvided !== weekdayActual) {
12382 getParsingFlags(config).weekdayMismatch = true;
12383 config._isValid = false;
12384 return false;
12385 }
12386 }
12387
12388 return true;
12389 }
12390
12391 var obsOffsets = {
12392 UT: 0,
12393 GMT: 0,
12394 EDT: -4 * 60,
12395 EST: -5 * 60,
12396 CDT: -5 * 60,
12397 CST: -6 * 60,
12398 MDT: -6 * 60,
12399 MST: -7 * 60,
12400 PDT: -7 * 60,
12401 PST: -8 * 60
12402 };
12403
12404 function calculateOffset(obsOffset, militaryOffset, numOffset) {
12405 if (obsOffset) {
12406 return obsOffsets[obsOffset];
12407 } else if (militaryOffset) {
12408 // the only allowed military tz is Z
12409 return 0;
12410 } else {
12411 var hm = parseInt(numOffset, 10);
12412 var m = hm % 100,
12413 h = (hm - m) / 100;
12414 return h * 60 + m;
12415 }
12416 } // date and time from ref 2822 format
12417
12418
12419 function configFromRFC2822(config) {
12420 var match = rfc2822.exec(preprocessRFC2822(config._i));
12421
12422 if (match) {
12423 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
12424
12425 if (!checkWeekday(match[1], parsedArray, config)) {
12426 return;
12427 }
12428
12429 config._a = parsedArray;
12430 config._tzm = calculateOffset(match[8], match[9], match[10]);
12431 config._d = createUTCDate.apply(null, config._a);
12432
12433 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
12434
12435 getParsingFlags(config).rfc2822 = true;
12436 } else {
12437 config._isValid = false;
12438 }
12439 } // date from iso format or fallback
12440
12441
12442 function configFromString(config) {
12443 var matched = aspNetJsonRegex.exec(config._i);
12444
12445 if (matched !== null) {
12446 config._d = new Date(+matched[1]);
12447 return;
12448 }
12449
12450 configFromISO(config);
12451
12452 if (config._isValid === false) {
12453 delete config._isValid;
12454 } else {
12455 return;
12456 }
12457
12458 configFromRFC2822(config);
12459
12460 if (config._isValid === false) {
12461 delete config._isValid;
12462 } else {
12463 return;
12464 } // Final attempt, use Input Fallback
12465
12466
12467 hooks.createFromInputFallback(config);
12468 }
12469
12470 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) {
12471 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
12472 }); // constant that refers to the ISO standard
12473
12474 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
12475
12476
12477 hooks.RFC_2822 = function () {}; // date from string and format string
12478
12479
12480 function configFromStringAndFormat(config) {
12481 // TODO: Move this to another part of the creation flow to prevent circular deps
12482 if (config._f === hooks.ISO_8601) {
12483 configFromISO(config);
12484 return;
12485 }
12486
12487 if (config._f === hooks.RFC_2822) {
12488 configFromRFC2822(config);
12489 return;
12490 }
12491
12492 config._a = [];
12493 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
12494
12495 var string = '' + config._i,
12496 i,
12497 parsedInput,
12498 tokens,
12499 token,
12500 skipped,
12501 stringLength = string.length,
12502 totalParsedInputLength = 0;
12503 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
12504
12505 for (i = 0; i < tokens.length; i++) {
12506 token = tokens[i];
12507 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
12508 // 'regex', getParseRegexForToken(token, config));
12509
12510 if (parsedInput) {
12511 skipped = string.substr(0, string.indexOf(parsedInput));
12512
12513 if (skipped.length > 0) {
12514 getParsingFlags(config).unusedInput.push(skipped);
12515 }
12516
12517 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
12518 totalParsedInputLength += parsedInput.length;
12519 } // don't parse if it's not a known token
12520
12521
12522 if (formatTokenFunctions[token]) {
12523 if (parsedInput) {
12524 getParsingFlags(config).empty = false;
12525 } else {
12526 getParsingFlags(config).unusedTokens.push(token);
12527 }
12528
12529 addTimeToArrayFromToken(token, parsedInput, config);
12530 } else if (config._strict && !parsedInput) {
12531 getParsingFlags(config).unusedTokens.push(token);
12532 }
12533 } // add remaining unparsed input length to the string
12534
12535
12536 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
12537
12538 if (string.length > 0) {
12539 getParsingFlags(config).unusedInput.push(string);
12540 } // clear _12h flag if hour is <= 12
12541
12542
12543 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
12544 getParsingFlags(config).bigHour = undefined;
12545 }
12546
12547 getParsingFlags(config).parsedDateParts = config._a.slice(0);
12548 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
12549
12550 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
12551 configFromArray(config);
12552 checkOverflow(config);
12553 }
12554
12555 function meridiemFixWrap(locale, hour, meridiem) {
12556 var isPm;
12557
12558 if (meridiem == null) {
12559 // nothing to do
12560 return hour;
12561 }
12562
12563 if (locale.meridiemHour != null) {
12564 return locale.meridiemHour(hour, meridiem);
12565 } else if (locale.isPM != null) {
12566 // Fallback
12567 isPm = locale.isPM(meridiem);
12568
12569 if (isPm && hour < 12) {
12570 hour += 12;
12571 }
12572
12573 if (!isPm && hour === 12) {
12574 hour = 0;
12575 }
12576
12577 return hour;
12578 } else {
12579 // this is not supposed to happen
12580 return hour;
12581 }
12582 } // date from string and array of format strings
12583
12584
12585 function configFromStringAndArray(config) {
12586 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
12587
12588 if (config._f.length === 0) {
12589 getParsingFlags(config).invalidFormat = true;
12590 config._d = new Date(NaN);
12591 return;
12592 }
12593
12594 for (i = 0; i < config._f.length; i++) {
12595 currentScore = 0;
12596 tempConfig = copyConfig({}, config);
12597
12598 if (config._useUTC != null) {
12599 tempConfig._useUTC = config._useUTC;
12600 }
12601
12602 tempConfig._f = config._f[i];
12603 configFromStringAndFormat(tempConfig);
12604
12605 if (!isValid(tempConfig)) {
12606 continue;
12607 } // if there is any input that was not parsed add a penalty for that format
12608
12609
12610 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
12611
12612 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
12613 getParsingFlags(tempConfig).score = currentScore;
12614
12615 if (scoreToBeat == null || currentScore < scoreToBeat) {
12616 scoreToBeat = currentScore;
12617 bestMoment = tempConfig;
12618 }
12619 }
12620
12621 extend(config, bestMoment || tempConfig);
12622 }
12623
12624 function configFromObject(config) {
12625 if (config._d) {
12626 return;
12627 }
12628
12629 var i = normalizeObjectUnits(config._i);
12630 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
12631 return obj && parseInt(obj, 10);
12632 });
12633 configFromArray(config);
12634 }
12635
12636 function createFromConfig(config) {
12637 var res = new Moment(checkOverflow(prepareConfig(config)));
12638
12639 if (res._nextDay) {
12640 // Adding is smart enough around DST
12641 res.add(1, 'd');
12642 res._nextDay = undefined;
12643 }
12644
12645 return res;
12646 }
12647
12648 function prepareConfig(config) {
12649 var input = config._i,
12650 format = config._f;
12651 config._locale = config._locale || getLocale(config._l);
12652
12653 if (input === null || format === undefined && input === '') {
12654 return createInvalid({
12655 nullInput: true
12656 });
12657 }
12658
12659 if (typeof input === 'string') {
12660 config._i = input = config._locale.preparse(input);
12661 }
12662
12663 if (isMoment(input)) {
12664 return new Moment(checkOverflow(input));
12665 } else if (isDate(input)) {
12666 config._d = input;
12667 } else if (isArray(format)) {
12668 configFromStringAndArray(config);
12669 } else if (format) {
12670 configFromStringAndFormat(config);
12671 } else {
12672 configFromInput(config);
12673 }
12674
12675 if (!isValid(config)) {
12676 config._d = null;
12677 }
12678
12679 return config;
12680 }
12681
12682 function configFromInput(config) {
12683 var input = config._i;
12684
12685 if (isUndefined(input)) {
12686 config._d = new Date(hooks.now());
12687 } else if (isDate(input)) {
12688 config._d = new Date(input.valueOf());
12689 } else if (typeof input === 'string') {
12690 configFromString(config);
12691 } else if (isArray(input)) {
12692 config._a = map(input.slice(0), function (obj) {
12693 return parseInt(obj, 10);
12694 });
12695 configFromArray(config);
12696 } else if (isObject(input)) {
12697 configFromObject(config);
12698 } else if (isNumber(input)) {
12699 // from milliseconds
12700 config._d = new Date(input);
12701 } else {
12702 hooks.createFromInputFallback(config);
12703 }
12704 }
12705
12706 function createLocalOrUTC(input, format, locale, strict, isUTC) {
12707 var c = {};
12708
12709 if (locale === true || locale === false) {
12710 strict = locale;
12711 locale = undefined;
12712 }
12713
12714 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
12715 input = undefined;
12716 } // object construction must be done this way.
12717 // https://github.com/moment/moment/issues/1423
12718
12719
12720 c._isAMomentObject = true;
12721 c._useUTC = c._isUTC = isUTC;
12722 c._l = locale;
12723 c._i = input;
12724 c._f = format;
12725 c._strict = strict;
12726 return createFromConfig(c);
12727 }
12728
12729 function createLocal(input, format, locale, strict) {
12730 return createLocalOrUTC(input, format, locale, strict, false);
12731 }
12732
12733 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
12734 var other = createLocal.apply(null, arguments);
12735
12736 if (this.isValid() && other.isValid()) {
12737 return other < this ? this : other;
12738 } else {
12739 return createInvalid();
12740 }
12741 });
12742 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
12743 var other = createLocal.apply(null, arguments);
12744
12745 if (this.isValid() && other.isValid()) {
12746 return other > this ? this : other;
12747 } else {
12748 return createInvalid();
12749 }
12750 }); // Pick a moment m from moments so that m[fn](other) is true for all
12751 // other. This relies on the function fn to be transitive.
12752 //
12753 // moments should either be an array of moment objects or an array, whose
12754 // first element is an array of moment objects.
12755
12756 function pickBy(fn, moments) {
12757 var res, i;
12758
12759 if (moments.length === 1 && isArray(moments[0])) {
12760 moments = moments[0];
12761 }
12762
12763 if (!moments.length) {
12764 return createLocal();
12765 }
12766
12767 res = moments[0];
12768
12769 for (i = 1; i < moments.length; ++i) {
12770 if (!moments[i].isValid() || moments[i][fn](res)) {
12771 res = moments[i];
12772 }
12773 }
12774
12775 return res;
12776 } // TODO: Use [].sort instead?
12777
12778
12779 function min() {
12780 var args = [].slice.call(arguments, 0);
12781 return pickBy('isBefore', args);
12782 }
12783
12784 function max() {
12785 var args = [].slice.call(arguments, 0);
12786 return pickBy('isAfter', args);
12787 }
12788
12789 var now = function () {
12790 return Date.now ? Date.now() : +new Date();
12791 };
12792
12793 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
12794
12795 function isDurationValid(m) {
12796 for (var key in m) {
12797 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
12798 return false;
12799 }
12800 }
12801
12802 var unitHasDecimal = false;
12803
12804 for (var i = 0; i < ordering.length; ++i) {
12805 if (m[ordering[i]]) {
12806 if (unitHasDecimal) {
12807 return false; // only allow non-integers for smallest unit
12808 }
12809
12810 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
12811 unitHasDecimal = true;
12812 }
12813 }
12814 }
12815
12816 return true;
12817 }
12818
12819 function isValid$1() {
12820 return this._isValid;
12821 }
12822
12823 function createInvalid$1() {
12824 return createDuration(NaN);
12825 }
12826
12827 function Duration(duration) {
12828 var normalizedInput = normalizeObjectUnits(duration),
12829 years = normalizedInput.year || 0,
12830 quarters = normalizedInput.quarter || 0,
12831 months = normalizedInput.month || 0,
12832 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
12833 days = normalizedInput.day || 0,
12834 hours = normalizedInput.hour || 0,
12835 minutes = normalizedInput.minute || 0,
12836 seconds = normalizedInput.second || 0,
12837 milliseconds = normalizedInput.millisecond || 0;
12838 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
12839
12840 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
12841 minutes * 6e4 + // 1000 * 60
12842 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
12843 // Because of dateAddRemove treats 24 hours as different from a
12844 // day when working around DST, we need to store them separately
12845
12846 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
12847 // which months you are are talking about, so we have to store
12848 // it separately.
12849
12850 this._months = +months + quarters * 3 + years * 12;
12851 this._data = {};
12852 this._locale = getLocale();
12853
12854 this._bubble();
12855 }
12856
12857 function isDuration(obj) {
12858 return obj instanceof Duration;
12859 }
12860
12861 function absRound(number) {
12862 if (number < 0) {
12863 return Math.round(-1 * number) * -1;
12864 } else {
12865 return Math.round(number);
12866 }
12867 } // FORMATTING
12868
12869
12870 function offset(token, separator) {
12871 addFormatToken(token, 0, 0, function () {
12872 var offset = this.utcOffset();
12873 var sign = '+';
12874
12875 if (offset < 0) {
12876 offset = -offset;
12877 sign = '-';
12878 }
12879
12880 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
12881 });
12882 }
12883
12884 offset('Z', ':');
12885 offset('ZZ', ''); // PARSING
12886
12887 addRegexToken('Z', matchShortOffset);
12888 addRegexToken('ZZ', matchShortOffset);
12889 addParseToken(['Z', 'ZZ'], function (input, array, config) {
12890 config._useUTC = true;
12891 config._tzm = offsetFromString(matchShortOffset, input);
12892 }); // HELPERS
12893 // timezone chunker
12894 // '+10:00' > ['10', '00']
12895 // '-1530' > ['-15', '30']
12896
12897 var chunkOffset = /([\+\-]|\d\d)/gi;
12898
12899 function offsetFromString(matcher, string) {
12900 var matches = (string || '').match(matcher);
12901
12902 if (matches === null) {
12903 return null;
12904 }
12905
12906 var chunk = matches[matches.length - 1] || [];
12907 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
12908 var minutes = +(parts[1] * 60) + toInt(parts[2]);
12909 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
12910 } // Return a moment from input, that is local/utc/zone equivalent to model.
12911
12912
12913 function cloneWithOffset(input, model) {
12914 var res, diff;
12915
12916 if (model._isUTC) {
12917 res = model.clone();
12918 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
12919
12920 res._d.setTime(res._d.valueOf() + diff);
12921
12922 hooks.updateOffset(res, false);
12923 return res;
12924 } else {
12925 return createLocal(input).local();
12926 }
12927 }
12928
12929 function getDateOffset(m) {
12930 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
12931 // https://github.com/moment/moment/pull/1871
12932 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
12933 } // HOOKS
12934 // This function will be called whenever a moment is mutated.
12935 // It is intended to keep the offset in sync with the timezone.
12936
12937
12938 hooks.updateOffset = function () {}; // MOMENTS
12939 // keepLocalTime = true means only change the timezone, without
12940 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
12941 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
12942 // +0200, so we adjust the time as needed, to be valid.
12943 //
12944 // Keeping the time actually adds/subtracts (one hour)
12945 // from the actual represented time. That is why we call updateOffset
12946 // a second time. In case it wants us to change the offset again
12947 // _changeInProgress == true case, then we have to adjust, because
12948 // there is no such time in the given timezone.
12949
12950
12951 function getSetOffset(input, keepLocalTime, keepMinutes) {
12952 var offset = this._offset || 0,
12953 localAdjust;
12954
12955 if (!this.isValid()) {
12956 return input != null ? this : NaN;
12957 }
12958
12959 if (input != null) {
12960 if (typeof input === 'string') {
12961 input = offsetFromString(matchShortOffset, input);
12962
12963 if (input === null) {
12964 return this;
12965 }
12966 } else if (Math.abs(input) < 16 && !keepMinutes) {
12967 input = input * 60;
12968 }
12969
12970 if (!this._isUTC && keepLocalTime) {
12971 localAdjust = getDateOffset(this);
12972 }
12973
12974 this._offset = input;
12975 this._isUTC = true;
12976
12977 if (localAdjust != null) {
12978 this.add(localAdjust, 'm');
12979 }
12980
12981 if (offset !== input) {
12982 if (!keepLocalTime || this._changeInProgress) {
12983 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
12984 } else if (!this._changeInProgress) {
12985 this._changeInProgress = true;
12986 hooks.updateOffset(this, true);
12987 this._changeInProgress = null;
12988 }
12989 }
12990
12991 return this;
12992 } else {
12993 return this._isUTC ? offset : getDateOffset(this);
12994 }
12995 }
12996
12997 function getSetZone(input, keepLocalTime) {
12998 if (input != null) {
12999 if (typeof input !== 'string') {
13000 input = -input;
13001 }
13002
13003 this.utcOffset(input, keepLocalTime);
13004 return this;
13005 } else {
13006 return -this.utcOffset();
13007 }
13008 }
13009
13010 function setOffsetToUTC(keepLocalTime) {
13011 return this.utcOffset(0, keepLocalTime);
13012 }
13013
13014 function setOffsetToLocal(keepLocalTime) {
13015 if (this._isUTC) {
13016 this.utcOffset(0, keepLocalTime);
13017 this._isUTC = false;
13018
13019 if (keepLocalTime) {
13020 this.subtract(getDateOffset(this), 'm');
13021 }
13022 }
13023
13024 return this;
13025 }
13026
13027 function setOffsetToParsedOffset() {
13028 if (this._tzm != null) {
13029 this.utcOffset(this._tzm, false, true);
13030 } else if (typeof this._i === 'string') {
13031 var tZone = offsetFromString(matchOffset, this._i);
13032
13033 if (tZone != null) {
13034 this.utcOffset(tZone);
13035 } else {
13036 this.utcOffset(0, true);
13037 }
13038 }
13039
13040 return this;
13041 }
13042
13043 function hasAlignedHourOffset(input) {
13044 if (!this.isValid()) {
13045 return false;
13046 }
13047
13048 input = input ? createLocal(input).utcOffset() : 0;
13049 return (this.utcOffset() - input) % 60 === 0;
13050 }
13051
13052 function isDaylightSavingTime() {
13053 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
13054 }
13055
13056 function isDaylightSavingTimeShifted() {
13057 if (!isUndefined(this._isDSTShifted)) {
13058 return this._isDSTShifted;
13059 }
13060
13061 var c = {};
13062 copyConfig(c, this);
13063 c = prepareConfig(c);
13064
13065 if (c._a) {
13066 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
13067 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
13068 } else {
13069 this._isDSTShifted = false;
13070 }
13071
13072 return this._isDSTShifted;
13073 }
13074
13075 function isLocal() {
13076 return this.isValid() ? !this._isUTC : false;
13077 }
13078
13079 function isUtcOffset() {
13080 return this.isValid() ? this._isUTC : false;
13081 }
13082
13083 function isUtc() {
13084 return this.isValid() ? this._isUTC && this._offset === 0 : false;
13085 } // ASP.NET json date format regex
13086
13087
13088 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
13089 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
13090 // and further modified to allow for strings containing both week and day
13091
13092 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)?)?$/;
13093
13094 function createDuration(input, key) {
13095 var duration = input,
13096 // matching against regexp is expensive, do it on demand
13097 match = null,
13098 sign,
13099 ret,
13100 diffRes;
13101
13102 if (isDuration(input)) {
13103 duration = {
13104 ms: input._milliseconds,
13105 d: input._days,
13106 M: input._months
13107 };
13108 } else if (isNumber(input)) {
13109 duration = {};
13110
13111 if (key) {
13112 duration[key] = input;
13113 } else {
13114 duration.milliseconds = input;
13115 }
13116 } else if (!!(match = aspNetRegex.exec(input))) {
13117 sign = match[1] === '-' ? -1 : 1;
13118 duration = {
13119 y: 0,
13120 d: toInt(match[DATE]) * sign,
13121 h: toInt(match[HOUR]) * sign,
13122 m: toInt(match[MINUTE]) * sign,
13123 s: toInt(match[SECOND]) * sign,
13124 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
13125
13126 };
13127 } else if (!!(match = isoRegex.exec(input))) {
13128 sign = match[1] === '-' ? -1 : 1;
13129 duration = {
13130 y: parseIso(match[2], sign),
13131 M: parseIso(match[3], sign),
13132 w: parseIso(match[4], sign),
13133 d: parseIso(match[5], sign),
13134 h: parseIso(match[6], sign),
13135 m: parseIso(match[7], sign),
13136 s: parseIso(match[8], sign)
13137 };
13138 } else if (duration == null) {
13139 // checks for null or undefined
13140 duration = {};
13141 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
13142 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
13143 duration = {};
13144 duration.ms = diffRes.milliseconds;
13145 duration.M = diffRes.months;
13146 }
13147
13148 ret = new Duration(duration);
13149
13150 if (isDuration(input) && hasOwnProp(input, '_locale')) {
13151 ret._locale = input._locale;
13152 }
13153
13154 return ret;
13155 }
13156
13157 createDuration.fn = Duration.prototype;
13158 createDuration.invalid = createInvalid$1;
13159
13160 function parseIso(inp, sign) {
13161 // We'd normally use ~~inp for this, but unfortunately it also
13162 // converts floats to ints.
13163 // inp may be undefined, so careful calling replace on it.
13164 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
13165
13166 return (isNaN(res) ? 0 : res) * sign;
13167 }
13168
13169 function positiveMomentsDifference(base, other) {
13170 var res = {};
13171 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
13172
13173 if (base.clone().add(res.months, 'M').isAfter(other)) {
13174 --res.months;
13175 }
13176
13177 res.milliseconds = +other - +base.clone().add(res.months, 'M');
13178 return res;
13179 }
13180
13181 function momentsDifference(base, other) {
13182 var res;
13183
13184 if (!(base.isValid() && other.isValid())) {
13185 return {
13186 milliseconds: 0,
13187 months: 0
13188 };
13189 }
13190
13191 other = cloneWithOffset(other, base);
13192
13193 if (base.isBefore(other)) {
13194 res = positiveMomentsDifference(base, other);
13195 } else {
13196 res = positiveMomentsDifference(other, base);
13197 res.milliseconds = -res.milliseconds;
13198 res.months = -res.months;
13199 }
13200
13201 return res;
13202 } // TODO: remove 'name' arg after deprecation is removed
13203
13204
13205 function createAdder(direction, name) {
13206 return function (val, period) {
13207 var dur, tmp; //invert the arguments, but complain about it
13208
13209 if (period !== null && !isNaN(+period)) {
13210 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.');
13211 tmp = val;
13212 val = period;
13213 period = tmp;
13214 }
13215
13216 val = typeof val === 'string' ? +val : val;
13217 dur = createDuration(val, period);
13218 addSubtract(this, dur, direction);
13219 return this;
13220 };
13221 }
13222
13223 function addSubtract(mom, duration, isAdding, updateOffset) {
13224 var milliseconds = duration._milliseconds,
13225 days = absRound(duration._days),
13226 months = absRound(duration._months);
13227
13228 if (!mom.isValid()) {
13229 // No op
13230 return;
13231 }
13232
13233 updateOffset = updateOffset == null ? true : updateOffset;
13234
13235 if (months) {
13236 setMonth(mom, get(mom, 'Month') + months * isAdding);
13237 }
13238
13239 if (days) {
13240 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
13241 }
13242
13243 if (milliseconds) {
13244 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
13245 }
13246
13247 if (updateOffset) {
13248 hooks.updateOffset(mom, days || months);
13249 }
13250 }
13251
13252 var add = createAdder(1, 'add');
13253 var subtract = createAdder(-1, 'subtract');
13254
13255 function getCalendarFormat(myMoment, now) {
13256 var diff = myMoment.diff(now, 'days', true);
13257 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
13258 }
13259
13260 function calendar$1(time, formats) {
13261 // We want to compare the start of today, vs this.
13262 // Getting start-of-today depends on whether we're local/utc/offset or not.
13263 var now = time || createLocal(),
13264 sod = cloneWithOffset(now, this).startOf('day'),
13265 format = hooks.calendarFormat(this, sod) || 'sameElse';
13266 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
13267 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
13268 }
13269
13270 function clone() {
13271 return new Moment(this);
13272 }
13273
13274 function isAfter(input, units) {
13275 var localInput = isMoment(input) ? input : createLocal(input);
13276
13277 if (!(this.isValid() && localInput.isValid())) {
13278 return false;
13279 }
13280
13281 units = normalizeUnits(units) || 'millisecond';
13282
13283 if (units === 'millisecond') {
13284 return this.valueOf() > localInput.valueOf();
13285 } else {
13286 return localInput.valueOf() < this.clone().startOf(units).valueOf();
13287 }
13288 }
13289
13290 function isBefore(input, units) {
13291 var localInput = isMoment(input) ? input : createLocal(input);
13292
13293 if (!(this.isValid() && localInput.isValid())) {
13294 return false;
13295 }
13296
13297 units = normalizeUnits(units) || 'millisecond';
13298
13299 if (units === 'millisecond') {
13300 return this.valueOf() < localInput.valueOf();
13301 } else {
13302 return this.clone().endOf(units).valueOf() < localInput.valueOf();
13303 }
13304 }
13305
13306 function isBetween(from, to, units, inclusivity) {
13307 var localFrom = isMoment(from) ? from : createLocal(from),
13308 localTo = isMoment(to) ? to : createLocal(to);
13309
13310 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
13311 return false;
13312 }
13313
13314 inclusivity = inclusivity || '()';
13315 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
13316 }
13317
13318 function isSame(input, units) {
13319 var localInput = isMoment(input) ? input : createLocal(input),
13320 inputMs;
13321
13322 if (!(this.isValid() && localInput.isValid())) {
13323 return false;
13324 }
13325
13326 units = normalizeUnits(units) || 'millisecond';
13327
13328 if (units === 'millisecond') {
13329 return this.valueOf() === localInput.valueOf();
13330 } else {
13331 inputMs = localInput.valueOf();
13332 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
13333 }
13334 }
13335
13336 function isSameOrAfter(input, units) {
13337 return this.isSame(input, units) || this.isAfter(input, units);
13338 }
13339
13340 function isSameOrBefore(input, units) {
13341 return this.isSame(input, units) || this.isBefore(input, units);
13342 }
13343
13344 function diff(input, units, asFloat) {
13345 var that, zoneDelta, output;
13346
13347 if (!this.isValid()) {
13348 return NaN;
13349 }
13350
13351 that = cloneWithOffset(input, this);
13352
13353 if (!that.isValid()) {
13354 return NaN;
13355 }
13356
13357 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
13358 units = normalizeUnits(units);
13359
13360 switch (units) {
13361 case 'year':
13362 output = monthDiff(this, that) / 12;
13363 break;
13364
13365 case 'month':
13366 output = monthDiff(this, that);
13367 break;
13368
13369 case 'quarter':
13370 output = monthDiff(this, that) / 3;
13371 break;
13372
13373 case 'second':
13374 output = (this - that) / 1e3;
13375 break;
13376 // 1000
13377
13378 case 'minute':
13379 output = (this - that) / 6e4;
13380 break;
13381 // 1000 * 60
13382
13383 case 'hour':
13384 output = (this - that) / 36e5;
13385 break;
13386 // 1000 * 60 * 60
13387
13388 case 'day':
13389 output = (this - that - zoneDelta) / 864e5;
13390 break;
13391 // 1000 * 60 * 60 * 24, negate dst
13392
13393 case 'week':
13394 output = (this - that - zoneDelta) / 6048e5;
13395 break;
13396 // 1000 * 60 * 60 * 24 * 7, negate dst
13397
13398 default:
13399 output = this - that;
13400 }
13401
13402 return asFloat ? output : absFloor(output);
13403 }
13404
13405 function monthDiff(a, b) {
13406 // difference in months
13407 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
13408 // b is in (anchor - 1 month, anchor + 1 month)
13409 anchor = a.clone().add(wholeMonthDiff, 'months'),
13410 anchor2,
13411 adjust;
13412
13413 if (b - anchor < 0) {
13414 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
13415
13416 adjust = (b - anchor) / (anchor - anchor2);
13417 } else {
13418 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
13419
13420 adjust = (b - anchor) / (anchor2 - anchor);
13421 } //check for negative zero, return zero if negative zero
13422
13423
13424 return -(wholeMonthDiff + adjust) || 0;
13425 }
13426
13427 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
13428 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
13429
13430 function toString() {
13431 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
13432 }
13433
13434 function toISOString(keepOffset) {
13435 if (!this.isValid()) {
13436 return null;
13437 }
13438
13439 var utc = keepOffset !== true;
13440 var m = utc ? this.clone().utc() : this;
13441
13442 if (m.year() < 0 || m.year() > 9999) {
13443 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
13444 }
13445
13446 if (isFunction(Date.prototype.toISOString)) {
13447 // native implementation is ~50x faster, use it when we can
13448 if (utc) {
13449 return this.toDate().toISOString();
13450 } else {
13451 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
13452 }
13453 }
13454
13455 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
13456 }
13457 /**
13458 * Return a human readable representation of a moment that can
13459 * also be evaluated to get a new moment which is the same
13460 *
13461 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
13462 */
13463
13464
13465 function inspect() {
13466 if (!this.isValid()) {
13467 return 'moment.invalid(/* ' + this._i + ' */)';
13468 }
13469
13470 var func = 'moment';
13471 var zone = '';
13472
13473 if (!this.isLocal()) {
13474 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
13475 zone = 'Z';
13476 }
13477
13478 var prefix = '[' + func + '("]';
13479 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
13480 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
13481 var suffix = zone + '[")]';
13482 return this.format(prefix + year + datetime + suffix);
13483 }
13484
13485 function format(inputString) {
13486 if (!inputString) {
13487 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
13488 }
13489
13490 var output = formatMoment(this, inputString);
13491 return this.localeData().postformat(output);
13492 }
13493
13494 function from(time, withoutSuffix) {
13495 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
13496 return createDuration({
13497 to: this,
13498 from: time
13499 }).locale(this.locale()).humanize(!withoutSuffix);
13500 } else {
13501 return this.localeData().invalidDate();
13502 }
13503 }
13504
13505 function fromNow(withoutSuffix) {
13506 return this.from(createLocal(), withoutSuffix);
13507 }
13508
13509 function to(time, withoutSuffix) {
13510 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
13511 return createDuration({
13512 from: this,
13513 to: time
13514 }).locale(this.locale()).humanize(!withoutSuffix);
13515 } else {
13516 return this.localeData().invalidDate();
13517 }
13518 }
13519
13520 function toNow(withoutSuffix) {
13521 return this.to(createLocal(), withoutSuffix);
13522 } // If passed a locale key, it will set the locale for this
13523 // instance. Otherwise, it will return the locale configuration
13524 // variables for this instance.
13525
13526
13527 function locale(key) {
13528 var newLocaleData;
13529
13530 if (key === undefined) {
13531 return this._locale._abbr;
13532 } else {
13533 newLocaleData = getLocale(key);
13534
13535 if (newLocaleData != null) {
13536 this._locale = newLocaleData;
13537 }
13538
13539 return this;
13540 }
13541 }
13542
13543 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
13544 if (key === undefined) {
13545 return this.localeData();
13546 } else {
13547 return this.locale(key);
13548 }
13549 });
13550
13551 function localeData() {
13552 return this._locale;
13553 }
13554
13555 var MS_PER_SECOND = 1000;
13556 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
13557 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
13558 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
13559
13560 function mod$1(dividend, divisor) {
13561 return (dividend % divisor + divisor) % divisor;
13562 }
13563
13564 function localStartOfDate(y, m, d) {
13565 // the date constructor remaps years 0-99 to 1900-1999
13566 if (y < 100 && y >= 0) {
13567 // preserve leap years using a full 400 year cycle, then reset
13568 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
13569 } else {
13570 return new Date(y, m, d).valueOf();
13571 }
13572 }
13573
13574 function utcStartOfDate(y, m, d) {
13575 // Date.UTC remaps years 0-99 to 1900-1999
13576 if (y < 100 && y >= 0) {
13577 // preserve leap years using a full 400 year cycle, then reset
13578 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
13579 } else {
13580 return Date.UTC(y, m, d);
13581 }
13582 }
13583
13584 function startOf(units) {
13585 var time;
13586 units = normalizeUnits(units);
13587
13588 if (units === undefined || units === 'millisecond' || !this.isValid()) {
13589 return this;
13590 }
13591
13592 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
13593
13594 switch (units) {
13595 case 'year':
13596 time = startOfDate(this.year(), 0, 1);
13597 break;
13598
13599 case 'quarter':
13600 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
13601 break;
13602
13603 case 'month':
13604 time = startOfDate(this.year(), this.month(), 1);
13605 break;
13606
13607 case 'week':
13608 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
13609 break;
13610
13611 case 'isoWeek':
13612 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
13613 break;
13614
13615 case 'day':
13616 case 'date':
13617 time = startOfDate(this.year(), this.month(), this.date());
13618 break;
13619
13620 case 'hour':
13621 time = this._d.valueOf();
13622 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
13623 break;
13624
13625 case 'minute':
13626 time = this._d.valueOf();
13627 time -= mod$1(time, MS_PER_MINUTE);
13628 break;
13629
13630 case 'second':
13631 time = this._d.valueOf();
13632 time -= mod$1(time, MS_PER_SECOND);
13633 break;
13634 }
13635
13636 this._d.setTime(time);
13637
13638 hooks.updateOffset(this, true);
13639 return this;
13640 }
13641
13642 function endOf(units) {
13643 var time;
13644 units = normalizeUnits(units);
13645
13646 if (units === undefined || units === 'millisecond' || !this.isValid()) {
13647 return this;
13648 }
13649
13650 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
13651
13652 switch (units) {
13653 case 'year':
13654 time = startOfDate(this.year() + 1, 0, 1) - 1;
13655 break;
13656
13657 case 'quarter':
13658 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
13659 break;
13660
13661 case 'month':
13662 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
13663 break;
13664
13665 case 'week':
13666 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
13667 break;
13668
13669 case 'isoWeek':
13670 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
13671 break;
13672
13673 case 'day':
13674 case 'date':
13675 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
13676 break;
13677
13678 case 'hour':
13679 time = this._d.valueOf();
13680 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
13681 break;
13682
13683 case 'minute':
13684 time = this._d.valueOf();
13685 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
13686 break;
13687
13688 case 'second':
13689 time = this._d.valueOf();
13690 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
13691 break;
13692 }
13693
13694 this._d.setTime(time);
13695
13696 hooks.updateOffset(this, true);
13697 return this;
13698 }
13699
13700 function valueOf() {
13701 return this._d.valueOf() - (this._offset || 0) * 60000;
13702 }
13703
13704 function unix() {
13705 return Math.floor(this.valueOf() / 1000);
13706 }
13707
13708 function toDate() {
13709 return new Date(this.valueOf());
13710 }
13711
13712 function toArray() {
13713 var m = this;
13714 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
13715 }
13716
13717 function toObject() {
13718 var m = this;
13719 return {
13720 years: m.year(),
13721 months: m.month(),
13722 date: m.date(),
13723 hours: m.hours(),
13724 minutes: m.minutes(),
13725 seconds: m.seconds(),
13726 milliseconds: m.milliseconds()
13727 };
13728 }
13729
13730 function toJSON() {
13731 // new Date(NaN).toJSON() === null
13732 return this.isValid() ? this.toISOString() : null;
13733 }
13734
13735 function isValid$2() {
13736 return isValid(this);
13737 }
13738
13739 function parsingFlags() {
13740 return extend({}, getParsingFlags(this));
13741 }
13742
13743 function invalidAt() {
13744 return getParsingFlags(this).overflow;
13745 }
13746
13747 function creationData() {
13748 return {
13749 input: this._i,
13750 format: this._f,
13751 locale: this._locale,
13752 isUTC: this._isUTC,
13753 strict: this._strict
13754 };
13755 } // FORMATTING
13756
13757
13758 addFormatToken(0, ['gg', 2], 0, function () {
13759 return this.weekYear() % 100;
13760 });
13761 addFormatToken(0, ['GG', 2], 0, function () {
13762 return this.isoWeekYear() % 100;
13763 });
13764
13765 function addWeekYearFormatToken(token, getter) {
13766 addFormatToken(0, [token, token.length], 0, getter);
13767 }
13768
13769 addWeekYearFormatToken('gggg', 'weekYear');
13770 addWeekYearFormatToken('ggggg', 'weekYear');
13771 addWeekYearFormatToken('GGGG', 'isoWeekYear');
13772 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
13773
13774 addUnitAlias('weekYear', 'gg');
13775 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
13776
13777 addUnitPriority('weekYear', 1);
13778 addUnitPriority('isoWeekYear', 1); // PARSING
13779
13780 addRegexToken('G', matchSigned);
13781 addRegexToken('g', matchSigned);
13782 addRegexToken('GG', match1to2, match2);
13783 addRegexToken('gg', match1to2, match2);
13784 addRegexToken('GGGG', match1to4, match4);
13785 addRegexToken('gggg', match1to4, match4);
13786 addRegexToken('GGGGG', match1to6, match6);
13787 addRegexToken('ggggg', match1to6, match6);
13788 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
13789 week[token.substr(0, 2)] = toInt(input);
13790 });
13791 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
13792 week[token] = hooks.parseTwoDigitYear(input);
13793 }); // MOMENTS
13794
13795 function getSetWeekYear(input) {
13796 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
13797 }
13798
13799 function getSetISOWeekYear(input) {
13800 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
13801 }
13802
13803 function getISOWeeksInYear() {
13804 return weeksInYear(this.year(), 1, 4);
13805 }
13806
13807 function getWeeksInYear() {
13808 var weekInfo = this.localeData()._week;
13809
13810 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
13811 }
13812
13813 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
13814 var weeksTarget;
13815
13816 if (input == null) {
13817 return weekOfYear(this, dow, doy).year;
13818 } else {
13819 weeksTarget = weeksInYear(input, dow, doy);
13820
13821 if (week > weeksTarget) {
13822 week = weeksTarget;
13823 }
13824
13825 return setWeekAll.call(this, input, week, weekday, dow, doy);
13826 }
13827 }
13828
13829 function setWeekAll(weekYear, week, weekday, dow, doy) {
13830 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
13831 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
13832 this.year(date.getUTCFullYear());
13833 this.month(date.getUTCMonth());
13834 this.date(date.getUTCDate());
13835 return this;
13836 } // FORMATTING
13837
13838
13839 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
13840
13841 addUnitAlias('quarter', 'Q'); // PRIORITY
13842
13843 addUnitPriority('quarter', 7); // PARSING
13844
13845 addRegexToken('Q', match1);
13846 addParseToken('Q', function (input, array) {
13847 array[MONTH] = (toInt(input) - 1) * 3;
13848 }); // MOMENTS
13849
13850 function getSetQuarter(input) {
13851 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
13852 } // FORMATTING
13853
13854
13855 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
13856
13857 addUnitAlias('date', 'D'); // PRIORITY
13858
13859 addUnitPriority('date', 9); // PARSING
13860
13861 addRegexToken('D', match1to2);
13862 addRegexToken('DD', match1to2, match2);
13863 addRegexToken('Do', function (isStrict, locale) {
13864 // TODO: Remove "ordinalParse" fallback in next major release.
13865 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
13866 });
13867 addParseToken(['D', 'DD'], DATE);
13868 addParseToken('Do', function (input, array) {
13869 array[DATE] = toInt(input.match(match1to2)[0]);
13870 }); // MOMENTS
13871
13872 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
13873
13874 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
13875
13876 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
13877
13878 addUnitPriority('dayOfYear', 4); // PARSING
13879
13880 addRegexToken('DDD', match1to3);
13881 addRegexToken('DDDD', match3);
13882 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
13883 config._dayOfYear = toInt(input);
13884 }); // HELPERS
13885 // MOMENTS
13886
13887 function getSetDayOfYear(input) {
13888 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
13889 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
13890 } // FORMATTING
13891
13892
13893 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
13894
13895 addUnitAlias('minute', 'm'); // PRIORITY
13896
13897 addUnitPriority('minute', 14); // PARSING
13898
13899 addRegexToken('m', match1to2);
13900 addRegexToken('mm', match1to2, match2);
13901 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
13902
13903 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
13904
13905 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
13906
13907 addUnitAlias('second', 's'); // PRIORITY
13908
13909 addUnitPriority('second', 15); // PARSING
13910
13911 addRegexToken('s', match1to2);
13912 addRegexToken('ss', match1to2, match2);
13913 addParseToken(['s', 'ss'], SECOND); // MOMENTS
13914
13915 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
13916
13917 addFormatToken('S', 0, 0, function () {
13918 return ~~(this.millisecond() / 100);
13919 });
13920 addFormatToken(0, ['SS', 2], 0, function () {
13921 return ~~(this.millisecond() / 10);
13922 });
13923 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
13924 addFormatToken(0, ['SSSS', 4], 0, function () {
13925 return this.millisecond() * 10;
13926 });
13927 addFormatToken(0, ['SSSSS', 5], 0, function () {
13928 return this.millisecond() * 100;
13929 });
13930 addFormatToken(0, ['SSSSSS', 6], 0, function () {
13931 return this.millisecond() * 1000;
13932 });
13933 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
13934 return this.millisecond() * 10000;
13935 });
13936 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
13937 return this.millisecond() * 100000;
13938 });
13939 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
13940 return this.millisecond() * 1000000;
13941 }); // ALIASES
13942
13943 addUnitAlias('millisecond', 'ms'); // PRIORITY
13944
13945 addUnitPriority('millisecond', 16); // PARSING
13946
13947 addRegexToken('S', match1to3, match1);
13948 addRegexToken('SS', match1to3, match2);
13949 addRegexToken('SSS', match1to3, match3);
13950 var token;
13951
13952 for (token = 'SSSS'; token.length <= 9; token += 'S') {
13953 addRegexToken(token, matchUnsigned);
13954 }
13955
13956 function parseMs(input, array) {
13957 array[MILLISECOND] = toInt(('0.' + input) * 1000);
13958 }
13959
13960 for (token = 'S'; token.length <= 9; token += 'S') {
13961 addParseToken(token, parseMs);
13962 } // MOMENTS
13963
13964
13965 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
13966
13967 addFormatToken('z', 0, 0, 'zoneAbbr');
13968 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
13969
13970 function getZoneAbbr() {
13971 return this._isUTC ? 'UTC' : '';
13972 }
13973
13974 function getZoneName() {
13975 return this._isUTC ? 'Coordinated Universal Time' : '';
13976 }
13977
13978 var proto = Moment.prototype;
13979 proto.add = add;
13980 proto.calendar = calendar$1;
13981 proto.clone = clone;
13982 proto.diff = diff;
13983 proto.endOf = endOf;
13984 proto.format = format;
13985 proto.from = from;
13986 proto.fromNow = fromNow;
13987 proto.to = to;
13988 proto.toNow = toNow;
13989 proto.get = stringGet;
13990 proto.invalidAt = invalidAt;
13991 proto.isAfter = isAfter;
13992 proto.isBefore = isBefore;
13993 proto.isBetween = isBetween;
13994 proto.isSame = isSame;
13995 proto.isSameOrAfter = isSameOrAfter;
13996 proto.isSameOrBefore = isSameOrBefore;
13997 proto.isValid = isValid$2;
13998 proto.lang = lang;
13999 proto.locale = locale;
14000 proto.localeData = localeData;
14001 proto.max = prototypeMax;
14002 proto.min = prototypeMin;
14003 proto.parsingFlags = parsingFlags;
14004 proto.set = stringSet;
14005 proto.startOf = startOf;
14006 proto.subtract = subtract;
14007 proto.toArray = toArray;
14008 proto.toObject = toObject;
14009 proto.toDate = toDate;
14010 proto.toISOString = toISOString;
14011 proto.inspect = inspect;
14012 proto.toJSON = toJSON;
14013 proto.toString = toString;
14014 proto.unix = unix;
14015 proto.valueOf = valueOf;
14016 proto.creationData = creationData;
14017 proto.year = getSetYear;
14018 proto.isLeapYear = getIsLeapYear;
14019 proto.weekYear = getSetWeekYear;
14020 proto.isoWeekYear = getSetISOWeekYear;
14021 proto.quarter = proto.quarters = getSetQuarter;
14022 proto.month = getSetMonth;
14023 proto.daysInMonth = getDaysInMonth;
14024 proto.week = proto.weeks = getSetWeek;
14025 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
14026 proto.weeksInYear = getWeeksInYear;
14027 proto.isoWeeksInYear = getISOWeeksInYear;
14028 proto.date = getSetDayOfMonth;
14029 proto.day = proto.days = getSetDayOfWeek;
14030 proto.weekday = getSetLocaleDayOfWeek;
14031 proto.isoWeekday = getSetISODayOfWeek;
14032 proto.dayOfYear = getSetDayOfYear;
14033 proto.hour = proto.hours = getSetHour;
14034 proto.minute = proto.minutes = getSetMinute;
14035 proto.second = proto.seconds = getSetSecond;
14036 proto.millisecond = proto.milliseconds = getSetMillisecond;
14037 proto.utcOffset = getSetOffset;
14038 proto.utc = setOffsetToUTC;
14039 proto.local = setOffsetToLocal;
14040 proto.parseZone = setOffsetToParsedOffset;
14041 proto.hasAlignedHourOffset = hasAlignedHourOffset;
14042 proto.isDST = isDaylightSavingTime;
14043 proto.isLocal = isLocal;
14044 proto.isUtcOffset = isUtcOffset;
14045 proto.isUtc = isUtc;
14046 proto.isUTC = isUtc;
14047 proto.zoneAbbr = getZoneAbbr;
14048 proto.zoneName = getZoneName;
14049 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
14050 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
14051 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
14052 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
14053 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
14054
14055 function createUnix(input) {
14056 return createLocal(input * 1000);
14057 }
14058
14059 function createInZone() {
14060 return createLocal.apply(null, arguments).parseZone();
14061 }
14062
14063 function preParsePostFormat(string) {
14064 return string;
14065 }
14066
14067 var proto$1 = Locale.prototype;
14068 proto$1.calendar = calendar;
14069 proto$1.longDateFormat = longDateFormat;
14070 proto$1.invalidDate = invalidDate;
14071 proto$1.ordinal = ordinal;
14072 proto$1.preparse = preParsePostFormat;
14073 proto$1.postformat = preParsePostFormat;
14074 proto$1.relativeTime = relativeTime;
14075 proto$1.pastFuture = pastFuture;
14076 proto$1.set = set;
14077 proto$1.months = localeMonths;
14078 proto$1.monthsShort = localeMonthsShort;
14079 proto$1.monthsParse = localeMonthsParse;
14080 proto$1.monthsRegex = monthsRegex;
14081 proto$1.monthsShortRegex = monthsShortRegex;
14082 proto$1.week = localeWeek;
14083 proto$1.firstDayOfYear = localeFirstDayOfYear;
14084 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
14085 proto$1.weekdays = localeWeekdays;
14086 proto$1.weekdaysMin = localeWeekdaysMin;
14087 proto$1.weekdaysShort = localeWeekdaysShort;
14088 proto$1.weekdaysParse = localeWeekdaysParse;
14089 proto$1.weekdaysRegex = weekdaysRegex;
14090 proto$1.weekdaysShortRegex = weekdaysShortRegex;
14091 proto$1.weekdaysMinRegex = weekdaysMinRegex;
14092 proto$1.isPM = localeIsPM;
14093 proto$1.meridiem = localeMeridiem;
14094
14095 function get$1(format, index, field, setter) {
14096 var locale = getLocale();
14097 var utc = createUTC().set(setter, index);
14098 return locale[field](utc, format);
14099 }
14100
14101 function listMonthsImpl(format, index, field) {
14102 if (isNumber(format)) {
14103 index = format;
14104 format = undefined;
14105 }
14106
14107 format = format || '';
14108
14109 if (index != null) {
14110 return get$1(format, index, field, 'month');
14111 }
14112
14113 var i;
14114 var out = [];
14115
14116 for (i = 0; i < 12; i++) {
14117 out[i] = get$1(format, i, field, 'month');
14118 }
14119
14120 return out;
14121 } // ()
14122 // (5)
14123 // (fmt, 5)
14124 // (fmt)
14125 // (true)
14126 // (true, 5)
14127 // (true, fmt, 5)
14128 // (true, fmt)
14129
14130
14131 function listWeekdaysImpl(localeSorted, format, index, field) {
14132 if (typeof localeSorted === 'boolean') {
14133 if (isNumber(format)) {
14134 index = format;
14135 format = undefined;
14136 }
14137
14138 format = format || '';
14139 } else {
14140 format = localeSorted;
14141 index = format;
14142 localeSorted = false;
14143
14144 if (isNumber(format)) {
14145 index = format;
14146 format = undefined;
14147 }
14148
14149 format = format || '';
14150 }
14151
14152 var locale = getLocale(),
14153 shift = localeSorted ? locale._week.dow : 0;
14154
14155 if (index != null) {
14156 return get$1(format, (index + shift) % 7, field, 'day');
14157 }
14158
14159 var i;
14160 var out = [];
14161
14162 for (i = 0; i < 7; i++) {
14163 out[i] = get$1(format, (i + shift) % 7, field, 'day');
14164 }
14165
14166 return out;
14167 }
14168
14169 function listMonths(format, index) {
14170 return listMonthsImpl(format, index, 'months');
14171 }
14172
14173 function listMonthsShort(format, index) {
14174 return listMonthsImpl(format, index, 'monthsShort');
14175 }
14176
14177 function listWeekdays(localeSorted, format, index) {
14178 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
14179 }
14180
14181 function listWeekdaysShort(localeSorted, format, index) {
14182 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
14183 }
14184
14185 function listWeekdaysMin(localeSorted, format, index) {
14186 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
14187 }
14188
14189 getSetGlobalLocale('en', {
14190 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
14191 ordinal: function (number) {
14192 var b = number % 10,
14193 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
14194 return number + output;
14195 }
14196 }); // Side effect imports
14197
14198 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
14199 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
14200 var mathAbs = Math.abs;
14201
14202 function abs() {
14203 var data = this._data;
14204 this._milliseconds = mathAbs(this._milliseconds);
14205 this._days = mathAbs(this._days);
14206 this._months = mathAbs(this._months);
14207 data.milliseconds = mathAbs(data.milliseconds);
14208 data.seconds = mathAbs(data.seconds);
14209 data.minutes = mathAbs(data.minutes);
14210 data.hours = mathAbs(data.hours);
14211 data.months = mathAbs(data.months);
14212 data.years = mathAbs(data.years);
14213 return this;
14214 }
14215
14216 function addSubtract$1(duration, input, value, direction) {
14217 var other = createDuration(input, value);
14218 duration._milliseconds += direction * other._milliseconds;
14219 duration._days += direction * other._days;
14220 duration._months += direction * other._months;
14221 return duration._bubble();
14222 } // supports only 2.0-style add(1, 's') or add(duration)
14223
14224
14225 function add$1(input, value) {
14226 return addSubtract$1(this, input, value, 1);
14227 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
14228
14229
14230 function subtract$1(input, value) {
14231 return addSubtract$1(this, input, value, -1);
14232 }
14233
14234 function absCeil(number) {
14235 if (number < 0) {
14236 return Math.floor(number);
14237 } else {
14238 return Math.ceil(number);
14239 }
14240 }
14241
14242 function bubble() {
14243 var milliseconds = this._milliseconds;
14244 var days = this._days;
14245 var months = this._months;
14246 var data = this._data;
14247 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
14248 // check: https://github.com/moment/moment/issues/2166
14249
14250 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
14251 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
14252 days = 0;
14253 months = 0;
14254 } // The following code bubbles up values, see the tests for
14255 // examples of what that means.
14256
14257
14258 data.milliseconds = milliseconds % 1000;
14259 seconds = absFloor(milliseconds / 1000);
14260 data.seconds = seconds % 60;
14261 minutes = absFloor(seconds / 60);
14262 data.minutes = minutes % 60;
14263 hours = absFloor(minutes / 60);
14264 data.hours = hours % 24;
14265 days += absFloor(hours / 24); // convert days to months
14266
14267 monthsFromDays = absFloor(daysToMonths(days));
14268 months += monthsFromDays;
14269 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
14270
14271 years = absFloor(months / 12);
14272 months %= 12;
14273 data.days = days;
14274 data.months = months;
14275 data.years = years;
14276 return this;
14277 }
14278
14279 function daysToMonths(days) {
14280 // 400 years have 146097 days (taking into account leap year rules)
14281 // 400 years have 12 months === 4800
14282 return days * 4800 / 146097;
14283 }
14284
14285 function monthsToDays(months) {
14286 // the reverse of daysToMonths
14287 return months * 146097 / 4800;
14288 }
14289
14290 function as(units) {
14291 if (!this.isValid()) {
14292 return NaN;
14293 }
14294
14295 var days;
14296 var months;
14297 var milliseconds = this._milliseconds;
14298 units = normalizeUnits(units);
14299
14300 if (units === 'month' || units === 'quarter' || units === 'year') {
14301 days = this._days + milliseconds / 864e5;
14302 months = this._months + daysToMonths(days);
14303
14304 switch (units) {
14305 case 'month':
14306 return months;
14307
14308 case 'quarter':
14309 return months / 3;
14310
14311 case 'year':
14312 return months / 12;
14313 }
14314 } else {
14315 // handle milliseconds separately because of floating point math errors (issue #1867)
14316 days = this._days + Math.round(monthsToDays(this._months));
14317
14318 switch (units) {
14319 case 'week':
14320 return days / 7 + milliseconds / 6048e5;
14321
14322 case 'day':
14323 return days + milliseconds / 864e5;
14324
14325 case 'hour':
14326 return days * 24 + milliseconds / 36e5;
14327
14328 case 'minute':
14329 return days * 1440 + milliseconds / 6e4;
14330
14331 case 'second':
14332 return days * 86400 + milliseconds / 1000;
14333 // Math.floor prevents floating point math errors here
14334
14335 case 'millisecond':
14336 return Math.floor(days * 864e5) + milliseconds;
14337
14338 default:
14339 throw new Error('Unknown unit ' + units);
14340 }
14341 }
14342 } // TODO: Use this.as('ms')?
14343
14344
14345 function valueOf$1() {
14346 if (!this.isValid()) {
14347 return NaN;
14348 }
14349
14350 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
14351 }
14352
14353 function makeAs(alias) {
14354 return function () {
14355 return this.as(alias);
14356 };
14357 }
14358
14359 var asMilliseconds = makeAs('ms');
14360 var asSeconds = makeAs('s');
14361 var asMinutes = makeAs('m');
14362 var asHours = makeAs('h');
14363 var asDays = makeAs('d');
14364 var asWeeks = makeAs('w');
14365 var asMonths = makeAs('M');
14366 var asQuarters = makeAs('Q');
14367 var asYears = makeAs('y');
14368
14369 function clone$1() {
14370 return createDuration(this);
14371 }
14372
14373 function get$2(units) {
14374 units = normalizeUnits(units);
14375 return this.isValid() ? this[units + 's']() : NaN;
14376 }
14377
14378 function makeGetter(name) {
14379 return function () {
14380 return this.isValid() ? this._data[name] : NaN;
14381 };
14382 }
14383
14384 var milliseconds = makeGetter('milliseconds');
14385 var seconds = makeGetter('seconds');
14386 var minutes = makeGetter('minutes');
14387 var hours = makeGetter('hours');
14388 var days = makeGetter('days');
14389 var months = makeGetter('months');
14390 var years = makeGetter('years');
14391
14392 function weeks() {
14393 return absFloor(this.days() / 7);
14394 }
14395
14396 var round = Math.round;
14397 var thresholds = {
14398 ss: 44,
14399 // a few seconds to seconds
14400 s: 45,
14401 // seconds to minute
14402 m: 45,
14403 // minutes to hour
14404 h: 22,
14405 // hours to day
14406 d: 26,
14407 // days to month
14408 M: 11 // months to year
14409
14410 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
14411
14412 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
14413 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
14414 }
14415
14416 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
14417 var duration = createDuration(posNegDuration).abs();
14418 var seconds = round(duration.as('s'));
14419 var minutes = round(duration.as('m'));
14420 var hours = round(duration.as('h'));
14421 var days = round(duration.as('d'));
14422 var months = round(duration.as('M'));
14423 var years = round(duration.as('y'));
14424 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];
14425 a[2] = withoutSuffix;
14426 a[3] = +posNegDuration > 0;
14427 a[4] = locale;
14428 return substituteTimeAgo.apply(null, a);
14429 } // This function allows you to set the rounding function for relative time strings
14430
14431
14432 function getSetRelativeTimeRounding(roundingFunction) {
14433 if (roundingFunction === undefined) {
14434 return round;
14435 }
14436
14437 if (typeof roundingFunction === 'function') {
14438 round = roundingFunction;
14439 return true;
14440 }
14441
14442 return false;
14443 } // This function allows you to set a threshold for relative time strings
14444
14445
14446 function getSetRelativeTimeThreshold(threshold, limit) {
14447 if (thresholds[threshold] === undefined) {
14448 return false;
14449 }
14450
14451 if (limit === undefined) {
14452 return thresholds[threshold];
14453 }
14454
14455 thresholds[threshold] = limit;
14456
14457 if (threshold === 's') {
14458 thresholds.ss = limit - 1;
14459 }
14460
14461 return true;
14462 }
14463
14464 function humanize(withSuffix) {
14465 if (!this.isValid()) {
14466 return this.localeData().invalidDate();
14467 }
14468
14469 var locale = this.localeData();
14470 var output = relativeTime$1(this, !withSuffix, locale);
14471
14472 if (withSuffix) {
14473 output = locale.pastFuture(+this, output);
14474 }
14475
14476 return locale.postformat(output);
14477 }
14478
14479 var abs$1 = Math.abs;
14480
14481 function sign(x) {
14482 return (x > 0) - (x < 0) || +x;
14483 }
14484
14485 function toISOString$1() {
14486 // for ISO strings we do not use the normal bubbling rules:
14487 // * milliseconds bubble up until they become hours
14488 // * days do not bubble at all
14489 // * months bubble up until they become years
14490 // This is because there is no context-free conversion between hours and days
14491 // (think of clock changes)
14492 // and also not between days and months (28-31 days per month)
14493 if (!this.isValid()) {
14494 return this.localeData().invalidDate();
14495 }
14496
14497 var seconds = abs$1(this._milliseconds) / 1000;
14498 var days = abs$1(this._days);
14499 var months = abs$1(this._months);
14500 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
14501
14502 minutes = absFloor(seconds / 60);
14503 hours = absFloor(minutes / 60);
14504 seconds %= 60;
14505 minutes %= 60; // 12 months -> 1 year
14506
14507 years = absFloor(months / 12);
14508 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
14509
14510 var Y = years;
14511 var M = months;
14512 var D = days;
14513 var h = hours;
14514 var m = minutes;
14515 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
14516 var total = this.asSeconds();
14517
14518 if (!total) {
14519 // this is the same as C#'s (Noda) and python (isodate)...
14520 // but not other JS (goog.date)
14521 return 'P0D';
14522 }
14523
14524 var totalSign = total < 0 ? '-' : '';
14525 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
14526 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
14527 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
14528 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' : '');
14529 }
14530
14531 var proto$2 = Duration.prototype;
14532 proto$2.isValid = isValid$1;
14533 proto$2.abs = abs;
14534 proto$2.add = add$1;
14535 proto$2.subtract = subtract$1;
14536 proto$2.as = as;
14537 proto$2.asMilliseconds = asMilliseconds;
14538 proto$2.asSeconds = asSeconds;
14539 proto$2.asMinutes = asMinutes;
14540 proto$2.asHours = asHours;
14541 proto$2.asDays = asDays;
14542 proto$2.asWeeks = asWeeks;
14543 proto$2.asMonths = asMonths;
14544 proto$2.asQuarters = asQuarters;
14545 proto$2.asYears = asYears;
14546 proto$2.valueOf = valueOf$1;
14547 proto$2._bubble = bubble;
14548 proto$2.clone = clone$1;
14549 proto$2.get = get$2;
14550 proto$2.milliseconds = milliseconds;
14551 proto$2.seconds = seconds;
14552 proto$2.minutes = minutes;
14553 proto$2.hours = hours;
14554 proto$2.days = days;
14555 proto$2.weeks = weeks;
14556 proto$2.months = months;
14557 proto$2.years = years;
14558 proto$2.humanize = humanize;
14559 proto$2.toISOString = toISOString$1;
14560 proto$2.toString = toISOString$1;
14561 proto$2.toJSON = toISOString$1;
14562 proto$2.locale = locale;
14563 proto$2.localeData = localeData;
14564 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
14565 proto$2.lang = lang; // Side effect imports
14566 // FORMATTING
14567
14568 addFormatToken('X', 0, 0, 'unix');
14569 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
14570
14571 addRegexToken('x', matchSigned);
14572 addRegexToken('X', matchTimestamp);
14573 addParseToken('X', function (input, array, config) {
14574 config._d = new Date(parseFloat(input, 10) * 1000);
14575 });
14576 addParseToken('x', function (input, array, config) {
14577 config._d = new Date(toInt(input));
14578 }); // Side effect imports
14579
14580 hooks.version = '2.24.0';
14581 setHookCallback(createLocal);
14582 hooks.fn = proto;
14583 hooks.min = min;
14584 hooks.max = max;
14585 hooks.now = now;
14586 hooks.utc = createUTC;
14587 hooks.unix = createUnix;
14588 hooks.months = listMonths;
14589 hooks.isDate = isDate;
14590 hooks.locale = getSetGlobalLocale;
14591 hooks.invalid = createInvalid;
14592 hooks.duration = createDuration;
14593 hooks.isMoment = isMoment;
14594 hooks.weekdays = listWeekdays;
14595 hooks.parseZone = createInZone;
14596 hooks.localeData = getLocale;
14597 hooks.isDuration = isDuration;
14598 hooks.monthsShort = listMonthsShort;
14599 hooks.weekdaysMin = listWeekdaysMin;
14600 hooks.defineLocale = defineLocale;
14601 hooks.updateLocale = updateLocale;
14602 hooks.locales = listLocales;
14603 hooks.weekdaysShort = listWeekdaysShort;
14604 hooks.normalizeUnits = normalizeUnits;
14605 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
14606 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
14607 hooks.calendarFormat = getCalendarFormat;
14608 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
14609
14610 hooks.HTML5_FMT = {
14611 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
14612 // <input type="datetime-local" />
14613 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
14614 // <input type="datetime-local" step="1" />
14615 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
14616 // <input type="datetime-local" step="0.001" />
14617 DATE: 'YYYY-MM-DD',
14618 // <input type="date" />
14619 TIME: 'HH:mm',
14620 // <input type="time" />
14621 TIME_SECONDS: 'HH:mm:ss',
14622 // <input type="time" step="1" />
14623 TIME_MS: 'HH:mm:ss.SSS',
14624 // <input type="time" step="0.001" />
14625 WEEK: 'GGGG-[W]WW',
14626 // <input type="week" />
14627 MONTH: 'YYYY-MM' // <input type="month" />
14628
14629 };
14630 return hooks;
14631 });
14632}); // Maps for number <-> hex string conversion
14633
14634var byteToHex$2$1 = [];
14635
14636for (var i$2$1 = 0; i$2$1 < 256; i$2$1++) {
14637 byteToHex$2$1[i$2$1] = (i$2$1 + 0x100).toString(16).substr(1);
14638}
14639/**
14640 * Generate 16 random bytes to be used as a base for UUID.
14641 *
14642 * @ignore
14643 */
14644
14645
14646var random$1$1 = function () {
14647 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
14648 // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
14649 // Moderately fast, high quality
14650 var _rnds8 = new Uint8Array(16);
14651
14652 return function whatwgRNG() {
14653 crypto.getRandomValues(_rnds8);
14654 return _rnds8;
14655 };
14656 } // Math.random()-based (RNG)
14657 //
14658 // If all else fails, use Math.random().
14659 // It's fast, but is of unspecified quality.
14660
14661
14662 var _rnds = new Array(16);
14663
14664 return function () {
14665 for (var i = 0, r; i < 16; i++) {
14666 if ((i & 0x03) === 0) {
14667 r = Math.random() * 0x100000000;
14668 }
14669
14670 _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
14671 }
14672
14673 return _rnds;
14674 }; // uuid.js
14675 //
14676 // Copyright (c) 2010-2012 Robert Kieffer
14677 // MIT License - http://opensource.org/licenses/mit-license.php
14678 // Unique ID creation requires a high quality random # generator. We feature
14679 // detect to determine the best RNG source, normalizing to a function that
14680 // returns 128-bits of randomness, since that's what's usually required
14681 // return require('./rng');
14682}();
14683
14684var byteToHex$1$1$1 = [];
14685
14686for (var i$1$1$1 = 0; i$1$1$1 < 256; i$1$1$1++) {
14687 byteToHex$1$1$1[i$1$1$1] = (i$1$1$1 + 0x100).toString(16).substr(1);
14688} // **`v1()` - Generate time-based UUID**
14689//
14690// Inspired by https://github.com/LiosK/UUID.js
14691// and http://docs.python.org/library/uuid.html
14692// random #'s we need to init node and clockseq
14693
14694
14695var seedBytes$1$1 = random$1$1(); // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
14696
14697var 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
14698
14699var defaultClockseq$1$1 = (seedBytes$1$1[6] << 8 | seedBytes$1$1[7]) & 0x3fff; // Previous uuid creation time
14700// for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/'
14701// code from http://momentjs.com/
14702
14703var ASPDateRegex$1 = /^\/?Date\((-?\d+)/i; // Hex color
14704
14705/**
14706 * Hue, Saturation, Value.
14707 */
14708
14709/**
14710 * Test whether given object is a number
14711 *
14712 * @param value - Input value of unknown type.
14713 *
14714 * @returns True if number, false otherwise.
14715 */
14716
14717function isNumber$1(value) {
14718 return value instanceof Number || typeof value === 'number';
14719}
14720/**
14721 * Test whether given object is a string
14722 *
14723 * @param value - Input value of unknown type.
14724 *
14725 * @returns True if string, false otherwise.
14726 */
14727
14728
14729function isString$1(value) {
14730 return value instanceof String || typeof value === 'string';
14731}
14732/**
14733 * Test whether given object is a Moment date.
14734 * @TODO: This is basically a workaround, if Moment was imported property it wouldn't necessary as moment.isMoment is a TS type guard.
14735 *
14736 * @param value - Input value of unknown type.
14737 *
14738 * @returns True if Moment instance, false otherwise.
14739 */
14740
14741
14742function isMoment$1(value) {
14743 return moment$1.isMoment(value);
14744}
14745/**
14746 * Copy property from b to a if property present in a.
14747 * If property in b explicitly set to null, delete it if `allowDeletion` set.
14748 *
14749 * Internal helper routine, should not be exported. Not added to `exports` for that reason.
14750 *
14751 * @param a - Target object.
14752 * @param b - Source object.
14753 * @param prop - Name of property to copy from b to a.
14754 * @param allowDeletion if true, delete property in a if explicitly set to null in b
14755 */
14756
14757
14758function copyOrDelete$1(a, b, prop, allowDeletion) {
14759 var doDeletion = false;
14760
14761 if (allowDeletion === true) {
14762 doDeletion = b[prop] === null && a[prop] !== undefined;
14763 }
14764
14765 if (doDeletion) {
14766 delete a[prop];
14767 } else {
14768 a[prop] = b[prop]; // Remember, this is a reference copy!
14769 }
14770}
14771/**
14772 * Deep extend an object a with the properties of object b
14773 *
14774 * @param a - Target object.
14775 * @param b - Source object.
14776 * @param protoExtend - If true, the prototype values will also be extended
14777 * (ie. the options objects that inherit from others will also get the inherited options).
14778 * @param allowDeletion - If true, the values of fields that are null will be deleted.
14779 *
14780 * @returns Argument a.
14781 */
14782
14783
14784function deepExtend$1(a, b) {
14785 var protoExtend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
14786 var allowDeletion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
14787
14788 for (var prop in b) {
14789 if (Object.prototype.hasOwnProperty.call(b, prop) || protoExtend === true) {
14790 if (b[prop] && b[prop].constructor === Object) {
14791 if (a[prop] === undefined) {
14792 a[prop] = {};
14793 }
14794
14795 if (a[prop].constructor === Object) {
14796 deepExtend$1(a[prop], b[prop], protoExtend); // NOTE: allowDeletion not propagated!
14797 } else {
14798 copyOrDelete$1(a, b, prop, allowDeletion);
14799 }
14800 } else if (Array.isArray(b[prop])) {
14801 a[prop] = [];
14802
14803 for (var i = 0; i < b[prop].length; i++) {
14804 a[prop].push(b[prop][i]);
14805 }
14806 } else {
14807 copyOrDelete$1(a, b, prop, allowDeletion);
14808 }
14809 }
14810 }
14811
14812 return a;
14813}
14814/**
14815 * Convert an object into another type
14816 *
14817 * @param object - Value of unknown type.
14818 * @param type - Name of the desired type.
14819 *
14820 * @returns Object in the desired type.
14821 * @throws Error
14822 */
14823
14824
14825function convert$1(object, type) {
14826 var match;
14827
14828 if (object === undefined) {
14829 return undefined;
14830 }
14831
14832 if (object === null) {
14833 return null;
14834 }
14835
14836 if (!type) {
14837 return object;
14838 }
14839
14840 if (!(typeof type === 'string') && !(type instanceof String)) {
14841 throw new Error('Type must be a string');
14842 } //noinspection FallthroughInSwitchStatementJS
14843
14844
14845 switch (type) {
14846 case 'boolean':
14847 case 'Boolean':
14848 return Boolean(object);
14849
14850 case 'number':
14851 case 'Number':
14852 if (isString$1(object) && !isNaN(Date.parse(object))) {
14853 return moment$1(object).valueOf();
14854 } else {
14855 // @TODO: I don't think that Number and String constructors are a good idea.
14856 // This could also fail if the object doesn't have valueOf method or if it's redefined.
14857 // For example: Object.create(null) or { valueOf: 7 }.
14858 return Number(object.valueOf());
14859 }
14860
14861 case 'string':
14862 case 'String':
14863 return String(object);
14864
14865 case 'Date':
14866 if (isNumber$1(object)) {
14867 return new Date(object);
14868 }
14869
14870 if (object instanceof Date) {
14871 return new Date(object.valueOf());
14872 } else if (isMoment$1(object)) {
14873 return new Date(object.valueOf());
14874 }
14875
14876 if (isString$1(object)) {
14877 match = ASPDateRegex$1.exec(object);
14878
14879 if (match) {
14880 // object is an ASP date
14881 return new Date(Number(match[1])); // parse number
14882 } else {
14883 return moment$1(new Date(object)).toDate(); // parse string
14884 }
14885 } else {
14886 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type Date');
14887 }
14888
14889 case 'Moment':
14890 if (isNumber$1(object)) {
14891 return moment$1(object);
14892 }
14893
14894 if (object instanceof Date) {
14895 return moment$1(object.valueOf());
14896 } else if (isMoment$1(object)) {
14897 return moment$1(object);
14898 }
14899
14900 if (isString$1(object)) {
14901 match = ASPDateRegex$1.exec(object);
14902
14903 if (match) {
14904 // object is an ASP date
14905 return moment$1(Number(match[1])); // parse number
14906 } else {
14907 return moment$1(object); // parse string
14908 }
14909 } else {
14910 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type Date');
14911 }
14912
14913 case 'ISODate':
14914 if (isNumber$1(object)) {
14915 return new Date(object);
14916 } else if (object instanceof Date) {
14917 return object.toISOString();
14918 } else if (isMoment$1(object)) {
14919 return object.toDate().toISOString();
14920 } else if (isString$1(object)) {
14921 match = ASPDateRegex$1.exec(object);
14922
14923 if (match) {
14924 // object is an ASP date
14925 return new Date(Number(match[1])).toISOString(); // parse number
14926 } else {
14927 return moment$1(object).format(); // ISO 8601
14928 }
14929 } else {
14930 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type ISODate');
14931 }
14932
14933 case 'ASPDate':
14934 if (isNumber$1(object)) {
14935 return '/Date(' + object + ')/';
14936 } else if (object instanceof Date) {
14937 return '/Date(' + object.valueOf() + ')/';
14938 } else if (isString$1(object)) {
14939 match = ASPDateRegex$1.exec(object);
14940
14941 var _value;
14942
14943 if (match) {
14944 // object is an ASP date
14945 _value = new Date(Number(match[1])).valueOf(); // parse number
14946 } else {
14947 _value = new Date(object).valueOf(); // parse string
14948 }
14949
14950 return '/Date(' + _value + ')/';
14951 } else {
14952 throw new Error('Cannot convert object of type ' + getType$1(object) + ' to type ASPDate');
14953 }
14954
14955 default:
14956 var never = type;
14957 throw new Error("Unknown type ".concat(never));
14958 }
14959}
14960/**
14961 * Get the type of an object, for example exports.getType([]) returns 'Array'
14962 *
14963 * @param object - Input value of unknown type.
14964 *
14965 * @returns Detected type.
14966 */
14967
14968
14969function getType$1(object) {
14970 var type = _typeof$1(object);
14971
14972 if (type === 'object') {
14973 if (object === null) {
14974 return 'null';
14975 }
14976
14977 if (object instanceof Boolean) {
14978 return 'Boolean';
14979 }
14980
14981 if (object instanceof Number) {
14982 return 'Number';
14983 }
14984
14985 if (object instanceof String) {
14986 return 'String';
14987 }
14988
14989 if (Array.isArray(object)) {
14990 return 'Array';
14991 }
14992
14993 if (object instanceof Date) {
14994 return 'Date';
14995 }
14996
14997 return 'Object';
14998 }
14999
15000 if (type === 'number') {
15001 return 'Number';
15002 }
15003
15004 if (type === 'boolean') {
15005 return 'Boolean';
15006 }
15007
15008 if (type === 'string') {
15009 return 'String';
15010 }
15011
15012 if (type === undefined) {
15013 return 'undefined';
15014 }
15015
15016 return type;
15017}
15018/**
15019 * Determine whether a value can be used as an id.
15020 *
15021 * @param value - Input value of unknown type.
15022 *
15023 * @returns True if the value is valid id, false otherwise.
15024 */
15025
15026
15027function isId(value) {
15028 return typeof value === "string" || typeof value === "number";
15029}
15030/* eslint @typescript-eslint/member-ordering: ["error", { "classes": ["field", "constructor", "method"] }] */
15031
15032/**
15033 * A queue.
15034 *
15035 * @typeParam T - The type of method names to be replaced by queued versions.
15036 */
15037
15038
15039var Queue =
15040/*#__PURE__*/
15041function () {
15042 /**
15043 * Construct a new Queue.
15044 *
15045 * @param options - Queue configuration.
15046 */
15047 function Queue(options) {
15048 classCallCheck(this, Queue);
15049 this._queue = [];
15050 this._timeout = null;
15051 this._extended = null; // options
15052
15053 this.delay = null;
15054 this.max = Infinity;
15055 this.setOptions(options);
15056 }
15057 /**
15058 * Update the configuration of the queue.
15059 *
15060 * @param options - Queue configuration.
15061 */
15062
15063
15064 createClass(Queue, [{
15065 key: "setOptions",
15066 value: function setOptions(options) {
15067 if (options && typeof options.delay !== "undefined") {
15068 this.delay = options.delay;
15069 }
15070
15071 if (options && typeof options.max !== "undefined") {
15072 this.max = options.max;
15073 }
15074
15075 this._flushIfNeeded();
15076 }
15077 /**
15078 * Extend an object with queuing functionality.
15079 * The object will be extended with a function flush, and the methods provided in options.replace will be replaced with queued ones.
15080 *
15081 * @param object - The object to be extended.
15082 * @param options - Additional options.
15083 *
15084 * @returns The created queue.
15085 */
15086
15087 }, {
15088 key: "destroy",
15089
15090 /**
15091 * Destroy the queue. The queue will first flush all queued actions, and in case it has extended an object, will restore the original object.
15092 */
15093 value: function destroy() {
15094 this.flush();
15095
15096 if (this._extended) {
15097 var object = this._extended.object;
15098 var methods = this._extended.methods;
15099
15100 for (var i = 0; i < methods.length; i++) {
15101 var method = methods[i];
15102
15103 if (method.original) {
15104 // @TODO: better solution?
15105 object[method.name] = method.original;
15106 } else {
15107 // @TODO: better solution?
15108 delete object[method.name];
15109 }
15110 }
15111
15112 this._extended = null;
15113 }
15114 }
15115 /**
15116 * Replace a method on an object with a queued version.
15117 *
15118 * @param object - Object having the method.
15119 * @param method - The method name.
15120 */
15121
15122 }, {
15123 key: "replace",
15124 value: function replace(object, method) {
15125 var me = this;
15126 var original = object[method];
15127
15128 if (!original) {
15129 throw new Error("Method " + method + " undefined");
15130 }
15131
15132 object[method] = function () {
15133 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
15134 args[_key] = arguments[_key];
15135 } // add this call to the queue
15136
15137
15138 me.queue({
15139 args: args,
15140 fn: original,
15141 context: this
15142 });
15143 };
15144 }
15145 /**
15146 * Queue a call.
15147 *
15148 * @param entry - The function or entry to be queued.
15149 */
15150
15151 }, {
15152 key: "queue",
15153 value: function queue(entry) {
15154 if (typeof entry === "function") {
15155 this._queue.push({
15156 fn: entry
15157 });
15158 } else {
15159 this._queue.push(entry);
15160 }
15161
15162 this._flushIfNeeded();
15163 }
15164 /**
15165 * Check whether the queue needs to be flushed.
15166 */
15167
15168 }, {
15169 key: "_flushIfNeeded",
15170 value: function _flushIfNeeded() {
15171 var _this = this; // flush when the maximum is exceeded.
15172
15173
15174 if (this._queue.length > this.max) {
15175 this.flush();
15176 } // flush after a period of inactivity when a delay is configured
15177
15178
15179 if (this._timeout != null) {
15180 clearTimeout(this._timeout);
15181 this._timeout = null;
15182 }
15183
15184 if (this.queue.length > 0 && typeof this.delay === "number") {
15185 this._timeout = setTimeout(function () {
15186 _this.flush();
15187 }, this.delay);
15188 }
15189 }
15190 /**
15191 * Flush all queued calls
15192 */
15193
15194 }, {
15195 key: "flush",
15196 value: function flush() {
15197 this._queue.splice(0).forEach(function (entry) {
15198 entry.fn.apply(entry.context || entry.fn, entry.args || []);
15199 });
15200 }
15201 }], [{
15202 key: "extend",
15203 value: function extend(object, options) {
15204 var queue = new Queue(options);
15205
15206 if (object.flush !== undefined) {
15207 throw new Error("Target object already has a property flush");
15208 }
15209
15210 object.flush = function () {
15211 queue.flush();
15212 };
15213
15214 var methods = [{
15215 name: "flush",
15216 original: undefined
15217 }];
15218
15219 if (options && options.replace) {
15220 for (var i = 0; i < options.replace.length; i++) {
15221 var name = options.replace[i];
15222 methods.push({
15223 name: name,
15224 // @TODO: better solution?
15225 original: object[name]
15226 }); // @TODO: better solution?
15227
15228 queue.replace(object, name);
15229 }
15230 }
15231
15232 queue._extended = {
15233 object: object,
15234 methods: methods
15235 };
15236 return queue;
15237 }
15238 }]);
15239 return Queue;
15240}();
15241/* eslint-disable @typescript-eslint/member-ordering */
15242
15243/**
15244 * [[DataSet]] code that can be reused in [[DataView]] or other similar implementations of [[DataInterface]].
15245 *
15246 * @typeParam Item - Item type that may or may not have an id.
15247 * @typeParam IdProp - Name of the property that contains the id.
15248 */
15249
15250
15251var DataSetPart =
15252/*#__PURE__*/
15253function () {
15254 function DataSetPart() {
15255 classCallCheck(this, DataSetPart);
15256 this._subscribers = {
15257 "*": [],
15258 add: [],
15259 remove: [],
15260 update: []
15261 };
15262 /**
15263 * @deprecated Use on instead (PS: DataView.subscribe === DataView.on).
15264 */
15265
15266 this.subscribe = DataSetPart.prototype.on;
15267 /**
15268 * @deprecated Use off instead (PS: DataView.unsubscribe === DataView.off).
15269 */
15270
15271 this.unsubscribe = DataSetPart.prototype.off;
15272 }
15273 /**
15274 * Trigger an event
15275 *
15276 * @param event - Event name.
15277 * @param payload - Event payload.
15278 * @param senderId - Id of the sender.
15279 */
15280
15281
15282 createClass(DataSetPart, [{
15283 key: "_trigger",
15284 value: function _trigger(event, payload, senderId) {
15285 if (event === "*") {
15286 throw new Error("Cannot trigger event *");
15287 }
15288
15289 [].concat(toConsumableArray(this._subscribers[event]), toConsumableArray(this._subscribers["*"])).forEach(function (subscriber) {
15290 subscriber(event, payload, senderId != null ? senderId : null);
15291 });
15292 }
15293 /**
15294 * Subscribe to an event, add an event listener.
15295 *
15296 * @remarks Non-function callbacks are ignored.
15297 *
15298 * @param event - Event name.
15299 * @param callback - Callback method.
15300 */
15301
15302 }, {
15303 key: "on",
15304 value: function on(event, callback) {
15305 if (typeof callback === "function") {
15306 this._subscribers[event].push(callback);
15307 } // @TODO: Maybe throw for invalid callbacks?
15308
15309 }
15310 /**
15311 * Unsubscribe from an event, remove an event listener.
15312 *
15313 * @remarks If the same callback was subscribed more than once **all** occurences will be removed.
15314 *
15315 * @param event - Event name.
15316 * @param callback - Callback method.
15317 */
15318
15319 }, {
15320 key: "off",
15321 value: function off(event, callback) {
15322 this._subscribers[event] = this._subscribers[event].filter(function (subscriber) {
15323 return subscriber !== callback;
15324 });
15325 }
15326 }]);
15327 return DataSetPart;
15328}();
15329
15330function _arrayWithHoles(arr) {
15331 if (Array.isArray(arr)) return arr;
15332}
15333
15334var arrayWithHoles = _arrayWithHoles;
15335
15336function _iterableToArrayLimit(arr, i) {
15337 var _arr = [];
15338 var _n = true;
15339 var _d = false;
15340 var _e = undefined;
15341
15342 try {
15343 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
15344 _arr.push(_s.value);
15345
15346 if (i && _arr.length === i) break;
15347 }
15348 } catch (err) {
15349 _d = true;
15350 _e = err;
15351 } finally {
15352 try {
15353 if (!_n && _i["return"] != null) _i["return"]();
15354 } finally {
15355 if (_d) throw _e;
15356 }
15357 }
15358
15359 return _arr;
15360}
15361
15362var iterableToArrayLimit = _iterableToArrayLimit;
15363
15364function _nonIterableRest() {
15365 throw new TypeError("Invalid attempt to destructure non-iterable instance");
15366}
15367
15368var nonIterableRest = _nonIterableRest;
15369
15370function _slicedToArray(arr, i) {
15371 return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
15372}
15373
15374var slicedToArray = _slicedToArray;
15375/**
15376 * Data stream
15377 *
15378 * @remarks
15379 * [[DataStream]] offers an always up to date stream of items from a [[DataSet]] or [[DataView]].
15380 * That means that the stream is evaluated at the time of iteration, conversion to another data type or when [[cache]] is called, not when the [[DataStream]] was created.
15381 * Multiple invocations of for example [[toItemArray]] may yield different results (if the data source like for example [[DataSet]] gets modified).
15382 *
15383 * @typeparam Item - The item type this stream is going to work with.
15384 */
15385
15386var DataStream =
15387/*#__PURE__*/
15388function () {
15389 /**
15390 * Create a new data stream.
15391 *
15392 * @param _pairs - The id, item pairs.
15393 */
15394 function DataStream(_pairs) {
15395 classCallCheck(this, DataStream);
15396 this._pairs = _pairs;
15397 }
15398 /**
15399 * Return an iterable of key, value pairs for every entry in the stream.
15400 */
15401
15402
15403 createClass(DataStream, [{
15404 key: Symbol.iterator,
15405 value:
15406 /*#__PURE__*/
15407 regenerator.mark(function value() {
15408 var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step$value, id, item;
15409
15410 return regenerator.wrap(function value$(_context) {
15411 while (1) {
15412 switch (_context.prev = _context.next) {
15413 case 0:
15414 _iteratorNormalCompletion = true;
15415 _didIteratorError = false;
15416 _iteratorError = undefined;
15417 _context.prev = 3;
15418 _iterator = this._pairs[Symbol.iterator]();
15419
15420 case 5:
15421 if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
15422 _context.next = 12;
15423 break;
15424 }
15425
15426 _step$value = slicedToArray(_step.value, 2), id = _step$value[0], item = _step$value[1];
15427 _context.next = 9;
15428 return [id, item];
15429
15430 case 9:
15431 _iteratorNormalCompletion = true;
15432 _context.next = 5;
15433 break;
15434
15435 case 12:
15436 _context.next = 18;
15437 break;
15438
15439 case 14:
15440 _context.prev = 14;
15441 _context.t0 = _context["catch"](3);
15442 _didIteratorError = true;
15443 _iteratorError = _context.t0;
15444
15445 case 18:
15446 _context.prev = 18;
15447 _context.prev = 19;
15448
15449 if (!_iteratorNormalCompletion && _iterator.return != null) {
15450 _iterator.return();
15451 }
15452
15453 case 21:
15454 _context.prev = 21;
15455
15456 if (!_didIteratorError) {
15457 _context.next = 24;
15458 break;
15459 }
15460
15461 throw _iteratorError;
15462
15463 case 24:
15464 return _context.finish(21);
15465
15466 case 25:
15467 return _context.finish(18);
15468
15469 case 26:
15470 case "end":
15471 return _context.stop();
15472 }
15473 }
15474 }, value, this, [[3, 14, 18, 26], [19,, 21, 25]]);
15475 })
15476 /**
15477 * Return an iterable of key, value pairs for every entry in the stream.
15478 */
15479
15480 }, {
15481 key: "entries",
15482 value:
15483 /*#__PURE__*/
15484 regenerator.mark(function entries() {
15485 var _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, _step2$value, id, item;
15486
15487 return regenerator.wrap(function entries$(_context2) {
15488 while (1) {
15489 switch (_context2.prev = _context2.next) {
15490 case 0:
15491 _iteratorNormalCompletion2 = true;
15492 _didIteratorError2 = false;
15493 _iteratorError2 = undefined;
15494 _context2.prev = 3;
15495 _iterator2 = this._pairs[Symbol.iterator]();
15496
15497 case 5:
15498 if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
15499 _context2.next = 12;
15500 break;
15501 }
15502
15503 _step2$value = slicedToArray(_step2.value, 2), id = _step2$value[0], item = _step2$value[1];
15504 _context2.next = 9;
15505 return [id, item];
15506
15507 case 9:
15508 _iteratorNormalCompletion2 = true;
15509 _context2.next = 5;
15510 break;
15511
15512 case 12:
15513 _context2.next = 18;
15514 break;
15515
15516 case 14:
15517 _context2.prev = 14;
15518 _context2.t0 = _context2["catch"](3);
15519 _didIteratorError2 = true;
15520 _iteratorError2 = _context2.t0;
15521
15522 case 18:
15523 _context2.prev = 18;
15524 _context2.prev = 19;
15525
15526 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
15527 _iterator2.return();
15528 }
15529
15530 case 21:
15531 _context2.prev = 21;
15532
15533 if (!_didIteratorError2) {
15534 _context2.next = 24;
15535 break;
15536 }
15537
15538 throw _iteratorError2;
15539
15540 case 24:
15541 return _context2.finish(21);
15542
15543 case 25:
15544 return _context2.finish(18);
15545
15546 case 26:
15547 case "end":
15548 return _context2.stop();
15549 }
15550 }
15551 }, entries, this, [[3, 14, 18, 26], [19,, 21, 25]]);
15552 })
15553 /**
15554 * Return an iterable of keys in the stream.
15555 */
15556
15557 }, {
15558 key: "keys",
15559 value:
15560 /*#__PURE__*/
15561 regenerator.mark(function keys() {
15562 var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, _step3$value, id;
15563
15564 return regenerator.wrap(function keys$(_context3) {
15565 while (1) {
15566 switch (_context3.prev = _context3.next) {
15567 case 0:
15568 _iteratorNormalCompletion3 = true;
15569 _didIteratorError3 = false;
15570 _iteratorError3 = undefined;
15571 _context3.prev = 3;
15572 _iterator3 = this._pairs[Symbol.iterator]();
15573
15574 case 5:
15575 if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
15576 _context3.next = 12;
15577 break;
15578 }
15579
15580 _step3$value = slicedToArray(_step3.value, 1), id = _step3$value[0];
15581 _context3.next = 9;
15582 return id;
15583
15584 case 9:
15585 _iteratorNormalCompletion3 = true;
15586 _context3.next = 5;
15587 break;
15588
15589 case 12:
15590 _context3.next = 18;
15591 break;
15592
15593 case 14:
15594 _context3.prev = 14;
15595 _context3.t0 = _context3["catch"](3);
15596 _didIteratorError3 = true;
15597 _iteratorError3 = _context3.t0;
15598
15599 case 18:
15600 _context3.prev = 18;
15601 _context3.prev = 19;
15602
15603 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
15604 _iterator3.return();
15605 }
15606
15607 case 21:
15608 _context3.prev = 21;
15609
15610 if (!_didIteratorError3) {
15611 _context3.next = 24;
15612 break;
15613 }
15614
15615 throw _iteratorError3;
15616
15617 case 24:
15618 return _context3.finish(21);
15619
15620 case 25:
15621 return _context3.finish(18);
15622
15623 case 26:
15624 case "end":
15625 return _context3.stop();
15626 }
15627 }
15628 }, keys, this, [[3, 14, 18, 26], [19,, 21, 25]]);
15629 })
15630 /**
15631 * Return an iterable of values in the stream.
15632 */
15633
15634 }, {
15635 key: "values",
15636 value:
15637 /*#__PURE__*/
15638 regenerator.mark(function values() {
15639 var _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, _step4$value, item;
15640
15641 return regenerator.wrap(function values$(_context4) {
15642 while (1) {
15643 switch (_context4.prev = _context4.next) {
15644 case 0:
15645 _iteratorNormalCompletion4 = true;
15646 _didIteratorError4 = false;
15647 _iteratorError4 = undefined;
15648 _context4.prev = 3;
15649 _iterator4 = this._pairs[Symbol.iterator]();
15650
15651 case 5:
15652 if (_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done) {
15653 _context4.next = 12;
15654 break;
15655 }
15656
15657 _step4$value = slicedToArray(_step4.value, 2), item = _step4$value[1];
15658 _context4.next = 9;
15659 return item;
15660
15661 case 9:
15662 _iteratorNormalCompletion4 = true;
15663 _context4.next = 5;
15664 break;
15665
15666 case 12:
15667 _context4.next = 18;
15668 break;
15669
15670 case 14:
15671 _context4.prev = 14;
15672 _context4.t0 = _context4["catch"](3);
15673 _didIteratorError4 = true;
15674 _iteratorError4 = _context4.t0;
15675
15676 case 18:
15677 _context4.prev = 18;
15678 _context4.prev = 19;
15679
15680 if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
15681 _iterator4.return();
15682 }
15683
15684 case 21:
15685 _context4.prev = 21;
15686
15687 if (!_didIteratorError4) {
15688 _context4.next = 24;
15689 break;
15690 }
15691
15692 throw _iteratorError4;
15693
15694 case 24:
15695 return _context4.finish(21);
15696
15697 case 25:
15698 return _context4.finish(18);
15699
15700 case 26:
15701 case "end":
15702 return _context4.stop();
15703 }
15704 }
15705 }, values, this, [[3, 14, 18, 26], [19,, 21, 25]]);
15706 })
15707 /**
15708 * Return an array containing all the ids in this stream.
15709 *
15710 * @remarks
15711 * The array may contain duplicities.
15712 *
15713 * @returns The array with all ids from this stream.
15714 */
15715
15716 }, {
15717 key: "toIdArray",
15718 value: function toIdArray() {
15719 return toConsumableArray(this._pairs).map(function (pair) {
15720 return pair[0];
15721 });
15722 }
15723 /**
15724 * Return an array containing all the items in this stream.
15725 *
15726 * @remarks
15727 * The array may contain duplicities.
15728 *
15729 * @returns The array with all items from this stream.
15730 */
15731
15732 }, {
15733 key: "toItemArray",
15734 value: function toItemArray() {
15735 return toConsumableArray(this._pairs).map(function (pair) {
15736 return pair[1];
15737 });
15738 }
15739 /**
15740 * Return an array containing all the entries in this stream.
15741 *
15742 * @remarks
15743 * The array may contain duplicities.
15744 *
15745 * @returns The array with all entries from this stream.
15746 */
15747
15748 }, {
15749 key: "toEntryArray",
15750 value: function toEntryArray() {
15751 return toConsumableArray(this._pairs);
15752 }
15753 /**
15754 * Return an object map containing all the items in this stream accessible by ids.
15755 *
15756 * @remarks
15757 * In case of duplicate ids (coerced to string so `7 == '7'`) the last encoutered appears in the returned object.
15758 *
15759 * @returns The object map of all id → item pairs from this stream.
15760 */
15761
15762 }, {
15763 key: "toObjectMap",
15764 value: function toObjectMap() {
15765 var map = Object.create(null);
15766 var _iteratorNormalCompletion5 = true;
15767 var _didIteratorError5 = false;
15768 var _iteratorError5 = undefined;
15769
15770 try {
15771 for (var _iterator5 = this._pairs[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
15772 var _step5$value = slicedToArray(_step5.value, 2),
15773 id = _step5$value[0],
15774 item = _step5$value[1];
15775
15776 map[id] = item;
15777 }
15778 } catch (err) {
15779 _didIteratorError5 = true;
15780 _iteratorError5 = err;
15781 } finally {
15782 try {
15783 if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
15784 _iterator5.return();
15785 }
15786 } finally {
15787 if (_didIteratorError5) {
15788 throw _iteratorError5;
15789 }
15790 }
15791 }
15792
15793 return map;
15794 }
15795 /**
15796 * Return a map containing all the items in this stream accessible by ids.
15797 *
15798 * @returns The map of all id → item pairs from this stream.
15799 */
15800
15801 }, {
15802 key: "toMap",
15803 value: function toMap() {
15804 return new Map(this._pairs);
15805 }
15806 /**
15807 * Return a set containing all the (unique) ids in this stream.
15808 *
15809 * @returns The set of all ids from this stream.
15810 */
15811
15812 }, {
15813 key: "toIdSet",
15814 value: function toIdSet() {
15815 return new Set(this.toIdArray());
15816 }
15817 /**
15818 * Return a set containing all the (unique) items in this stream.
15819 *
15820 * @returns The set of all items from this stream.
15821 */
15822
15823 }, {
15824 key: "toItemSet",
15825 value: function toItemSet() {
15826 return new Set(this.toItemArray());
15827 }
15828 /**
15829 * Cache the items from this stream.
15830 *
15831 * @remarks
15832 * This method allows for items to be fetched immediatelly and used (possibly multiple times) later.
15833 * It can also be used to optimize performance as [[DataStream]] would otherwise reevaluate everything upon each iteration.
15834 *
15835 * ## Example
15836 * ```javascript
15837 * const ds = new DataSet([…])
15838 *
15839 * const cachedStream = ds.stream()
15840 * .filter(…)
15841 * .sort(…)
15842 * .map(…)
15843 * .cached(…) // Data are fetched, processed and cached here.
15844 *
15845 * ds.clear()
15846 * chachedStream // Still has all the items.
15847 * ```
15848 *
15849 * @returns A new [[DataStream]] with cached items (detached from the original [[DataSet]]).
15850 */
15851
15852 }, {
15853 key: "cache",
15854 value: function cache() {
15855 return new DataStream(toConsumableArray(this._pairs));
15856 }
15857 /**
15858 * Get the distinct values of given property.
15859 *
15860 * @param callback - The function that picks and possibly converts the property.
15861 *
15862 * @typeparam T - The type of the distinct value.
15863 *
15864 * @returns A set of all distinct properties.
15865 */
15866
15867 }, {
15868 key: "distinct",
15869 value: function distinct(callback) {
15870 var set = new Set();
15871 var _iteratorNormalCompletion6 = true;
15872 var _didIteratorError6 = false;
15873 var _iteratorError6 = undefined;
15874
15875 try {
15876 for (var _iterator6 = this._pairs[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
15877 var _step6$value = slicedToArray(_step6.value, 2),
15878 id = _step6$value[0],
15879 item = _step6$value[1];
15880
15881 set.add(callback(item, id));
15882 }
15883 } catch (err) {
15884 _didIteratorError6 = true;
15885 _iteratorError6 = err;
15886 } finally {
15887 try {
15888 if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
15889 _iterator6.return();
15890 }
15891 } finally {
15892 if (_didIteratorError6) {
15893 throw _iteratorError6;
15894 }
15895 }
15896 }
15897
15898 return set;
15899 }
15900 /**
15901 * Filter the items of the stream.
15902 *
15903 * @param callback - The function that decides whether an item will be included.
15904 *
15905 * @returns A new data stream with the filtered items.
15906 */
15907
15908 }, {
15909 key: "filter",
15910 value: function filter(callback) {
15911 var pairs = this._pairs;
15912 return new DataStream(defineProperty$1({}, Symbol.iterator,
15913 /*#__PURE__*/
15914 regenerator.mark(function _callee() {
15915 var _iteratorNormalCompletion7, _didIteratorError7, _iteratorError7, _iterator7, _step7, _step7$value, id, item;
15916
15917 return regenerator.wrap(function _callee$(_context5) {
15918 while (1) {
15919 switch (_context5.prev = _context5.next) {
15920 case 0:
15921 _iteratorNormalCompletion7 = true;
15922 _didIteratorError7 = false;
15923 _iteratorError7 = undefined;
15924 _context5.prev = 3;
15925 _iterator7 = pairs[Symbol.iterator]();
15926
15927 case 5:
15928 if (_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done) {
15929 _context5.next = 13;
15930 break;
15931 }
15932
15933 _step7$value = slicedToArray(_step7.value, 2), id = _step7$value[0], item = _step7$value[1];
15934
15935 if (!callback(item, id)) {
15936 _context5.next = 10;
15937 break;
15938 }
15939
15940 _context5.next = 10;
15941 return [id, item];
15942
15943 case 10:
15944 _iteratorNormalCompletion7 = true;
15945 _context5.next = 5;
15946 break;
15947
15948 case 13:
15949 _context5.next = 19;
15950 break;
15951
15952 case 15:
15953 _context5.prev = 15;
15954 _context5.t0 = _context5["catch"](3);
15955 _didIteratorError7 = true;
15956 _iteratorError7 = _context5.t0;
15957
15958 case 19:
15959 _context5.prev = 19;
15960 _context5.prev = 20;
15961
15962 if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
15963 _iterator7.return();
15964 }
15965
15966 case 22:
15967 _context5.prev = 22;
15968
15969 if (!_didIteratorError7) {
15970 _context5.next = 25;
15971 break;
15972 }
15973
15974 throw _iteratorError7;
15975
15976 case 25:
15977 return _context5.finish(22);
15978
15979 case 26:
15980 return _context5.finish(19);
15981
15982 case 27:
15983 case "end":
15984 return _context5.stop();
15985 }
15986 }
15987 }, _callee, null, [[3, 15, 19, 27], [20,, 22, 26]]);
15988 })));
15989 }
15990 /**
15991 * Execute a callback for each item of the stream.
15992 *
15993 * @param callback - The function that will be invoked for each item.
15994 */
15995
15996 }, {
15997 key: "forEach",
15998 value: function forEach(callback) {
15999 var _iteratorNormalCompletion8 = true;
16000 var _didIteratorError8 = false;
16001 var _iteratorError8 = undefined;
16002
16003 try {
16004 for (var _iterator8 = this._pairs[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
16005 var _step8$value = slicedToArray(_step8.value, 2),
16006 id = _step8$value[0],
16007 item = _step8$value[1];
16008
16009 callback(item, id);
16010 }
16011 } catch (err) {
16012 _didIteratorError8 = true;
16013 _iteratorError8 = err;
16014 } finally {
16015 try {
16016 if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
16017 _iterator8.return();
16018 }
16019 } finally {
16020 if (_didIteratorError8) {
16021 throw _iteratorError8;
16022 }
16023 }
16024 }
16025 }
16026 /**
16027 * Map the items into a different type.
16028 *
16029 * @param callback - The function that does the conversion.
16030 *
16031 * @typeparam Mapped - The type of the item after mapping.
16032 *
16033 * @returns A new data stream with the mapped items.
16034 */
16035
16036 }, {
16037 key: "map",
16038 value: function map(callback) {
16039 var pairs = this._pairs;
16040 return new DataStream(defineProperty$1({}, Symbol.iterator,
16041 /*#__PURE__*/
16042 regenerator.mark(function _callee2() {
16043 var _iteratorNormalCompletion9, _didIteratorError9, _iteratorError9, _iterator9, _step9, _step9$value, id, item;
16044
16045 return regenerator.wrap(function _callee2$(_context6) {
16046 while (1) {
16047 switch (_context6.prev = _context6.next) {
16048 case 0:
16049 _iteratorNormalCompletion9 = true;
16050 _didIteratorError9 = false;
16051 _iteratorError9 = undefined;
16052 _context6.prev = 3;
16053 _iterator9 = pairs[Symbol.iterator]();
16054
16055 case 5:
16056 if (_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done) {
16057 _context6.next = 12;
16058 break;
16059 }
16060
16061 _step9$value = slicedToArray(_step9.value, 2), id = _step9$value[0], item = _step9$value[1];
16062 _context6.next = 9;
16063 return [id, callback(item, id)];
16064
16065 case 9:
16066 _iteratorNormalCompletion9 = true;
16067 _context6.next = 5;
16068 break;
16069
16070 case 12:
16071 _context6.next = 18;
16072 break;
16073
16074 case 14:
16075 _context6.prev = 14;
16076 _context6.t0 = _context6["catch"](3);
16077 _didIteratorError9 = true;
16078 _iteratorError9 = _context6.t0;
16079
16080 case 18:
16081 _context6.prev = 18;
16082 _context6.prev = 19;
16083
16084 if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
16085 _iterator9.return();
16086 }
16087
16088 case 21:
16089 _context6.prev = 21;
16090
16091 if (!_didIteratorError9) {
16092 _context6.next = 24;
16093 break;
16094 }
16095
16096 throw _iteratorError9;
16097
16098 case 24:
16099 return _context6.finish(21);
16100
16101 case 25:
16102 return _context6.finish(18);
16103
16104 case 26:
16105 case "end":
16106 return _context6.stop();
16107 }
16108 }
16109 }, _callee2, null, [[3, 14, 18, 26], [19,, 21, 25]]);
16110 })));
16111 }
16112 /**
16113 * Get the item with the maximum value of given property.
16114 *
16115 * @param callback - The function that picks and possibly converts the property.
16116 *
16117 * @returns The item with the maximum if found otherwise null.
16118 */
16119
16120 }, {
16121 key: "max",
16122 value: function max(callback) {
16123 var iter = this._pairs[Symbol.iterator]();
16124
16125 var curr = iter.next();
16126
16127 if (curr.done) {
16128 return null;
16129 }
16130
16131 var maxItem = curr.value[1];
16132 var maxValue = callback(curr.value[1], curr.value[0]);
16133
16134 while (!(curr = iter.next()).done) {
16135 var _curr$value = slicedToArray(curr.value, 2),
16136 id = _curr$value[0],
16137 item = _curr$value[1];
16138
16139 var _value = callback(item, id);
16140
16141 if (_value > maxValue) {
16142 maxValue = _value;
16143 maxItem = item;
16144 }
16145 }
16146
16147 return maxItem;
16148 }
16149 /**
16150 * Get the item with the minimum value of given property.
16151 *
16152 * @param callback - The function that picks and possibly converts the property.
16153 *
16154 * @returns The item with the minimum if found otherwise null.
16155 */
16156
16157 }, {
16158 key: "min",
16159 value: function min(callback) {
16160 var iter = this._pairs[Symbol.iterator]();
16161
16162 var curr = iter.next();
16163
16164 if (curr.done) {
16165 return null;
16166 }
16167
16168 var minItem = curr.value[1];
16169 var minValue = callback(curr.value[1], curr.value[0]);
16170
16171 while (!(curr = iter.next()).done) {
16172 var _curr$value2 = slicedToArray(curr.value, 2),
16173 id = _curr$value2[0],
16174 item = _curr$value2[1];
16175
16176 var _value2 = callback(item, id);
16177
16178 if (_value2 < minValue) {
16179 minValue = _value2;
16180 minItem = item;
16181 }
16182 }
16183
16184 return minItem;
16185 }
16186 /**
16187 * Reduce the items into a single value.
16188 *
16189 * @param callback - The function that does the reduction.
16190 * @param accumulator - The initial value of the accumulator.
16191 *
16192 * @typeparam T - The type of the accumulated value.
16193 *
16194 * @returns The reduced value.
16195 */
16196
16197 }, {
16198 key: "reduce",
16199 value: function reduce(callback, accumulator) {
16200 var _iteratorNormalCompletion10 = true;
16201 var _didIteratorError10 = false;
16202 var _iteratorError10 = undefined;
16203
16204 try {
16205 for (var _iterator10 = this._pairs[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
16206 var _step10$value = slicedToArray(_step10.value, 2),
16207 id = _step10$value[0],
16208 item = _step10$value[1];
16209
16210 accumulator = callback(accumulator, item, id);
16211 }
16212 } catch (err) {
16213 _didIteratorError10 = true;
16214 _iteratorError10 = err;
16215 } finally {
16216 try {
16217 if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
16218 _iterator10.return();
16219 }
16220 } finally {
16221 if (_didIteratorError10) {
16222 throw _iteratorError10;
16223 }
16224 }
16225 }
16226
16227 return accumulator;
16228 }
16229 /**
16230 * Sort the items.
16231 *
16232 * @param callback - Item comparator.
16233 *
16234 * @returns A new stream with sorted items.
16235 */
16236
16237 }, {
16238 key: "sort",
16239 value: function sort(callback) {
16240 var _this = this;
16241
16242 return new DataStream(defineProperty$1({}, Symbol.iterator, function () {
16243 return toConsumableArray(_this._pairs).sort(function (_ref3, _ref4) {
16244 var _ref5 = slicedToArray(_ref3, 2),
16245 idA = _ref5[0],
16246 itemA = _ref5[1];
16247
16248 var _ref6 = slicedToArray(_ref4, 2),
16249 idB = _ref6[0],
16250 itemB = _ref6[1];
16251
16252 return callback(itemA, itemB, idA, idB);
16253 })[Symbol.iterator]();
16254 }));
16255 }
16256 }]);
16257 return DataStream;
16258}();
16259
16260function ownKeys$1(object, enumerableOnly) {
16261 var keys = Object.keys(object);
16262
16263 if (Object.getOwnPropertySymbols) {
16264 keys.push.apply(keys, Object.getOwnPropertySymbols(object));
16265 }
16266
16267 if (enumerableOnly) keys = keys.filter(function (sym) {
16268 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
16269 });
16270 return keys;
16271}
16272
16273function _objectSpread(target) {
16274 for (var i = 1; i < arguments.length; i++) {
16275 var source = arguments[i] != null ? arguments[i] : {};
16276
16277 if (i % 2) {
16278 ownKeys$1(source, true).forEach(function (key) {
16279 defineProperty$1(target, key, source[key]);
16280 });
16281 } else if (Object.getOwnPropertyDescriptors) {
16282 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
16283 } else {
16284 ownKeys$1(source).forEach(function (key) {
16285 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
16286 });
16287 }
16288 }
16289
16290 return target;
16291}
16292/**
16293 * # DataSet
16294 *
16295 * 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.
16296 *
16297 * ## Example
16298 *
16299 * The following example shows how to use a DataSet.
16300 *
16301 * ```javascript
16302 * // create a DataSet
16303 * var options = {};
16304 * var data = new vis.DataSet(options);
16305 *
16306 * // add items
16307 * // note that the data items can contain different properties and data formats
16308 * data.add([
16309 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
16310 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
16311 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
16312 * {id: 4, text: 'item 4'}
16313 * ]);
16314 *
16315 * // subscribe to any change in the DataSet
16316 * data.on('*', function (event, properties, senderId) {
16317 * console.log('event', event, properties);
16318 * });
16319 *
16320 * // update an existing item
16321 * data.update({id: 2, group: 1});
16322 *
16323 * // remove an item
16324 * data.remove(4);
16325 *
16326 * // get all ids
16327 * var ids = data.getIds();
16328 * console.log('ids', ids);
16329 *
16330 * // get a specific item
16331 * var item1 = data.get(1);
16332 * console.log('item1', item1);
16333 *
16334 * // retrieve a filtered subset of the data
16335 * var items = data.get({
16336 * filter: function (item) {
16337 * return item.group == 1;
16338 * }
16339 * });
16340 * console.log('filtered items', items);
16341 *
16342 * // retrieve formatted items
16343 * var items = data.get({
16344 * fields: ['id', 'date'],
16345 * type: {
16346 * date: 'ISODate'
16347 * }
16348 * });
16349 * console.log('formatted items', items);
16350 * ```
16351 *
16352 * @typeParam Item - Item type that may or may not have an id.
16353 * @typeParam IdProp - Name of the property that contains the id.
16354 */
16355
16356
16357var DataSet =
16358/*#__PURE__*/
16359function (_DataSetPart) {
16360 inherits(DataSet, _DataSetPart);
16361 /**
16362 * Construct a new DataSet.
16363 *
16364 * @param data - Initial data or options.
16365 * @param options - Options (type error if data is also options).
16366 */
16367
16368 function DataSet(data, options) {
16369 var _this;
16370
16371 classCallCheck(this, DataSet);
16372 _this = possibleConstructorReturn(this, getPrototypeOf(DataSet).call(this)); // correctly read optional arguments
16373
16374 if (data && !Array.isArray(data)) {
16375 options = data;
16376 data = [];
16377 }
16378
16379 _this._options = options || {};
16380 _this._data = new Map(); // map with data indexed by id
16381
16382 _this.length = 0; // number of items in the DataSet
16383
16384 _this._idProp = _this._options.fieldId || "id"; // name of the field containing id
16385
16386 _this._type = {}; // internal field types (NOTE: this can differ from this._options.type)
16387 // all variants of a Date are internally stored as Date, so we can convert
16388 // from everything to everything (also from ISODate to Number for example)
16389
16390 if (_this._options.type) {
16391 var fields = Object.keys(_this._options.type);
16392
16393 for (var i = 0, len = fields.length; i < len; i++) {
16394 var field = fields[i];
16395 var value = _this._options.type[field];
16396
16397 if (value == "Date" || value == "ISODate" || value == "ASPDate") {
16398 _this._type[field] = "Date";
16399 } else {
16400 _this._type[field] = value;
16401 }
16402 }
16403 } // add initial data when provided
16404
16405
16406 if (data && data.length) {
16407 _this.add(data);
16408 }
16409
16410 _this.setOptions(options);
16411
16412 return _this;
16413 }
16414 /**
16415 * Set new options.
16416 *
16417 * @param options - The new options.
16418 */
16419
16420
16421 createClass(DataSet, [{
16422 key: "setOptions",
16423 value: function setOptions(options) {
16424 if (options && options.queue !== undefined) {
16425 if (options.queue === false) {
16426 // delete queue if loaded
16427 if (this._queue) {
16428 this._queue.destroy();
16429
16430 delete this._queue;
16431 }
16432 } else {
16433 // create queue and update its options
16434 if (!this._queue) {
16435 this._queue = Queue.extend(this, {
16436 replace: ["add", "update", "remove"]
16437 });
16438 }
16439
16440 if (options.queue && _typeof_1(options.queue) === "object") {
16441 this._queue.setOptions(options.queue);
16442 }
16443 }
16444 }
16445 }
16446 /**
16447 * Add a data item or an array with items.
16448 *
16449 * 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.
16450 *
16451 * ## Example
16452 *
16453 * ```javascript
16454 * // create a DataSet
16455 * const data = new vis.DataSet()
16456 *
16457 * // add items
16458 * const ids = data.add([
16459 * { id: 1, text: 'item 1' },
16460 * { id: 2, text: 'item 2' },
16461 * { text: 'item without an id' }
16462 * ])
16463 *
16464 * console.log(ids) // [1, 2, '<UUIDv4>']
16465 * ```
16466 *
16467 * @param data - Items to be added (ids will be generated if missing).
16468 * @param senderId - Sender id.
16469 *
16470 * @returns addedIds - Array with the ids (generated if not present) of the added items.
16471 *
16472 * @throws When an item with the same id as any of the added items already exists.
16473 */
16474
16475 }, {
16476 key: "add",
16477 value: function add(data, senderId) {
16478 var addedIds = [];
16479 var id;
16480
16481 if (Array.isArray(data)) {
16482 // Array
16483 for (var i = 0, len = data.length; i < len; i++) {
16484 id = this._addItem(data[i]);
16485 addedIds.push(id);
16486 }
16487 } else if (data && _typeof_1(data) === "object") {
16488 // Single item
16489 id = this._addItem(data);
16490 addedIds.push(id);
16491 } else {
16492 throw new Error("Unknown dataType");
16493 }
16494
16495 if (addedIds.length) {
16496 this._trigger("add", {
16497 items: addedIds
16498 }, senderId);
16499 }
16500
16501 return addedIds;
16502 }
16503 /**
16504 * Update existing items. When an item does not exist, it will be created.
16505 *
16506 * @remarks
16507 * The provided properties will be merged in the existing item. When an item does not exist, it will be created.
16508 *
16509 * 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.
16510 *
16511 * ## Example
16512 *
16513 * ```javascript
16514 * // create a DataSet
16515 * const data = new vis.DataSet([
16516 * { id: 1, text: 'item 1' },
16517 * { id: 2, text: 'item 2' },
16518 * { id: 3, text: 'item 3' }
16519 * ])
16520 *
16521 * // update items
16522 * const ids = data.update([
16523 * { id: 2, text: 'item 2 (updated)' },
16524 * { id: 4, text: 'item 4 (new)' }
16525 * ])
16526 *
16527 * console.log(ids) // [2, 4]
16528 * ```
16529 *
16530 * ## Warning for TypeScript users
16531 * This method may introduce partial items into the data set. Use add or updateOnly instead for better type safety.
16532 *
16533 * @param data - Items to be updated (if the id is already present) or added (if the id is missing).
16534 * @param senderId - Sender id.
16535 *
16536 * @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.
16537 *
16538 * @throws When the supplied data is neither an item nor an array of items.
16539 */
16540
16541 }, {
16542 key: "update",
16543 value: function update(data, senderId) {
16544 var _this2 = this;
16545
16546 var addedIds = [];
16547 var updatedIds = [];
16548 var oldData = [];
16549 var updatedData = [];
16550 var idProp = this._idProp;
16551
16552 var addOrUpdate = function addOrUpdate(item) {
16553 var origId = item[idProp];
16554
16555 if (origId != null && _this2._data.has(origId)) {
16556 var fullItem = item; // it has an id, therefore it is a fullitem
16557
16558 var oldItem = Object.assign({}, _this2._data.get(origId)); // update item
16559
16560 var id = _this2._updateItem(fullItem);
16561
16562 updatedIds.push(id);
16563 updatedData.push(fullItem);
16564 oldData.push(oldItem);
16565 } else {
16566 // add new item
16567 var _id = _this2._addItem(item);
16568
16569 addedIds.push(_id);
16570 }
16571 };
16572
16573 if (Array.isArray(data)) {
16574 // Array
16575 for (var i = 0, len = data.length; i < len; i++) {
16576 if (data[i] && _typeof_1(data[i]) === "object") {
16577 addOrUpdate(data[i]);
16578 } else {
16579 console.warn("Ignoring input item, which is not an object at index " + i);
16580 }
16581 }
16582 } else if (data && _typeof_1(data) === "object") {
16583 // Single item
16584 addOrUpdate(data);
16585 } else {
16586 throw new Error("Unknown dataType");
16587 }
16588
16589 if (addedIds.length) {
16590 this._trigger("add", {
16591 items: addedIds
16592 }, senderId);
16593 }
16594
16595 if (updatedIds.length) {
16596 var props = {
16597 items: updatedIds,
16598 oldData: oldData,
16599 data: updatedData
16600 }; // TODO: remove deprecated property 'data' some day
16601 //Object.defineProperty(props, 'data', {
16602 // 'get': (function() {
16603 // 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');
16604 // return updatedData;
16605 // }).bind(this)
16606 //});
16607
16608 this._trigger("update", props, senderId);
16609 }
16610
16611 return addedIds.concat(updatedIds);
16612 }
16613 /**
16614 * Update existing items. When an item does not exist, an error will be thrown.
16615 *
16616 * @remarks
16617 * The provided properties will be deeply merged into the existing item.
16618 * When an item does not exist (id not present in the data set or absent), an error will be thrown and nothing will be changed.
16619 *
16620 * After the items are updated, the DataSet will trigger an event `update`.
16621 * When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
16622 *
16623 * ## Example
16624 *
16625 * ```javascript
16626 * // create a DataSet
16627 * const data = new vis.DataSet([
16628 * { id: 1, text: 'item 1' },
16629 * { id: 2, text: 'item 2' },
16630 * { id: 3, text: 'item 3' },
16631 * ])
16632 *
16633 * // update items
16634 * const ids = data.update([
16635 * { id: 2, text: 'item 2 (updated)' }, // works
16636 * // { id: 4, text: 'item 4 (new)' }, // would throw
16637 * // { text: 'item 4 (new)' }, // would also throw
16638 * ])
16639 *
16640 * console.log(ids) // [2]
16641 * ```
16642 *
16643 * @param data - Updates (the id and optionally other props) to the items in this data set.
16644 * @param senderId - Sender id.
16645 *
16646 * @returns updatedIds - The ids of the updated items.
16647 *
16648 * @throws When the supplied data is neither an item nor an array of items, when the ids are missing.
16649 */
16650
16651 }, {
16652 key: "updateOnly",
16653 value: function updateOnly(data, senderId) {
16654 var _this3 = this;
16655
16656 if (!Array.isArray(data)) {
16657 data = [data];
16658 }
16659
16660 var updateEventData = data.map(function (update) {
16661 var oldData = _this3._data.get(update[_this3._idProp]);
16662
16663 if (oldData == null) {
16664 throw new Error("Updating non-existent items is not allowed.");
16665 }
16666
16667 return {
16668 oldData: oldData,
16669 update: update
16670 };
16671 }).map(function (_ref) {
16672 var oldData = _ref.oldData,
16673 update = _ref.update;
16674 var id = oldData[_this3._idProp];
16675 var updatedData = deepExtend$1(deepExtend$1({}, oldData), update);
16676
16677 _this3._data.set(id, updatedData);
16678
16679 return {
16680 id: id,
16681 oldData: oldData,
16682 updatedData: updatedData
16683 };
16684 });
16685
16686 if (updateEventData.length) {
16687 var props = {
16688 items: updateEventData.map(function (value) {
16689 return value.id;
16690 }),
16691 oldData: updateEventData.map(function (value) {
16692 return value.oldData;
16693 }),
16694 data: updateEventData.map(function (value) {
16695 return value.updatedData;
16696 })
16697 }; // TODO: remove deprecated property 'data' some day
16698 //Object.defineProperty(props, 'data', {
16699 // 'get': (function() {
16700 // 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');
16701 // return updatedData;
16702 // }).bind(this)
16703 //});
16704
16705 this._trigger("update", props, senderId);
16706
16707 return props.items;
16708 } else {
16709 return [];
16710 }
16711 }
16712 /** @inheritdoc */
16713
16714 }, {
16715 key: "get",
16716 value: function get(first, second) {
16717 // @TODO: Woudn't it be better to split this into multiple methods?
16718 // parse the arguments
16719 var id = undefined;
16720 var ids = undefined;
16721 var options = undefined;
16722
16723 if (isId(first)) {
16724 // get(id [, options])
16725 id = first;
16726 options = second;
16727 } else if (Array.isArray(first)) {
16728 // get(ids [, options])
16729 ids = first;
16730 options = second;
16731 } else {
16732 // get([, options])
16733 options = first;
16734 } // determine the return type
16735
16736
16737 var returnType = options && options.returnType === "Object" ? "Object" : "Array"; // @TODO: WTF is this? Or am I missing something?
16738 // var returnType
16739 // if (options && options.returnType) {
16740 // var allowedValues = ['Array', 'Object']
16741 // returnType =
16742 // allowedValues.indexOf(options.returnType) == -1
16743 // ? 'Array'
16744 // : options.returnType
16745 // } else {
16746 // returnType = 'Array'
16747 // }
16748 // build options
16749
16750 var type = options && options.type || this._options.type;
16751 var filter = options && options.filter;
16752 var items = [];
16753 var item = null;
16754 var itemIds = null;
16755 var itemId = null; // convert items
16756
16757 if (id != null) {
16758 // return a single item
16759 item = this._getItem(id, type);
16760
16761 if (item && filter && !filter(item)) {
16762 item = null;
16763 }
16764 } else if (ids != null) {
16765 // return a subset of items
16766 for (var i = 0, len = ids.length; i < len; i++) {
16767 item = this._getItem(ids[i], type);
16768
16769 if (item != null && (!filter || filter(item))) {
16770 items.push(item);
16771 }
16772 }
16773 } else {
16774 // return all items
16775 itemIds = toConsumableArray(this._data.keys());
16776
16777 for (var _i = 0, _len = itemIds.length; _i < _len; _i++) {
16778 itemId = itemIds[_i];
16779 item = this._getItem(itemId, type);
16780
16781 if (item != null && (!filter || filter(item))) {
16782 items.push(item);
16783 }
16784 }
16785 } // order the results
16786
16787
16788 if (options && options.order && id == undefined) {
16789 this._sort(items, options.order);
16790 } // filter fields of the items
16791
16792
16793 if (options && options.fields) {
16794 var fields = options.fields;
16795
16796 if (id != undefined && item != null) {
16797 item = this._filterFields(item, fields);
16798 } else {
16799 for (var _i2 = 0, _len2 = items.length; _i2 < _len2; _i2++) {
16800 items[_i2] = this._filterFields(items[_i2], fields);
16801 }
16802 }
16803 } // return the results
16804
16805
16806 if (returnType == "Object") {
16807 var result = {};
16808
16809 for (var _i3 = 0, _len3 = items.length; _i3 < _len3; _i3++) {
16810 var resultant = items[_i3]; // @TODO: Shoudn't this be this._fieldId?
16811 // result[resultant.id] = resultant
16812
16813 var _id2 = resultant[this._idProp];
16814 result[_id2] = resultant;
16815 }
16816
16817 return result;
16818 } else {
16819 if (id != null) {
16820 // a single item
16821 return item;
16822 } else {
16823 // just return our array
16824 return items;
16825 }
16826 }
16827 }
16828 /** @inheritdoc */
16829
16830 }, {
16831 key: "getIds",
16832 value: function getIds(options) {
16833 var data = this._data;
16834 var filter = options && options.filter;
16835 var order = options && options.order;
16836 var type = options && options.type || this._options.type;
16837 var itemIds = toConsumableArray(data.keys());
16838 var ids = [];
16839 var item;
16840 var items;
16841
16842 if (filter) {
16843 // get filtered items
16844 if (order) {
16845 // create ordered list
16846 items = [];
16847
16848 for (var i = 0, len = itemIds.length; i < len; i++) {
16849 var id = itemIds[i];
16850 item = this._getItem(id, type);
16851
16852 if (filter(item)) {
16853 items.push(item);
16854 }
16855 }
16856
16857 this._sort(items, order);
16858
16859 for (var _i4 = 0, _len4 = items.length; _i4 < _len4; _i4++) {
16860 ids.push(items[_i4][this._idProp]);
16861 }
16862 } else {
16863 // create unordered list
16864 for (var _i5 = 0, _len5 = itemIds.length; _i5 < _len5; _i5++) {
16865 var _id3 = itemIds[_i5];
16866 item = this._getItem(_id3, type);
16867
16868 if (filter(item)) {
16869 ids.push(item[this._idProp]);
16870 }
16871 }
16872 }
16873 } else {
16874 // get all items
16875 if (order) {
16876 // create an ordered list
16877 items = [];
16878
16879 for (var _i6 = 0, _len6 = itemIds.length; _i6 < _len6; _i6++) {
16880 var _id4 = itemIds[_i6];
16881 items.push(data.get(_id4));
16882 }
16883
16884 this._sort(items, order);
16885
16886 for (var _i7 = 0, _len7 = items.length; _i7 < _len7; _i7++) {
16887 ids.push(items[_i7][this._idProp]);
16888 }
16889 } else {
16890 // create unordered list
16891 for (var _i8 = 0, _len8 = itemIds.length; _i8 < _len8; _i8++) {
16892 var _id5 = itemIds[_i8];
16893 item = data.get(_id5);
16894 ids.push(item[this._idProp]);
16895 }
16896 }
16897 }
16898
16899 return ids;
16900 }
16901 /** @inheritdoc */
16902
16903 }, {
16904 key: "getDataSet",
16905 value: function getDataSet() {
16906 return this;
16907 }
16908 /** @inheritdoc */
16909
16910 }, {
16911 key: "forEach",
16912 value: function forEach(callback, options) {
16913 var filter = options && options.filter;
16914 var type = options && options.type || this._options.type;
16915 var data = this._data;
16916 var itemIds = toConsumableArray(data.keys());
16917
16918 if (options && options.order) {
16919 // execute forEach on ordered list
16920 var items = this.get(options);
16921
16922 for (var i = 0, len = items.length; i < len; i++) {
16923 var item = items[i];
16924 var id = item[this._idProp];
16925 callback(item, id);
16926 }
16927 } else {
16928 // unordered
16929 for (var _i9 = 0, _len9 = itemIds.length; _i9 < _len9; _i9++) {
16930 var _id6 = itemIds[_i9];
16931
16932 var _item = this._getItem(_id6, type);
16933
16934 if (!filter || filter(_item)) {
16935 callback(_item, _id6);
16936 }
16937 }
16938 }
16939 }
16940 /** @inheritdoc */
16941
16942 }, {
16943 key: "map",
16944 value: function map(callback, options) {
16945 var filter = options && options.filter;
16946 var type = options && options.type || this._options.type;
16947 var mappedItems = [];
16948 var data = this._data;
16949 var itemIds = toConsumableArray(data.keys()); // convert and filter items
16950
16951 for (var i = 0, len = itemIds.length; i < len; i++) {
16952 var id = itemIds[i];
16953
16954 var item = this._getItem(id, type);
16955
16956 if (!filter || filter(item)) {
16957 mappedItems.push(callback(item, id));
16958 }
16959 } // order items
16960
16961
16962 if (options && options.order) {
16963 this._sort(mappedItems, options.order);
16964 }
16965
16966 return mappedItems;
16967 }
16968 /**
16969 * Filter the fields of an item.
16970 *
16971 * @param item - The item whose fields should be filtered.
16972 * @param fields - The names of the fields that will be kept.
16973 *
16974 * @typeParam K - Field name type.
16975 *
16976 * @returns The item without any additional fields.
16977 */
16978
16979 }, {
16980 key: "_filterFields",
16981 value: function _filterFields(item, fields) {
16982 if (!item) {
16983 // item is null
16984 return item;
16985 }
16986
16987 return (Array.isArray(fields) ? // Use the supplied array
16988 fields : // Use the keys of the supplied object
16989 Object.keys(fields)).reduce(function (filteredItem, field) {
16990 filteredItem[field] = item[field];
16991 return filteredItem;
16992 }, {});
16993 }
16994 /**
16995 * Sort the provided array with items.
16996 *
16997 * @param items - Items to be sorted in place.
16998 * @param order - A field name or custom sort function.
16999 *
17000 * @typeParam T - The type of the items in the items array.
17001 */
17002
17003 }, {
17004 key: "_sort",
17005 value: function _sort(items, order) {
17006 if (typeof order === "string") {
17007 // order by provided field name
17008 var name = order; // field name
17009
17010 items.sort(function (a, b) {
17011 // @TODO: How to treat missing properties?
17012 var av = a[name];
17013 var bv = b[name];
17014 return av > bv ? 1 : av < bv ? -1 : 0;
17015 });
17016 } else if (typeof order === "function") {
17017 // order by sort function
17018 items.sort(order);
17019 } else {
17020 // TODO: extend order by an Object {field:string, direction:string}
17021 // where direction can be 'asc' or 'desc'
17022 throw new TypeError("Order must be a function or a string");
17023 }
17024 }
17025 /**
17026 * Remove an item or multiple items by “reference” (only the id is used) or by id.
17027 *
17028 * 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.
17029 *
17030 * 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.
17031 *
17032 * ## Example
17033 * ```javascript
17034 * // create a DataSet
17035 * const data = new vis.DataSet([
17036 * { id: 1, text: 'item 1' },
17037 * { id: 2, text: 'item 2' },
17038 * { id: 3, text: 'item 3' }
17039 * ])
17040 *
17041 * // remove items
17042 * const ids = data.remove([2, { id: 3 }, 4])
17043 *
17044 * console.log(ids) // [2, 3]
17045 * ```
17046 *
17047 * @param id - One or more items or ids of items to be removed.
17048 * @param senderId - Sender id.
17049 *
17050 * @returns The ids of the removed items.
17051 */
17052
17053 }, {
17054 key: "remove",
17055 value: function remove(id, senderId) {
17056 var removedIds = [];
17057 var removedItems = []; // force everything to be an array for simplicity
17058
17059 var ids = Array.isArray(id) ? id : [id];
17060
17061 for (var i = 0, len = ids.length; i < len; i++) {
17062 var item = this._remove(ids[i]);
17063
17064 if (item) {
17065 var itemId = item[this._idProp];
17066
17067 if (itemId != null) {
17068 removedIds.push(itemId);
17069 removedItems.push(item);
17070 }
17071 }
17072 }
17073
17074 if (removedIds.length) {
17075 this._trigger("remove", {
17076 items: removedIds,
17077 oldData: removedItems
17078 }, senderId);
17079 }
17080
17081 return removedIds;
17082 }
17083 /**
17084 * Remove an item by its id or reference.
17085 *
17086 * @param id - Id of an item or the item itself.
17087 *
17088 * @returns The removed item if removed, null otherwise.
17089 */
17090
17091 }, {
17092 key: "_remove",
17093 value: function _remove(id) {
17094 // @TODO: It origianlly returned the item although the docs say id.
17095 // The code expects the item, so probably an error in the docs.
17096 var ident; // confirm the id to use based on the args type
17097
17098 if (isId(id)) {
17099 ident = id;
17100 } else if (id && _typeof_1(id) === "object") {
17101 ident = id[this._idProp]; // look for the identifier field using ._idProp
17102 } // do the removing if the item is found
17103
17104
17105 if (ident != null && this._data.has(ident)) {
17106 var item = this._data.get(ident) || null;
17107
17108 this._data.delete(ident);
17109
17110 --this.length;
17111 return item;
17112 }
17113
17114 return null;
17115 }
17116 /**
17117 * Clear the entire data set.
17118 *
17119 * 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.
17120 *
17121 * @param senderId - Sender id.
17122 *
17123 * @returns removedIds - The ids of all removed items.
17124 */
17125
17126 }, {
17127 key: "clear",
17128 value: function clear(senderId) {
17129 var ids = toConsumableArray(this._data.keys());
17130 var items = [];
17131
17132 for (var i = 0, len = ids.length; i < len; i++) {
17133 items.push(this._data.get(ids[i]));
17134 }
17135
17136 this._data.clear();
17137
17138 this.length = 0;
17139
17140 this._trigger("remove", {
17141 items: ids,
17142 oldData: items
17143 }, senderId);
17144
17145 return ids;
17146 }
17147 /**
17148 * Find the item with maximum value of a specified field.
17149 *
17150 * @param field - Name of the property that should be searched for max value.
17151 *
17152 * @returns Item containing max value, or null if no items.
17153 */
17154
17155 }, {
17156 key: "max",
17157 value: function max(field) {
17158 var max = null;
17159 var maxField = null;
17160 var _iteratorNormalCompletion = true;
17161 var _didIteratorError = false;
17162 var _iteratorError = undefined;
17163
17164 try {
17165 for (var _iterator = this._data.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
17166 var item = _step.value;
17167 var itemField = item[field];
17168
17169 if (typeof itemField === "number" && (maxField == null || itemField > maxField)) {
17170 max = item;
17171 maxField = itemField;
17172 }
17173 }
17174 } catch (err) {
17175 _didIteratorError = true;
17176 _iteratorError = err;
17177 } finally {
17178 try {
17179 if (!_iteratorNormalCompletion && _iterator.return != null) {
17180 _iterator.return();
17181 }
17182 } finally {
17183 if (_didIteratorError) {
17184 throw _iteratorError;
17185 }
17186 }
17187 }
17188
17189 return max || null;
17190 }
17191 /**
17192 * Find the item with minimum value of a specified field.
17193 *
17194 * @param field - Name of the property that should be searched for min value.
17195 *
17196 * @returns Item containing min value, or null if no items.
17197 */
17198
17199 }, {
17200 key: "min",
17201 value: function min(field) {
17202 var min = null;
17203 var minField = null;
17204 var _iteratorNormalCompletion2 = true;
17205 var _didIteratorError2 = false;
17206 var _iteratorError2 = undefined;
17207
17208 try {
17209 for (var _iterator2 = this._data.values()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
17210 var item = _step2.value;
17211 var itemField = item[field];
17212
17213 if (typeof itemField === "number" && (minField == null || itemField < minField)) {
17214 min = item;
17215 minField = itemField;
17216 }
17217 }
17218 } catch (err) {
17219 _didIteratorError2 = true;
17220 _iteratorError2 = err;
17221 } finally {
17222 try {
17223 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
17224 _iterator2.return();
17225 }
17226 } finally {
17227 if (_didIteratorError2) {
17228 throw _iteratorError2;
17229 }
17230 }
17231 }
17232
17233 return min || null;
17234 }
17235 /**
17236 * Find all distinct values of a specified field
17237 *
17238 * @param prop - The property name whose distinct values should be returned.
17239 *
17240 * @returns Unordered array containing all distinct values. Items without specified property are ignored.
17241 */
17242
17243 }, {
17244 key: "distinct",
17245 value: function distinct(prop) {
17246 var data = this._data;
17247 var itemIds = toConsumableArray(data.keys());
17248 var values = [];
17249 var fieldType = this._options.type && this._options.type[prop] || null;
17250 var count = 0;
17251
17252 for (var i = 0, len = itemIds.length; i < len; i++) {
17253 var id = itemIds[i];
17254 var item = data.get(id);
17255 var value = item[prop];
17256 var exists = false;
17257
17258 for (var j = 0; j < count; j++) {
17259 if (values[j] == value) {
17260 exists = true;
17261 break;
17262 }
17263 }
17264
17265 if (!exists && value !== undefined) {
17266 values[count] = value;
17267 count++;
17268 }
17269 }
17270
17271 if (fieldType) {
17272 for (var _i10 = 0, _len10 = values.length; _i10 < _len10; _i10++) {
17273 values[_i10] = convert$1(values[_i10], fieldType);
17274 }
17275 }
17276
17277 return values;
17278 }
17279 /**
17280 * Add a single item. Will fail when an item with the same id already exists.
17281 *
17282 * @param item - A new item to be added.
17283 *
17284 * @returns Added item's id. An id is generated when it is not present in the item.
17285 */
17286
17287 }, {
17288 key: "_addItem",
17289 value: function _addItem(item) {
17290 var id = item[this._idProp];
17291
17292 if (id != null) {
17293 // check whether this id is already taken
17294 if (this._data.has(id)) {
17295 // item already exists
17296 throw new Error("Cannot add item: item with id " + id + " already exists");
17297 }
17298 } else {
17299 // generate an id
17300 id = uuid4$1();
17301 item[this._idProp] = id;
17302 }
17303
17304 var d = {};
17305 var fields = Object.keys(item);
17306
17307 for (var i = 0, len = fields.length; i < len; i++) {
17308 var field = fields[i];
17309 var fieldType = this._type[field]; // type may be undefined
17310
17311 d[field] = convert$1(item[field], fieldType);
17312 }
17313
17314 this._data.set(id, d);
17315
17316 ++this.length;
17317 return id;
17318 }
17319 /**
17320 * Get an item. Fields can be converted to a specific type
17321 *
17322 * @param id - Id of the requested item.
17323 * @param types - Property name to type name object map of type converstions.
17324 *
17325 * @returns The item, optionally after type conversion.
17326 */
17327
17328 }, {
17329 key: "_getItem",
17330 value: function _getItem(id, types) {
17331 // @TODO: I have no idea how to type this.
17332 // get the item from the dataset
17333 var raw = this._data.get(id);
17334
17335 if (!raw) {
17336 return null;
17337 } // convert the items field types
17338
17339
17340 var converted;
17341 var fields = Object.keys(raw);
17342
17343 if (types) {
17344 converted = {};
17345
17346 for (var i = 0, len = fields.length; i < len; i++) {
17347 var field = fields[i];
17348 var value = raw[field];
17349 converted[field] = convert$1(value, types[field]);
17350 }
17351 } else {
17352 // no field types specified, no converting needed
17353 converted = _objectSpread({}, raw);
17354 }
17355
17356 if (converted[this._idProp] == null) {
17357 converted[this._idProp] = raw.id;
17358 }
17359
17360 return converted;
17361 }
17362 /**
17363 * Update a single item: merge with existing item.
17364 * Will fail when the item has no id, or when there does not exist an item with the same id.
17365 *
17366 * @param item - The new item
17367 *
17368 * @returns The id of the updated item.
17369 */
17370
17371 }, {
17372 key: "_updateItem",
17373 value: function _updateItem(item) {
17374 var id = item[this._idProp];
17375
17376 if (id == null) {
17377 throw new Error("Cannot update item: item has no id (item: " + JSON.stringify(item) + ")");
17378 }
17379
17380 var d = this._data.get(id);
17381
17382 if (!d) {
17383 // item doesn't exist
17384 throw new Error("Cannot update item: no item with id " + id + " found");
17385 } // merge with current item
17386
17387
17388 var fields = Object.keys(item);
17389
17390 for (var i = 0, len = fields.length; i < len; i++) {
17391 var field = fields[i];
17392 var fieldType = this._type[field]; // type may be undefined
17393
17394 d[field] = convert$1(item[field], fieldType);
17395 }
17396
17397 return id;
17398 }
17399 /** @inheritdoc */
17400
17401 }, {
17402 key: "stream",
17403 value: function stream(ids) {
17404 if (ids) {
17405 var data = this._data;
17406 return new DataStream(defineProperty$1({}, Symbol.iterator,
17407 /*#__PURE__*/
17408 regenerator.mark(function _callee() {
17409 var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, id, item;
17410
17411 return regenerator.wrap(function _callee$(_context) {
17412 while (1) {
17413 switch (_context.prev = _context.next) {
17414 case 0:
17415 _iteratorNormalCompletion3 = true;
17416 _didIteratorError3 = false;
17417 _iteratorError3 = undefined;
17418 _context.prev = 3;
17419 _iterator3 = ids[Symbol.iterator]();
17420
17421 case 5:
17422 if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
17423 _context.next = 14;
17424 break;
17425 }
17426
17427 id = _step3.value;
17428 item = data.get(id);
17429
17430 if (!(item != null)) {
17431 _context.next = 11;
17432 break;
17433 }
17434
17435 _context.next = 11;
17436 return [id, item];
17437
17438 case 11:
17439 _iteratorNormalCompletion3 = true;
17440 _context.next = 5;
17441 break;
17442
17443 case 14:
17444 _context.next = 20;
17445 break;
17446
17447 case 16:
17448 _context.prev = 16;
17449 _context.t0 = _context["catch"](3);
17450 _didIteratorError3 = true;
17451 _iteratorError3 = _context.t0;
17452
17453 case 20:
17454 _context.prev = 20;
17455 _context.prev = 21;
17456
17457 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
17458 _iterator3.return();
17459 }
17460
17461 case 23:
17462 _context.prev = 23;
17463
17464 if (!_didIteratorError3) {
17465 _context.next = 26;
17466 break;
17467 }
17468
17469 throw _iteratorError3;
17470
17471 case 26:
17472 return _context.finish(23);
17473
17474 case 27:
17475 return _context.finish(20);
17476
17477 case 28:
17478 case "end":
17479 return _context.stop();
17480 }
17481 }
17482 }, _callee, null, [[3, 16, 20, 28], [21,, 23, 27]]);
17483 })));
17484 } else {
17485 return new DataStream(defineProperty$1({}, Symbol.iterator, this._data.entries.bind(this._data)));
17486 }
17487 }
17488 }]);
17489 return DataSet;
17490}(DataSetPart);
17491/**
17492 * DataView
17493 *
17494 * 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.
17495 *
17496 * ## Example
17497 * ```javascript
17498 * // create a DataSet
17499 * var data = new vis.DataSet();
17500 * data.add([
17501 * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
17502 * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
17503 * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
17504 * {id: 4, text: 'item 4'}
17505 * ]);
17506 *
17507 * // create a DataView
17508 * // the view will only contain items having a property group with value 1,
17509 * // and will only output fields id, text, and date.
17510 * var view = new vis.DataView(data, {
17511 * filter: function (item) {
17512 * return (item.group == 1);
17513 * },
17514 * fields: ['id', 'text', 'date']
17515 * });
17516 *
17517 * // subscribe to any change in the DataView
17518 * view.on('*', function (event, properties, senderId) {
17519 * console.log('event', event, properties);
17520 * });
17521 *
17522 * // update an item in the data set
17523 * data.update({id: 2, group: 1});
17524 *
17525 * // get all ids in the view
17526 * var ids = view.getIds();
17527 * console.log('ids', ids); // will output [1, 2]
17528 *
17529 * // get all items in the view
17530 * var items = view.get();
17531 * ```
17532 *
17533 * @typeParam Item - Item type that may or may not have an id.
17534 * @typeParam IdProp - Name of the property that contains the id.
17535 */
17536
17537
17538var DataView =
17539/*#__PURE__*/
17540function (_DataSetPart) {
17541 inherits(DataView, _DataSetPart);
17542 /**
17543 * Create a DataView.
17544 *
17545 * @param data - The instance containing data (directly or indirectly).
17546 * @param options - Options to configure this data view.
17547 */
17548
17549 function DataView(data, options) {
17550 var _this;
17551
17552 classCallCheck(this, DataView);
17553 _this = possibleConstructorReturn(this, getPrototypeOf(DataView).call(this));
17554 /** @inheritdoc */
17555
17556 _this.length = 0;
17557 _this._ids = new Set(); // ids of the items currently in memory (just contains a boolean true)
17558
17559 _this._options = options || {};
17560 _this._listener = _this._onEvent.bind(assertThisInitialized(_this));
17561
17562 _this.setData(data);
17563
17564 return _this;
17565 } // TODO: implement a function .config() to dynamically update things like configured filter
17566 // and trigger changes accordingly
17567
17568 /**
17569 * Set a data source for the view.
17570 *
17571 * @param data - The instance containing data (directly or indirectly).
17572 */
17573
17574
17575 createClass(DataView, [{
17576 key: "setData",
17577 value: function setData(data) {
17578 if (this._data) {
17579 // unsubscribe from current dataset
17580 if (this._data.off) {
17581 this._data.off("*", this._listener);
17582 } // trigger a remove of all items in memory
17583
17584
17585 var ids = this._data.getIds({
17586 filter: this._options.filter
17587 });
17588
17589 var items = this._data.get(ids);
17590
17591 this._ids.clear();
17592
17593 this.length = 0;
17594
17595 this._trigger("remove", {
17596 items: ids,
17597 oldData: items
17598 });
17599 }
17600
17601 if (data != null) {
17602 this._data = data; // trigger an add of all added items
17603
17604 var _ids = this._data.getIds({
17605 filter: this._options.filter
17606 });
17607
17608 for (var i = 0, len = _ids.length; i < len; i++) {
17609 var id = _ids[i];
17610
17611 this._ids.add(id);
17612 }
17613
17614 this.length = _ids.length;
17615
17616 this._trigger("add", {
17617 items: _ids
17618 });
17619 } else {
17620 this._data = new DataSet();
17621 } // subscribe to new dataset
17622
17623
17624 if (this._data.on) {
17625 this._data.on("*", this._listener);
17626 }
17627 }
17628 /**
17629 * Refresh the DataView.
17630 * Useful when the DataView has a filter function containing a variable parameter.
17631 */
17632
17633 }, {
17634 key: "refresh",
17635 value: function refresh() {
17636 var ids = this._data.getIds({
17637 filter: this._options.filter
17638 });
17639
17640 var oldIds = toConsumableArray(this._ids);
17641 var newIds = {};
17642 var addedIds = [];
17643 var removedIds = [];
17644 var removedItems = []; // check for additions
17645
17646 for (var i = 0, len = ids.length; i < len; i++) {
17647 var id = ids[i];
17648 newIds[id] = true;
17649
17650 if (!this._ids.has(id)) {
17651 addedIds.push(id);
17652
17653 this._ids.add(id);
17654 }
17655 } // check for removals
17656
17657
17658 for (var _i = 0, _len = oldIds.length; _i < _len; _i++) {
17659 var _id = oldIds[_i];
17660
17661 var item = this._data.get(_id);
17662
17663 if (item == null) {
17664 // @TODO: Investigate.
17665 // Doesn't happen during tests or examples.
17666 // Is it really impossible or could it eventually happen?
17667 // How to handle it if it does? The types guarantee non-nullable items.
17668 console.error("If you see this, report it please.");
17669 } else if (!newIds[_id]) {
17670 removedIds.push(_id);
17671 removedItems.push(item);
17672
17673 this._ids.delete(_id);
17674 }
17675 }
17676
17677 this.length += addedIds.length - removedIds.length; // trigger events
17678
17679 if (addedIds.length) {
17680 this._trigger("add", {
17681 items: addedIds
17682 });
17683 }
17684
17685 if (removedIds.length) {
17686 this._trigger("remove", {
17687 items: removedIds,
17688 oldData: removedItems
17689 });
17690 }
17691 }
17692 /** @inheritdoc */
17693
17694 }, {
17695 key: "get",
17696 value: function get(first, second) {
17697 if (this._data == null) {
17698 return null;
17699 } // parse the arguments
17700
17701
17702 var ids = null;
17703 var options;
17704
17705 if (isId(first) || Array.isArray(first)) {
17706 ids = first;
17707 options = second;
17708 } else {
17709 options = first;
17710 } // extend the options with the default options and provided options
17711
17712
17713 var viewOptions = Object.assign({}, this._options, options); // create a combined filter method when needed
17714
17715 var thisFilter = this._options.filter;
17716 var optionsFilter = options && options.filter;
17717
17718 if (thisFilter && optionsFilter) {
17719 viewOptions.filter = function (item) {
17720 return thisFilter(item) && optionsFilter(item);
17721 };
17722 }
17723
17724 if (ids == null) {
17725 return this._data.get(viewOptions);
17726 } else {
17727 return this._data.get(ids, viewOptions);
17728 }
17729 }
17730 /** @inheritdoc */
17731
17732 }, {
17733 key: "getIds",
17734 value: function getIds(options) {
17735 if (this._data.length) {
17736 var defaultFilter = this._options.filter;
17737 var optionsFilter = options != null ? options.filter : null;
17738 var filter;
17739
17740 if (optionsFilter) {
17741 if (defaultFilter) {
17742 filter = function filter(item) {
17743 return defaultFilter(item) && optionsFilter(item);
17744 };
17745 } else {
17746 filter = optionsFilter;
17747 }
17748 } else {
17749 filter = defaultFilter;
17750 }
17751
17752 return this._data.getIds({
17753 filter: filter,
17754 order: options && options.order
17755 });
17756 } else {
17757 return [];
17758 }
17759 }
17760 /** @inheritdoc */
17761
17762 }, {
17763 key: "forEach",
17764 value: function forEach(callback, options) {
17765 if (this._data) {
17766 var defaultFilter = this._options.filter;
17767 var optionsFilter = options && options.filter;
17768 var filter;
17769
17770 if (optionsFilter) {
17771 if (defaultFilter) {
17772 filter = function filter(item) {
17773 return defaultFilter(item) && optionsFilter(item);
17774 };
17775 } else {
17776 filter = optionsFilter;
17777 }
17778 } else {
17779 filter = defaultFilter;
17780 }
17781
17782 this._data.forEach(callback, {
17783 filter: filter,
17784 order: options && options.order
17785 });
17786 }
17787 }
17788 /** @inheritdoc */
17789
17790 }, {
17791 key: "map",
17792 value: function map(callback, options) {
17793 if (this._data) {
17794 var defaultFilter = this._options.filter;
17795 var optionsFilter = options && options.filter;
17796 var filter;
17797
17798 if (optionsFilter) {
17799 if (defaultFilter) {
17800 filter = function filter(item) {
17801 return defaultFilter(item) && optionsFilter(item);
17802 };
17803 } else {
17804 filter = optionsFilter;
17805 }
17806 } else {
17807 filter = defaultFilter;
17808 }
17809
17810 return this._data.map(callback, {
17811 filter: filter,
17812 order: options && options.order
17813 });
17814 } else {
17815 return [];
17816 }
17817 }
17818 /** @inheritdoc */
17819
17820 }, {
17821 key: "getDataSet",
17822 value: function getDataSet() {
17823 return this._data.getDataSet();
17824 }
17825 /** @inheritdoc */
17826
17827 }, {
17828 key: "stream",
17829 value: function stream(ids) {
17830 return this._data.stream(ids || defineProperty$1({}, Symbol.iterator, this._ids.keys.bind(this._ids)));
17831 }
17832 /**
17833 * 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.
17834 *
17835 * @param event - The name of the event.
17836 * @param params - Parameters of the event.
17837 * @param senderId - Id supplied by the sender.
17838 */
17839
17840 }, {
17841 key: "_onEvent",
17842 value: function _onEvent(event, params, senderId) {
17843 if (!params || !params.items || !this._data) {
17844 return;
17845 }
17846
17847 var ids = params.items;
17848 var addedIds = [];
17849 var updatedIds = [];
17850 var removedIds = [];
17851 var oldItems = [];
17852 var updatedItems = [];
17853 var removedItems = [];
17854
17855 switch (event) {
17856 case "add":
17857 // filter the ids of the added items
17858 for (var i = 0, len = ids.length; i < len; i++) {
17859 var id = ids[i];
17860 var item = this.get(id);
17861
17862 if (item) {
17863 this._ids.add(id);
17864
17865 addedIds.push(id);
17866 }
17867 }
17868
17869 break;
17870
17871 case "update":
17872 // determine the event from the views viewpoint: an updated
17873 // item can be added, updated, or removed from this view.
17874 for (var _i2 = 0, _len2 = ids.length; _i2 < _len2; _i2++) {
17875 var _id2 = ids[_i2];
17876
17877 var _item = this.get(_id2);
17878
17879 if (_item) {
17880 if (this._ids.has(_id2)) {
17881 updatedIds.push(_id2);
17882 updatedItems.push(params.data[_i2]);
17883 oldItems.push(params.oldData[_i2]);
17884 } else {
17885 this._ids.add(_id2);
17886
17887 addedIds.push(_id2);
17888 }
17889 } else {
17890 if (this._ids.has(_id2)) {
17891 this._ids.delete(_id2);
17892
17893 removedIds.push(_id2);
17894 removedItems.push(params.oldData[_i2]);
17895 }
17896 }
17897 }
17898
17899 break;
17900
17901 case "remove":
17902 // filter the ids of the removed items
17903 for (var _i3 = 0, _len3 = ids.length; _i3 < _len3; _i3++) {
17904 var _id3 = ids[_i3];
17905
17906 if (this._ids.has(_id3)) {
17907 this._ids.delete(_id3);
17908
17909 removedIds.push(_id3);
17910 removedItems.push(params.oldData[_i3]);
17911 }
17912 }
17913
17914 break;
17915 }
17916
17917 this.length += addedIds.length - removedIds.length;
17918
17919 if (addedIds.length) {
17920 this._trigger("add", {
17921 items: addedIds
17922 }, senderId);
17923 }
17924
17925 if (updatedIds.length) {
17926 this._trigger("update", {
17927 items: updatedIds,
17928 oldData: oldItems,
17929 data: updatedItems
17930 }, senderId);
17931 }
17932
17933 if (removedIds.length) {
17934 this._trigger("remove", {
17935 items: removedIds,
17936 oldData: removedItems
17937 }, senderId);
17938 }
17939 }
17940 }]);
17941 return DataView;
17942}(DataSetPart);
17943
17944var index = {
17945 DataSet: DataSet,
17946 DataView: DataView,
17947 Queue: Queue
17948};
17949
17950/**
17951 * Expose `Emitter`.
17952 */
17953var emitterComponent = Emitter;
17954/**
17955 * Initialize a new `Emitter`.
17956 *
17957 * @api public
17958 */
17959
17960function Emitter(obj) {
17961 if (obj) return mixin(obj);
17962}
17963/**
17964 * Mixin the emitter properties.
17965 *
17966 * @param {Object} obj
17967 * @return {Object}
17968 * @api private
17969 */
17970
17971function mixin(obj) {
17972 for (var key in Emitter.prototype) {
17973 obj[key] = Emitter.prototype[key];
17974 }
17975
17976 return obj;
17977}
17978/**
17979 * Listen on the given `event` with `fn`.
17980 *
17981 * @param {String} event
17982 * @param {Function} fn
17983 * @return {Emitter}
17984 * @api public
17985 */
17986
17987
17988Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
17989 this._callbacks = this._callbacks || {};
17990 (this._callbacks[event] = this._callbacks[event] || []).push(fn);
17991 return this;
17992};
17993/**
17994 * Adds an `event` listener that will be invoked a single
17995 * time then automatically removed.
17996 *
17997 * @param {String} event
17998 * @param {Function} fn
17999 * @return {Emitter}
18000 * @api public
18001 */
18002
18003
18004Emitter.prototype.once = function (event, fn) {
18005 var self = this;
18006 this._callbacks = this._callbacks || {};
18007
18008 function on() {
18009 self.off(event, on);
18010 fn.apply(this, arguments);
18011 }
18012
18013 on.fn = fn;
18014 this.on(event, on);
18015 return this;
18016};
18017/**
18018 * Remove the given callback for `event` or all
18019 * registered callbacks.
18020 *
18021 * @param {String} event
18022 * @param {Function} fn
18023 * @return {Emitter}
18024 * @api public
18025 */
18026
18027
18028Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
18029 this._callbacks = this._callbacks || {}; // all
18030
18031 if (0 == arguments.length) {
18032 this._callbacks = {};
18033 return this;
18034 } // specific event
18035
18036
18037 var callbacks = this._callbacks[event];
18038 if (!callbacks) return this; // remove all handlers
18039
18040 if (1 == arguments.length) {
18041 delete this._callbacks[event];
18042 return this;
18043 } // remove specific handler
18044
18045
18046 var cb;
18047
18048 for (var i = 0; i < callbacks.length; i++) {
18049 cb = callbacks[i];
18050
18051 if (cb === fn || cb.fn === fn) {
18052 callbacks.splice(i, 1);
18053 break;
18054 }
18055 }
18056
18057 return this;
18058};
18059/**
18060 * Emit `event` with the given args.
18061 *
18062 * @param {String} event
18063 * @param {Mixed} ...
18064 * @return {Emitter}
18065 */
18066
18067
18068Emitter.prototype.emit = function (event) {
18069 this._callbacks = this._callbacks || {};
18070 var args = [].slice.call(arguments, 1),
18071 callbacks = this._callbacks[event];
18072
18073 if (callbacks) {
18074 callbacks = callbacks.slice(0);
18075
18076 for (var i = 0, len = callbacks.length; i < len; ++i) {
18077 callbacks[i].apply(this, args);
18078 }
18079 }
18080
18081 return this;
18082};
18083/**
18084 * Return array of callbacks for `event`.
18085 *
18086 * @param {String} event
18087 * @return {Array}
18088 * @api public
18089 */
18090
18091
18092Emitter.prototype.listeners = function (event) {
18093 this._callbacks = this._callbacks || {};
18094 return this._callbacks[event] || [];
18095};
18096/**
18097 * Check if this emitter has `event` handlers.
18098 *
18099 * @param {String} event
18100 * @return {Boolean}
18101 * @api public
18102 */
18103
18104
18105Emitter.prototype.hasListeners = function (event) {
18106 return !!this.listeners(event).length;
18107};
18108
18109/**
18110 * @prototype Point3d
18111 * @param {number} [x]
18112 * @param {number} [y]
18113 * @param {number} [z]
18114 */
18115function Point3d(x, y, z) {
18116 this.x = x !== undefined ? x : 0;
18117 this.y = y !== undefined ? y : 0;
18118 this.z = z !== undefined ? z : 0;
18119}
18120/**
18121 * Subtract the two provided points, returns a-b
18122 * @param {Point3d} a
18123 * @param {Point3d} b
18124 * @return {Point3d} a-b
18125 */
18126
18127
18128Point3d.subtract = function (a, b) {
18129 var sub = new Point3d();
18130 sub.x = a.x - b.x;
18131 sub.y = a.y - b.y;
18132 sub.z = a.z - b.z;
18133 return sub;
18134};
18135/**
18136 * Add the two provided points, returns a+b
18137 * @param {Point3d} a
18138 * @param {Point3d} b
18139 * @return {Point3d} a+b
18140 */
18141
18142
18143Point3d.add = function (a, b) {
18144 var sum = new Point3d();
18145 sum.x = a.x + b.x;
18146 sum.y = a.y + b.y;
18147 sum.z = a.z + b.z;
18148 return sum;
18149};
18150/**
18151 * Calculate the average of two 3d points
18152 * @param {Point3d} a
18153 * @param {Point3d} b
18154 * @return {Point3d} The average, (a+b)/2
18155 */
18156
18157
18158Point3d.avg = function (a, b) {
18159 return new Point3d((a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2);
18160};
18161/**
18162 * Calculate the cross product of the two provided points, returns axb
18163 * Documentation: http://en.wikipedia.org/wiki/Cross_product
18164 * @param {Point3d} a
18165 * @param {Point3d} b
18166 * @return {Point3d} cross product axb
18167 */
18168
18169
18170Point3d.crossProduct = function (a, b) {
18171 var crossproduct = new Point3d();
18172 crossproduct.x = a.y * b.z - a.z * b.y;
18173 crossproduct.y = a.z * b.x - a.x * b.z;
18174 crossproduct.z = a.x * b.y - a.y * b.x;
18175 return crossproduct;
18176};
18177/**
18178 * Rtrieve the length of the vector (or the distance from this point to the origin
18179 * @return {number} length
18180 */
18181
18182
18183Point3d.prototype.length = function () {
18184 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
18185};
18186
18187var Point3d_1 = Point3d;
18188
18189/**
18190 * @prototype Point2d
18191 * @param {number} [x]
18192 * @param {number} [y]
18193 */
18194function Point2d(x, y) {
18195 this.x = x !== undefined ? x : 0;
18196 this.y = y !== undefined ? y : 0;
18197}
18198
18199var Point2d_1 = Point2d;
18200
18201/**
18202 * An html slider control with start/stop/prev/next buttons
18203 *
18204 * @constructor Slider
18205 * @param {Element} container The element where the slider will be created
18206 * @param {Object} options Available options:
18207 * {boolean} visible If true (default) the
18208 * slider is visible.
18209 */
18210
18211function Slider(container, options) {
18212 if (container === undefined) {
18213 throw new Error('No container element defined');
18214 }
18215
18216 this.container = container;
18217 this.visible = options && options.visible != undefined ? options.visible : true;
18218
18219 if (this.visible) {
18220 this.frame = document.createElement('DIV'); //this.frame.style.backgroundColor = '#E5E5E5';
18221
18222 this.frame.style.width = '100%';
18223 this.frame.style.position = 'relative';
18224 this.container.appendChild(this.frame);
18225 this.frame.prev = document.createElement('INPUT');
18226 this.frame.prev.type = 'BUTTON';
18227 this.frame.prev.value = 'Prev';
18228 this.frame.appendChild(this.frame.prev);
18229 this.frame.play = document.createElement('INPUT');
18230 this.frame.play.type = 'BUTTON';
18231 this.frame.play.value = 'Play';
18232 this.frame.appendChild(this.frame.play);
18233 this.frame.next = document.createElement('INPUT');
18234 this.frame.next.type = 'BUTTON';
18235 this.frame.next.value = 'Next';
18236 this.frame.appendChild(this.frame.next);
18237 this.frame.bar = document.createElement('INPUT');
18238 this.frame.bar.type = 'BUTTON';
18239 this.frame.bar.style.position = 'absolute';
18240 this.frame.bar.style.border = '1px solid red';
18241 this.frame.bar.style.width = '100px';
18242 this.frame.bar.style.height = '6px';
18243 this.frame.bar.style.borderRadius = '2px';
18244 this.frame.bar.style.MozBorderRadius = '2px';
18245 this.frame.bar.style.border = '1px solid #7F7F7F';
18246 this.frame.bar.style.backgroundColor = '#E5E5E5';
18247 this.frame.appendChild(this.frame.bar);
18248 this.frame.slide = document.createElement('INPUT');
18249 this.frame.slide.type = 'BUTTON';
18250 this.frame.slide.style.margin = '0px';
18251 this.frame.slide.value = ' ';
18252 this.frame.slide.style.position = 'relative';
18253 this.frame.slide.style.left = '-100px';
18254 this.frame.appendChild(this.frame.slide); // create events
18255
18256 var me = this;
18257
18258 this.frame.slide.onmousedown = function (event) {
18259 me._onMouseDown(event);
18260 };
18261
18262 this.frame.prev.onclick = function (event) {
18263 me.prev(event);
18264 };
18265
18266 this.frame.play.onclick = function (event) {
18267 me.togglePlay(event);
18268 };
18269
18270 this.frame.next.onclick = function (event) {
18271 me.next(event);
18272 };
18273 }
18274
18275 this.onChangeCallback = undefined;
18276 this.values = [];
18277 this.index = undefined;
18278 this.playTimeout = undefined;
18279 this.playInterval = 1000; // milliseconds
18280
18281 this.playLoop = true;
18282}
18283/**
18284 * Select the previous index
18285 */
18286
18287
18288Slider.prototype.prev = function () {
18289 var index = this.getIndex();
18290
18291 if (index > 0) {
18292 index--;
18293 this.setIndex(index);
18294 }
18295};
18296/**
18297 * Select the next index
18298 */
18299
18300
18301Slider.prototype.next = function () {
18302 var index = this.getIndex();
18303
18304 if (index < this.values.length - 1) {
18305 index++;
18306 this.setIndex(index);
18307 }
18308};
18309/**
18310 * Select the next index
18311 */
18312
18313
18314Slider.prototype.playNext = function () {
18315 var start = new Date();
18316 var index = this.getIndex();
18317
18318 if (index < this.values.length - 1) {
18319 index++;
18320 this.setIndex(index);
18321 } else if (this.playLoop) {
18322 // jump to the start
18323 index = 0;
18324 this.setIndex(index);
18325 }
18326
18327 var end = new Date();
18328 var diff = end - start; // calculate how much time it to to set the index and to execute the callback
18329 // function.
18330
18331 var interval = Math.max(this.playInterval - diff, 0); // document.title = diff // TODO: cleanup
18332
18333 var me = this;
18334 this.playTimeout = setTimeout(function () {
18335 me.playNext();
18336 }, interval);
18337};
18338/**
18339 * Toggle start or stop playing
18340 */
18341
18342
18343Slider.prototype.togglePlay = function () {
18344 if (this.playTimeout === undefined) {
18345 this.play();
18346 } else {
18347 this.stop();
18348 }
18349};
18350/**
18351 * Start playing
18352 */
18353
18354
18355Slider.prototype.play = function () {
18356 // Test whether already playing
18357 if (this.playTimeout) return;
18358 this.playNext();
18359
18360 if (this.frame) {
18361 this.frame.play.value = 'Stop';
18362 }
18363};
18364/**
18365 * Stop playing
18366 */
18367
18368
18369Slider.prototype.stop = function () {
18370 clearInterval(this.playTimeout);
18371 this.playTimeout = undefined;
18372
18373 if (this.frame) {
18374 this.frame.play.value = 'Play';
18375 }
18376};
18377/**
18378 * Set a callback function which will be triggered when the value of the
18379 * slider bar has changed.
18380 *
18381 * @param {function} callback
18382 */
18383
18384
18385Slider.prototype.setOnChangeCallback = function (callback) {
18386 this.onChangeCallback = callback;
18387};
18388/**
18389 * Set the interval for playing the list
18390 * @param {number} interval The interval in milliseconds
18391 */
18392
18393
18394Slider.prototype.setPlayInterval = function (interval) {
18395 this.playInterval = interval;
18396};
18397/**
18398 * Retrieve the current play interval
18399 * @return {number} interval The interval in milliseconds
18400 */
18401
18402
18403Slider.prototype.getPlayInterval = function () {
18404 return this.playInterval;
18405};
18406/**
18407 * Set looping on or off
18408 * @param {boolean} doLoop If true, the slider will jump to the start when
18409 * the end is passed, and will jump to the end
18410 * when the start is passed.
18411 *
18412 */
18413
18414
18415Slider.prototype.setPlayLoop = function (doLoop) {
18416 this.playLoop = doLoop;
18417};
18418/**
18419 * Execute the onchange callback function
18420 */
18421
18422
18423Slider.prototype.onChange = function () {
18424 if (this.onChangeCallback !== undefined) {
18425 this.onChangeCallback();
18426 }
18427};
18428/**
18429 * redraw the slider on the correct place
18430 */
18431
18432
18433Slider.prototype.redraw = function () {
18434 if (this.frame) {
18435 // resize the bar
18436 this.frame.bar.style.top = this.frame.clientHeight / 2 - this.frame.bar.offsetHeight / 2 + 'px';
18437 this.frame.bar.style.width = this.frame.clientWidth - this.frame.prev.clientWidth - this.frame.play.clientWidth - this.frame.next.clientWidth - 30 + 'px'; // position the slider button
18438
18439 var left = this.indexToLeft(this.index);
18440 this.frame.slide.style.left = left + 'px';
18441 }
18442};
18443/**
18444 * Set the list with values for the slider
18445 * @param {Array} values A javascript array with values (any type)
18446 */
18447
18448
18449Slider.prototype.setValues = function (values) {
18450 this.values = values;
18451 if (this.values.length > 0) this.setIndex(0);else this.index = undefined;
18452};
18453/**
18454 * Select a value by its index
18455 * @param {number} index
18456 */
18457
18458
18459Slider.prototype.setIndex = function (index) {
18460 if (index < this.values.length) {
18461 this.index = index;
18462 this.redraw();
18463 this.onChange();
18464 } else {
18465 throw new Error('Index out of range');
18466 }
18467};
18468/**
18469 * retrieve the index of the currently selected vaue
18470 * @return {number} index
18471 */
18472
18473
18474Slider.prototype.getIndex = function () {
18475 return this.index;
18476};
18477/**
18478 * retrieve the currently selected value
18479 * @return {*} value
18480 */
18481
18482
18483Slider.prototype.get = function () {
18484 return this.values[this.index];
18485};
18486
18487Slider.prototype._onMouseDown = function (event) {
18488 // only react on left mouse button down
18489 var leftButtonDown = event.which ? event.which === 1 : event.button === 1;
18490 if (!leftButtonDown) return;
18491 this.startClientX = event.clientX;
18492 this.startSlideX = parseFloat(this.frame.slide.style.left);
18493 this.frame.style.cursor = 'move'; // add event listeners to handle moving the contents
18494 // we store the function onmousemove and onmouseup in the graph, so we can
18495 // remove the eventlisteners lateron in the function mouseUp()
18496
18497 var me = this;
18498
18499 this.onmousemove = function (event) {
18500 me._onMouseMove(event);
18501 };
18502
18503 this.onmouseup = function (event) {
18504 me._onMouseUp(event);
18505 };
18506
18507 util.addEventListener(document, 'mousemove', this.onmousemove);
18508 util.addEventListener(document, 'mouseup', this.onmouseup);
18509 util.preventDefault(event);
18510};
18511
18512Slider.prototype.leftToIndex = function (left) {
18513 var width = parseFloat(this.frame.bar.style.width) - this.frame.slide.clientWidth - 10;
18514 var x = left - 3;
18515 var index = Math.round(x / width * (this.values.length - 1));
18516 if (index < 0) index = 0;
18517 if (index > this.values.length - 1) index = this.values.length - 1;
18518 return index;
18519};
18520
18521Slider.prototype.indexToLeft = function (index) {
18522 var width = parseFloat(this.frame.bar.style.width) - this.frame.slide.clientWidth - 10;
18523 var x = index / (this.values.length - 1) * width;
18524 var left = x + 3;
18525 return left;
18526};
18527
18528Slider.prototype._onMouseMove = function (event) {
18529 var diff = event.clientX - this.startClientX;
18530 var x = this.startSlideX + diff;
18531 var index = this.leftToIndex(x);
18532 this.setIndex(index);
18533 util.preventDefault();
18534};
18535
18536Slider.prototype._onMouseUp = function (event) {
18537 // eslint-disable-line no-unused-vars
18538 this.frame.style.cursor = 'auto'; // remove event listeners
18539
18540 util.removeEventListener(document, 'mousemove', this.onmousemove);
18541 util.removeEventListener(document, 'mouseup', this.onmouseup);
18542 util.preventDefault();
18543};
18544
18545var Slider_1 = Slider;
18546
18547/**
18548 * @prototype StepNumber
18549 * The class StepNumber is an iterator for Numbers. You provide a start and end
18550 * value, and a best step size. StepNumber itself rounds to fixed values and
18551 * a finds the step that best fits the provided step.
18552 *
18553 * If prettyStep is true, the step size is chosen as close as possible to the
18554 * provided step, but being a round value like 1, 2, 5, 10, 20, 50, ....
18555 *
18556 * Example usage:
18557 * var step = new StepNumber(0, 10, 2.5, true);
18558 * step.start();
18559 * while (!step.end()) {
18560 * alert(step.getCurrent());
18561 * step.next();
18562 * }
18563 *
18564 * Version: 1.0
18565 *
18566 * @param {number} start The start value
18567 * @param {number} end The end value
18568 * @param {number} step Optional. Step size. Must be a positive value.
18569 * @param {boolean} prettyStep Optional. If true, the step size is rounded
18570 * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...)
18571 */
18572function StepNumber(start, end, step, prettyStep) {
18573 // set default values
18574 this._start = 0;
18575 this._end = 0;
18576 this._step = 1;
18577 this.prettyStep = true;
18578 this.precision = 5;
18579 this._current = 0;
18580 this.setRange(start, end, step, prettyStep);
18581}
18582/**
18583 * Check for input values, to prevent disasters from happening
18584 *
18585 * Source: http://stackoverflow.com/a/1830844
18586 *
18587 * @param {string} n
18588 * @returns {boolean}
18589 */
18590
18591
18592StepNumber.prototype.isNumeric = function (n) {
18593 return !isNaN(parseFloat(n)) && isFinite(n);
18594};
18595/**
18596 * Set a new range: start, end and step.
18597 *
18598 * @param {number} start The start value
18599 * @param {number} end The end value
18600 * @param {number} step Optional. Step size. Must be a positive value.
18601 * @param {boolean} prettyStep Optional. If true, the step size is rounded
18602 * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...)
18603 */
18604
18605
18606StepNumber.prototype.setRange = function (start, end, step, prettyStep) {
18607 if (!this.isNumeric(start)) {
18608 throw new Error('Parameter \'start\' is not numeric; value: ' + start);
18609 }
18610
18611 if (!this.isNumeric(end)) {
18612 throw new Error('Parameter \'end\' is not numeric; value: ' + start);
18613 }
18614
18615 if (!this.isNumeric(step)) {
18616 throw new Error('Parameter \'step\' is not numeric; value: ' + start);
18617 }
18618
18619 this._start = start ? start : 0;
18620 this._end = end ? end : 0;
18621 this.setStep(step, prettyStep);
18622};
18623/**
18624 * Set a new step size
18625 * @param {number} step New step size. Must be a positive value
18626 * @param {boolean} prettyStep Optional. If true, the provided step is rounded
18627 * to a pretty step size (like 1, 2, 5, 10, 20, 50, ...)
18628 */
18629
18630
18631StepNumber.prototype.setStep = function (step, prettyStep) {
18632 if (step === undefined || step <= 0) return;
18633 if (prettyStep !== undefined) this.prettyStep = prettyStep;
18634 if (this.prettyStep === true) this._step = StepNumber.calculatePrettyStep(step);else this._step = step;
18635};
18636/**
18637 * Calculate a nice step size, closest to the desired step size.
18638 * Returns a value in one of the ranges 1*10^n, 2*10^n, or 5*10^n, where n is an
18639 * integer Number. For example 1, 2, 5, 10, 20, 50, etc...
18640 * @param {number} step Desired step size
18641 * @return {number} Nice step size
18642 */
18643
18644
18645StepNumber.calculatePrettyStep = function (step) {
18646 var log10 = function log10(x) {
18647 return Math.log(x) / Math.LN10;
18648 }; // try three steps (multiple of 1, 2, or 5
18649
18650
18651 var step1 = Math.pow(10, Math.round(log10(step))),
18652 step2 = 2 * Math.pow(10, Math.round(log10(step / 2))),
18653 step5 = 5 * Math.pow(10, Math.round(log10(step / 5))); // choose the best step (closest to minimum step)
18654
18655 var prettyStep = step1;
18656 if (Math.abs(step2 - step) <= Math.abs(prettyStep - step)) prettyStep = step2;
18657 if (Math.abs(step5 - step) <= Math.abs(prettyStep - step)) prettyStep = step5; // for safety
18658
18659 if (prettyStep <= 0) {
18660 prettyStep = 1;
18661 }
18662
18663 return prettyStep;
18664};
18665/**
18666 * returns the current value of the step
18667 * @return {number} current value
18668 */
18669
18670
18671StepNumber.prototype.getCurrent = function () {
18672 return parseFloat(this._current.toPrecision(this.precision));
18673};
18674/**
18675 * returns the current step size
18676 * @return {number} current step size
18677 */
18678
18679
18680StepNumber.prototype.getStep = function () {
18681 return this._step;
18682};
18683/**
18684 * Set the current to its starting value.
18685 *
18686 * By default, this will be the largest value smaller than start, which
18687 * is a multiple of the step size.
18688 *
18689 * Parameters checkFirst is optional, default false.
18690 * If set to true, move the current value one step if smaller than start.
18691 *
18692 * @param {boolean} [checkFirst=false]
18693 */
18694
18695
18696StepNumber.prototype.start = function (checkFirst) {
18697 if (checkFirst === undefined) {
18698 checkFirst = false;
18699 }
18700
18701 this._current = this._start - this._start % this._step;
18702
18703 if (checkFirst) {
18704 if (this.getCurrent() < this._start) {
18705 this.next();
18706 }
18707 }
18708};
18709/**
18710 * Do a step, add the step size to the current value
18711 */
18712
18713
18714StepNumber.prototype.next = function () {
18715 this._current += this._step;
18716};
18717/**
18718 * Returns true whether the end is reached
18719 * @return {boolean} True if the current value has passed the end value.
18720 */
18721
18722
18723StepNumber.prototype.end = function () {
18724 return this._current > this._end;
18725};
18726
18727var StepNumber_1 = StepNumber;
18728
18729function _typeof$2(obj) {
18730 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
18731 _typeof$2 = function (obj) {
18732 return typeof obj;
18733 };
18734 } else {
18735 _typeof$2 = function (obj) {
18736 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
18737 };
18738 }
18739
18740 return _typeof$2(obj);
18741}
18742
18743function _classCallCheck$1(instance, Constructor) {
18744 if (!(instance instanceof Constructor)) {
18745 throw new TypeError("Cannot call a class as a function");
18746 }
18747}
18748
18749function _defineProperties$1(target, props) {
18750 for (var i = 0; i < props.length; i++) {
18751 var descriptor = props[i];
18752 descriptor.enumerable = descriptor.enumerable || false;
18753 descriptor.configurable = true;
18754 if ("value" in descriptor) descriptor.writable = true;
18755 Object.defineProperty(target, descriptor.key, descriptor);
18756 }
18757}
18758
18759function _createClass$1(Constructor, protoProps, staticProps) {
18760 if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
18761 if (staticProps) _defineProperties$1(Constructor, staticProps);
18762 return Constructor;
18763}
18764
18765/**
18766 * The camera is mounted on a (virtual) camera arm. The camera arm can rotate
18767 * The camera is always looking in the direction of the origin of the arm.
18768 * This way, the camera always rotates around one fixed point, the location
18769 * of the camera arm.
18770 *
18771 * Documentation:
18772 * http://en.wikipedia.org/wiki/3D_projection
18773 * @class Camera
18774 */
18775
18776function Camera() {
18777 this.armLocation = new Point3d_1();
18778 this.armRotation = {};
18779 this.armRotation.horizontal = 0;
18780 this.armRotation.vertical = 0;
18781 this.armLength = 1.7;
18782 this.cameraOffset = new Point3d_1();
18783 this.offsetMultiplier = 0.6;
18784 this.cameraLocation = new Point3d_1();
18785 this.cameraRotation = new Point3d_1(0.5 * Math.PI, 0, 0);
18786 this.calculateCameraOrientation();
18787}
18788/**
18789 * Set offset camera in camera coordinates
18790 * @param {number} x offset by camera horisontal
18791 * @param {number} y offset by camera vertical
18792 */
18793
18794
18795Camera.prototype.setOffset = function (x, y) {
18796 var abs = Math.abs,
18797 sign = Math.sign,
18798 mul = this.offsetMultiplier,
18799 border = this.armLength * mul;
18800
18801 if (abs(x) > border) {
18802 x = sign(x) * border;
18803 }
18804
18805 if (abs(y) > border) {
18806 y = sign(y) * border;
18807 }
18808
18809 this.cameraOffset.x = x;
18810 this.cameraOffset.y = y;
18811 this.calculateCameraOrientation();
18812};
18813/**
18814 * Get camera offset by horizontal and vertical
18815 * @returns {number}
18816 */
18817
18818
18819Camera.prototype.getOffset = function () {
18820 return this.cameraOffset;
18821};
18822/**
18823 * Set the location (origin) of the arm
18824 * @param {number} x Normalized value of x
18825 * @param {number} y Normalized value of y
18826 * @param {number} z Normalized value of z
18827 */
18828
18829
18830Camera.prototype.setArmLocation = function (x, y, z) {
18831 this.armLocation.x = x;
18832 this.armLocation.y = y;
18833 this.armLocation.z = z;
18834 this.calculateCameraOrientation();
18835};
18836/**
18837 * Set the rotation of the camera arm
18838 * @param {number} horizontal The horizontal rotation, between 0 and 2*PI.
18839 * Optional, can be left undefined.
18840 * @param {number} vertical The vertical rotation, between 0 and 0.5*PI
18841 * if vertical=0.5*PI, the graph is shown from the
18842 * top. Optional, can be left undefined.
18843 */
18844
18845
18846Camera.prototype.setArmRotation = function (horizontal, vertical) {
18847 if (horizontal !== undefined) {
18848 this.armRotation.horizontal = horizontal;
18849 }
18850
18851 if (vertical !== undefined) {
18852 this.armRotation.vertical = vertical;
18853 if (this.armRotation.vertical < 0) this.armRotation.vertical = 0;
18854 if (this.armRotation.vertical > 0.5 * Math.PI) this.armRotation.vertical = 0.5 * Math.PI;
18855 }
18856
18857 if (horizontal !== undefined || vertical !== undefined) {
18858 this.calculateCameraOrientation();
18859 }
18860};
18861/**
18862 * Retrieve the current arm rotation
18863 * @return {object} An object with parameters horizontal and vertical
18864 */
18865
18866
18867Camera.prototype.getArmRotation = function () {
18868 var rot = {};
18869 rot.horizontal = this.armRotation.horizontal;
18870 rot.vertical = this.armRotation.vertical;
18871 return rot;
18872};
18873/**
18874 * Set the (normalized) length of the camera arm.
18875 * @param {number} length A length between 0.71 and 5.0
18876 */
18877
18878
18879Camera.prototype.setArmLength = function (length) {
18880 if (length === undefined) return;
18881 this.armLength = length; // Radius must be larger than the corner of the graph,
18882 // which has a distance of sqrt(0.5^2+0.5^2) = 0.71 from the center of the
18883 // graph
18884
18885 if (this.armLength < 0.71) this.armLength = 0.71;
18886 if (this.armLength > 5.0) this.armLength = 5.0;
18887 this.setOffset(this.cameraOffset.x, this.cameraOffset.y);
18888 this.calculateCameraOrientation();
18889};
18890/**
18891 * Retrieve the arm length
18892 * @return {number} length
18893 */
18894
18895
18896Camera.prototype.getArmLength = function () {
18897 return this.armLength;
18898};
18899/**
18900 * Retrieve the camera location
18901 * @return {Point3d} cameraLocation
18902 */
18903
18904
18905Camera.prototype.getCameraLocation = function () {
18906 return this.cameraLocation;
18907};
18908/**
18909 * Retrieve the camera rotation
18910 * @return {Point3d} cameraRotation
18911 */
18912
18913
18914Camera.prototype.getCameraRotation = function () {
18915 return this.cameraRotation;
18916};
18917/**
18918 * Calculate the location and rotation of the camera based on the
18919 * position and orientation of the camera arm
18920 */
18921
18922
18923Camera.prototype.calculateCameraOrientation = function () {
18924 // calculate location of the camera
18925 this.cameraLocation.x = this.armLocation.x - this.armLength * Math.sin(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical);
18926 this.cameraLocation.y = this.armLocation.y - this.armLength * Math.cos(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical);
18927 this.cameraLocation.z = this.armLocation.z + this.armLength * Math.sin(this.armRotation.vertical); // calculate rotation of the camera
18928
18929 this.cameraRotation.x = Math.PI / 2 - this.armRotation.vertical;
18930 this.cameraRotation.y = 0;
18931 this.cameraRotation.z = -this.armRotation.horizontal;
18932 var xa = this.cameraRotation.x;
18933 var za = this.cameraRotation.z;
18934 var dx = this.cameraOffset.x;
18935 var dy = this.cameraOffset.y;
18936 var sin = Math.sin,
18937 cos = Math.cos;
18938 this.cameraLocation.x = this.cameraLocation.x + dx * cos(za) + dy * -sin(za) * cos(xa);
18939 this.cameraLocation.y = this.cameraLocation.y + dx * sin(za) + dy * cos(za) * cos(xa);
18940 this.cameraLocation.z = this.cameraLocation.z + dy * sin(xa);
18941};
18942
18943var Camera_1 = Camera;
18944
18945// This modules handles the options for Graph3d.
18946//
18947////////////////////////////////////////////////////////////////////////////////
18948// enumerate the available styles
18949
18950var STYLE = {
18951 BAR: 0,
18952 BARCOLOR: 1,
18953 BARSIZE: 2,
18954 DOT: 3,
18955 DOTLINE: 4,
18956 DOTCOLOR: 5,
18957 DOTSIZE: 6,
18958 GRID: 7,
18959 LINE: 8,
18960 SURFACE: 9
18961}; // The string representations of the styles
18962
18963var STYLENAME = {
18964 'dot': STYLE.DOT,
18965 'dot-line': STYLE.DOTLINE,
18966 'dot-color': STYLE.DOTCOLOR,
18967 'dot-size': STYLE.DOTSIZE,
18968 'line': STYLE.LINE,
18969 'grid': STYLE.GRID,
18970 'surface': STYLE.SURFACE,
18971 'bar': STYLE.BAR,
18972 'bar-color': STYLE.BARCOLOR,
18973 'bar-size': STYLE.BARSIZE
18974};
18975/**
18976 * Field names in the options hash which are of relevance to the user.
18977 *
18978 * Specifically, these are the fields which require no special handling,
18979 * and can be directly copied over.
18980 */
18981
18982var OPTIONKEYS = ['width', 'height', 'filterLabel', 'legendLabel', 'xLabel', 'yLabel', 'zLabel', 'xValueLabel', 'yValueLabel', 'zValueLabel', 'showXAxis', 'showYAxis', 'showZAxis', 'showGrid', 'showPerspective', 'showShadow', 'keepAspectRatio', 'verticalRatio', 'dotSizeRatio', 'dotSizeMinFraction', 'dotSizeMaxFraction', 'showAnimationControls', 'animationInterval', 'animationPreload', 'animationAutoStart', 'axisColor', 'gridColor', 'xCenter', 'yCenter', 'zoomable', 'ctrlToZoom'];
18983/**
18984 * Field names in the options hash which are of relevance to the user.
18985 *
18986 * Same as OPTIONKEYS, but internally these fields are stored with
18987 * prefix 'default' in the name.
18988 */
18989
18990var PREFIXEDOPTIONKEYS = ['xBarWidth', 'yBarWidth', 'valueMin', 'valueMax', 'xMin', 'xMax', 'xStep', 'yMin', 'yMax', 'yStep', 'zMin', 'zMax', 'zStep']; // Placeholder for DEFAULTS reference
18991
18992var DEFAULTS = undefined;
18993/**
18994 * Check if given hash is empty.
18995 *
18996 * Source: http://stackoverflow.com/a/679937
18997 *
18998 * @param {object} obj
18999 * @returns {boolean}
19000 */
19001
19002function isEmpty(obj) {
19003 for (var prop in obj) {
19004 if (obj.hasOwnProperty(prop)) return false;
19005 }
19006
19007 return true;
19008}
19009/**
19010 * Make first letter of parameter upper case.
19011 *
19012 * Source: http://stackoverflow.com/a/1026087
19013 *
19014 * @param {string} str
19015 * @returns {string}
19016 */
19017
19018
19019function capitalize(str) {
19020 if (str === undefined || str === "" || typeof str != "string") {
19021 return str;
19022 }
19023
19024 return str.charAt(0).toUpperCase() + str.slice(1);
19025}
19026/**
19027 * Add a prefix to a field name, taking style guide into account
19028 *
19029 * @param {string} prefix
19030 * @param {string} fieldName
19031 * @returns {string}
19032 */
19033
19034
19035function prefixFieldName(prefix, fieldName) {
19036 if (prefix === undefined || prefix === "") {
19037 return fieldName;
19038 }
19039
19040 return prefix + capitalize(fieldName);
19041}
19042/**
19043 * Forcibly copy fields from src to dst in a controlled manner.
19044 *
19045 * A given field in dst will always be overwitten. If this field
19046 * is undefined or not present in src, the field in dst will
19047 * be explicitly set to undefined.
19048 *
19049 * The intention here is to be able to reset all option fields.
19050 *
19051 * Only the fields mentioned in array 'fields' will be handled.
19052 *
19053 * @param {object} src
19054 * @param {object} dst
19055 * @param {array<string>} fields array with names of fields to copy
19056 * @param {string} [prefix] prefix to use for the target fields.
19057 */
19058
19059
19060function forceCopy(src, dst, fields, prefix) {
19061 var srcKey;
19062 var dstKey;
19063
19064 for (var i = 0; i < fields.length; ++i) {
19065 srcKey = fields[i];
19066 dstKey = prefixFieldName(prefix, srcKey);
19067 dst[dstKey] = src[srcKey];
19068 }
19069}
19070/**
19071 * Copy fields from src to dst in a safe and controlled manner.
19072 *
19073 * Only the fields mentioned in array 'fields' will be copied over,
19074 * and only if these are actually defined.
19075 *
19076 * @param {object} src
19077 * @param {object} dst
19078 * @param {array<string>} fields array with names of fields to copy
19079 * @param {string} [prefix] prefix to use for the target fields.
19080 */
19081
19082
19083function safeCopy(src, dst, fields, prefix) {
19084 var srcKey;
19085 var dstKey;
19086
19087 for (var i = 0; i < fields.length; ++i) {
19088 srcKey = fields[i];
19089 if (src[srcKey] === undefined) continue;
19090 dstKey = prefixFieldName(prefix, srcKey);
19091 dst[dstKey] = src[srcKey];
19092 }
19093}
19094/**
19095 * Initialize dst with the values in src.
19096 *
19097 * src is the hash with the default values.
19098 * A reference DEFAULTS to this hash is stored locally for
19099 * further handling.
19100 *
19101 * For now, dst is assumed to be a Graph3d instance.
19102 * @param {object} src
19103 * @param {object} dst
19104 */
19105
19106
19107function setDefaults(src, dst) {
19108 if (src === undefined || isEmpty(src)) {
19109 throw new Error('No DEFAULTS passed');
19110 }
19111
19112 if (dst === undefined) {
19113 throw new Error('No dst passed');
19114 } // Remember defaults for future reference
19115
19116
19117 DEFAULTS = src; // Handle the defaults which can be simply copied over
19118
19119 forceCopy(src, dst, OPTIONKEYS);
19120 forceCopy(src, dst, PREFIXEDOPTIONKEYS, 'default'); // Handle the more complex ('special') fields
19121
19122 setSpecialSettings(src, dst); // Following are internal fields, not part of the user settings
19123
19124 dst.margin = 10; // px
19125
19126 dst.showGrayBottom = false; // TODO: this does not work correctly
19127
19128 dst.showTooltip = false;
19129 dst.onclick_callback = null;
19130 dst.eye = new Point3d_1(0, 0, -1); // TODO: set eye.z about 3/4 of the width of the window?
19131}
19132/**
19133 *
19134 * @param {object} options
19135 * @param {object} dst
19136 */
19137
19138
19139function setOptions(options, dst) {
19140 if (options === undefined) {
19141 return;
19142 }
19143
19144 if (dst === undefined) {
19145 throw new Error('No dst passed');
19146 }
19147
19148 if (DEFAULTS === undefined || isEmpty(DEFAULTS)) {
19149 throw new Error('DEFAULTS not set for module Settings');
19150 } // Handle the parameters which can be simply copied over
19151
19152
19153 safeCopy(options, dst, OPTIONKEYS);
19154 safeCopy(options, dst, PREFIXEDOPTIONKEYS, 'default'); // Handle the more complex ('special') fields
19155
19156 setSpecialSettings(options, dst);
19157}
19158/**
19159 * Special handling for certain parameters
19160 *
19161 * 'Special' here means: setting requires more than a simple copy
19162 *
19163 * @param {object} src
19164 * @param {object} dst
19165 */
19166
19167
19168function setSpecialSettings(src, dst) {
19169 if (src.backgroundColor !== undefined) {
19170 setBackgroundColor(src.backgroundColor, dst);
19171 }
19172
19173 setDataColor(src.dataColor, dst);
19174 setStyle(src.style, dst);
19175 setShowLegend(src.showLegend, dst);
19176 setCameraPosition(src.cameraPosition, dst); // As special fields go, this is an easy one; just a translation of the name.
19177 // Can't use this.tooltip directly, because that field exists internally
19178
19179 if (src.tooltip !== undefined) {
19180 dst.showTooltip = src.tooltip;
19181 }
19182
19183 if (src.onclick != undefined) {
19184 dst.onclick_callback = src.onclick;
19185 }
19186
19187 if (src.tooltipStyle !== undefined) {
19188 util.selectiveDeepExtend(['tooltipStyle'], dst, src);
19189 }
19190}
19191/**
19192 * Set the value of setting 'showLegend'
19193 *
19194 * This depends on the value of the style fields, so it must be called
19195 * after the style field has been initialized.
19196 *
19197 * @param {boolean} showLegend
19198 * @param {object} dst
19199 */
19200
19201
19202function setShowLegend(showLegend, dst) {
19203 if (showLegend === undefined) {
19204 // If the default was auto, make a choice for this field
19205 var isAutoByDefault = DEFAULTS.showLegend === undefined;
19206
19207 if (isAutoByDefault) {
19208 // these styles default to having legends
19209 var isLegendGraphStyle = dst.style === STYLE.DOTCOLOR || dst.style === STYLE.DOTSIZE;
19210 dst.showLegend = isLegendGraphStyle;
19211 }
19212 } else {
19213 dst.showLegend = showLegend;
19214 }
19215}
19216/**
19217 * Retrieve the style index from given styleName
19218 * @param {string} styleName Style name such as 'dot', 'grid', 'dot-line'
19219 * @return {number} styleNumber Enumeration value representing the style, or -1
19220 * when not found
19221 */
19222
19223
19224function getStyleNumberByName(styleName) {
19225 var number = STYLENAME[styleName];
19226
19227 if (number === undefined) {
19228 return -1;
19229 }
19230
19231 return number;
19232}
19233/**
19234 * Check if given number is a valid style number.
19235 *
19236 * @param {string | number} style
19237 * @return {boolean} true if valid, false otherwise
19238 */
19239
19240
19241function checkStyleNumber(style) {
19242 var valid = false;
19243
19244 for (var n in STYLE) {
19245 if (STYLE[n] === style) {
19246 valid = true;
19247 break;
19248 }
19249 }
19250
19251 return valid;
19252}
19253/**
19254 *
19255 * @param {string | number} style
19256 * @param {Object} dst
19257 */
19258
19259
19260function setStyle(style, dst) {
19261 if (style === undefined) {
19262 return; // Nothing to do
19263 }
19264
19265 var styleNumber;
19266
19267 if (typeof style === 'string') {
19268 styleNumber = getStyleNumberByName(style);
19269
19270 if (styleNumber === -1) {
19271 throw new Error('Style \'' + style + '\' is invalid');
19272 }
19273 } else {
19274 // Do a pedantic check on style number value
19275 if (!checkStyleNumber(style)) {
19276 throw new Error('Style \'' + style + '\' is invalid');
19277 }
19278
19279 styleNumber = style;
19280 }
19281
19282 dst.style = styleNumber;
19283}
19284/**
19285 * Set the background styling for the graph
19286 * @param {string | {fill: string, stroke: string, strokeWidth: string}} backgroundColor
19287 * @param {Object} dst
19288 */
19289
19290
19291function setBackgroundColor(backgroundColor, dst) {
19292 var fill = 'white';
19293 var stroke = 'gray';
19294 var strokeWidth = 1;
19295
19296 if (typeof backgroundColor === 'string') {
19297 fill = backgroundColor;
19298 stroke = 'none';
19299 strokeWidth = 0;
19300 } else if (_typeof$2(backgroundColor) === 'object') {
19301 if (backgroundColor.fill !== undefined) fill = backgroundColor.fill;
19302 if (backgroundColor.stroke !== undefined) stroke = backgroundColor.stroke;
19303 if (backgroundColor.strokeWidth !== undefined) strokeWidth = backgroundColor.strokeWidth;
19304 } else {
19305 throw new Error('Unsupported type of backgroundColor');
19306 }
19307
19308 dst.frame.style.backgroundColor = fill;
19309 dst.frame.style.borderColor = stroke;
19310 dst.frame.style.borderWidth = strokeWidth + 'px';
19311 dst.frame.style.borderStyle = 'solid';
19312}
19313/**
19314 *
19315 * @param {string | Object} dataColor
19316 * @param {Object} dst
19317 */
19318
19319
19320function setDataColor(dataColor, dst) {
19321 if (dataColor === undefined) {
19322 return; // Nothing to do
19323 }
19324
19325 if (dst.dataColor === undefined) {
19326 dst.dataColor = {};
19327 }
19328
19329 if (typeof dataColor === 'string') {
19330 dst.dataColor.fill = dataColor;
19331 dst.dataColor.stroke = dataColor;
19332 } else {
19333 if (dataColor.fill) {
19334 dst.dataColor.fill = dataColor.fill;
19335 }
19336
19337 if (dataColor.stroke) {
19338 dst.dataColor.stroke = dataColor.stroke;
19339 }
19340
19341 if (dataColor.strokeWidth !== undefined) {
19342 dst.dataColor.strokeWidth = dataColor.strokeWidth;
19343 }
19344 }
19345}
19346/**
19347 *
19348 * @param {Object} cameraPosition
19349 * @param {Object} dst
19350 */
19351
19352
19353function setCameraPosition(cameraPosition, dst) {
19354 var camPos = cameraPosition;
19355
19356 if (camPos === undefined) {
19357 return;
19358 }
19359
19360 if (dst.camera === undefined) {
19361 dst.camera = new Camera_1();
19362 }
19363
19364 dst.camera.setArmRotation(camPos.horizontal, camPos.vertical);
19365 dst.camera.setArmLength(camPos.distance);
19366}
19367
19368var STYLE_1 = STYLE;
19369var setDefaults_1 = setDefaults;
19370var setOptions_1 = setOptions;
19371var setCameraPosition_1 = setCameraPosition;
19372var Settings = {
19373 STYLE: STYLE_1,
19374 setDefaults: setDefaults_1,
19375 setOptions: setOptions_1,
19376 setCameraPosition: setCameraPosition_1
19377};
19378
19379var errorFound = false;
19380var allOptions;
19381var printStyle = 'background: #FFeeee; color: #dd0000';
19382/**
19383 * Used to validate options.
19384 */
19385
19386var Validator =
19387/*#__PURE__*/
19388function () {
19389 /**
19390 * @ignore
19391 */
19392 function Validator() {
19393 _classCallCheck$1(this, Validator);
19394 }
19395 /**
19396 * Main function to be called
19397 * @param {Object} options
19398 * @param {Object} referenceOptions
19399 * @param {Object} subObject
19400 * @returns {boolean}
19401 * @static
19402 */
19403
19404
19405 _createClass$1(Validator, null, [{
19406 key: "validate",
19407 value: function validate(options, referenceOptions, subObject) {
19408 errorFound = false;
19409 allOptions = referenceOptions;
19410 var usedOptions = referenceOptions;
19411
19412 if (subObject !== undefined) {
19413 usedOptions = referenceOptions[subObject];
19414 }
19415
19416 Validator.parse(options, usedOptions, []);
19417 return errorFound;
19418 }
19419 /**
19420 * Will traverse an object recursively and check every value
19421 * @param {Object} options
19422 * @param {Object} referenceOptions
19423 * @param {array} path | where to look for the actual option
19424 * @static
19425 */
19426
19427 }, {
19428 key: "parse",
19429 value: function parse(options, referenceOptions, path) {
19430 for (var option in options) {
19431 if (options.hasOwnProperty(option)) {
19432 Validator.check(option, options, referenceOptions, path);
19433 }
19434 }
19435 }
19436 /**
19437 * Check every value. If the value is an object, call the parse function on that object.
19438 * @param {string} option
19439 * @param {Object} options
19440 * @param {Object} referenceOptions
19441 * @param {array} path | where to look for the actual option
19442 * @static
19443 */
19444
19445 }, {
19446 key: "check",
19447 value: function check(option, options, referenceOptions, path) {
19448 if (referenceOptions[option] === undefined && referenceOptions.__any__ === undefined) {
19449 Validator.getSuggestion(option, referenceOptions, path);
19450 return;
19451 }
19452
19453 var referenceOption = option;
19454 var is_object = true;
19455
19456 if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {
19457 // NOTE: This only triggers if the __any__ is in the top level of the options object.
19458 // THAT'S A REALLY BAD PLACE TO ALLOW IT!!!!
19459 // TODO: Examine if needed, remove if possible
19460 // __any__ is a wildcard. Any value is accepted and will be further analysed by reference.
19461 referenceOption = '__any__'; // if the any-subgroup is not a predefined object in the configurator,
19462 // we do not look deeper into the object.
19463
19464 is_object = Validator.getType(options[option]) === 'object';
19465 }
19466
19467 var refOptionObj = referenceOptions[referenceOption];
19468
19469 if (is_object && refOptionObj.__type__ !== undefined) {
19470 refOptionObj = refOptionObj.__type__;
19471 }
19472
19473 Validator.checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path);
19474 }
19475 /**
19476 *
19477 * @param {string} option | the option property
19478 * @param {Object} options | The supplied options object
19479 * @param {Object} referenceOptions | The reference options containing all options and their allowed formats
19480 * @param {string} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
19481 * @param {string} refOptionObj | This is the type object from the reference options
19482 * @param {Array} path | where in the object is the option
19483 * @static
19484 */
19485
19486 }, {
19487 key: "checkFields",
19488 value: function checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path) {
19489 var log = function log(message) {
19490 console.log('%c' + message + Validator.printLocation(path, option), printStyle);
19491 };
19492
19493 var optionType = Validator.getType(options[option]);
19494 var refOptionType = refOptionObj[optionType];
19495
19496 if (refOptionType !== undefined) {
19497 // if the type is correct, we check if it is supposed to be one of a few select values
19498 if (Validator.getType(refOptionType) === 'array' && refOptionType.indexOf(options[option]) === -1) {
19499 log('Invalid option detected in "' + option + '".' + ' Allowed values are:' + Validator.print(refOptionType) + ' not "' + options[option] + '". ');
19500 errorFound = true;
19501 } else if (optionType === 'object' && referenceOption !== "__any__") {
19502 path = util.copyAndExtendArray(path, option);
19503 Validator.parse(options[option], referenceOptions[referenceOption], path);
19504 }
19505 } else if (refOptionObj['any'] === undefined) {
19506 // type of the field is incorrect and the field cannot be any
19507 log('Invalid type received for "' + option + '". Expected: ' + Validator.print(Object.keys(refOptionObj)) + '. Received [' + optionType + '] "' + options[option] + '"');
19508 errorFound = true;
19509 }
19510 }
19511 /**
19512 *
19513 * @param {Object|boolean|number|string|Array.<number>|Date|Node|Moment|undefined|null} object
19514 * @returns {string}
19515 * @static
19516 */
19517
19518 }, {
19519 key: "getType",
19520 value: function getType(object) {
19521 var type = _typeof$2(object);
19522
19523 if (type === 'object') {
19524 if (object === null) {
19525 return 'null';
19526 }
19527
19528 if (object instanceof Boolean) {
19529 return 'boolean';
19530 }
19531
19532 if (object instanceof Number) {
19533 return 'number';
19534 }
19535
19536 if (object instanceof String) {
19537 return 'string';
19538 }
19539
19540 if (Array.isArray(object)) {
19541 return 'array';
19542 }
19543
19544 if (object instanceof Date) {
19545 return 'date';
19546 }
19547
19548 if (object.nodeType !== undefined) {
19549 return 'dom';
19550 }
19551
19552 if (object._isAMomentObject === true) {
19553 return 'moment';
19554 }
19555
19556 return 'object';
19557 } else if (type === 'number') {
19558 return 'number';
19559 } else if (type === 'boolean') {
19560 return 'boolean';
19561 } else if (type === 'string') {
19562 return 'string';
19563 } else if (type === undefined) {
19564 return 'undefined';
19565 }
19566
19567 return type;
19568 }
19569 /**
19570 * @param {string} option
19571 * @param {Object} options
19572 * @param {Array.<string>} path
19573 * @static
19574 */
19575
19576 }, {
19577 key: "getSuggestion",
19578 value: function getSuggestion(option, options, path) {
19579 var localSearch = Validator.findInOptions(option, options, path, false);
19580 var globalSearch = Validator.findInOptions(option, allOptions, [], true);
19581 var localSearchThreshold = 8;
19582 var globalSearchThreshold = 4;
19583 var msg;
19584
19585 if (localSearch.indexMatch !== undefined) {
19586 msg = ' in ' + Validator.printLocation(localSearch.path, option, '') + 'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n';
19587 } else if (globalSearch.distance <= globalSearchThreshold && localSearch.distance > globalSearch.distance) {
19588 msg = ' in ' + Validator.printLocation(localSearch.path, option, '') + 'Perhaps it was misplaced? Matching option found at: ' + Validator.printLocation(globalSearch.path, globalSearch.closestMatch, '');
19589 } else if (localSearch.distance <= localSearchThreshold) {
19590 msg = '. Did you mean "' + localSearch.closestMatch + '"?' + Validator.printLocation(localSearch.path, option);
19591 } else {
19592 msg = '. Did you mean one of these: ' + Validator.print(Object.keys(options)) + Validator.printLocation(path, option);
19593 }
19594
19595 console.log('%cUnknown option detected: "' + option + '"' + msg, printStyle);
19596 errorFound = true;
19597 }
19598 /**
19599 * traverse the options in search for a match.
19600 * @param {string} option
19601 * @param {Object} options
19602 * @param {Array} path | where to look for the actual option
19603 * @param {boolean} [recursive=false]
19604 * @returns {{closestMatch: string, path: Array, distance: number}}
19605 * @static
19606 */
19607
19608 }, {
19609 key: "findInOptions",
19610 value: function findInOptions(option, options, path) {
19611 var recursive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
19612 var min = 1e9;
19613 var closestMatch = '';
19614 var closestMatchPath = [];
19615 var lowerCaseOption = option.toLowerCase();
19616 var indexMatch = undefined;
19617
19618 for (var op in options) {
19619 // eslint-disable-line guard-for-in
19620 var distance = void 0;
19621
19622 if (options[op].__type__ !== undefined && recursive === true) {
19623 var result = Validator.findInOptions(option, options[op], util.copyAndExtendArray(path, op));
19624
19625 if (min > result.distance) {
19626 closestMatch = result.closestMatch;
19627 closestMatchPath = result.path;
19628 min = result.distance;
19629 indexMatch = result.indexMatch;
19630 }
19631 } else {
19632 if (op.toLowerCase().indexOf(lowerCaseOption) !== -1) {
19633 indexMatch = op;
19634 }
19635
19636 distance = Validator.levenshteinDistance(option, op);
19637
19638 if (min > distance) {
19639 closestMatch = op;
19640 closestMatchPath = util.copyArray(path);
19641 min = distance;
19642 }
19643 }
19644 }
19645
19646 return {
19647 closestMatch: closestMatch,
19648 path: closestMatchPath,
19649 distance: min,
19650 indexMatch: indexMatch
19651 };
19652 }
19653 /**
19654 * @param {Array.<string>} path
19655 * @param {Object} option
19656 * @param {string} prefix
19657 * @returns {String}
19658 * @static
19659 */
19660
19661 }, {
19662 key: "printLocation",
19663 value: function printLocation(path, option) {
19664 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Problem value found at: \n';
19665 var str = '\n\n' + prefix + 'options = {\n';
19666
19667 for (var i = 0; i < path.length; i++) {
19668 for (var j = 0; j < i + 1; j++) {
19669 str += ' ';
19670 }
19671
19672 str += path[i] + ': {\n';
19673 }
19674
19675 for (var _j = 0; _j < path.length + 1; _j++) {
19676 str += ' ';
19677 }
19678
19679 str += option + '\n';
19680
19681 for (var _i = 0; _i < path.length + 1; _i++) {
19682 for (var _j2 = 0; _j2 < path.length - _i; _j2++) {
19683 str += ' ';
19684 }
19685
19686 str += '}\n';
19687 }
19688
19689 return str + '\n\n';
19690 }
19691 /**
19692 * @param {Object} options
19693 * @returns {String}
19694 * @static
19695 */
19696
19697 }, {
19698 key: "print",
19699 value: function print(options) {
19700 return JSON.stringify(options).replace(/(\")|(\[)|(\])|(,"__type__")/g, "").replace(/(\,)/g, ', ');
19701 }
19702 /**
19703 * Compute the edit distance between the two given strings
19704 * http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
19705 *
19706 * Copyright (c) 2011 Andrei Mackenzie
19707 *
19708 * 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:
19709 *
19710 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
19711 *
19712 * 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.
19713 *
19714 * @param {string} a
19715 * @param {string} b
19716 * @returns {Array.<Array.<number>>}}
19717 * @static
19718 */
19719
19720 }, {
19721 key: "levenshteinDistance",
19722 value: function levenshteinDistance(a, b) {
19723 if (a.length === 0) return b.length;
19724 if (b.length === 0) return a.length;
19725 var matrix = []; // increment along the first column of each row
19726
19727 var i;
19728
19729 for (i = 0; i <= b.length; i++) {
19730 matrix[i] = [i];
19731 } // increment each column in the first row
19732
19733
19734 var j;
19735
19736 for (j = 0; j <= a.length; j++) {
19737 matrix[0][j] = j;
19738 } // Fill in the rest of the matrix
19739
19740
19741 for (i = 1; i <= b.length; i++) {
19742 for (j = 1; j <= a.length; j++) {
19743 if (b.charAt(i - 1) == a.charAt(j - 1)) {
19744 matrix[i][j] = matrix[i - 1][j - 1];
19745 } else {
19746 matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
19747 Math.min(matrix[i][j - 1] + 1, // insertion
19748 matrix[i - 1][j] + 1)); // deletion
19749 }
19750 }
19751 }
19752
19753 return matrix[b.length][a.length];
19754 }
19755 }]);
19756
19757 return Validator;
19758}();
19759
19760var Validator$1 = /*#__PURE__*/Object.freeze({
19761 Validator: Validator,
19762 printStyle: printStyle
19763});
19764
19765/**
19766 * This object contains all possible options. It will check if the types are correct, if required if the option is one
19767 * of the allowed values.
19768 *
19769 * __any__ means that the name of the property does not matter.
19770 * __type__ is a required field for all objects and contains the allowed types of all objects
19771 */
19772var string = 'string';
19773var bool = 'boolean';
19774var number = 'number';
19775var object = 'object'; // should only be in a __type__ property
19776// Following not used here, but useful for reference
19777//let array = 'array';
19778//let dom = 'dom';
19779//let any = 'any';
19780
19781var colorOptions = {
19782 fill: {
19783 string: string
19784 },
19785 stroke: {
19786 string: string
19787 },
19788 strokeWidth: {
19789 number: number
19790 },
19791 __type__: {
19792 string: string,
19793 object: object,
19794 'undefined': 'undefined'
19795 }
19796};
19797/**
19798 * Order attempted to be alphabetical.
19799 * - x/y/z-prefixes ignored in sorting
19800 * - __type__ always at end
19801 * - globals at end
19802 */
19803
19804var allOptions$1 = {
19805 animationAutoStart: {
19806 boolean: bool,
19807 'undefined': 'undefined'
19808 },
19809 animationInterval: {
19810 number: number
19811 },
19812 animationPreload: {
19813 boolean: bool
19814 },
19815 axisColor: {
19816 string: string
19817 },
19818 backgroundColor: colorOptions,
19819 xBarWidth: {
19820 number: number,
19821 'undefined': 'undefined'
19822 },
19823 yBarWidth: {
19824 number: number,
19825 'undefined': 'undefined'
19826 },
19827 cameraPosition: {
19828 distance: {
19829 number: number
19830 },
19831 horizontal: {
19832 number: number
19833 },
19834 vertical: {
19835 number: number
19836 },
19837 __type__: {
19838 object: object
19839 }
19840 },
19841 zoomable: {
19842 boolean: bool
19843 },
19844 ctrlToZoom: {
19845 boolean: bool
19846 },
19847 xCenter: {
19848 string: string
19849 },
19850 yCenter: {
19851 string: string
19852 },
19853 dataColor: colorOptions,
19854 dotSizeMinFraction: {
19855 number: number
19856 },
19857 dotSizeMaxFraction: {
19858 number: number
19859 },
19860 dotSizeRatio: {
19861 number: number
19862 },
19863 filterLabel: {
19864 string: string
19865 },
19866 gridColor: {
19867 string: string
19868 },
19869 onclick: {
19870 'function': 'function'
19871 },
19872 keepAspectRatio: {
19873 boolean: bool
19874 },
19875 xLabel: {
19876 string: string
19877 },
19878 yLabel: {
19879 string: string
19880 },
19881 zLabel: {
19882 string: string
19883 },
19884 legendLabel: {
19885 string: string
19886 },
19887 xMin: {
19888 number: number,
19889 'undefined': 'undefined'
19890 },
19891 yMin: {
19892 number: number,
19893 'undefined': 'undefined'
19894 },
19895 zMin: {
19896 number: number,
19897 'undefined': 'undefined'
19898 },
19899 xMax: {
19900 number: number,
19901 'undefined': 'undefined'
19902 },
19903 yMax: {
19904 number: number,
19905 'undefined': 'undefined'
19906 },
19907 zMax: {
19908 number: number,
19909 'undefined': 'undefined'
19910 },
19911 showAnimationControls: {
19912 boolean: bool,
19913 'undefined': 'undefined'
19914 },
19915 showGrid: {
19916 boolean: bool
19917 },
19918 showLegend: {
19919 boolean: bool,
19920 'undefined': 'undefined'
19921 },
19922 showPerspective: {
19923 boolean: bool
19924 },
19925 showShadow: {
19926 boolean: bool
19927 },
19928 showXAxis: {
19929 boolean: bool
19930 },
19931 showYAxis: {
19932 boolean: bool
19933 },
19934 showZAxis: {
19935 boolean: bool
19936 },
19937 xStep: {
19938 number: number,
19939 'undefined': 'undefined'
19940 },
19941 yStep: {
19942 number: number,
19943 'undefined': 'undefined'
19944 },
19945 zStep: {
19946 number: number,
19947 'undefined': 'undefined'
19948 },
19949 style: {
19950 number: number,
19951 // TODO: either Graph3d.DEFAULT has string, or number allowed in documentation
19952 string: ['bar', 'bar-color', 'bar-size', 'dot', 'dot-line', 'dot-color', 'dot-size', 'line', 'grid', 'surface']
19953 },
19954 tooltip: {
19955 boolean: bool,
19956 'function': 'function'
19957 },
19958 tooltipStyle: {
19959 content: {
19960 color: {
19961 string: string
19962 },
19963 background: {
19964 string: string
19965 },
19966 border: {
19967 string: string
19968 },
19969 borderRadius: {
19970 string: string
19971 },
19972 boxShadow: {
19973 string: string
19974 },
19975 padding: {
19976 string: string
19977 },
19978 __type__: {
19979 object: object
19980 }
19981 },
19982 line: {
19983 borderLeft: {
19984 string: string
19985 },
19986 height: {
19987 string: string
19988 },
19989 width: {
19990 string: string
19991 },
19992 pointerEvents: {
19993 string: string
19994 },
19995 __type__: {
19996 object: object
19997 }
19998 },
19999 dot: {
20000 border: {
20001 string: string
20002 },
20003 borderRadius: {
20004 string: string
20005 },
20006 height: {
20007 string: string
20008 },
20009 width: {
20010 string: string
20011 },
20012 pointerEvents: {
20013 string: string
20014 },
20015 __type__: {
20016 object: object
20017 }
20018 },
20019 __type__: {
20020 object: object
20021 }
20022 },
20023 xValueLabel: {
20024 'function': 'function'
20025 },
20026 yValueLabel: {
20027 'function': 'function'
20028 },
20029 zValueLabel: {
20030 'function': 'function'
20031 },
20032 valueMax: {
20033 number: number,
20034 'undefined': 'undefined'
20035 },
20036 valueMin: {
20037 number: number,
20038 'undefined': 'undefined'
20039 },
20040 verticalRatio: {
20041 number: number
20042 },
20043 //globals :
20044 height: {
20045 string: string
20046 },
20047 width: {
20048 string: string
20049 },
20050 __type__: {
20051 object: object
20052 }
20053};
20054
20055var options = /*#__PURE__*/Object.freeze({
20056 allOptions: allOptions$1
20057});
20058
20059/**
20060 * @prototype Range
20061 *
20062 * Helper class to make working with related min and max values easier.
20063 *
20064 * The range is inclusive; a given value is considered part of the range if:
20065 *
20066 * this.min <= value <= this.max
20067 */
20068function Range() {
20069 this.min = undefined;
20070 this.max = undefined;
20071}
20072/**
20073 * Adjust the range so that the passed value fits in it.
20074 *
20075 * If the value is outside of the current extremes, adjust
20076 * the min or max so that the value is within the range.
20077 *
20078 * @param {number} value Numeric value to fit in range
20079 */
20080
20081
20082Range.prototype.adjust = function (value) {
20083 if (value === undefined) return;
20084
20085 if (this.min === undefined || this.min > value) {
20086 this.min = value;
20087 }
20088
20089 if (this.max === undefined || this.max < value) {
20090 this.max = value;
20091 }
20092};
20093/**
20094 * Adjust the current range so that the passed range fits in it.
20095 *
20096 * @param {Range} range Range instance to fit in current instance
20097 */
20098
20099
20100Range.prototype.combine = function (range) {
20101 this.add(range.min);
20102 this.add(range.max);
20103};
20104/**
20105 * Expand the range by the given value
20106 *
20107 * min will be lowered by given value;
20108 * max will be raised by given value
20109 *
20110 * Shrinking by passing a negative value is allowed.
20111 *
20112 * @param {number} val Amount by which to expand or shrink current range with
20113 */
20114
20115
20116Range.prototype.expand = function (val) {
20117 if (val === undefined) {
20118 return;
20119 }
20120
20121 var newMin = this.min - val;
20122 var newMax = this.max + val; // Note that following allows newMin === newMax.
20123 // This should be OK, since method expand() allows this also.
20124
20125 if (newMin > newMax) {
20126 throw new Error('Passed expansion value makes range invalid');
20127 }
20128
20129 this.min = newMin;
20130 this.max = newMax;
20131};
20132/**
20133 * Determine the full range width of current instance.
20134 *
20135 * @returns {num} The calculated width of this range
20136 */
20137
20138
20139Range.prototype.range = function () {
20140 return this.max - this.min;
20141};
20142/**
20143 * Determine the central point of current instance.
20144 *
20145 * @returns {number} the value in the middle of min and max
20146 */
20147
20148
20149Range.prototype.center = function () {
20150 return (this.min + this.max) / 2;
20151};
20152
20153var Range_1 = Range;
20154
20155var DataView$1 = index.DataView;
20156/**
20157 * @class Filter
20158 *
20159 * @param {DataGroup} dataGroup the data group
20160 * @param {number} column The index of the column to be filtered
20161 * @param {Graph3d} graph The graph
20162 */
20163
20164function Filter(dataGroup, column, graph) {
20165 this.dataGroup = dataGroup;
20166 this.column = column;
20167 this.graph = graph; // the parent graph
20168
20169 this.index = undefined;
20170 this.value = undefined; // read all distinct values and select the first one
20171
20172 this.values = dataGroup.getDistinctValues(this.column);
20173
20174 if (this.values.length > 0) {
20175 this.selectValue(0);
20176 } // create an array with the filtered datapoints. this will be loaded afterwards
20177
20178
20179 this.dataPoints = [];
20180 this.loaded = false;
20181 this.onLoadCallback = undefined;
20182
20183 if (graph.animationPreload) {
20184 this.loaded = false;
20185 this.loadInBackground();
20186 } else {
20187 this.loaded = true;
20188 }
20189}
20190/**
20191 * Return the label
20192 * @return {string} label
20193 */
20194
20195
20196Filter.prototype.isLoaded = function () {
20197 return this.loaded;
20198};
20199/**
20200 * Return the loaded progress
20201 * @return {number} percentage between 0 and 100
20202 */
20203
20204
20205Filter.prototype.getLoadedProgress = function () {
20206 var len = this.values.length;
20207 var i = 0;
20208
20209 while (this.dataPoints[i]) {
20210 i++;
20211 }
20212
20213 return Math.round(i / len * 100);
20214};
20215/**
20216 * Return the label
20217 * @return {string} label
20218 */
20219
20220
20221Filter.prototype.getLabel = function () {
20222 return this.graph.filterLabel;
20223};
20224/**
20225 * Return the columnIndex of the filter
20226 * @return {number} columnIndex
20227 */
20228
20229
20230Filter.prototype.getColumn = function () {
20231 return this.column;
20232};
20233/**
20234 * Return the currently selected value. Returns undefined if there is no selection
20235 * @return {*} value
20236 */
20237
20238
20239Filter.prototype.getSelectedValue = function () {
20240 if (this.index === undefined) return undefined;
20241 return this.values[this.index];
20242};
20243/**
20244 * Retrieve all values of the filter
20245 * @return {Array} values
20246 */
20247
20248
20249Filter.prototype.getValues = function () {
20250 return this.values;
20251};
20252/**
20253 * Retrieve one value of the filter
20254 * @param {number} index
20255 * @return {*} value
20256 */
20257
20258
20259Filter.prototype.getValue = function (index) {
20260 if (index >= this.values.length) throw new Error('Index out of range');
20261 return this.values[index];
20262};
20263/**
20264 * Retrieve the (filtered) dataPoints for the currently selected filter index
20265 * @param {number} [index] (optional)
20266 * @return {Array} dataPoints
20267 */
20268
20269
20270Filter.prototype._getDataPoints = function (index) {
20271 if (index === undefined) index = this.index;
20272 if (index === undefined) return [];
20273 var dataPoints;
20274
20275 if (this.dataPoints[index]) {
20276 dataPoints = this.dataPoints[index];
20277 } else {
20278 var f = {};
20279 f.column = this.column;
20280 f.value = this.values[index];
20281 var dataView = new DataView$1(this.dataGroup.getDataSet(), {
20282 filter: function filter(item) {
20283 return item[f.column] == f.value;
20284 }
20285 }).get();
20286 dataPoints = this.dataGroup._getDataPoints(dataView);
20287 this.dataPoints[index] = dataPoints;
20288 }
20289
20290 return dataPoints;
20291};
20292/**
20293 * Set a callback function when the filter is fully loaded.
20294 *
20295 * @param {function} callback
20296 */
20297
20298
20299Filter.prototype.setOnLoadCallback = function (callback) {
20300 this.onLoadCallback = callback;
20301};
20302/**
20303 * Add a value to the list with available values for this filter
20304 * No double entries will be created.
20305 * @param {number} index
20306 */
20307
20308
20309Filter.prototype.selectValue = function (index) {
20310 if (index >= this.values.length) throw new Error('Index out of range');
20311 this.index = index;
20312 this.value = this.values[index];
20313};
20314/**
20315 * Load all filtered rows in the background one by one
20316 * Start this method without providing an index!
20317 *
20318 * @param {number} [index=0]
20319 */
20320
20321
20322Filter.prototype.loadInBackground = function (index) {
20323 if (index === undefined) index = 0;
20324 var frame = this.graph.frame;
20325
20326 if (index < this.values.length) {
20327 // create a progress box
20328 if (frame.progress === undefined) {
20329 frame.progress = document.createElement('DIV');
20330 frame.progress.style.position = 'absolute';
20331 frame.progress.style.color = 'gray';
20332 frame.appendChild(frame.progress);
20333 }
20334
20335 var progress = this.getLoadedProgress();
20336 frame.progress.innerHTML = 'Loading animation... ' + progress + '%'; // TODO: this is no nice solution...
20337
20338 frame.progress.style.bottom = 60 + 'px'; // TODO: use height of slider
20339
20340 frame.progress.style.left = 10 + 'px';
20341 var me = this;
20342 setTimeout(function () {
20343 me.loadInBackground(index + 1);
20344 }, 10);
20345 this.loaded = false;
20346 } else {
20347 this.loaded = true; // remove the progress box
20348
20349 if (frame.progress !== undefined) {
20350 frame.removeChild(frame.progress);
20351 frame.progress = undefined;
20352 }
20353
20354 if (this.onLoadCallback) this.onLoadCallback();
20355 }
20356};
20357
20358var Filter_1 = Filter;
20359
20360var DataSet$1 = index.DataSet;
20361var DataView$2 = index.DataView;
20362/**
20363 * Creates a container for all data of one specific 3D-graph.
20364 *
20365 * On construction, the container is totally empty; the data
20366 * needs to be initialized with method initializeData().
20367 * Failure to do so will result in the following exception begin thrown
20368 * on instantiation of Graph3D:
20369 *
20370 * Error: Array, DataSet, or DataView expected
20371 *
20372 * @constructor DataGroup
20373 */
20374
20375function DataGroup() {
20376 this.dataTable = null; // The original data table
20377}
20378/**
20379 * Initializes the instance from the passed data.
20380 *
20381 * Calculates minimum and maximum values and column index values.
20382 *
20383 * The graph3d instance is used internally to access the settings for
20384 * the given instance.
20385 * TODO: Pass settings only instead.
20386 *
20387 * @param {vis.Graph3d} graph3d Reference to the calling Graph3D instance.
20388 * @param {Array | DataSet | DataView} rawData The data containing the items for
20389 * the Graph.
20390 * @param {number} style Style Number
20391 * @returns {Array.<Object>}
20392 */
20393
20394
20395DataGroup.prototype.initializeData = function (graph3d, rawData, style) {
20396 if (rawData === undefined) return;
20397
20398 if (Array.isArray(rawData)) {
20399 rawData = new DataSet$1(rawData);
20400 }
20401
20402 var data;
20403
20404 if (rawData instanceof DataSet$1 || rawData instanceof DataView$2) {
20405 data = rawData.get();
20406 } else {
20407 throw new Error('Array, DataSet, or DataView expected');
20408 }
20409
20410 if (data.length == 0) return;
20411 this.style = style; // unsubscribe from the dataTable
20412
20413 if (this.dataSet) {
20414 this.dataSet.off('*', this._onChange);
20415 }
20416
20417 this.dataSet = rawData;
20418 this.dataTable = data; // subscribe to changes in the dataset
20419
20420 var me = this;
20421
20422 this._onChange = function () {
20423 graph3d.setData(me.dataSet);
20424 };
20425
20426 this.dataSet.on('*', this._onChange); // determine the location of x,y,z,value,filter columns
20427
20428 this.colX = 'x';
20429 this.colY = 'y';
20430 this.colZ = 'z';
20431 var withBars = graph3d.hasBars(style); // determine barWidth from data
20432
20433 if (withBars) {
20434 if (graph3d.defaultXBarWidth !== undefined) {
20435 this.xBarWidth = graph3d.defaultXBarWidth;
20436 } else {
20437 this.xBarWidth = this.getSmallestDifference(data, this.colX) || 1;
20438 }
20439
20440 if (graph3d.defaultYBarWidth !== undefined) {
20441 this.yBarWidth = graph3d.defaultYBarWidth;
20442 } else {
20443 this.yBarWidth = this.getSmallestDifference(data, this.colY) || 1;
20444 }
20445 } // calculate minima and maxima
20446
20447
20448 this._initializeRange(data, this.colX, graph3d, withBars);
20449
20450 this._initializeRange(data, this.colY, graph3d, withBars);
20451
20452 this._initializeRange(data, this.colZ, graph3d, false);
20453
20454 if (data[0].hasOwnProperty('style')) {
20455 this.colValue = 'style';
20456 var valueRange = this.getColumnRange(data, this.colValue);
20457
20458 this._setRangeDefaults(valueRange, graph3d.defaultValueMin, graph3d.defaultValueMax);
20459
20460 this.valueRange = valueRange;
20461 } // Initialize data filter if a filter column is provided
20462
20463
20464 var table = this.getDataTable();
20465
20466 if (table[0].hasOwnProperty('filter')) {
20467 if (this.dataFilter === undefined) {
20468 this.dataFilter = new Filter_1(this, 'filter', graph3d);
20469 this.dataFilter.setOnLoadCallback(function () {
20470 graph3d.redraw();
20471 });
20472 }
20473 }
20474
20475 var dataPoints;
20476
20477 if (this.dataFilter) {
20478 // apply filtering
20479 dataPoints = this.dataFilter._getDataPoints();
20480 } else {
20481 // no filtering. load all data
20482 dataPoints = this._getDataPoints(this.getDataTable());
20483 }
20484
20485 return dataPoints;
20486};
20487/**
20488 * Collect the range settings for the given data column.
20489 *
20490 * This internal method is intended to make the range
20491 * initalization more generic.
20492 *
20493 * TODO: if/when combined settings per axis defined, get rid of this.
20494 *
20495 * @private
20496 *
20497 * @param {'x'|'y'|'z'} column The data column to process
20498 * @param {vis.Graph3d} graph3d Reference to the calling Graph3D instance;
20499 * required for access to settings
20500 * @returns {Object}
20501 */
20502
20503
20504DataGroup.prototype._collectRangeSettings = function (column, graph3d) {
20505 var index = ['x', 'y', 'z'].indexOf(column);
20506
20507 if (index == -1) {
20508 throw new Error('Column \'' + column + '\' invalid');
20509 }
20510
20511 var upper = column.toUpperCase();
20512 return {
20513 barWidth: this[column + 'BarWidth'],
20514 min: graph3d['default' + upper + 'Min'],
20515 max: graph3d['default' + upper + 'Max'],
20516 step: graph3d['default' + upper + 'Step'],
20517 range_label: column + 'Range',
20518 // Name of instance field to write to
20519 step_label: column + 'Step' // Name of instance field to write to
20520
20521 };
20522};
20523/**
20524 * Initializes the settings per given column.
20525 *
20526 * TODO: if/when combined settings per axis defined, rewrite this.
20527 *
20528 * @private
20529 *
20530 * @param {DataSet | DataView} data The data containing the items for the Graph
20531 * @param {'x'|'y'|'z'} column The data column to process
20532 * @param {vis.Graph3d} graph3d Reference to the calling Graph3D instance;
20533 * required for access to settings
20534 * @param {boolean} withBars True if initializing for bar graph
20535 */
20536
20537
20538DataGroup.prototype._initializeRange = function (data, column, graph3d, withBars) {
20539 var NUMSTEPS = 5;
20540
20541 var settings = this._collectRangeSettings(column, graph3d);
20542
20543 var range = this.getColumnRange(data, column);
20544
20545 if (withBars && column != 'z') {
20546 // Safeguard for 'z'; it doesn't have a bar width
20547 range.expand(settings.barWidth / 2);
20548 }
20549
20550 this._setRangeDefaults(range, settings.min, settings.max);
20551
20552 this[settings.range_label] = range;
20553 this[settings.step_label] = settings.step !== undefined ? settings.step : range.range() / NUMSTEPS;
20554};
20555/**
20556 * Creates a list with all the different values in the data for the given column.
20557 *
20558 * If no data passed, use the internal data of this instance.
20559 *
20560 * @param {'x'|'y'|'z'} column The data column to process
20561 * @param {DataSet|DataView|undefined} data The data containing the items for the Graph
20562 *
20563 * @returns {Array} All distinct values in the given column data, sorted ascending.
20564 */
20565
20566
20567DataGroup.prototype.getDistinctValues = function (column, data) {
20568 if (data === undefined) {
20569 data = this.dataTable;
20570 }
20571
20572 var values = [];
20573
20574 for (var i = 0; i < data.length; i++) {
20575 var value = data[i][column] || 0;
20576
20577 if (values.indexOf(value) === -1) {
20578 values.push(value);
20579 }
20580 }
20581
20582 return values.sort(function (a, b) {
20583 return a - b;
20584 });
20585};
20586/**
20587 * Determine the smallest difference between the values for given
20588 * column in the passed data set.
20589 *
20590 * @param {DataSet|DataView|undefined} data The data containing the items for the Graph
20591 * @param {'x'|'y'|'z'} column The data column to process
20592 *
20593 * @returns {number|null} Smallest difference value or
20594 * null, if it can't be determined.
20595 */
20596
20597
20598DataGroup.prototype.getSmallestDifference = function (data, column) {
20599 var values = this.getDistinctValues(data, column); // Get all the distinct diffs
20600 // Array values is assumed to be sorted here
20601
20602 var smallest_diff = null;
20603
20604 for (var i = 1; i < values.length; i++) {
20605 var diff = values[i] - values[i - 1];
20606
20607 if (smallest_diff == null || smallest_diff > diff) {
20608 smallest_diff = diff;
20609 }
20610 }
20611
20612 return smallest_diff;
20613};
20614/**
20615 * Get the absolute min/max values for the passed data column.
20616 *
20617 * @param {DataSet|DataView|undefined} data The data containing the items for the Graph
20618 * @param {'x'|'y'|'z'} column The data column to process
20619 *
20620 * @returns {Range} A Range instance with min/max members properly set.
20621 */
20622
20623
20624DataGroup.prototype.getColumnRange = function (data, column) {
20625 var range = new Range_1(); // Adjust the range so that it covers all values in the passed data elements.
20626
20627 for (var i = 0; i < data.length; i++) {
20628 var item = data[i][column];
20629 range.adjust(item);
20630 }
20631
20632 return range;
20633};
20634/**
20635 * Determines the number of rows in the current data.
20636 *
20637 * @returns {number}
20638 */
20639
20640
20641DataGroup.prototype.getNumberOfRows = function () {
20642 return this.dataTable.length;
20643};
20644/**
20645 * Set default values for range
20646 *
20647 * The default values override the range values, if defined.
20648 *
20649 * Because it's possible that only defaultMin or defaultMax is set, it's better
20650 * to pass in a range already set with the min/max set from the data. Otherwise,
20651 * it's quite hard to process the min/max properly.
20652 *
20653 * @param {vis.Range} range
20654 * @param {number} [defaultMin=range.min]
20655 * @param {number} [defaultMax=range.max]
20656 * @private
20657 */
20658
20659
20660DataGroup.prototype._setRangeDefaults = function (range, defaultMin, defaultMax) {
20661 if (defaultMin !== undefined) {
20662 range.min = defaultMin;
20663 }
20664
20665 if (defaultMax !== undefined) {
20666 range.max = defaultMax;
20667 } // This is the original way that the default min/max values were adjusted.
20668 // TODO: Perhaps it's better if an error is thrown if the values do not agree.
20669 // But this will change the behaviour.
20670
20671
20672 if (range.max <= range.min) range.max = range.min + 1;
20673};
20674
20675DataGroup.prototype.getDataTable = function () {
20676 return this.dataTable;
20677};
20678
20679DataGroup.prototype.getDataSet = function () {
20680 return this.dataSet;
20681};
20682/**
20683 * Return all data values as a list of Point3d objects
20684 * @param {Array.<Object>} data
20685 * @returns {Array.<Object>}
20686 */
20687
20688
20689DataGroup.prototype.getDataPoints = function (data) {
20690 var dataPoints = [];
20691
20692 for (var i = 0; i < data.length; i++) {
20693 var point = new Point3d_1();
20694 point.x = data[i][this.colX] || 0;
20695 point.y = data[i][this.colY] || 0;
20696 point.z = data[i][this.colZ] || 0;
20697 point.data = data[i];
20698
20699 if (this.colValue !== undefined) {
20700 point.value = data[i][this.colValue] || 0;
20701 }
20702
20703 var obj = {};
20704 obj.point = point;
20705 obj.bottom = new Point3d_1(point.x, point.y, this.zRange.min);
20706 obj.trans = undefined;
20707 obj.screen = undefined;
20708 dataPoints.push(obj);
20709 }
20710
20711 return dataPoints;
20712};
20713/**
20714 * Copy all values from the data table to a matrix.
20715 *
20716 * The provided values are supposed to form a grid of (x,y) positions.
20717 * @param {Array.<Object>} data
20718 * @returns {Array.<Object>}
20719 * @private
20720 */
20721
20722
20723DataGroup.prototype.initDataAsMatrix = function (data) {
20724 // TODO: store the created matrix dataPoints in the filters instead of
20725 // reloading each time.
20726 var x, y, i, obj; // create two lists with all present x and y values
20727
20728 var dataX = this.getDistinctValues(this.colX, data);
20729 var dataY = this.getDistinctValues(this.colY, data);
20730 var dataPoints = this.getDataPoints(data); // create a grid, a 2d matrix, with all values.
20731
20732 var dataMatrix = []; // temporary data matrix
20733
20734 for (i = 0; i < dataPoints.length; i++) {
20735 obj = dataPoints[i]; // TODO: implement Array().indexOf() for Internet Explorer
20736
20737 var xIndex = dataX.indexOf(obj.point.x);
20738 var yIndex = dataY.indexOf(obj.point.y);
20739
20740 if (dataMatrix[xIndex] === undefined) {
20741 dataMatrix[xIndex] = [];
20742 }
20743
20744 dataMatrix[xIndex][yIndex] = obj;
20745 } // fill in the pointers to the neighbors.
20746
20747
20748 for (x = 0; x < dataMatrix.length; x++) {
20749 for (y = 0; y < dataMatrix[x].length; y++) {
20750 if (dataMatrix[x][y]) {
20751 dataMatrix[x][y].pointRight = x < dataMatrix.length - 1 ? dataMatrix[x + 1][y] : undefined;
20752 dataMatrix[x][y].pointTop = y < dataMatrix[x].length - 1 ? dataMatrix[x][y + 1] : undefined;
20753 dataMatrix[x][y].pointCross = x < dataMatrix.length - 1 && y < dataMatrix[x].length - 1 ? dataMatrix[x + 1][y + 1] : undefined;
20754 }
20755 }
20756 }
20757
20758 return dataPoints;
20759};
20760/**
20761 * Return common information, if present
20762 *
20763 * @returns {string}
20764 */
20765
20766
20767DataGroup.prototype.getInfo = function () {
20768 var dataFilter = this.dataFilter;
20769 if (!dataFilter) return undefined;
20770 return dataFilter.getLabel() + ': ' + dataFilter.getSelectedValue();
20771};
20772/**
20773 * Reload the data
20774 */
20775
20776
20777DataGroup.prototype.reload = function () {
20778 if (this.dataTable) {
20779 this.setData(this.dataTable);
20780 }
20781};
20782/**
20783 * Filter the data based on the current filter
20784 *
20785 * @param {Array} data
20786 * @returns {Array} dataPoints Array with point objects which can be drawn on
20787 * screen
20788 */
20789
20790
20791DataGroup.prototype._getDataPoints = function (data) {
20792 var dataPoints = [];
20793
20794 if (this.style === Settings.STYLE.GRID || this.style === Settings.STYLE.SURFACE) {
20795 dataPoints = this.initDataAsMatrix(data);
20796 } else {
20797 // 'dot', 'dot-line', etc.
20798 this._checkValueField(data);
20799
20800 dataPoints = this.getDataPoints(data);
20801
20802 if (this.style === Settings.STYLE.LINE) {
20803 // Add next member points for line drawing
20804 for (var i = 0; i < dataPoints.length; i++) {
20805 if (i > 0) {
20806 dataPoints[i - 1].pointNext = dataPoints[i];
20807 }
20808 }
20809 }
20810 }
20811
20812 return dataPoints;
20813};
20814/**
20815 * Check if the state is consistent for the use of the value field.
20816 *
20817 * Throws if a problem is detected.
20818 *
20819 * @param {Array.<Object>} data
20820 * @private
20821 */
20822
20823
20824DataGroup.prototype._checkValueField = function (data) {
20825 var hasValueField = this.style === Settings.STYLE.BARCOLOR || this.style === Settings.STYLE.BARSIZE || this.style === Settings.STYLE.DOTCOLOR || this.style === Settings.STYLE.DOTSIZE;
20826
20827 if (!hasValueField) {
20828 return; // No need to check further
20829 } // Following field must be present for the current graph style
20830
20831
20832 if (this.colValue === undefined) {
20833 throw new Error('Expected data to have ' + ' field \'style\' ' + ' for graph style \'' + this.style + '\'');
20834 } // The data must also contain this field.
20835 // Note that only first data element is checked.
20836
20837
20838 if (data[0][this.colValue] === undefined) {
20839 throw new Error('Expected data to have ' + ' field \'' + this.colValue + '\' ' + ' for graph style \'' + this.style + '\'');
20840 }
20841};
20842
20843var DataGroup_1 = DataGroup;
20844
20845var Validator$2 = Validator$1.Validator;
20846var printStyle$1 = Validator$1.printStyle;
20847var allOptions$2 = options.allOptions; /// enumerate the available styles
20848
20849Graph3d.STYLE = Settings.STYLE;
20850/**
20851 * Following label is used in the settings to describe values which should be
20852 * determined by the code while running, from the current data and graph style.
20853 *
20854 * Using 'undefined' directly achieves the same thing, but this is more
20855 * descriptive by describing the intent.
20856 */
20857
20858var autoByDefault = undefined;
20859/**
20860 * Default values for option settings.
20861 *
20862 * These are the values used when a Graph3d instance is initialized without
20863 * custom settings.
20864 *
20865 * If a field is not in this list, a default value of 'autoByDefault' is assumed,
20866 * which is just an alias for 'undefined'.
20867 */
20868
20869Graph3d.DEFAULTS = {
20870 width: '400px',
20871 height: '400px',
20872 filterLabel: 'time',
20873 legendLabel: 'value',
20874 xLabel: 'x',
20875 yLabel: 'y',
20876 zLabel: 'z',
20877 xValueLabel: function xValueLabel(v) {
20878 return v;
20879 },
20880 yValueLabel: function yValueLabel(v) {
20881 return v;
20882 },
20883 zValueLabel: function zValueLabel(v) {
20884 return v;
20885 },
20886 showXAxis: true,
20887 showYAxis: true,
20888 showZAxis: true,
20889 showGrid: true,
20890 showPerspective: true,
20891 showShadow: false,
20892 keepAspectRatio: true,
20893 verticalRatio: 0.5,
20894 // 0.1 to 1.0, where 1.0 results in a 'cube'
20895 dotSizeRatio: 0.02,
20896 // size of the dots as a fraction of the graph width
20897 dotSizeMinFraction: 0.5,
20898 // size of min-value dot as a fraction of dotSizeRatio
20899 dotSizeMaxFraction: 2.5,
20900 // size of max-value dot as a fraction of dotSizeRatio
20901 showAnimationControls: autoByDefault,
20902 animationInterval: 1000,
20903 // milliseconds
20904 animationPreload: false,
20905 animationAutoStart: autoByDefault,
20906 axisColor: '#4D4D4D',
20907 gridColor: '#D3D3D3',
20908 xCenter: '55%',
20909 yCenter: '50%',
20910 style: Graph3d.STYLE.DOT,
20911 tooltip: false,
20912 tooltipStyle: {
20913 content: {
20914 padding: '10px',
20915 border: '1px solid #4d4d4d',
20916 color: '#1a1a1a',
20917 background: 'rgba(255,255,255,0.7)',
20918 borderRadius: '2px',
20919 boxShadow: '5px 5px 10px rgba(128,128,128,0.5)'
20920 },
20921 line: {
20922 height: '40px',
20923 width: '0',
20924 borderLeft: '1px solid #4d4d4d',
20925 pointerEvents: 'none'
20926 },
20927 dot: {
20928 height: '0',
20929 width: '0',
20930 border: '5px solid #4d4d4d',
20931 borderRadius: '5px',
20932 pointerEvents: 'none'
20933 }
20934 },
20935 dataColor: {
20936 fill: '#7DC1FF',
20937 stroke: '#3267D2',
20938 strokeWidth: 1 // px
20939
20940 },
20941 cameraPosition: {
20942 horizontal: 1.0,
20943 vertical: 0.5,
20944 distance: 1.7
20945 },
20946 zoomable: true,
20947 ctrlToZoom: false,
20948
20949 /*
20950 The following fields are 'auto by default', see above.
20951 */
20952 showLegend: autoByDefault,
20953 // determined by graph style
20954 backgroundColor: autoByDefault,
20955 xBarWidth: autoByDefault,
20956 yBarWidth: autoByDefault,
20957 valueMin: autoByDefault,
20958 valueMax: autoByDefault,
20959 xMin: autoByDefault,
20960 xMax: autoByDefault,
20961 xStep: autoByDefault,
20962 yMin: autoByDefault,
20963 yMax: autoByDefault,
20964 yStep: autoByDefault,
20965 zMin: autoByDefault,
20966 zMax: autoByDefault,
20967 zStep: autoByDefault
20968}; // -----------------------------------------------------------------------------
20969// Class Graph3d
20970// -----------------------------------------------------------------------------
20971
20972/**
20973 * Graph3d displays data in 3d.
20974 *
20975 * Graph3d is developed in javascript as a Google Visualization Chart.
20976 *
20977 * @constructor Graph3d
20978 * @param {Element} container The DOM element in which the Graph3d will
20979 * be created. Normally a div element.
20980 * @param {DataSet | DataView | Array} [data]
20981 * @param {Object} [options]
20982 */
20983
20984function Graph3d(container, data, options) {
20985 if (!(this instanceof Graph3d)) {
20986 throw new SyntaxError('Constructor must be called with the new operator');
20987 } // create variables and set default values
20988
20989
20990 this.containerElement = container;
20991 this.dataGroup = new DataGroup_1();
20992 this.dataPoints = null; // The table with point objects
20993 // create a frame and canvas
20994
20995 this.create();
20996 Settings.setDefaults(Graph3d.DEFAULTS, this); // the column indexes
20997
20998 this.colX = undefined;
20999 this.colY = undefined;
21000 this.colZ = undefined;
21001 this.colValue = undefined; // TODO: customize axis range
21002 // apply options (also when undefined)
21003
21004 this.setOptions(options); // apply data
21005
21006 this.setData(data);
21007} // Extend Graph3d with an Emitter mixin
21008
21009
21010emitterComponent(Graph3d.prototype);
21011/**
21012 * Calculate the scaling values, dependent on the range in x, y, and z direction
21013 */
21014
21015Graph3d.prototype._setScale = function () {
21016 this.scale = new Point3d_1(1 / this.xRange.range(), 1 / this.yRange.range(), 1 / this.zRange.range()); // keep aspect ration between x and y scale if desired
21017
21018 if (this.keepAspectRatio) {
21019 if (this.scale.x < this.scale.y) {
21020 //noinspection JSSuspiciousNameCombination
21021 this.scale.y = this.scale.x;
21022 } else {
21023 //noinspection JSSuspiciousNameCombination
21024 this.scale.x = this.scale.y;
21025 }
21026 } // scale the vertical axis
21027
21028
21029 this.scale.z *= this.verticalRatio; // TODO: can this be automated? verticalRatio?
21030 // determine scale for (optional) value
21031
21032 if (this.valueRange !== undefined) {
21033 this.scale.value = 1 / this.valueRange.range();
21034 } // position the camera arm
21035
21036
21037 var xCenter = this.xRange.center() * this.scale.x;
21038 var yCenter = this.yRange.center() * this.scale.y;
21039 var zCenter = this.zRange.center() * this.scale.z;
21040 this.camera.setArmLocation(xCenter, yCenter, zCenter);
21041};
21042/**
21043 * Convert a 3D location to a 2D location on screen
21044 * Source: ttp://en.wikipedia.org/wiki/3D_projection
21045 *
21046 * @param {Point3d} point3d A 3D point with parameters x, y, z
21047 * @returns {Point2d} point2d A 2D point with parameters x, y
21048 */
21049
21050
21051Graph3d.prototype._convert3Dto2D = function (point3d) {
21052 var translation = this._convertPointToTranslation(point3d);
21053
21054 return this._convertTranslationToScreen(translation);
21055};
21056/**
21057 * Convert a 3D location its translation seen from the camera
21058 * Source: http://en.wikipedia.org/wiki/3D_projection
21059 *
21060 * @param {Point3d} point3d A 3D point with parameters x, y, z
21061 * @returns {Point3d} translation A 3D point with parameters x, y, z This is
21062 * the translation of the point, seen from the
21063 * camera.
21064 */
21065
21066
21067Graph3d.prototype._convertPointToTranslation = function (point3d) {
21068 var cameraLocation = this.camera.getCameraLocation(),
21069 cameraRotation = this.camera.getCameraRotation(),
21070 ax = point3d.x * this.scale.x,
21071 ay = point3d.y * this.scale.y,
21072 az = point3d.z * this.scale.z,
21073 cx = cameraLocation.x,
21074 cy = cameraLocation.y,
21075 cz = cameraLocation.z,
21076 // calculate angles
21077 sinTx = Math.sin(cameraRotation.x),
21078 cosTx = Math.cos(cameraRotation.x),
21079 sinTy = Math.sin(cameraRotation.y),
21080 cosTy = Math.cos(cameraRotation.y),
21081 sinTz = Math.sin(cameraRotation.z),
21082 cosTz = Math.cos(cameraRotation.z),
21083 // calculate translation
21084 dx = cosTy * (sinTz * (ay - cy) + cosTz * (ax - cx)) - sinTy * (az - cz),
21085 dy = sinTx * (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) + cosTx * (cosTz * (ay - cy) - sinTz * (ax - cx)),
21086 dz = cosTx * (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) - sinTx * (cosTz * (ay - cy) - sinTz * (ax - cx));
21087 return new Point3d_1(dx, dy, dz);
21088};
21089/**
21090 * Convert a translation point to a point on the screen
21091 *
21092 * @param {Point3d} translation A 3D point with parameters x, y, z This is
21093 * the translation of the point, seen from the
21094 * camera.
21095 * @returns {Point2d} point2d A 2D point with parameters x, y
21096 */
21097
21098
21099Graph3d.prototype._convertTranslationToScreen = function (translation) {
21100 var ex = this.eye.x,
21101 ey = this.eye.y,
21102 ez = this.eye.z,
21103 dx = translation.x,
21104 dy = translation.y,
21105 dz = translation.z; // calculate position on screen from translation
21106
21107 var bx;
21108 var by;
21109
21110 if (this.showPerspective) {
21111 bx = (dx - ex) * (ez / dz);
21112 by = (dy - ey) * (ez / dz);
21113 } else {
21114 bx = dx * -(ez / this.camera.getArmLength());
21115 by = dy * -(ez / this.camera.getArmLength());
21116 } // shift and scale the point to the center of the screen
21117 // use the width of the graph to scale both horizontally and vertically.
21118
21119
21120 return new Point2d_1(this.currentXCenter + bx * this.frame.canvas.clientWidth, this.currentYCenter - by * this.frame.canvas.clientWidth);
21121};
21122/**
21123 * Calculate the translations and screen positions of all points
21124 *
21125 * @param {Array.<Point3d>} points
21126 * @private
21127 */
21128
21129
21130Graph3d.prototype._calcTranslations = function (points) {
21131 for (var i = 0; i < points.length; i++) {
21132 var point = points[i];
21133 point.trans = this._convertPointToTranslation(point.point);
21134 point.screen = this._convertTranslationToScreen(point.trans); // calculate the translation of the point at the bottom (needed for sorting)
21135
21136 var transBottom = this._convertPointToTranslation(point.bottom);
21137
21138 point.dist = this.showPerspective ? transBottom.length() : -transBottom.z;
21139 } // sort the points on depth of their (x,y) position (not on z)
21140
21141
21142 var sortDepth = function sortDepth(a, b) {
21143 return b.dist - a.dist;
21144 };
21145
21146 points.sort(sortDepth);
21147};
21148/**
21149 * Transfer min/max values to the Graph3d instance.
21150 */
21151
21152
21153Graph3d.prototype._initializeRanges = function () {
21154 // TODO: later on, all min/maxes of all datagroups will be combined here
21155 var dg = this.dataGroup;
21156 this.xRange = dg.xRange;
21157 this.yRange = dg.yRange;
21158 this.zRange = dg.zRange;
21159 this.valueRange = dg.valueRange; // Values currently needed but which need to be sorted out for
21160 // the multiple graph case.
21161
21162 this.xStep = dg.xStep;
21163 this.yStep = dg.yStep;
21164 this.zStep = dg.zStep;
21165 this.xBarWidth = dg.xBarWidth;
21166 this.yBarWidth = dg.yBarWidth;
21167 this.colX = dg.colX;
21168 this.colY = dg.colY;
21169 this.colZ = dg.colZ;
21170 this.colValue = dg.colValue; // set the scale dependent on the ranges.
21171
21172 this._setScale();
21173};
21174/**
21175 * Return all data values as a list of Point3d objects
21176 *
21177 * @param {vis.DataSet} data
21178 * @returns {Array.<Object>}
21179 */
21180
21181
21182Graph3d.prototype.getDataPoints = function (data) {
21183 var dataPoints = [];
21184
21185 for (var i = 0; i < data.length; i++) {
21186 var point = new Point3d_1();
21187 point.x = data[i][this.colX] || 0;
21188 point.y = data[i][this.colY] || 0;
21189 point.z = data[i][this.colZ] || 0;
21190 point.data = data[i];
21191
21192 if (this.colValue !== undefined) {
21193 point.value = data[i][this.colValue] || 0;
21194 }
21195
21196 var obj = {};
21197 obj.point = point;
21198 obj.bottom = new Point3d_1(point.x, point.y, this.zRange.min);
21199 obj.trans = undefined;
21200 obj.screen = undefined;
21201 dataPoints.push(obj);
21202 }
21203
21204 return dataPoints;
21205};
21206/**
21207 * Filter the data based on the current filter
21208 *
21209 * @param {Array} data
21210 * @returns {Array} dataPoints Array with point objects which can be drawn on
21211 * screen
21212 */
21213
21214
21215Graph3d.prototype._getDataPoints = function (data) {
21216 // TODO: store the created matrix dataPoints in the filters instead of
21217 // reloading each time.
21218 var x, y, i, obj;
21219 var dataPoints = [];
21220
21221 if (this.style === Graph3d.STYLE.GRID || this.style === Graph3d.STYLE.SURFACE) {
21222 // copy all values from the data table to a matrix
21223 // the provided values are supposed to form a grid of (x,y) positions
21224 // create two lists with all present x and y values
21225 var dataX = this.dataGroup.getDistinctValues(this.colX, data);
21226 var dataY = this.dataGroup.getDistinctValues(this.colY, data);
21227 dataPoints = this.getDataPoints(data); // create a grid, a 2d matrix, with all values.
21228
21229 var dataMatrix = []; // temporary data matrix
21230
21231 for (i = 0; i < dataPoints.length; i++) {
21232 obj = dataPoints[i]; // TODO: implement Array().indexOf() for Internet Explorer
21233
21234 var xIndex = dataX.indexOf(obj.point.x);
21235 var yIndex = dataY.indexOf(obj.point.y);
21236
21237 if (dataMatrix[xIndex] === undefined) {
21238 dataMatrix[xIndex] = [];
21239 }
21240
21241 dataMatrix[xIndex][yIndex] = obj;
21242 } // fill in the pointers to the neighbors.
21243
21244
21245 for (x = 0; x < dataMatrix.length; x++) {
21246 for (y = 0; y < dataMatrix[x].length; y++) {
21247 if (dataMatrix[x][y]) {
21248 dataMatrix[x][y].pointRight = x < dataMatrix.length - 1 ? dataMatrix[x + 1][y] : undefined;
21249 dataMatrix[x][y].pointTop = y < dataMatrix[x].length - 1 ? dataMatrix[x][y + 1] : undefined;
21250 dataMatrix[x][y].pointCross = x < dataMatrix.length - 1 && y < dataMatrix[x].length - 1 ? dataMatrix[x + 1][y + 1] : undefined;
21251 }
21252 }
21253 }
21254 } else {
21255 // 'dot', 'dot-line', etc.
21256 this._checkValueField(data);
21257
21258 dataPoints = this.getDataPoints(data);
21259
21260 if (this.style === Graph3d.STYLE.LINE) {
21261 // Add next member points for line drawing
21262 for (i = 0; i < dataPoints.length; i++) {
21263 if (i > 0) {
21264 dataPoints[i - 1].pointNext = dataPoints[i];
21265 }
21266 }
21267 }
21268 }
21269
21270 return dataPoints;
21271};
21272/**
21273 * Create the main frame for the Graph3d.
21274 *
21275 * This function is executed once when a Graph3d object is created. The frame
21276 * contains a canvas, and this canvas contains all objects like the axis and
21277 * nodes.
21278 */
21279
21280
21281Graph3d.prototype.create = function () {
21282 // remove all elements from the container element.
21283 while (this.containerElement.hasChildNodes()) {
21284 this.containerElement.removeChild(this.containerElement.firstChild);
21285 }
21286
21287 this.frame = document.createElement('div');
21288 this.frame.style.position = 'relative';
21289 this.frame.style.overflow = 'hidden'; // create the graph canvas (HTML canvas element)
21290
21291 this.frame.canvas = document.createElement('canvas');
21292 this.frame.canvas.style.position = 'relative';
21293 this.frame.appendChild(this.frame.canvas); //if (!this.frame.canvas.getContext) {
21294
21295 {
21296 var noCanvas = document.createElement('DIV');
21297 noCanvas.style.color = 'red';
21298 noCanvas.style.fontWeight = 'bold';
21299 noCanvas.style.padding = '10px';
21300 noCanvas.innerHTML = 'Error: your browser does not support HTML canvas';
21301 this.frame.canvas.appendChild(noCanvas);
21302 }
21303 this.frame.filter = document.createElement('div');
21304 this.frame.filter.style.position = 'absolute';
21305 this.frame.filter.style.bottom = '0px';
21306 this.frame.filter.style.left = '0px';
21307 this.frame.filter.style.width = '100%';
21308 this.frame.appendChild(this.frame.filter); // add event listeners to handle moving and zooming the contents
21309
21310 var me = this;
21311
21312 var onmousedown = function onmousedown(event) {
21313 me._onMouseDown(event);
21314 };
21315
21316 var ontouchstart = function ontouchstart(event) {
21317 me._onTouchStart(event);
21318 };
21319
21320 var onmousewheel = function onmousewheel(event) {
21321 me._onWheel(event);
21322 };
21323
21324 var ontooltip = function ontooltip(event) {
21325 me._onTooltip(event);
21326 };
21327
21328 var onclick = function onclick(event) {
21329 me._onClick(event);
21330 }; // TODO: these events are never cleaned up... can give a 'memory leakage'
21331
21332
21333 util.addEventListener(this.frame.canvas, 'mousedown', onmousedown);
21334 util.addEventListener(this.frame.canvas, 'touchstart', ontouchstart);
21335 util.addEventListener(this.frame.canvas, 'mousewheel', onmousewheel);
21336 util.addEventListener(this.frame.canvas, 'mousemove', ontooltip);
21337 util.addEventListener(this.frame.canvas, 'click', onclick); // add the new graph to the container element
21338
21339 this.containerElement.appendChild(this.frame);
21340};
21341/**
21342 * Set a new size for the graph
21343 *
21344 * @param {number} width
21345 * @param {number} height
21346 * @private
21347 */
21348
21349
21350Graph3d.prototype._setSize = function (width, height) {
21351 this.frame.style.width = width;
21352 this.frame.style.height = height;
21353
21354 this._resizeCanvas();
21355};
21356/**
21357 * Resize the canvas to the current size of the frame
21358 */
21359
21360
21361Graph3d.prototype._resizeCanvas = function () {
21362 this.frame.canvas.style.width = '100%';
21363 this.frame.canvas.style.height = '100%';
21364 this.frame.canvas.width = this.frame.canvas.clientWidth;
21365 this.frame.canvas.height = this.frame.canvas.clientHeight; // adjust with for margin
21366
21367 this.frame.filter.style.width = this.frame.canvas.clientWidth - 2 * 10 + 'px';
21368};
21369/**
21370 * Start playing the animation, if requested and filter present. Only applicable
21371 * when animation data is available.
21372 */
21373
21374
21375Graph3d.prototype.animationStart = function () {
21376 // start animation when option is true
21377 if (!this.animationAutoStart || !this.dataGroup.dataFilter) return;
21378 if (!this.frame.filter || !this.frame.filter.slider) throw new Error('No animation available');
21379 this.frame.filter.slider.play();
21380};
21381/**
21382 * Stop animation
21383 */
21384
21385
21386Graph3d.prototype.animationStop = function () {
21387 if (!this.frame.filter || !this.frame.filter.slider) return;
21388 this.frame.filter.slider.stop();
21389};
21390/**
21391 * Resize the center position based on the current values in this.xCenter
21392 * and this.yCenter (which are strings with a percentage or a value
21393 * in pixels). The center positions are the variables this.currentXCenter
21394 * and this.currentYCenter
21395 */
21396
21397
21398Graph3d.prototype._resizeCenter = function () {
21399 // calculate the horizontal center position
21400 if (this.xCenter.charAt(this.xCenter.length - 1) === '%') {
21401 this.currentXCenter = parseFloat(this.xCenter) / 100 * this.frame.canvas.clientWidth;
21402 } else {
21403 this.currentXCenter = parseFloat(this.xCenter); // supposed to be in px
21404 } // calculate the vertical center position
21405
21406
21407 if (this.yCenter.charAt(this.yCenter.length - 1) === '%') {
21408 this.currentYCenter = parseFloat(this.yCenter) / 100 * (this.frame.canvas.clientHeight - this.frame.filter.clientHeight);
21409 } else {
21410 this.currentYCenter = parseFloat(this.yCenter); // supposed to be in px
21411 }
21412};
21413/**
21414 * Retrieve the current camera rotation
21415 *
21416 * @returns {object} An object with parameters horizontal, vertical, and
21417 * distance
21418 */
21419
21420
21421Graph3d.prototype.getCameraPosition = function () {
21422 var pos = this.camera.getArmRotation();
21423 pos.distance = this.camera.getArmLength();
21424 return pos;
21425};
21426/**
21427 * Load data into the 3D Graph
21428 *
21429 * @param {vis.DataSet} data
21430 * @private
21431 */
21432
21433
21434Graph3d.prototype._readData = function (data) {
21435 // read the data
21436 this.dataPoints = this.dataGroup.initializeData(this, data, this.style);
21437
21438 this._initializeRanges();
21439
21440 this._redrawFilter();
21441};
21442/**
21443 * Replace the dataset of the Graph3d
21444 *
21445 * @param {Array | DataSet | DataView} data
21446 */
21447
21448
21449Graph3d.prototype.setData = function (data) {
21450 if (data === undefined || data === null) return;
21451
21452 this._readData(data);
21453
21454 this.redraw();
21455 this.animationStart();
21456};
21457/**
21458 * Update the options. Options will be merged with current options
21459 *
21460 * @param {Object} options
21461 */
21462
21463
21464Graph3d.prototype.setOptions = function (options) {
21465 if (options === undefined) return;
21466 var errorFound = Validator$2.validate(options, allOptions$2);
21467
21468 if (errorFound === true) {
21469 console.log('%cErrors have been found in the supplied options object.', printStyle$1);
21470 }
21471
21472 this.animationStop();
21473 Settings.setOptions(options, this);
21474 this.setPointDrawingMethod();
21475
21476 this._setSize(this.width, this.height);
21477
21478 this.setData(this.dataGroup.getDataTable());
21479 this.animationStart();
21480};
21481/**
21482 * Determine which point drawing method to use for the current graph style.
21483 */
21484
21485
21486Graph3d.prototype.setPointDrawingMethod = function () {
21487 var method = undefined;
21488
21489 switch (this.style) {
21490 case Graph3d.STYLE.BAR:
21491 method = Graph3d.prototype._redrawBarGraphPoint;
21492 break;
21493
21494 case Graph3d.STYLE.BARCOLOR:
21495 method = Graph3d.prototype._redrawBarColorGraphPoint;
21496 break;
21497
21498 case Graph3d.STYLE.BARSIZE:
21499 method = Graph3d.prototype._redrawBarSizeGraphPoint;
21500 break;
21501
21502 case Graph3d.STYLE.DOT:
21503 method = Graph3d.prototype._redrawDotGraphPoint;
21504 break;
21505
21506 case Graph3d.STYLE.DOTLINE:
21507 method = Graph3d.prototype._redrawDotLineGraphPoint;
21508 break;
21509
21510 case Graph3d.STYLE.DOTCOLOR:
21511 method = Graph3d.prototype._redrawDotColorGraphPoint;
21512 break;
21513
21514 case Graph3d.STYLE.DOTSIZE:
21515 method = Graph3d.prototype._redrawDotSizeGraphPoint;
21516 break;
21517
21518 case Graph3d.STYLE.SURFACE:
21519 method = Graph3d.prototype._redrawSurfaceGraphPoint;
21520 break;
21521
21522 case Graph3d.STYLE.GRID:
21523 method = Graph3d.prototype._redrawGridGraphPoint;
21524 break;
21525
21526 case Graph3d.STYLE.LINE:
21527 method = Graph3d.prototype._redrawLineGraphPoint;
21528 break;
21529
21530 default:
21531 throw new Error('Can not determine point drawing method ' + 'for graph style \'' + this.style + '\'');
21532 }
21533
21534 this._pointDrawingMethod = method;
21535};
21536/**
21537 * Redraw the Graph.
21538 */
21539
21540
21541Graph3d.prototype.redraw = function () {
21542 if (this.dataPoints === undefined) {
21543 throw new Error('Graph data not initialized');
21544 }
21545
21546 this._resizeCanvas();
21547
21548 this._resizeCenter();
21549
21550 this._redrawSlider();
21551
21552 this._redrawClear();
21553
21554 this._redrawAxis();
21555
21556 this._redrawDataGraph();
21557
21558 this._redrawInfo();
21559
21560 this._redrawLegend();
21561};
21562/**
21563 * Get drawing context without exposing canvas
21564 *
21565 * @returns {CanvasRenderingContext2D}
21566 * @private
21567 */
21568
21569
21570Graph3d.prototype._getContext = function () {
21571 var canvas = this.frame.canvas;
21572 var ctx = canvas.getContext('2d');
21573 ctx.lineJoin = 'round';
21574 ctx.lineCap = 'round';
21575 return ctx;
21576};
21577/**
21578 * Clear the canvas before redrawing
21579 */
21580
21581
21582Graph3d.prototype._redrawClear = function () {
21583 var canvas = this.frame.canvas;
21584 var ctx = canvas.getContext('2d');
21585 ctx.clearRect(0, 0, canvas.width, canvas.height);
21586};
21587
21588Graph3d.prototype._dotSize = function () {
21589 return this.frame.clientWidth * this.dotSizeRatio;
21590};
21591/**
21592 * Get legend width
21593 *
21594 * @returns {*}
21595 * @private
21596 */
21597
21598
21599Graph3d.prototype._getLegendWidth = function () {
21600 var width;
21601
21602 if (this.style === Graph3d.STYLE.DOTSIZE) {
21603 var dotSize = this._dotSize(); //width = dotSize / 2 + dotSize * 2;
21604
21605
21606 width = dotSize * this.dotSizeMaxFraction;
21607 } else if (this.style === Graph3d.STYLE.BARSIZE) {
21608 width = this.xBarWidth;
21609 } else {
21610 width = 20;
21611 }
21612
21613 return width;
21614};
21615/**
21616 * Redraw the legend based on size, dot color, or surface height
21617 */
21618
21619
21620Graph3d.prototype._redrawLegend = function () {
21621 //Return without drawing anything, if no legend is specified
21622 if (this.showLegend !== true) {
21623 return;
21624 } // Do not draw legend when graph style does not support
21625
21626
21627 if (this.style === Graph3d.STYLE.LINE || this.style === Graph3d.STYLE.BARSIZE //TODO add legend support for BARSIZE
21628 ) {
21629 return;
21630 } // Legend types - size and color. Determine if size legend.
21631
21632
21633 var isSizeLegend = this.style === Graph3d.STYLE.BARSIZE || this.style === Graph3d.STYLE.DOTSIZE; // Legend is either tracking z values or style values. This flag if false means use z values.
21634
21635 var isValueLegend = this.style === Graph3d.STYLE.DOTSIZE || this.style === Graph3d.STYLE.DOTCOLOR || this.style === Graph3d.STYLE.BARCOLOR;
21636 var height = Math.max(this.frame.clientHeight * 0.25, 100);
21637 var top = this.margin;
21638
21639 var width = this._getLegendWidth(); // px - overwritten by size legend
21640
21641
21642 var right = this.frame.clientWidth - this.margin;
21643 var left = right - width;
21644 var bottom = top + height;
21645
21646 var ctx = this._getContext();
21647
21648 ctx.lineWidth = 1;
21649 ctx.font = '14px arial'; // TODO: put in options
21650
21651 if (isSizeLegend === false) {
21652 // draw the color bar
21653 var ymin = 0;
21654 var ymax = height; // Todo: make height customizable
21655
21656 var y;
21657
21658 for (y = ymin; y < ymax; y++) {
21659 var f = (y - ymin) / (ymax - ymin);
21660 var hue = f * 240;
21661
21662 var color = this._hsv2rgb(hue, 1, 1);
21663
21664 ctx.strokeStyle = color;
21665 ctx.beginPath();
21666 ctx.moveTo(left, top + y);
21667 ctx.lineTo(right, top + y);
21668 ctx.stroke();
21669 }
21670
21671 ctx.strokeStyle = this.axisColor;
21672 ctx.strokeRect(left, top, width, height);
21673 } else {
21674 // draw the size legend box
21675 var widthMin;
21676
21677 if (this.style === Graph3d.STYLE.DOTSIZE) {
21678 // Get the proportion to max and min right
21679 widthMin = width * (this.dotSizeMinFraction / this.dotSizeMaxFraction);
21680 } else if (this.style === Graph3d.STYLE.BARSIZE) ;
21681
21682 ctx.strokeStyle = this.axisColor;
21683 ctx.fillStyle = this.dataColor.fill;
21684 ctx.beginPath();
21685 ctx.moveTo(left, top);
21686 ctx.lineTo(right, top);
21687 ctx.lineTo(left + widthMin, bottom);
21688 ctx.lineTo(left, bottom);
21689 ctx.closePath();
21690 ctx.fill();
21691 ctx.stroke();
21692 } // print value text along the legend edge
21693
21694
21695 var gridLineLen = 5; // px
21696
21697 var legendMin = isValueLegend ? this.valueRange.min : this.zRange.min;
21698 var legendMax = isValueLegend ? this.valueRange.max : this.zRange.max;
21699 var step = new StepNumber_1(legendMin, legendMax, (legendMax - legendMin) / 5, true);
21700 step.start(true);
21701 var from;
21702 var to;
21703
21704 while (!step.end()) {
21705 y = bottom - (step.getCurrent() - legendMin) / (legendMax - legendMin) * height;
21706 from = new Point2d_1(left - gridLineLen, y);
21707 to = new Point2d_1(left, y);
21708
21709 this._line(ctx, from, to);
21710
21711 ctx.textAlign = 'right';
21712 ctx.textBaseline = 'middle';
21713 ctx.fillStyle = this.axisColor;
21714 ctx.fillText(step.getCurrent(), left - 2 * gridLineLen, y);
21715 step.next();
21716 }
21717
21718 ctx.textAlign = 'right';
21719 ctx.textBaseline = 'top';
21720 var label = this.legendLabel;
21721 ctx.fillText(label, right, bottom + this.margin);
21722};
21723/**
21724 * Redraw the filter
21725 */
21726
21727
21728Graph3d.prototype._redrawFilter = function () {
21729 var dataFilter = this.dataGroup.dataFilter;
21730 var filter = this.frame.filter;
21731 filter.innerHTML = '';
21732
21733 if (!dataFilter) {
21734 filter.slider = undefined;
21735 return;
21736 }
21737
21738 var options = {
21739 'visible': this.showAnimationControls
21740 };
21741 var slider = new Slider_1(filter, options);
21742 filter.slider = slider; // TODO: css here is not nice here...
21743
21744 filter.style.padding = '10px'; //this.frame.filter.style.backgroundColor = '#EFEFEF';
21745
21746 slider.setValues(dataFilter.values);
21747 slider.setPlayInterval(this.animationInterval); // create an event handler
21748
21749 var me = this;
21750
21751 var onchange = function onchange() {
21752 var dataFilter = me.dataGroup.dataFilter;
21753 var index = slider.getIndex();
21754 dataFilter.selectValue(index);
21755 me.dataPoints = dataFilter._getDataPoints();
21756 me.redraw();
21757 };
21758
21759 slider.setOnChangeCallback(onchange);
21760};
21761/**
21762 * Redraw the slider
21763 */
21764
21765
21766Graph3d.prototype._redrawSlider = function () {
21767 if (this.frame.filter.slider !== undefined) {
21768 this.frame.filter.slider.redraw();
21769 }
21770};
21771/**
21772 * Redraw common information
21773 */
21774
21775
21776Graph3d.prototype._redrawInfo = function () {
21777 var info = this.dataGroup.getInfo();
21778 if (info === undefined) return;
21779
21780 var ctx = this._getContext();
21781
21782 ctx.font = '14px arial'; // TODO: put in options
21783
21784 ctx.lineStyle = 'gray';
21785 ctx.fillStyle = 'gray';
21786 ctx.textAlign = 'left';
21787 ctx.textBaseline = 'top';
21788 var x = this.margin;
21789 var y = this.margin;
21790 ctx.fillText(info, x, y);
21791};
21792/**
21793 * Draw a line between 2d points 'from' and 'to'.
21794 *
21795 * If stroke style specified, set that as well.
21796 *
21797 * @param {CanvasRenderingContext2D} ctx
21798 * @param {vis.Point2d} from
21799 * @param {vis.Point2d} to
21800 * @param {string} [strokeStyle]
21801 * @private
21802 */
21803
21804
21805Graph3d.prototype._line = function (ctx, from, to, strokeStyle) {
21806 if (strokeStyle !== undefined) {
21807 ctx.strokeStyle = strokeStyle;
21808 }
21809
21810 ctx.beginPath();
21811 ctx.moveTo(from.x, from.y);
21812 ctx.lineTo(to.x, to.y);
21813 ctx.stroke();
21814};
21815/**
21816 *
21817 * @param {CanvasRenderingContext2D} ctx
21818 * @param {vis.Point3d} point3d
21819 * @param {string} text
21820 * @param {number} armAngle
21821 * @param {number} [yMargin=0]
21822 */
21823
21824
21825Graph3d.prototype.drawAxisLabelX = function (ctx, point3d, text, armAngle, yMargin) {
21826 if (yMargin === undefined) {
21827 yMargin = 0;
21828 }
21829
21830 var point2d = this._convert3Dto2D(point3d);
21831
21832 if (Math.cos(armAngle * 2) > 0) {
21833 ctx.textAlign = 'center';
21834 ctx.textBaseline = 'top';
21835 point2d.y += yMargin;
21836 } else if (Math.sin(armAngle * 2) < 0) {
21837 ctx.textAlign = 'right';
21838 ctx.textBaseline = 'middle';
21839 } else {
21840 ctx.textAlign = 'left';
21841 ctx.textBaseline = 'middle';
21842 }
21843
21844 ctx.fillStyle = this.axisColor;
21845 ctx.fillText(text, point2d.x, point2d.y);
21846};
21847/**
21848 *
21849 * @param {CanvasRenderingContext2D} ctx
21850 * @param {vis.Point3d} point3d
21851 * @param {string} text
21852 * @param {number} armAngle
21853 * @param {number} [yMargin=0]
21854 */
21855
21856
21857Graph3d.prototype.drawAxisLabelY = function (ctx, point3d, text, armAngle, yMargin) {
21858 if (yMargin === undefined) {
21859 yMargin = 0;
21860 }
21861
21862 var point2d = this._convert3Dto2D(point3d);
21863
21864 if (Math.cos(armAngle * 2) < 0) {
21865 ctx.textAlign = 'center';
21866 ctx.textBaseline = 'top';
21867 point2d.y += yMargin;
21868 } else if (Math.sin(armAngle * 2) > 0) {
21869 ctx.textAlign = 'right';
21870 ctx.textBaseline = 'middle';
21871 } else {
21872 ctx.textAlign = 'left';
21873 ctx.textBaseline = 'middle';
21874 }
21875
21876 ctx.fillStyle = this.axisColor;
21877 ctx.fillText(text, point2d.x, point2d.y);
21878};
21879/**
21880 *
21881 * @param {CanvasRenderingContext2D} ctx
21882 * @param {vis.Point3d} point3d
21883 * @param {string} text
21884 * @param {number} [offset=0]
21885 */
21886
21887
21888Graph3d.prototype.drawAxisLabelZ = function (ctx, point3d, text, offset) {
21889 if (offset === undefined) {
21890 offset = 0;
21891 }
21892
21893 var point2d = this._convert3Dto2D(point3d);
21894
21895 ctx.textAlign = 'right';
21896 ctx.textBaseline = 'middle';
21897 ctx.fillStyle = this.axisColor;
21898 ctx.fillText(text, point2d.x - offset, point2d.y);
21899};
21900/**
21901
21902
21903/**
21904 * Draw a line between 2d points 'from' and 'to'.
21905 *
21906 * If stroke style specified, set that as well.
21907 *
21908 * @param {CanvasRenderingContext2D} ctx
21909 * @param {vis.Point2d} from
21910 * @param {vis.Point2d} to
21911 * @param {string} [strokeStyle]
21912 * @private
21913 */
21914
21915
21916Graph3d.prototype._line3d = function (ctx, from, to, strokeStyle) {
21917 var from2d = this._convert3Dto2D(from);
21918
21919 var to2d = this._convert3Dto2D(to);
21920
21921 this._line(ctx, from2d, to2d, strokeStyle);
21922};
21923/**
21924 * Redraw the axis
21925 */
21926
21927
21928Graph3d.prototype._redrawAxis = function () {
21929 var ctx = this._getContext(),
21930 from,
21931 to,
21932 step,
21933 prettyStep,
21934 text,
21935 xText,
21936 yText,
21937 zText,
21938 offset,
21939 xOffset,
21940 yOffset; // TODO: get the actual rendered style of the containerElement
21941 //ctx.font = this.containerElement.style.font;
21942
21943
21944 ctx.font = 24 / this.camera.getArmLength() + 'px arial'; // calculate the length for the short grid lines
21945
21946 var gridLenX = 0.025 / this.scale.x;
21947 var gridLenY = 0.025 / this.scale.y;
21948 var textMargin = 5 / this.camera.getArmLength(); // px
21949
21950 var armAngle = this.camera.getArmRotation().horizontal;
21951 var armVector = new Point2d_1(Math.cos(armAngle), Math.sin(armAngle));
21952 var xRange = this.xRange;
21953 var yRange = this.yRange;
21954 var zRange = this.zRange;
21955 var point3d; // draw x-grid lines
21956
21957 ctx.lineWidth = 1;
21958 prettyStep = this.defaultXStep === undefined;
21959 step = new StepNumber_1(xRange.min, xRange.max, this.xStep, prettyStep);
21960 step.start(true);
21961
21962 while (!step.end()) {
21963 var x = step.getCurrent();
21964
21965 if (this.showGrid) {
21966 from = new Point3d_1(x, yRange.min, zRange.min);
21967 to = new Point3d_1(x, yRange.max, zRange.min);
21968
21969 this._line3d(ctx, from, to, this.gridColor);
21970 } else if (this.showXAxis) {
21971 from = new Point3d_1(x, yRange.min, zRange.min);
21972 to = new Point3d_1(x, yRange.min + gridLenX, zRange.min);
21973
21974 this._line3d(ctx, from, to, this.axisColor);
21975
21976 from = new Point3d_1(x, yRange.max, zRange.min);
21977 to = new Point3d_1(x, yRange.max - gridLenX, zRange.min);
21978
21979 this._line3d(ctx, from, to, this.axisColor);
21980 }
21981
21982 if (this.showXAxis) {
21983 yText = armVector.x > 0 ? yRange.min : yRange.max;
21984 point3d = new Point3d_1(x, yText, zRange.min);
21985 var msg = ' ' + this.xValueLabel(x) + ' ';
21986 this.drawAxisLabelX(ctx, point3d, msg, armAngle, textMargin);
21987 }
21988
21989 step.next();
21990 } // draw y-grid lines
21991
21992
21993 ctx.lineWidth = 1;
21994 prettyStep = this.defaultYStep === undefined;
21995 step = new StepNumber_1(yRange.min, yRange.max, this.yStep, prettyStep);
21996 step.start(true);
21997
21998 while (!step.end()) {
21999 var y = step.getCurrent();
22000
22001 if (this.showGrid) {
22002 from = new Point3d_1(xRange.min, y, zRange.min);
22003 to = new Point3d_1(xRange.max, y, zRange.min);
22004
22005 this._line3d(ctx, from, to, this.gridColor);
22006 } else if (this.showYAxis) {
22007 from = new Point3d_1(xRange.min, y, zRange.min);
22008 to = new Point3d_1(xRange.min + gridLenY, y, zRange.min);
22009
22010 this._line3d(ctx, from, to, this.axisColor);
22011
22012 from = new Point3d_1(xRange.max, y, zRange.min);
22013 to = new Point3d_1(xRange.max - gridLenY, y, zRange.min);
22014
22015 this._line3d(ctx, from, to, this.axisColor);
22016 }
22017
22018 if (this.showYAxis) {
22019 xText = armVector.y > 0 ? xRange.min : xRange.max;
22020 point3d = new Point3d_1(xText, y, zRange.min);
22021
22022 var _msg = ' ' + this.yValueLabel(y) + ' ';
22023
22024 this.drawAxisLabelY(ctx, point3d, _msg, armAngle, textMargin);
22025 }
22026
22027 step.next();
22028 } // draw z-grid lines and axis
22029
22030
22031 if (this.showZAxis) {
22032 ctx.lineWidth = 1;
22033 prettyStep = this.defaultZStep === undefined;
22034 step = new StepNumber_1(zRange.min, zRange.max, this.zStep, prettyStep);
22035 step.start(true);
22036 xText = armVector.x > 0 ? xRange.min : xRange.max;
22037 yText = armVector.y < 0 ? yRange.min : yRange.max;
22038
22039 while (!step.end()) {
22040 var z = step.getCurrent(); // TODO: make z-grid lines really 3d?
22041
22042 var from3d = new Point3d_1(xText, yText, z);
22043
22044 var from2d = this._convert3Dto2D(from3d);
22045
22046 to = new Point2d_1(from2d.x - textMargin, from2d.y);
22047
22048 this._line(ctx, from2d, to, this.axisColor);
22049
22050 var _msg2 = this.zValueLabel(z) + ' ';
22051
22052 this.drawAxisLabelZ(ctx, from3d, _msg2, 5);
22053 step.next();
22054 }
22055
22056 ctx.lineWidth = 1;
22057 from = new Point3d_1(xText, yText, zRange.min);
22058 to = new Point3d_1(xText, yText, zRange.max);
22059
22060 this._line3d(ctx, from, to, this.axisColor);
22061 } // draw x-axis
22062
22063
22064 if (this.showXAxis) {
22065 var xMin2d;
22066 var xMax2d;
22067 ctx.lineWidth = 1; // line at yMin
22068
22069 xMin2d = new Point3d_1(xRange.min, yRange.min, zRange.min);
22070 xMax2d = new Point3d_1(xRange.max, yRange.min, zRange.min);
22071
22072 this._line3d(ctx, xMin2d, xMax2d, this.axisColor); // line at ymax
22073
22074
22075 xMin2d = new Point3d_1(xRange.min, yRange.max, zRange.min);
22076 xMax2d = new Point3d_1(xRange.max, yRange.max, zRange.min);
22077
22078 this._line3d(ctx, xMin2d, xMax2d, this.axisColor);
22079 } // draw y-axis
22080
22081
22082 if (this.showYAxis) {
22083 ctx.lineWidth = 1; // line at xMin
22084
22085 from = new Point3d_1(xRange.min, yRange.min, zRange.min);
22086 to = new Point3d_1(xRange.min, yRange.max, zRange.min);
22087
22088 this._line3d(ctx, from, to, this.axisColor); // line at xMax
22089
22090
22091 from = new Point3d_1(xRange.max, yRange.min, zRange.min);
22092 to = new Point3d_1(xRange.max, yRange.max, zRange.min);
22093
22094 this._line3d(ctx, from, to, this.axisColor);
22095 } // draw x-label
22096
22097
22098 var xLabel = this.xLabel;
22099
22100 if (xLabel.length > 0 && this.showXAxis) {
22101 yOffset = 0.1 / this.scale.y;
22102 xText = (xRange.max + 3 * xRange.min) / 4;
22103 yText = armVector.x > 0 ? yRange.min - yOffset : yRange.max + yOffset;
22104 text = new Point3d_1(xText, yText, zRange.min);
22105 this.drawAxisLabelX(ctx, text, xLabel, armAngle);
22106 } // draw y-label
22107
22108
22109 var yLabel = this.yLabel;
22110
22111 if (yLabel.length > 0 && this.showYAxis) {
22112 xOffset = 0.1 / this.scale.x;
22113 xText = armVector.y > 0 ? xRange.min - xOffset : xRange.max + xOffset;
22114 yText = (yRange.max + 3 * yRange.min) / 4;
22115 text = new Point3d_1(xText, yText, zRange.min);
22116 this.drawAxisLabelY(ctx, text, yLabel, armAngle);
22117 } // draw z-label
22118
22119
22120 var zLabel = this.zLabel;
22121
22122 if (zLabel.length > 0 && this.showZAxis) {
22123 offset = 30; // pixels. // TODO: relate to the max width of the values on the z axis?
22124
22125 xText = armVector.x > 0 ? xRange.min : xRange.max;
22126 yText = armVector.y < 0 ? yRange.min : yRange.max;
22127 zText = (zRange.max + 3 * zRange.min) / 4;
22128 text = new Point3d_1(xText, yText, zText);
22129 this.drawAxisLabelZ(ctx, text, zLabel, offset);
22130 }
22131};
22132/**
22133 * Calculate the color based on the given value.
22134 * @param {number} H Hue, a value be between 0 and 360
22135 * @param {number} S Saturation, a value between 0 and 1
22136 * @param {number} V Value, a value between 0 and 1
22137 * @returns {string}
22138 * @private
22139 */
22140
22141
22142Graph3d.prototype._hsv2rgb = function (H, S, V) {
22143 var R, G, B, C, Hi, X;
22144 C = V * S;
22145 Hi = Math.floor(H / 60); // hi = 0,1,2,3,4,5
22146
22147 X = C * (1 - Math.abs(H / 60 % 2 - 1));
22148
22149 switch (Hi) {
22150 case 0:
22151 R = C;
22152 G = X;
22153 B = 0;
22154 break;
22155
22156 case 1:
22157 R = X;
22158 G = C;
22159 B = 0;
22160 break;
22161
22162 case 2:
22163 R = 0;
22164 G = C;
22165 B = X;
22166 break;
22167
22168 case 3:
22169 R = 0;
22170 G = X;
22171 B = C;
22172 break;
22173
22174 case 4:
22175 R = X;
22176 G = 0;
22177 B = C;
22178 break;
22179
22180 case 5:
22181 R = C;
22182 G = 0;
22183 B = X;
22184 break;
22185
22186 default:
22187 R = 0;
22188 G = 0;
22189 B = 0;
22190 break;
22191 }
22192
22193 return 'RGB(' + parseInt(R * 255) + ',' + parseInt(G * 255) + ',' + parseInt(B * 255) + ')';
22194};
22195/**
22196 *
22197 * @param {vis.Point3d} point
22198 * @returns {*}
22199 * @private
22200 */
22201
22202
22203Graph3d.prototype._getStrokeWidth = function (point) {
22204 if (point !== undefined) {
22205 if (this.showPerspective) {
22206 return 1 / -point.trans.z * this.dataColor.strokeWidth;
22207 } else {
22208 return -(this.eye.z / this.camera.getArmLength()) * this.dataColor.strokeWidth;
22209 }
22210 }
22211
22212 return this.dataColor.strokeWidth;
22213}; // -----------------------------------------------------------------------------
22214// Drawing primitives for the graphs
22215// -----------------------------------------------------------------------------
22216
22217/**
22218 * Draw a bar element in the view with the given properties.
22219 *
22220 * @param {CanvasRenderingContext2D} ctx
22221 * @param {Object} point
22222 * @param {number} xWidth
22223 * @param {number} yWidth
22224 * @param {string} color
22225 * @param {string} borderColor
22226 * @private
22227 */
22228
22229
22230Graph3d.prototype._redrawBar = function (ctx, point, xWidth, yWidth, color, borderColor) {
22231 var surface; // calculate all corner points
22232
22233 var me = this;
22234 var point3d = point.point;
22235 var zMin = this.zRange.min;
22236 var top = [{
22237 point: new Point3d_1(point3d.x - xWidth, point3d.y - yWidth, point3d.z)
22238 }, {
22239 point: new Point3d_1(point3d.x + xWidth, point3d.y - yWidth, point3d.z)
22240 }, {
22241 point: new Point3d_1(point3d.x + xWidth, point3d.y + yWidth, point3d.z)
22242 }, {
22243 point: new Point3d_1(point3d.x - xWidth, point3d.y + yWidth, point3d.z)
22244 }];
22245 var bottom = [{
22246 point: new Point3d_1(point3d.x - xWidth, point3d.y - yWidth, zMin)
22247 }, {
22248 point: new Point3d_1(point3d.x + xWidth, point3d.y - yWidth, zMin)
22249 }, {
22250 point: new Point3d_1(point3d.x + xWidth, point3d.y + yWidth, zMin)
22251 }, {
22252 point: new Point3d_1(point3d.x - xWidth, point3d.y + yWidth, zMin)
22253 }]; // calculate screen location of the points
22254
22255 top.forEach(function (obj) {
22256 obj.screen = me._convert3Dto2D(obj.point);
22257 });
22258 bottom.forEach(function (obj) {
22259 obj.screen = me._convert3Dto2D(obj.point);
22260 }); // create five sides, calculate both corner points and center points
22261
22262 var surfaces = [{
22263 corners: top,
22264 center: Point3d_1.avg(bottom[0].point, bottom[2].point)
22265 }, {
22266 corners: [top[0], top[1], bottom[1], bottom[0]],
22267 center: Point3d_1.avg(bottom[1].point, bottom[0].point)
22268 }, {
22269 corners: [top[1], top[2], bottom[2], bottom[1]],
22270 center: Point3d_1.avg(bottom[2].point, bottom[1].point)
22271 }, {
22272 corners: [top[2], top[3], bottom[3], bottom[2]],
22273 center: Point3d_1.avg(bottom[3].point, bottom[2].point)
22274 }, {
22275 corners: [top[3], top[0], bottom[0], bottom[3]],
22276 center: Point3d_1.avg(bottom[0].point, bottom[3].point)
22277 }];
22278 point.surfaces = surfaces; // calculate the distance of each of the surface centers to the camera
22279
22280 for (var j = 0; j < surfaces.length; j++) {
22281 surface = surfaces[j];
22282
22283 var transCenter = this._convertPointToTranslation(surface.center);
22284
22285 surface.dist = this.showPerspective ? transCenter.length() : -transCenter.z; // TODO: this dept calculation doesn't work 100% of the cases due to perspective,
22286 // but the current solution is fast/simple and works in 99.9% of all cases
22287 // the issue is visible in example 14, with graph.setCameraPosition({horizontal: 2.97, vertical: 0.5, distance: 0.9})
22288 } // order the surfaces by their (translated) depth
22289
22290
22291 surfaces.sort(function (a, b) {
22292 var diff = b.dist - a.dist;
22293 if (diff) return diff; // if equal depth, sort the top surface last
22294
22295 if (a.corners === top) return 1;
22296 if (b.corners === top) return -1; // both are equal
22297
22298 return 0;
22299 }); // draw the ordered surfaces
22300
22301 ctx.lineWidth = this._getStrokeWidth(point);
22302 ctx.strokeStyle = borderColor;
22303 ctx.fillStyle = color; // NOTE: we start at j=2 instead of j=0 as we don't need to draw the two surfaces at the backside
22304
22305 for (var _j = 2; _j < surfaces.length; _j++) {
22306 surface = surfaces[_j];
22307
22308 this._polygon(ctx, surface.corners);
22309 }
22310};
22311/**
22312 * Draw a polygon using the passed points and fill it with the passed style and stroke.
22313 *
22314 * @param {CanvasRenderingContext2D} ctx
22315 * @param {Array.<vis.Point3d>} points an array of points.
22316 * @param {string} [fillStyle] the fill style to set
22317 * @param {string} [strokeStyle] the stroke style to set
22318 */
22319
22320
22321Graph3d.prototype._polygon = function (ctx, points, fillStyle, strokeStyle) {
22322 if (points.length < 2) {
22323 return;
22324 }
22325
22326 if (fillStyle !== undefined) {
22327 ctx.fillStyle = fillStyle;
22328 }
22329
22330 if (strokeStyle !== undefined) {
22331 ctx.strokeStyle = strokeStyle;
22332 }
22333
22334 ctx.beginPath();
22335 ctx.moveTo(points[0].screen.x, points[0].screen.y);
22336
22337 for (var i = 1; i < points.length; ++i) {
22338 var point = points[i];
22339 ctx.lineTo(point.screen.x, point.screen.y);
22340 }
22341
22342 ctx.closePath();
22343 ctx.fill();
22344 ctx.stroke(); // TODO: only draw stroke when strokeWidth > 0
22345};
22346/**
22347 * @param {CanvasRenderingContext2D} ctx
22348 * @param {object} point
22349 * @param {string} color
22350 * @param {string} borderColor
22351 * @param {number} [size=this._dotSize()]
22352 * @private
22353 */
22354
22355
22356Graph3d.prototype._drawCircle = function (ctx, point, color, borderColor, size) {
22357 var radius = this._calcRadius(point, size);
22358
22359 ctx.lineWidth = this._getStrokeWidth(point);
22360 ctx.strokeStyle = borderColor;
22361 ctx.fillStyle = color;
22362 ctx.beginPath();
22363 ctx.arc(point.screen.x, point.screen.y, radius, 0, Math.PI * 2, true);
22364 ctx.fill();
22365 ctx.stroke();
22366};
22367/**
22368 * Determine the colors for the 'regular' graph styles.
22369 *
22370 * @param {object} point
22371 * @returns {{fill, border}}
22372 * @private
22373 */
22374
22375
22376Graph3d.prototype._getColorsRegular = function (point) {
22377 // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0
22378 var hue = (1 - (point.point.z - this.zRange.min) * this.scale.z / this.verticalRatio) * 240;
22379
22380 var color = this._hsv2rgb(hue, 1, 1);
22381
22382 var borderColor = this._hsv2rgb(hue, 1, 0.8);
22383
22384 return {
22385 fill: color,
22386 border: borderColor
22387 };
22388};
22389/**
22390 * Get the colors for the 'color' graph styles.
22391 * These styles are currently: 'bar-color' and 'dot-color'
22392 * Color may be set as a string representation of HTML color, like #ff00ff,
22393 * or calculated from a number, for example, distance from this point
22394 * The first option is useful when we have some pre-given legend, to which we have to adjust ourselves
22395 * The second option is useful when we are interested in automatically setting the color, from some value,
22396 * using some color scale
22397 * @param {object} point
22398 * @returns {{fill: *, border: *}}
22399 * @private
22400 */
22401
22402
22403Graph3d.prototype._getColorsColor = function (point) {
22404 // calculate the color based on the value
22405 var color, borderColor;
22406
22407 if (typeof point.point.value === "string") {
22408 color = point.point.value;
22409 borderColor = point.point.value;
22410 } else {
22411 var hue = (1 - (point.point.value - this.valueRange.min) * this.scale.value) * 240;
22412 color = this._hsv2rgb(hue, 1, 1);
22413 borderColor = this._hsv2rgb(hue, 1, 0.8);
22414 }
22415
22416 return {
22417 fill: color,
22418 border: borderColor
22419 };
22420};
22421/**
22422 * Get the colors for the 'size' graph styles.
22423 * These styles are currently: 'bar-size' and 'dot-size'
22424 *
22425 * @returns {{fill: *, border: (string|colorOptions.stroke|{string, undefined}|string|colorOptions.stroke|{string}|*)}}
22426 * @private
22427 */
22428
22429
22430Graph3d.prototype._getColorsSize = function () {
22431 return {
22432 fill: this.dataColor.fill,
22433 border: this.dataColor.stroke
22434 };
22435};
22436/**
22437 * Determine the size of a point on-screen, as determined by the
22438 * distance to the camera.
22439 *
22440 * @param {Object} point
22441 * @param {number} [size=this._dotSize()] the size that needs to be translated to screen coordinates.
22442 * optional; if not passed, use the default point size.
22443 * @returns {number}
22444 * @private
22445 */
22446
22447
22448Graph3d.prototype._calcRadius = function (point, size) {
22449 if (size === undefined) {
22450 size = this._dotSize();
22451 }
22452
22453 var radius;
22454
22455 if (this.showPerspective) {
22456 radius = size / -point.trans.z;
22457 } else {
22458 radius = size * -(this.eye.z / this.camera.getArmLength());
22459 }
22460
22461 if (radius < 0) {
22462 radius = 0;
22463 }
22464
22465 return radius;
22466}; // -----------------------------------------------------------------------------
22467// Methods for drawing points per graph style.
22468// -----------------------------------------------------------------------------
22469
22470/**
22471 * Draw single datapoint for graph style 'bar'.
22472 *
22473 * @param {CanvasRenderingContext2D} ctx
22474 * @param {Object} point
22475 * @private
22476 */
22477
22478
22479Graph3d.prototype._redrawBarGraphPoint = function (ctx, point) {
22480 var xWidth = this.xBarWidth / 2;
22481 var yWidth = this.yBarWidth / 2;
22482
22483 var colors = this._getColorsRegular(point);
22484
22485 this._redrawBar(ctx, point, xWidth, yWidth, colors.fill, colors.border);
22486};
22487/**
22488 * Draw single datapoint for graph style 'bar-color'.
22489 *
22490 * @param {CanvasRenderingContext2D} ctx
22491 * @param {Object} point
22492 * @private
22493 */
22494
22495
22496Graph3d.prototype._redrawBarColorGraphPoint = function (ctx, point) {
22497 var xWidth = this.xBarWidth / 2;
22498 var yWidth = this.yBarWidth / 2;
22499
22500 var colors = this._getColorsColor(point);
22501
22502 this._redrawBar(ctx, point, xWidth, yWidth, colors.fill, colors.border);
22503};
22504/**
22505 * Draw single datapoint for graph style 'bar-size'.
22506 *
22507 * @param {CanvasRenderingContext2D} ctx
22508 * @param {Object} point
22509 * @private
22510 */
22511
22512
22513Graph3d.prototype._redrawBarSizeGraphPoint = function (ctx, point) {
22514 // calculate size for the bar
22515 var fraction = (point.point.value - this.valueRange.min) / this.valueRange.range();
22516 var xWidth = this.xBarWidth / 2 * (fraction * 0.8 + 0.2);
22517 var yWidth = this.yBarWidth / 2 * (fraction * 0.8 + 0.2);
22518
22519 var colors = this._getColorsSize();
22520
22521 this._redrawBar(ctx, point, xWidth, yWidth, colors.fill, colors.border);
22522};
22523/**
22524 * Draw single datapoint for graph style 'dot'.
22525 *
22526 * @param {CanvasRenderingContext2D} ctx
22527 * @param {Object} point
22528 * @private
22529 */
22530
22531
22532Graph3d.prototype._redrawDotGraphPoint = function (ctx, point) {
22533 var colors = this._getColorsRegular(point);
22534
22535 this._drawCircle(ctx, point, colors.fill, colors.border);
22536};
22537/**
22538 * Draw single datapoint for graph style 'dot-line'.
22539 *
22540 * @param {CanvasRenderingContext2D} ctx
22541 * @param {Object} point
22542 * @private
22543 */
22544
22545
22546Graph3d.prototype._redrawDotLineGraphPoint = function (ctx, point) {
22547 // draw a vertical line from the XY-plane to the graph value
22548 var from = this._convert3Dto2D(point.bottom);
22549
22550 ctx.lineWidth = 1;
22551
22552 this._line(ctx, from, point.screen, this.gridColor);
22553
22554 this._redrawDotGraphPoint(ctx, point);
22555};
22556/**
22557 * Draw single datapoint for graph style 'dot-color'.
22558 *
22559 * @param {CanvasRenderingContext2D} ctx
22560 * @param {Object} point
22561 * @private
22562 */
22563
22564
22565Graph3d.prototype._redrawDotColorGraphPoint = function (ctx, point) {
22566 var colors = this._getColorsColor(point);
22567
22568 this._drawCircle(ctx, point, colors.fill, colors.border);
22569};
22570/**
22571 * Draw single datapoint for graph style 'dot-size'.
22572 *
22573 * @param {CanvasRenderingContext2D} ctx
22574 * @param {Object} point
22575 * @private
22576 */
22577
22578
22579Graph3d.prototype._redrawDotSizeGraphPoint = function (ctx, point) {
22580 var dotSize = this._dotSize();
22581
22582 var fraction = (point.point.value - this.valueRange.min) / this.valueRange.range();
22583 var sizeMin = dotSize * this.dotSizeMinFraction;
22584 var sizeRange = dotSize * this.dotSizeMaxFraction - sizeMin;
22585 var size = sizeMin + sizeRange * fraction;
22586
22587 var colors = this._getColorsSize();
22588
22589 this._drawCircle(ctx, point, colors.fill, colors.border, size);
22590};
22591/**
22592 * Draw single datapoint for graph style 'surface'.
22593 *
22594 * @param {CanvasRenderingContext2D} ctx
22595 * @param {Object} point
22596 * @private
22597 */
22598
22599
22600Graph3d.prototype._redrawSurfaceGraphPoint = function (ctx, point) {
22601 var right = point.pointRight;
22602 var top = point.pointTop;
22603 var cross = point.pointCross;
22604
22605 if (point === undefined || right === undefined || top === undefined || cross === undefined) {
22606 return;
22607 }
22608
22609 var topSideVisible = true;
22610 var fillStyle;
22611 var strokeStyle;
22612
22613 if (this.showGrayBottom || this.showShadow) {
22614 // calculate the cross product of the two vectors from center
22615 // to left and right, in order to know whether we are looking at the
22616 // bottom or at the top side. We can also use the cross product
22617 // for calculating light intensity
22618 var aDiff = Point3d_1.subtract(cross.trans, point.trans);
22619 var bDiff = Point3d_1.subtract(top.trans, right.trans);
22620 var crossproduct = Point3d_1.crossProduct(aDiff, bDiff);
22621 var len = crossproduct.length(); // FIXME: there is a bug with determining the surface side (shadow or colored)
22622
22623 topSideVisible = crossproduct.z > 0;
22624 }
22625
22626 if (topSideVisible) {
22627 // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0
22628 var zAvg = (point.point.z + right.point.z + top.point.z + cross.point.z) / 4;
22629 var h = (1 - (zAvg - this.zRange.min) * this.scale.z / this.verticalRatio) * 240;
22630 var s = 1; // saturation
22631
22632 var v;
22633
22634 if (this.showShadow) {
22635 v = Math.min(1 + crossproduct.x / len / 2, 1); // value. TODO: scale
22636
22637 fillStyle = this._hsv2rgb(h, s, v);
22638 strokeStyle = fillStyle;
22639 } else {
22640 v = 1;
22641 fillStyle = this._hsv2rgb(h, s, v);
22642 strokeStyle = this.axisColor; // TODO: should be customizable
22643 }
22644 } else {
22645 fillStyle = 'gray';
22646 strokeStyle = this.axisColor;
22647 }
22648
22649 ctx.lineWidth = this._getStrokeWidth(point); // TODO: only draw stroke when strokeWidth > 0
22650
22651 var points = [point, right, cross, top];
22652
22653 this._polygon(ctx, points, fillStyle, strokeStyle);
22654};
22655/**
22656 * Helper method for _redrawGridGraphPoint()
22657 *
22658 * @param {CanvasRenderingContext2D} ctx
22659 * @param {Object} from
22660 * @param {Object} to
22661 * @private
22662 */
22663
22664
22665Graph3d.prototype._drawGridLine = function (ctx, from, to) {
22666 if (from === undefined || to === undefined) {
22667 return;
22668 } // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0
22669
22670
22671 var zAvg = (from.point.z + to.point.z) / 2;
22672 var h = (1 - (zAvg - this.zRange.min) * this.scale.z / this.verticalRatio) * 240;
22673 ctx.lineWidth = this._getStrokeWidth(from) * 2;
22674 ctx.strokeStyle = this._hsv2rgb(h, 1, 1);
22675
22676 this._line(ctx, from.screen, to.screen);
22677};
22678/**
22679 * Draw single datapoint for graph style 'Grid'.
22680 *
22681 * @param {CanvasRenderingContext2D} ctx
22682 * @param {Object} point
22683 * @private
22684 */
22685
22686
22687Graph3d.prototype._redrawGridGraphPoint = function (ctx, point) {
22688 this._drawGridLine(ctx, point, point.pointRight);
22689
22690 this._drawGridLine(ctx, point, point.pointTop);
22691};
22692/**
22693 * Draw single datapoint for graph style 'line'.
22694 *
22695 * @param {CanvasRenderingContext2D} ctx
22696 * @param {Object} point
22697 * @private
22698 */
22699
22700
22701Graph3d.prototype._redrawLineGraphPoint = function (ctx, point) {
22702 if (point.pointNext === undefined) {
22703 return;
22704 }
22705
22706 ctx.lineWidth = this._getStrokeWidth(point);
22707 ctx.strokeStyle = this.dataColor.stroke;
22708
22709 this._line(ctx, point.screen, point.pointNext.screen);
22710};
22711/**
22712 * Draw all datapoints for currently selected graph style.
22713 *
22714 */
22715
22716
22717Graph3d.prototype._redrawDataGraph = function () {
22718 var ctx = this._getContext();
22719
22720 var i;
22721 if (this.dataPoints === undefined || this.dataPoints.length <= 0) return; // TODO: throw exception?
22722
22723 this._calcTranslations(this.dataPoints);
22724
22725 for (i = 0; i < this.dataPoints.length; i++) {
22726 var point = this.dataPoints[i]; // Using call() ensures that the correct context is used
22727
22728 this._pointDrawingMethod.call(this, ctx, point);
22729 }
22730}; // -----------------------------------------------------------------------------
22731// End methods for drawing points per graph style.
22732// -----------------------------------------------------------------------------
22733
22734/**
22735 * Store startX, startY and startOffset for mouse operations
22736 *
22737 * @param {Event} event The event that occurred
22738 */
22739
22740
22741Graph3d.prototype._storeMousePosition = function (event) {
22742 // get mouse position (different code for IE and all other browsers)
22743 this.startMouseX = getMouseX(event);
22744 this.startMouseY = getMouseY(event);
22745 this._startCameraOffset = this.camera.getOffset();
22746};
22747/**
22748 * Start a moving operation inside the provided parent element
22749 * @param {Event} event The event that occurred (required for
22750 * retrieving the mouse position)
22751 */
22752
22753
22754Graph3d.prototype._onMouseDown = function (event) {
22755 event = event || window.event; // check if mouse is still down (may be up when focus is lost for example
22756 // in an iframe)
22757
22758 if (this.leftButtonDown) {
22759 this._onMouseUp(event);
22760 } // only react on left mouse button down
22761
22762
22763 this.leftButtonDown = event.which ? event.which === 1 : event.button === 1;
22764 if (!this.leftButtonDown && !this.touchDown) return;
22765
22766 this._storeMousePosition(event);
22767
22768 this.startStart = new Date(this.start);
22769 this.startEnd = new Date(this.end);
22770 this.startArmRotation = this.camera.getArmRotation();
22771 this.frame.style.cursor = 'move'; // add event listeners to handle moving the contents
22772 // we store the function onmousemove and onmouseup in the graph, so we can
22773 // remove the eventlisteners lateron in the function mouseUp()
22774
22775 var me = this;
22776
22777 this.onmousemove = function (event) {
22778 me._onMouseMove(event);
22779 };
22780
22781 this.onmouseup = function (event) {
22782 me._onMouseUp(event);
22783 };
22784
22785 util.addEventListener(document, 'mousemove', me.onmousemove);
22786 util.addEventListener(document, 'mouseup', me.onmouseup);
22787 util.preventDefault(event);
22788};
22789/**
22790 * Perform moving operating.
22791 * This function activated from within the funcion Graph.mouseDown().
22792 * @param {Event} event Well, eehh, the event
22793 */
22794
22795
22796Graph3d.prototype._onMouseMove = function (event) {
22797 this.moving = true;
22798 event = event || window.event; // calculate change in mouse position
22799
22800 var diffX = parseFloat(getMouseX(event)) - this.startMouseX;
22801 var diffY = parseFloat(getMouseY(event)) - this.startMouseY; // move with ctrl or rotate by other
22802
22803 if (event && event.ctrlKey === true) {
22804 // calculate change in mouse position
22805 var scaleX = this.frame.clientWidth * 0.5;
22806 var scaleY = this.frame.clientHeight * 0.5;
22807 var offXNew = (this._startCameraOffset.x || 0) - diffX / scaleX * this.camera.armLength * 0.8;
22808 var offYNew = (this._startCameraOffset.y || 0) + diffY / scaleY * this.camera.armLength * 0.8;
22809 this.camera.setOffset(offXNew, offYNew);
22810
22811 this._storeMousePosition(event);
22812 } else {
22813 var horizontalNew = this.startArmRotation.horizontal + diffX / 200;
22814 var verticalNew = this.startArmRotation.vertical + diffY / 200;
22815 var snapAngle = 4; // degrees
22816
22817 var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI); // snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc...
22818 // the -0.001 is to take care that the vertical axis is always drawn at the left front corner
22819
22820 if (Math.abs(Math.sin(horizontalNew)) < snapValue) {
22821 horizontalNew = Math.round(horizontalNew / Math.PI) * Math.PI - 0.001;
22822 }
22823
22824 if (Math.abs(Math.cos(horizontalNew)) < snapValue) {
22825 horizontalNew = (Math.round(horizontalNew / Math.PI - 0.5) + 0.5) * Math.PI - 0.001;
22826 } // snap vertically to nice angles
22827
22828
22829 if (Math.abs(Math.sin(verticalNew)) < snapValue) {
22830 verticalNew = Math.round(verticalNew / Math.PI) * Math.PI;
22831 }
22832
22833 if (Math.abs(Math.cos(verticalNew)) < snapValue) {
22834 verticalNew = (Math.round(verticalNew / Math.PI - 0.5) + 0.5) * Math.PI;
22835 }
22836
22837 this.camera.setArmRotation(horizontalNew, verticalNew);
22838 }
22839
22840 this.redraw(); // fire a cameraPositionChange event
22841
22842 var parameters = this.getCameraPosition();
22843 this.emit('cameraPositionChange', parameters);
22844 util.preventDefault(event);
22845};
22846/**
22847 * Stop moving operating.
22848 * This function activated from within the funcion Graph.mouseDown().
22849 * @param {Event} event The event
22850 */
22851
22852
22853Graph3d.prototype._onMouseUp = function (event) {
22854 this.frame.style.cursor = 'auto';
22855 this.leftButtonDown = false; // remove event listeners here
22856
22857 util.removeEventListener(document, 'mousemove', this.onmousemove);
22858 util.removeEventListener(document, 'mouseup', this.onmouseup);
22859 util.preventDefault(event);
22860};
22861/**
22862 * @param {Event} event The event
22863 */
22864
22865
22866Graph3d.prototype._onClick = function (event) {
22867 if (!this.onclick_callback) return;
22868
22869 if (!this.moving) {
22870 var boundingRect = this.frame.getBoundingClientRect();
22871 var mouseX = getMouseX(event) - boundingRect.left;
22872 var mouseY = getMouseY(event) - boundingRect.top;
22873
22874 var dataPoint = this._dataPointFromXY(mouseX, mouseY);
22875
22876 if (dataPoint) this.onclick_callback(dataPoint.point.data);
22877 } else {
22878 // disable onclick callback, if it came immediately after rotate/pan
22879 this.moving = false;
22880 }
22881
22882 util.preventDefault(event);
22883};
22884/**
22885 * After having moved the mouse, a tooltip should pop up when the mouse is resting on a data point
22886 * @param {Event} event A mouse move event
22887 */
22888
22889
22890Graph3d.prototype._onTooltip = function (event) {
22891 var delay = 300; // ms
22892
22893 var boundingRect = this.frame.getBoundingClientRect();
22894 var mouseX = getMouseX(event) - boundingRect.left;
22895 var mouseY = getMouseY(event) - boundingRect.top;
22896
22897 if (!this.showTooltip) {
22898 return;
22899 }
22900
22901 if (this.tooltipTimeout) {
22902 clearTimeout(this.tooltipTimeout);
22903 } // (delayed) display of a tooltip only if no mouse button is down
22904
22905
22906 if (this.leftButtonDown) {
22907 this._hideTooltip();
22908
22909 return;
22910 }
22911
22912 if (this.tooltip && this.tooltip.dataPoint) {
22913 // tooltip is currently visible
22914 var dataPoint = this._dataPointFromXY(mouseX, mouseY);
22915
22916 if (dataPoint !== this.tooltip.dataPoint) {
22917 // datapoint changed
22918 if (dataPoint) {
22919 this._showTooltip(dataPoint);
22920 } else {
22921 this._hideTooltip();
22922 }
22923 }
22924 } else {
22925 // tooltip is currently not visible
22926 var me = this;
22927 this.tooltipTimeout = setTimeout(function () {
22928 me.tooltipTimeout = null; // show a tooltip if we have a data point
22929
22930 var dataPoint = me._dataPointFromXY(mouseX, mouseY);
22931
22932 if (dataPoint) {
22933 me._showTooltip(dataPoint);
22934 }
22935 }, delay);
22936 }
22937};
22938/**
22939 * Event handler for touchstart event on mobile devices
22940 * @param {Event} event The event
22941 */
22942
22943
22944Graph3d.prototype._onTouchStart = function (event) {
22945 this.touchDown = true;
22946 var me = this;
22947
22948 this.ontouchmove = function (event) {
22949 me._onTouchMove(event);
22950 };
22951
22952 this.ontouchend = function (event) {
22953 me._onTouchEnd(event);
22954 };
22955
22956 util.addEventListener(document, 'touchmove', me.ontouchmove);
22957 util.addEventListener(document, 'touchend', me.ontouchend);
22958
22959 this._onMouseDown(event);
22960};
22961/**
22962 * Event handler for touchmove event on mobile devices
22963 * @param {Event} event The event
22964 */
22965
22966
22967Graph3d.prototype._onTouchMove = function (event) {
22968 this._onMouseMove(event);
22969};
22970/**
22971 * Event handler for touchend event on mobile devices
22972 * @param {Event} event The event
22973 */
22974
22975
22976Graph3d.prototype._onTouchEnd = function (event) {
22977 this.touchDown = false;
22978 util.removeEventListener(document, 'touchmove', this.ontouchmove);
22979 util.removeEventListener(document, 'touchend', this.ontouchend);
22980
22981 this._onMouseUp(event);
22982};
22983/**
22984 * Event handler for mouse wheel event, used to zoom the graph
22985 * Code from http://adomas.org/javascript-mouse-wheel/
22986 * @param {Event} event The event
22987 */
22988
22989
22990Graph3d.prototype._onWheel = function (event) {
22991 if (!event)
22992 /* For IE. */
22993 event = window.event;
22994
22995 if (this.zoomable && (!this.ctrlToZoom || event.ctrlKey)) {
22996 // retrieve delta
22997 var delta = 0;
22998
22999 if (event.wheelDelta) {
23000 /* IE/Opera. */
23001 delta = event.wheelDelta / 120;
23002 } else if (event.detail) {
23003 /* Mozilla case. */
23004 // In Mozilla, sign of delta is different than in IE.
23005 // Also, delta is multiple of 3.
23006 delta = -event.detail / 3;
23007 } // If delta is nonzero, handle it.
23008 // Basically, delta is now positive if wheel was scrolled up,
23009 // and negative, if wheel was scrolled down.
23010
23011
23012 if (delta) {
23013 var oldLength = this.camera.getArmLength();
23014 var newLength = oldLength * (1 - delta / 10);
23015 this.camera.setArmLength(newLength);
23016 this.redraw();
23017
23018 this._hideTooltip();
23019 } // fire a cameraPositionChange event
23020
23021
23022 var parameters = this.getCameraPosition();
23023 this.emit('cameraPositionChange', parameters); // Prevent default actions caused by mouse wheel.
23024 // That might be ugly, but we handle scrolls somehow
23025 // anyway, so don't bother here..
23026
23027 util.preventDefault(event);
23028 }
23029};
23030/**
23031 * Test whether a point lies inside given 2D triangle
23032 *
23033 * @param {vis.Point2d} point
23034 * @param {vis.Point2d[]} triangle
23035 * @returns {boolean} true if given point lies inside or on the edge of the
23036 * triangle, false otherwise
23037 * @private
23038 */
23039
23040
23041Graph3d.prototype._insideTriangle = function (point, triangle) {
23042 var a = triangle[0],
23043 b = triangle[1],
23044 c = triangle[2];
23045 /**
23046 *
23047 * @param {number} x
23048 * @returns {number}
23049 */
23050
23051 function sign(x) {
23052 return x > 0 ? 1 : x < 0 ? -1 : 0;
23053 }
23054
23055 var as = sign((b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x));
23056 var bs = sign((c.x - b.x) * (point.y - b.y) - (c.y - b.y) * (point.x - b.x));
23057 var cs = sign((a.x - c.x) * (point.y - c.y) - (a.y - c.y) * (point.x - c.x)); // each of the three signs must be either equal to each other or zero
23058
23059 return (as == 0 || bs == 0 || as == bs) && (bs == 0 || cs == 0 || bs == cs) && (as == 0 || cs == 0 || as == cs);
23060};
23061/**
23062 * Find a data point close to given screen position (x, y)
23063 *
23064 * @param {number} x
23065 * @param {number} y
23066 * @returns {Object | null} The closest data point or null if not close to any
23067 * data point
23068 * @private
23069 */
23070
23071
23072Graph3d.prototype._dataPointFromXY = function (x, y) {
23073 var i,
23074 distMax = 100,
23075 // px
23076 dataPoint = null,
23077 closestDataPoint = null,
23078 closestDist = null,
23079 center = new Point2d_1(x, y);
23080
23081 if (this.style === Graph3d.STYLE.BAR || this.style === Graph3d.STYLE.BARCOLOR || this.style === Graph3d.STYLE.BARSIZE) {
23082 // the data points are ordered from far away to closest
23083 for (i = this.dataPoints.length - 1; i >= 0; i--) {
23084 dataPoint = this.dataPoints[i];
23085 var surfaces = dataPoint.surfaces;
23086
23087 if (surfaces) {
23088 for (var s = surfaces.length - 1; s >= 0; s--) {
23089 // split each surface in two triangles, and see if the center point is inside one of these
23090 var surface = surfaces[s];
23091 var corners = surface.corners;
23092 var triangle1 = [corners[0].screen, corners[1].screen, corners[2].screen];
23093 var triangle2 = [corners[2].screen, corners[3].screen, corners[0].screen];
23094
23095 if (this._insideTriangle(center, triangle1) || this._insideTriangle(center, triangle2)) {
23096 // return immediately at the first hit
23097 return dataPoint;
23098 }
23099 }
23100 }
23101 }
23102 } else {
23103 // find the closest data point, using distance to the center of the point on 2d screen
23104 for (i = 0; i < this.dataPoints.length; i++) {
23105 dataPoint = this.dataPoints[i];
23106 var point = dataPoint.screen;
23107
23108 if (point) {
23109 var distX = Math.abs(x - point.x);
23110 var distY = Math.abs(y - point.y);
23111 var dist = Math.sqrt(distX * distX + distY * distY);
23112
23113 if ((closestDist === null || dist < closestDist) && dist < distMax) {
23114 closestDist = dist;
23115 closestDataPoint = dataPoint;
23116 }
23117 }
23118 }
23119 }
23120
23121 return closestDataPoint;
23122};
23123/**
23124 * Determine if the given style has bars
23125 *
23126 * @param {number} style the style to check
23127 * @returns {boolean} true if bar style, false otherwise
23128 */
23129
23130
23131Graph3d.prototype.hasBars = function (style) {
23132 return style == Graph3d.STYLE.BAR || style == Graph3d.STYLE.BARCOLOR || style == Graph3d.STYLE.BARSIZE;
23133};
23134/**
23135 * Display a tooltip for given data point
23136 * @param {Object} dataPoint
23137 * @private
23138 */
23139
23140
23141Graph3d.prototype._showTooltip = function (dataPoint) {
23142 var content, line, dot;
23143
23144 if (!this.tooltip) {
23145 content = document.createElement('div');
23146 Object.assign(content.style, {}, this.tooltipStyle.content);
23147 content.style.position = 'absolute';
23148 line = document.createElement('div');
23149 Object.assign(line.style, {}, this.tooltipStyle.line);
23150 line.style.position = 'absolute';
23151 dot = document.createElement('div');
23152 Object.assign(dot.style, {}, this.tooltipStyle.dot);
23153 dot.style.position = 'absolute';
23154 this.tooltip = {
23155 dataPoint: null,
23156 dom: {
23157 content: content,
23158 line: line,
23159 dot: dot
23160 }
23161 };
23162 } else {
23163 content = this.tooltip.dom.content;
23164 line = this.tooltip.dom.line;
23165 dot = this.tooltip.dom.dot;
23166 }
23167
23168 this._hideTooltip();
23169
23170 this.tooltip.dataPoint = dataPoint;
23171
23172 if (typeof this.showTooltip === 'function') {
23173 content.innerHTML = this.showTooltip(dataPoint.point);
23174 } else {
23175 content.innerHTML = '<table>' + '<tr><td>' + this.xLabel + ':</td><td>' + dataPoint.point.x + '</td></tr>' + '<tr><td>' + this.yLabel + ':</td><td>' + dataPoint.point.y + '</td></tr>' + '<tr><td>' + this.zLabel + ':</td><td>' + dataPoint.point.z + '</td></tr>' + '</table>';
23176 }
23177
23178 content.style.left = '0';
23179 content.style.top = '0';
23180 this.frame.appendChild(content);
23181 this.frame.appendChild(line);
23182 this.frame.appendChild(dot); // calculate sizes
23183
23184 var contentWidth = content.offsetWidth;
23185 var contentHeight = content.offsetHeight;
23186 var lineHeight = line.offsetHeight;
23187 var dotWidth = dot.offsetWidth;
23188 var dotHeight = dot.offsetHeight;
23189 var left = dataPoint.screen.x - contentWidth / 2;
23190 left = Math.min(Math.max(left, 10), this.frame.clientWidth - 10 - contentWidth);
23191 line.style.left = dataPoint.screen.x + 'px';
23192 line.style.top = dataPoint.screen.y - lineHeight + 'px';
23193 content.style.left = left + 'px';
23194 content.style.top = dataPoint.screen.y - lineHeight - contentHeight + 'px';
23195 dot.style.left = dataPoint.screen.x - dotWidth / 2 + 'px';
23196 dot.style.top = dataPoint.screen.y - dotHeight / 2 + 'px';
23197};
23198/**
23199 * Hide the tooltip when displayed
23200 * @private
23201 */
23202
23203
23204Graph3d.prototype._hideTooltip = function () {
23205 if (this.tooltip) {
23206 this.tooltip.dataPoint = null;
23207
23208 for (var prop in this.tooltip.dom) {
23209 if (this.tooltip.dom.hasOwnProperty(prop)) {
23210 var elem = this.tooltip.dom[prop];
23211
23212 if (elem && elem.parentNode) {
23213 elem.parentNode.removeChild(elem);
23214 }
23215 }
23216 }
23217 }
23218};
23219/**--------------------------------------------------------------------------**/
23220
23221/**
23222 * Get the horizontal mouse position from a mouse event
23223 *
23224 * @param {Event} event
23225 * @returns {number} mouse x
23226 */
23227
23228
23229function getMouseX(event) {
23230 if ('clientX' in event) return event.clientX;
23231 return event.targetTouches[0] && event.targetTouches[0].clientX || 0;
23232}
23233/**
23234 * Get the vertical mouse position from a mouse event
23235 *
23236 * @param {Event} event
23237 * @returns {number} mouse y
23238 */
23239
23240
23241function getMouseY(event) {
23242 if ('clientY' in event) return event.clientY;
23243 return event.targetTouches[0] && event.targetTouches[0].clientY || 0;
23244} // -----------------------------------------------------------------------------
23245// Public methods for specific settings
23246// -----------------------------------------------------------------------------
23247
23248/**
23249 * Set the rotation and distance of the camera
23250 *
23251 * @param {Object} pos An object with the camera position
23252 * @param {number} [pos.horizontal] The horizontal rotation, between 0 and 2*PI.
23253 * Optional, can be left undefined.
23254 * @param {number} [pos.vertical] The vertical rotation, between 0 and 0.5*PI.
23255 * if vertical=0.5*PI, the graph is shown from
23256 * the top. Optional, can be left undefined.
23257 * @param {number} [pos.distance] The (normalized) distance of the camera to the
23258 * center of the graph, a value between 0.71 and
23259 * 5.0. Optional, can be left undefined.
23260 */
23261
23262
23263Graph3d.prototype.setCameraPosition = function (pos) {
23264 Settings.setCameraPosition(pos, this);
23265 this.redraw();
23266};
23267/**
23268 * Set a new size for the graph
23269 *
23270 * @param {string} width Width in pixels or percentage (for example '800px'
23271 * or '50%')
23272 * @param {string} height Height in pixels or percentage (for example '400px'
23273 * or '30%')
23274 */
23275
23276
23277Graph3d.prototype.setSize = function (width, height) {
23278 this._setSize(width, height);
23279
23280 this.redraw();
23281}; // -----------------------------------------------------------------------------
23282// End public methods for specific settings
23283// -----------------------------------------------------------------------------
23284
23285
23286var Graph3d_1 = Graph3d;
23287
23288var moment$2 = createCommonjsModule$1(function (module, exports) {
23289
23290 (function (global, factory) {
23291 module.exports = factory() ;
23292 })(commonjsGlobal$1, function () {
23293
23294 var hookCallback;
23295
23296 function hooks() {
23297 return hookCallback.apply(null, arguments);
23298 } // This is done to register the method called with moment()
23299 // without creating circular dependencies.
23300
23301
23302 function setHookCallback(callback) {
23303 hookCallback = callback;
23304 }
23305
23306 function isArray(input) {
23307 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
23308 }
23309
23310 function isObject(input) {
23311 // IE8 will treat undefined and null as object if it wasn't for
23312 // input != null
23313 return input != null && Object.prototype.toString.call(input) === '[object Object]';
23314 }
23315
23316 function isObjectEmpty(obj) {
23317 if (Object.getOwnPropertyNames) {
23318 return Object.getOwnPropertyNames(obj).length === 0;
23319 } else {
23320 var k;
23321
23322 for (k in obj) {
23323 if (obj.hasOwnProperty(k)) {
23324 return false;
23325 }
23326 }
23327
23328 return true;
23329 }
23330 }
23331
23332 function isUndefined(input) {
23333 return input === void 0;
23334 }
23335
23336 function isNumber(input) {
23337 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
23338 }
23339
23340 function isDate(input) {
23341 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
23342 }
23343
23344 function map(arr, fn) {
23345 var res = [],
23346 i;
23347
23348 for (i = 0; i < arr.length; ++i) {
23349 res.push(fn(arr[i], i));
23350 }
23351
23352 return res;
23353 }
23354
23355 function hasOwnProp(a, b) {
23356 return Object.prototype.hasOwnProperty.call(a, b);
23357 }
23358
23359 function extend(a, b) {
23360 for (var i in b) {
23361 if (hasOwnProp(b, i)) {
23362 a[i] = b[i];
23363 }
23364 }
23365
23366 if (hasOwnProp(b, 'toString')) {
23367 a.toString = b.toString;
23368 }
23369
23370 if (hasOwnProp(b, 'valueOf')) {
23371 a.valueOf = b.valueOf;
23372 }
23373
23374 return a;
23375 }
23376
23377 function createUTC(input, format, locale, strict) {
23378 return createLocalOrUTC(input, format, locale, strict, true).utc();
23379 }
23380
23381 function defaultParsingFlags() {
23382 // We need to deep clone this object.
23383 return {
23384 empty: false,
23385 unusedTokens: [],
23386 unusedInput: [],
23387 overflow: -2,
23388 charsLeftOver: 0,
23389 nullInput: false,
23390 invalidMonth: null,
23391 invalidFormat: false,
23392 userInvalidated: false,
23393 iso: false,
23394 parsedDateParts: [],
23395 meridiem: null,
23396 rfc2822: false,
23397 weekdayMismatch: false
23398 };
23399 }
23400
23401 function getParsingFlags(m) {
23402 if (m._pf == null) {
23403 m._pf = defaultParsingFlags();
23404 }
23405
23406 return m._pf;
23407 }
23408
23409 var some;
23410
23411 if (Array.prototype.some) {
23412 some = Array.prototype.some;
23413 } else {
23414 some = function (fun) {
23415 var t = Object(this);
23416 var len = t.length >>> 0;
23417
23418 for (var i = 0; i < len; i++) {
23419 if (i in t && fun.call(this, t[i], i, t)) {
23420 return true;
23421 }
23422 }
23423
23424 return false;
23425 };
23426 }
23427
23428 function isValid(m) {
23429 if (m._isValid == null) {
23430 var flags = getParsingFlags(m);
23431 var parsedParts = some.call(flags.parsedDateParts, function (i) {
23432 return i != null;
23433 });
23434 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);
23435
23436 if (m._strict) {
23437 isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined;
23438 }
23439
23440 if (Object.isFrozen == null || !Object.isFrozen(m)) {
23441 m._isValid = isNowValid;
23442 } else {
23443 return isNowValid;
23444 }
23445 }
23446
23447 return m._isValid;
23448 }
23449
23450 function createInvalid(flags) {
23451 var m = createUTC(NaN);
23452
23453 if (flags != null) {
23454 extend(getParsingFlags(m), flags);
23455 } else {
23456 getParsingFlags(m).userInvalidated = true;
23457 }
23458
23459 return m;
23460 } // Plugins that add properties should also add the key here (null value),
23461 // so we can properly clone ourselves.
23462
23463
23464 var momentProperties = hooks.momentProperties = [];
23465
23466 function copyConfig(to, from) {
23467 var i, prop, val;
23468
23469 if (!isUndefined(from._isAMomentObject)) {
23470 to._isAMomentObject = from._isAMomentObject;
23471 }
23472
23473 if (!isUndefined(from._i)) {
23474 to._i = from._i;
23475 }
23476
23477 if (!isUndefined(from._f)) {
23478 to._f = from._f;
23479 }
23480
23481 if (!isUndefined(from._l)) {
23482 to._l = from._l;
23483 }
23484
23485 if (!isUndefined(from._strict)) {
23486 to._strict = from._strict;
23487 }
23488
23489 if (!isUndefined(from._tzm)) {
23490 to._tzm = from._tzm;
23491 }
23492
23493 if (!isUndefined(from._isUTC)) {
23494 to._isUTC = from._isUTC;
23495 }
23496
23497 if (!isUndefined(from._offset)) {
23498 to._offset = from._offset;
23499 }
23500
23501 if (!isUndefined(from._pf)) {
23502 to._pf = getParsingFlags(from);
23503 }
23504
23505 if (!isUndefined(from._locale)) {
23506 to._locale = from._locale;
23507 }
23508
23509 if (momentProperties.length > 0) {
23510 for (i = 0; i < momentProperties.length; i++) {
23511 prop = momentProperties[i];
23512 val = from[prop];
23513
23514 if (!isUndefined(val)) {
23515 to[prop] = val;
23516 }
23517 }
23518 }
23519
23520 return to;
23521 }
23522
23523 var updateInProgress = false; // Moment prototype object
23524
23525 function Moment(config) {
23526 copyConfig(this, config);
23527 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
23528
23529 if (!this.isValid()) {
23530 this._d = new Date(NaN);
23531 } // Prevent infinite loop in case updateOffset creates new moment
23532 // objects.
23533
23534
23535 if (updateInProgress === false) {
23536 updateInProgress = true;
23537 hooks.updateOffset(this);
23538 updateInProgress = false;
23539 }
23540 }
23541
23542 function isMoment(obj) {
23543 return obj instanceof Moment || obj != null && obj._isAMomentObject != null;
23544 }
23545
23546 function absFloor(number) {
23547 if (number < 0) {
23548 // -0 -> 0
23549 return Math.ceil(number) || 0;
23550 } else {
23551 return Math.floor(number);
23552 }
23553 }
23554
23555 function toInt(argumentForCoercion) {
23556 var coercedNumber = +argumentForCoercion,
23557 value = 0;
23558
23559 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
23560 value = absFloor(coercedNumber);
23561 }
23562
23563 return value;
23564 } // compare two arrays, return the number of differences
23565
23566
23567 function compareArrays(array1, array2, dontConvert) {
23568 var len = Math.min(array1.length, array2.length),
23569 lengthDiff = Math.abs(array1.length - array2.length),
23570 diffs = 0,
23571 i;
23572
23573 for (i = 0; i < len; i++) {
23574 if (dontConvert && array1[i] !== array2[i] || !dontConvert && toInt(array1[i]) !== toInt(array2[i])) {
23575 diffs++;
23576 }
23577 }
23578
23579 return diffs + lengthDiff;
23580 }
23581
23582 function warn(msg) {
23583 if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
23584 console.warn('Deprecation warning: ' + msg);
23585 }
23586 }
23587
23588 function deprecate(msg, fn) {
23589 var firstTime = true;
23590 return extend(function () {
23591 if (hooks.deprecationHandler != null) {
23592 hooks.deprecationHandler(null, msg);
23593 }
23594
23595 if (firstTime) {
23596 var args = [];
23597 var arg;
23598
23599 for (var i = 0; i < arguments.length; i++) {
23600 arg = '';
23601
23602 if (typeof arguments[i] === 'object') {
23603 arg += '\n[' + i + '] ';
23604
23605 for (var key in arguments[0]) {
23606 arg += key + ': ' + arguments[0][key] + ', ';
23607 }
23608
23609 arg = arg.slice(0, -2); // Remove trailing comma and space
23610 } else {
23611 arg = arguments[i];
23612 }
23613
23614 args.push(arg);
23615 }
23616
23617 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + new Error().stack);
23618 firstTime = false;
23619 }
23620
23621 return fn.apply(this, arguments);
23622 }, fn);
23623 }
23624
23625 var deprecations = {};
23626
23627 function deprecateSimple(name, msg) {
23628 if (hooks.deprecationHandler != null) {
23629 hooks.deprecationHandler(name, msg);
23630 }
23631
23632 if (!deprecations[name]) {
23633 warn(msg);
23634 deprecations[name] = true;
23635 }
23636 }
23637
23638 hooks.suppressDeprecationWarnings = false;
23639 hooks.deprecationHandler = null;
23640
23641 function isFunction(input) {
23642 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
23643 }
23644
23645 function set(config) {
23646 var prop, i;
23647
23648 for (i in config) {
23649 prop = config[i];
23650
23651 if (isFunction(prop)) {
23652 this[i] = prop;
23653 } else {
23654 this['_' + i] = prop;
23655 }
23656 }
23657
23658 this._config = config; // Lenient ordinal parsing accepts just a number in addition to
23659 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
23660 // TODO: Remove "ordinalParse" fallback in next major release.
23661
23662 this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + /\d{1,2}/.source);
23663 }
23664
23665 function mergeConfigs(parentConfig, childConfig) {
23666 var res = extend({}, parentConfig),
23667 prop;
23668
23669 for (prop in childConfig) {
23670 if (hasOwnProp(childConfig, prop)) {
23671 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
23672 res[prop] = {};
23673 extend(res[prop], parentConfig[prop]);
23674 extend(res[prop], childConfig[prop]);
23675 } else if (childConfig[prop] != null) {
23676 res[prop] = childConfig[prop];
23677 } else {
23678 delete res[prop];
23679 }
23680 }
23681 }
23682
23683 for (prop in parentConfig) {
23684 if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) {
23685 // make sure changes to properties don't modify parent config
23686 res[prop] = extend({}, res[prop]);
23687 }
23688 }
23689
23690 return res;
23691 }
23692
23693 function Locale(config) {
23694 if (config != null) {
23695 this.set(config);
23696 }
23697 }
23698
23699 var keys;
23700
23701 if (Object.keys) {
23702 keys = Object.keys;
23703 } else {
23704 keys = function (obj) {
23705 var i,
23706 res = [];
23707
23708 for (i in obj) {
23709 if (hasOwnProp(obj, i)) {
23710 res.push(i);
23711 }
23712 }
23713
23714 return res;
23715 };
23716 }
23717
23718 var defaultCalendar = {
23719 sameDay: '[Today at] LT',
23720 nextDay: '[Tomorrow at] LT',
23721 nextWeek: 'dddd [at] LT',
23722 lastDay: '[Yesterday at] LT',
23723 lastWeek: '[Last] dddd [at] LT',
23724 sameElse: 'L'
23725 };
23726
23727 function calendar(key, mom, now) {
23728 var output = this._calendar[key] || this._calendar['sameElse'];
23729 return isFunction(output) ? output.call(mom, now) : output;
23730 }
23731
23732 var defaultLongDateFormat = {
23733 LTS: 'h:mm:ss A',
23734 LT: 'h:mm A',
23735 L: 'MM/DD/YYYY',
23736 LL: 'MMMM D, YYYY',
23737 LLL: 'MMMM D, YYYY h:mm A',
23738 LLLL: 'dddd, MMMM D, YYYY h:mm A'
23739 };
23740
23741 function longDateFormat(key) {
23742 var format = this._longDateFormat[key],
23743 formatUpper = this._longDateFormat[key.toUpperCase()];
23744
23745 if (format || !formatUpper) {
23746 return format;
23747 }
23748
23749 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
23750 return val.slice(1);
23751 });
23752 return this._longDateFormat[key];
23753 }
23754
23755 var defaultInvalidDate = 'Invalid date';
23756
23757 function invalidDate() {
23758 return this._invalidDate;
23759 }
23760
23761 var defaultOrdinal = '%d';
23762 var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
23763
23764 function ordinal(number) {
23765 return this._ordinal.replace('%d', number);
23766 }
23767
23768 var defaultRelativeTime = {
23769 future: 'in %s',
23770 past: '%s ago',
23771 s: 'a few seconds',
23772 ss: '%d seconds',
23773 m: 'a minute',
23774 mm: '%d minutes',
23775 h: 'an hour',
23776 hh: '%d hours',
23777 d: 'a day',
23778 dd: '%d days',
23779 M: 'a month',
23780 MM: '%d months',
23781 y: 'a year',
23782 yy: '%d years'
23783 };
23784
23785 function relativeTime(number, withoutSuffix, string, isFuture) {
23786 var output = this._relativeTime[string];
23787 return isFunction(output) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number);
23788 }
23789
23790 function pastFuture(diff, output) {
23791 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
23792 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
23793 }
23794
23795 var aliases = {};
23796
23797 function addUnitAlias(unit, shorthand) {
23798 var lowerCase = unit.toLowerCase();
23799 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
23800 }
23801
23802 function normalizeUnits(units) {
23803 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
23804 }
23805
23806 function normalizeObjectUnits(inputObject) {
23807 var normalizedInput = {},
23808 normalizedProp,
23809 prop;
23810
23811 for (prop in inputObject) {
23812 if (hasOwnProp(inputObject, prop)) {
23813 normalizedProp = normalizeUnits(prop);
23814
23815 if (normalizedProp) {
23816 normalizedInput[normalizedProp] = inputObject[prop];
23817 }
23818 }
23819 }
23820
23821 return normalizedInput;
23822 }
23823
23824 var priorities = {};
23825
23826 function addUnitPriority(unit, priority) {
23827 priorities[unit] = priority;
23828 }
23829
23830 function getPrioritizedUnits(unitsObj) {
23831 var units = [];
23832
23833 for (var u in unitsObj) {
23834 units.push({
23835 unit: u,
23836 priority: priorities[u]
23837 });
23838 }
23839
23840 units.sort(function (a, b) {
23841 return a.priority - b.priority;
23842 });
23843 return units;
23844 }
23845
23846 function zeroFill(number, targetLength, forceSign) {
23847 var absNumber = '' + Math.abs(number),
23848 zerosToFill = targetLength - absNumber.length,
23849 sign = number >= 0;
23850 return (sign ? forceSign ? '+' : '' : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
23851 }
23852
23853 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;
23854 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
23855 var formatFunctions = {};
23856 var formatTokenFunctions = {}; // token: 'M'
23857 // padded: ['MM', 2]
23858 // ordinal: 'Mo'
23859 // callback: function () { this.month() + 1 }
23860
23861 function addFormatToken(token, padded, ordinal, callback) {
23862 var func = callback;
23863
23864 if (typeof callback === 'string') {
23865 func = function () {
23866 return this[callback]();
23867 };
23868 }
23869
23870 if (token) {
23871 formatTokenFunctions[token] = func;
23872 }
23873
23874 if (padded) {
23875 formatTokenFunctions[padded[0]] = function () {
23876 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
23877 };
23878 }
23879
23880 if (ordinal) {
23881 formatTokenFunctions[ordinal] = function () {
23882 return this.localeData().ordinal(func.apply(this, arguments), token);
23883 };
23884 }
23885 }
23886
23887 function removeFormattingTokens(input) {
23888 if (input.match(/\[[\s\S]/)) {
23889 return input.replace(/^\[|\]$/g, '');
23890 }
23891
23892 return input.replace(/\\/g, '');
23893 }
23894
23895 function makeFormatFunction(format) {
23896 var array = format.match(formattingTokens),
23897 i,
23898 length;
23899
23900 for (i = 0, length = array.length; i < length; i++) {
23901 if (formatTokenFunctions[array[i]]) {
23902 array[i] = formatTokenFunctions[array[i]];
23903 } else {
23904 array[i] = removeFormattingTokens(array[i]);
23905 }
23906 }
23907
23908 return function (mom) {
23909 var output = '',
23910 i;
23911
23912 for (i = 0; i < length; i++) {
23913 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
23914 }
23915
23916 return output;
23917 };
23918 } // format date using native date object
23919
23920
23921 function formatMoment(m, format) {
23922 if (!m.isValid()) {
23923 return m.localeData().invalidDate();
23924 }
23925
23926 format = expandFormat(format, m.localeData());
23927 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
23928 return formatFunctions[format](m);
23929 }
23930
23931 function expandFormat(format, locale) {
23932 var i = 5;
23933
23934 function replaceLongDateFormatTokens(input) {
23935 return locale.longDateFormat(input) || input;
23936 }
23937
23938 localFormattingTokens.lastIndex = 0;
23939
23940 while (i >= 0 && localFormattingTokens.test(format)) {
23941 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
23942 localFormattingTokens.lastIndex = 0;
23943 i -= 1;
23944 }
23945
23946 return format;
23947 }
23948
23949 var match1 = /\d/; // 0 - 9
23950
23951 var match2 = /\d\d/; // 00 - 99
23952
23953 var match3 = /\d{3}/; // 000 - 999
23954
23955 var match4 = /\d{4}/; // 0000 - 9999
23956
23957 var match6 = /[+-]?\d{6}/; // -999999 - 999999
23958
23959 var match1to2 = /\d\d?/; // 0 - 99
23960
23961 var match3to4 = /\d\d\d\d?/; // 999 - 9999
23962
23963 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
23964
23965 var match1to3 = /\d{1,3}/; // 0 - 999
23966
23967 var match1to4 = /\d{1,4}/; // 0 - 9999
23968
23969 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
23970
23971 var matchUnsigned = /\d+/; // 0 - inf
23972
23973 var matchSigned = /[+-]?\d+/; // -inf - inf
23974
23975 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
23976
23977 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
23978
23979 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
23980 // any word (or two) characters or numbers including two/three word month in arabic.
23981 // includes scottish gaelic two word and hyphenated months
23982
23983 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;
23984 var regexes = {};
23985
23986 function addRegexToken(token, regex, strictRegex) {
23987 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
23988 return isStrict && strictRegex ? strictRegex : regex;
23989 };
23990 }
23991
23992 function getParseRegexForToken(token, config) {
23993 if (!hasOwnProp(regexes, token)) {
23994 return new RegExp(unescapeFormat(token));
23995 }
23996
23997 return regexes[token](config._strict, config._locale);
23998 } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
23999
24000
24001 function unescapeFormat(s) {
24002 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
24003 return p1 || p2 || p3 || p4;
24004 }));
24005 }
24006
24007 function regexEscape(s) {
24008 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
24009 }
24010
24011 var tokens = {};
24012
24013 function addParseToken(token, callback) {
24014 var i,
24015 func = callback;
24016
24017 if (typeof token === 'string') {
24018 token = [token];
24019 }
24020
24021 if (isNumber(callback)) {
24022 func = function (input, array) {
24023 array[callback] = toInt(input);
24024 };
24025 }
24026
24027 for (i = 0; i < token.length; i++) {
24028 tokens[token[i]] = func;
24029 }
24030 }
24031
24032 function addWeekParseToken(token, callback) {
24033 addParseToken(token, function (input, array, config, token) {
24034 config._w = config._w || {};
24035 callback(input, config._w, config, token);
24036 });
24037 }
24038
24039 function addTimeToArrayFromToken(token, input, config) {
24040 if (input != null && hasOwnProp(tokens, token)) {
24041 tokens[token](input, config._a, config, token);
24042 }
24043 }
24044
24045 var YEAR = 0;
24046 var MONTH = 1;
24047 var DATE = 2;
24048 var HOUR = 3;
24049 var MINUTE = 4;
24050 var SECOND = 5;
24051 var MILLISECOND = 6;
24052 var WEEK = 7;
24053 var WEEKDAY = 8; // FORMATTING
24054
24055 addFormatToken('Y', 0, 0, function () {
24056 var y = this.year();
24057 return y <= 9999 ? '' + y : '+' + y;
24058 });
24059 addFormatToken(0, ['YY', 2], 0, function () {
24060 return this.year() % 100;
24061 });
24062 addFormatToken(0, ['YYYY', 4], 0, 'year');
24063 addFormatToken(0, ['YYYYY', 5], 0, 'year');
24064 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES
24065
24066 addUnitAlias('year', 'y'); // PRIORITIES
24067
24068 addUnitPriority('year', 1); // PARSING
24069
24070 addRegexToken('Y', matchSigned);
24071 addRegexToken('YY', match1to2, match2);
24072 addRegexToken('YYYY', match1to4, match4);
24073 addRegexToken('YYYYY', match1to6, match6);
24074 addRegexToken('YYYYYY', match1to6, match6);
24075 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
24076 addParseToken('YYYY', function (input, array) {
24077 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
24078 });
24079 addParseToken('YY', function (input, array) {
24080 array[YEAR] = hooks.parseTwoDigitYear(input);
24081 });
24082 addParseToken('Y', function (input, array) {
24083 array[YEAR] = parseInt(input, 10);
24084 }); // HELPERS
24085
24086 function daysInYear(year) {
24087 return isLeapYear(year) ? 366 : 365;
24088 }
24089
24090 function isLeapYear(year) {
24091 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
24092 } // HOOKS
24093
24094
24095 hooks.parseTwoDigitYear = function (input) {
24096 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
24097 }; // MOMENTS
24098
24099
24100 var getSetYear = makeGetSet('FullYear', true);
24101
24102 function getIsLeapYear() {
24103 return isLeapYear(this.year());
24104 }
24105
24106 function makeGetSet(unit, keepTime) {
24107 return function (value) {
24108 if (value != null) {
24109 set$1(this, unit, value);
24110 hooks.updateOffset(this, keepTime);
24111 return this;
24112 } else {
24113 return get(this, unit);
24114 }
24115 };
24116 }
24117
24118 function get(mom, unit) {
24119 return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
24120 }
24121
24122 function set$1(mom, unit, value) {
24123 if (mom.isValid() && !isNaN(value)) {
24124 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
24125 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
24126 } else {
24127 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
24128 }
24129 }
24130 } // MOMENTS
24131
24132
24133 function stringGet(units) {
24134 units = normalizeUnits(units);
24135
24136 if (isFunction(this[units])) {
24137 return this[units]();
24138 }
24139
24140 return this;
24141 }
24142
24143 function stringSet(units, value) {
24144 if (typeof units === 'object') {
24145 units = normalizeObjectUnits(units);
24146 var prioritized = getPrioritizedUnits(units);
24147
24148 for (var i = 0; i < prioritized.length; i++) {
24149 this[prioritized[i].unit](units[prioritized[i].unit]);
24150 }
24151 } else {
24152 units = normalizeUnits(units);
24153
24154 if (isFunction(this[units])) {
24155 return this[units](value);
24156 }
24157 }
24158
24159 return this;
24160 }
24161
24162 function mod(n, x) {
24163 return (n % x + x) % x;
24164 }
24165
24166 var indexOf;
24167
24168 if (Array.prototype.indexOf) {
24169 indexOf = Array.prototype.indexOf;
24170 } else {
24171 indexOf = function (o) {
24172 // I know
24173 var i;
24174
24175 for (i = 0; i < this.length; ++i) {
24176 if (this[i] === o) {
24177 return i;
24178 }
24179 }
24180
24181 return -1;
24182 };
24183 }
24184
24185 function daysInMonth(year, month) {
24186 if (isNaN(year) || isNaN(month)) {
24187 return NaN;
24188 }
24189
24190 var modMonth = mod(month, 12);
24191 year += (month - modMonth) / 12;
24192 return modMonth === 1 ? isLeapYear(year) ? 29 : 28 : 31 - modMonth % 7 % 2;
24193 } // FORMATTING
24194
24195
24196 addFormatToken('M', ['MM', 2], 'Mo', function () {
24197 return this.month() + 1;
24198 });
24199 addFormatToken('MMM', 0, 0, function (format) {
24200 return this.localeData().monthsShort(this, format);
24201 });
24202 addFormatToken('MMMM', 0, 0, function (format) {
24203 return this.localeData().months(this, format);
24204 }); // ALIASES
24205
24206 addUnitAlias('month', 'M'); // PRIORITY
24207
24208 addUnitPriority('month', 8); // PARSING
24209
24210 addRegexToken('M', match1to2);
24211 addRegexToken('MM', match1to2, match2);
24212 addRegexToken('MMM', function (isStrict, locale) {
24213 return locale.monthsShortRegex(isStrict);
24214 });
24215 addRegexToken('MMMM', function (isStrict, locale) {
24216 return locale.monthsRegex(isStrict);
24217 });
24218 addParseToken(['M', 'MM'], function (input, array) {
24219 array[MONTH] = toInt(input) - 1;
24220 });
24221 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
24222 var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid.
24223
24224
24225 if (month != null) {
24226 array[MONTH] = month;
24227 } else {
24228 getParsingFlags(config).invalidMonth = input;
24229 }
24230 }); // LOCALES
24231
24232 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
24233 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
24234
24235 function localeMonths(m, format) {
24236 if (!m) {
24237 return isArray(this._months) ? this._months : this._months['standalone'];
24238 }
24239
24240 return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
24241 }
24242
24243 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
24244
24245 function localeMonthsShort(m, format) {
24246 if (!m) {
24247 return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone'];
24248 }
24249
24250 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
24251 }
24252
24253 function handleStrictParse(monthName, format, strict) {
24254 var i,
24255 ii,
24256 mom,
24257 llc = monthName.toLocaleLowerCase();
24258
24259 if (!this._monthsParse) {
24260 // this is not used
24261 this._monthsParse = [];
24262 this._longMonthsParse = [];
24263 this._shortMonthsParse = [];
24264
24265 for (i = 0; i < 12; ++i) {
24266 mom = createUTC([2000, i]);
24267 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
24268 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
24269 }
24270 }
24271
24272 if (strict) {
24273 if (format === 'MMM') {
24274 ii = indexOf.call(this._shortMonthsParse, llc);
24275 return ii !== -1 ? ii : null;
24276 } else {
24277 ii = indexOf.call(this._longMonthsParse, llc);
24278 return ii !== -1 ? ii : null;
24279 }
24280 } else {
24281 if (format === 'MMM') {
24282 ii = indexOf.call(this._shortMonthsParse, llc);
24283
24284 if (ii !== -1) {
24285 return ii;
24286 }
24287
24288 ii = indexOf.call(this._longMonthsParse, llc);
24289 return ii !== -1 ? ii : null;
24290 } else {
24291 ii = indexOf.call(this._longMonthsParse, llc);
24292
24293 if (ii !== -1) {
24294 return ii;
24295 }
24296
24297 ii = indexOf.call(this._shortMonthsParse, llc);
24298 return ii !== -1 ? ii : null;
24299 }
24300 }
24301 }
24302
24303 function localeMonthsParse(monthName, format, strict) {
24304 var i, mom, regex;
24305
24306 if (this._monthsParseExact) {
24307 return handleStrictParse.call(this, monthName, format, strict);
24308 }
24309
24310 if (!this._monthsParse) {
24311 this._monthsParse = [];
24312 this._longMonthsParse = [];
24313 this._shortMonthsParse = [];
24314 } // TODO: add sorting
24315 // Sorting makes sure if one month (or abbr) is a prefix of another
24316 // see sorting in computeMonthsParse
24317
24318
24319 for (i = 0; i < 12; i++) {
24320 // make the regex if we don't have it already
24321 mom = createUTC([2000, i]);
24322
24323 if (strict && !this._longMonthsParse[i]) {
24324 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
24325 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
24326 }
24327
24328 if (!strict && !this._monthsParse[i]) {
24329 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
24330 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
24331 } // test the regex
24332
24333
24334 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
24335 return i;
24336 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
24337 return i;
24338 } else if (!strict && this._monthsParse[i].test(monthName)) {
24339 return i;
24340 }
24341 }
24342 } // MOMENTS
24343
24344
24345 function setMonth(mom, value) {
24346 var dayOfMonth;
24347
24348 if (!mom.isValid()) {
24349 // No op
24350 return mom;
24351 }
24352
24353 if (typeof value === 'string') {
24354 if (/^\d+$/.test(value)) {
24355 value = toInt(value);
24356 } else {
24357 value = mom.localeData().monthsParse(value); // TODO: Another silent failure?
24358
24359 if (!isNumber(value)) {
24360 return mom;
24361 }
24362 }
24363 }
24364
24365 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
24366
24367 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
24368
24369 return mom;
24370 }
24371
24372 function getSetMonth(value) {
24373 if (value != null) {
24374 setMonth(this, value);
24375 hooks.updateOffset(this, true);
24376 return this;
24377 } else {
24378 return get(this, 'Month');
24379 }
24380 }
24381
24382 function getDaysInMonth() {
24383 return daysInMonth(this.year(), this.month());
24384 }
24385
24386 var defaultMonthsShortRegex = matchWord;
24387
24388 function monthsShortRegex(isStrict) {
24389 if (this._monthsParseExact) {
24390 if (!hasOwnProp(this, '_monthsRegex')) {
24391 computeMonthsParse.call(this);
24392 }
24393
24394 if (isStrict) {
24395 return this._monthsShortStrictRegex;
24396 } else {
24397 return this._monthsShortRegex;
24398 }
24399 } else {
24400 if (!hasOwnProp(this, '_monthsShortRegex')) {
24401 this._monthsShortRegex = defaultMonthsShortRegex;
24402 }
24403
24404 return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex;
24405 }
24406 }
24407
24408 var defaultMonthsRegex = matchWord;
24409
24410 function monthsRegex(isStrict) {
24411 if (this._monthsParseExact) {
24412 if (!hasOwnProp(this, '_monthsRegex')) {
24413 computeMonthsParse.call(this);
24414 }
24415
24416 if (isStrict) {
24417 return this._monthsStrictRegex;
24418 } else {
24419 return this._monthsRegex;
24420 }
24421 } else {
24422 if (!hasOwnProp(this, '_monthsRegex')) {
24423 this._monthsRegex = defaultMonthsRegex;
24424 }
24425
24426 return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex;
24427 }
24428 }
24429
24430 function computeMonthsParse() {
24431 function cmpLenRev(a, b) {
24432 return b.length - a.length;
24433 }
24434
24435 var shortPieces = [],
24436 longPieces = [],
24437 mixedPieces = [],
24438 i,
24439 mom;
24440
24441 for (i = 0; i < 12; i++) {
24442 // make the regex if we don't have it already
24443 mom = createUTC([2000, i]);
24444 shortPieces.push(this.monthsShort(mom, ''));
24445 longPieces.push(this.months(mom, ''));
24446 mixedPieces.push(this.months(mom, ''));
24447 mixedPieces.push(this.monthsShort(mom, ''));
24448 } // Sorting makes sure if one month (or abbr) is a prefix of another it
24449 // will match the longer piece.
24450
24451
24452 shortPieces.sort(cmpLenRev);
24453 longPieces.sort(cmpLenRev);
24454 mixedPieces.sort(cmpLenRev);
24455
24456 for (i = 0; i < 12; i++) {
24457 shortPieces[i] = regexEscape(shortPieces[i]);
24458 longPieces[i] = regexEscape(longPieces[i]);
24459 }
24460
24461 for (i = 0; i < 24; i++) {
24462 mixedPieces[i] = regexEscape(mixedPieces[i]);
24463 }
24464
24465 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
24466 this._monthsShortRegex = this._monthsRegex;
24467 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
24468 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
24469 }
24470
24471 function createDate(y, m, d, h, M, s, ms) {
24472 // can't just apply() to create a date:
24473 // https://stackoverflow.com/q/181348
24474 var date; // the date constructor remaps years 0-99 to 1900-1999
24475
24476 if (y < 100 && y >= 0) {
24477 // preserve leap years using a full 400 year cycle, then reset
24478 date = new Date(y + 400, m, d, h, M, s, ms);
24479
24480 if (isFinite(date.getFullYear())) {
24481 date.setFullYear(y);
24482 }
24483 } else {
24484 date = new Date(y, m, d, h, M, s, ms);
24485 }
24486
24487 return date;
24488 }
24489
24490 function createUTCDate(y) {
24491 var date; // the Date.UTC function remaps years 0-99 to 1900-1999
24492
24493 if (y < 100 && y >= 0) {
24494 var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset
24495
24496 args[0] = y + 400;
24497 date = new Date(Date.UTC.apply(null, args));
24498
24499 if (isFinite(date.getUTCFullYear())) {
24500 date.setUTCFullYear(y);
24501 }
24502 } else {
24503 date = new Date(Date.UTC.apply(null, arguments));
24504 }
24505
24506 return date;
24507 } // start-of-first-week - start-of-year
24508
24509
24510 function firstWeekOffset(year, dow, doy) {
24511 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
24512 fwd = 7 + dow - doy,
24513 // first-week day local weekday -- which local weekday is fwd
24514 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
24515 return -fwdlw + fwd - 1;
24516 } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
24517
24518
24519 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
24520 var localWeekday = (7 + weekday - dow) % 7,
24521 weekOffset = firstWeekOffset(year, dow, doy),
24522 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
24523 resYear,
24524 resDayOfYear;
24525
24526 if (dayOfYear <= 0) {
24527 resYear = year - 1;
24528 resDayOfYear = daysInYear(resYear) + dayOfYear;
24529 } else if (dayOfYear > daysInYear(year)) {
24530 resYear = year + 1;
24531 resDayOfYear = dayOfYear - daysInYear(year);
24532 } else {
24533 resYear = year;
24534 resDayOfYear = dayOfYear;
24535 }
24536
24537 return {
24538 year: resYear,
24539 dayOfYear: resDayOfYear
24540 };
24541 }
24542
24543 function weekOfYear(mom, dow, doy) {
24544 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
24545 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
24546 resWeek,
24547 resYear;
24548
24549 if (week < 1) {
24550 resYear = mom.year() - 1;
24551 resWeek = week + weeksInYear(resYear, dow, doy);
24552 } else if (week > weeksInYear(mom.year(), dow, doy)) {
24553 resWeek = week - weeksInYear(mom.year(), dow, doy);
24554 resYear = mom.year() + 1;
24555 } else {
24556 resYear = mom.year();
24557 resWeek = week;
24558 }
24559
24560 return {
24561 week: resWeek,
24562 year: resYear
24563 };
24564 }
24565
24566 function weeksInYear(year, dow, doy) {
24567 var weekOffset = firstWeekOffset(year, dow, doy),
24568 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
24569 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
24570 } // FORMATTING
24571
24572
24573 addFormatToken('w', ['ww', 2], 'wo', 'week');
24574 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES
24575
24576 addUnitAlias('week', 'w');
24577 addUnitAlias('isoWeek', 'W'); // PRIORITIES
24578
24579 addUnitPriority('week', 5);
24580 addUnitPriority('isoWeek', 5); // PARSING
24581
24582 addRegexToken('w', match1to2);
24583 addRegexToken('ww', match1to2, match2);
24584 addRegexToken('W', match1to2);
24585 addRegexToken('WW', match1to2, match2);
24586 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
24587 week[token.substr(0, 1)] = toInt(input);
24588 }); // HELPERS
24589 // LOCALES
24590
24591 function localeWeek(mom) {
24592 return weekOfYear(mom, this._week.dow, this._week.doy).week;
24593 }
24594
24595 var defaultLocaleWeek = {
24596 dow: 0,
24597 // Sunday is the first day of the week.
24598 doy: 6 // The week that contains Jan 6th is the first week of the year.
24599
24600 };
24601
24602 function localeFirstDayOfWeek() {
24603 return this._week.dow;
24604 }
24605
24606 function localeFirstDayOfYear() {
24607 return this._week.doy;
24608 } // MOMENTS
24609
24610
24611 function getSetWeek(input) {
24612 var week = this.localeData().week(this);
24613 return input == null ? week : this.add((input - week) * 7, 'd');
24614 }
24615
24616 function getSetISOWeek(input) {
24617 var week = weekOfYear(this, 1, 4).week;
24618 return input == null ? week : this.add((input - week) * 7, 'd');
24619 } // FORMATTING
24620
24621
24622 addFormatToken('d', 0, 'do', 'day');
24623 addFormatToken('dd', 0, 0, function (format) {
24624 return this.localeData().weekdaysMin(this, format);
24625 });
24626 addFormatToken('ddd', 0, 0, function (format) {
24627 return this.localeData().weekdaysShort(this, format);
24628 });
24629 addFormatToken('dddd', 0, 0, function (format) {
24630 return this.localeData().weekdays(this, format);
24631 });
24632 addFormatToken('e', 0, 0, 'weekday');
24633 addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES
24634
24635 addUnitAlias('day', 'd');
24636 addUnitAlias('weekday', 'e');
24637 addUnitAlias('isoWeekday', 'E'); // PRIORITY
24638
24639 addUnitPriority('day', 11);
24640 addUnitPriority('weekday', 11);
24641 addUnitPriority('isoWeekday', 11); // PARSING
24642
24643 addRegexToken('d', match1to2);
24644 addRegexToken('e', match1to2);
24645 addRegexToken('E', match1to2);
24646 addRegexToken('dd', function (isStrict, locale) {
24647 return locale.weekdaysMinRegex(isStrict);
24648 });
24649 addRegexToken('ddd', function (isStrict, locale) {
24650 return locale.weekdaysShortRegex(isStrict);
24651 });
24652 addRegexToken('dddd', function (isStrict, locale) {
24653 return locale.weekdaysRegex(isStrict);
24654 });
24655 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
24656 var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid
24657
24658
24659 if (weekday != null) {
24660 week.d = weekday;
24661 } else {
24662 getParsingFlags(config).invalidWeekday = input;
24663 }
24664 });
24665 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
24666 week[token] = toInt(input);
24667 }); // HELPERS
24668
24669 function parseWeekday(input, locale) {
24670 if (typeof input !== 'string') {
24671 return input;
24672 }
24673
24674 if (!isNaN(input)) {
24675 return parseInt(input, 10);
24676 }
24677
24678 input = locale.weekdaysParse(input);
24679
24680 if (typeof input === 'number') {
24681 return input;
24682 }
24683
24684 return null;
24685 }
24686
24687 function parseIsoWeekday(input, locale) {
24688 if (typeof input === 'string') {
24689 return locale.weekdaysParse(input) % 7 || 7;
24690 }
24691
24692 return isNaN(input) ? null : input;
24693 } // LOCALES
24694
24695
24696 function shiftWeekdays(ws, n) {
24697 return ws.slice(n, 7).concat(ws.slice(0, n));
24698 }
24699
24700 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
24701
24702 function localeWeekdays(m, format) {
24703 var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[m && m !== true && this._weekdays.isFormat.test(format) ? 'format' : 'standalone'];
24704 return m === true ? shiftWeekdays(weekdays, this._week.dow) : m ? weekdays[m.day()] : weekdays;
24705 }
24706
24707 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
24708
24709 function localeWeekdaysShort(m) {
24710 return m === true ? shiftWeekdays(this._weekdaysShort, this._week.dow) : m ? this._weekdaysShort[m.day()] : this._weekdaysShort;
24711 }
24712
24713 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
24714
24715 function localeWeekdaysMin(m) {
24716 return m === true ? shiftWeekdays(this._weekdaysMin, this._week.dow) : m ? this._weekdaysMin[m.day()] : this._weekdaysMin;
24717 }
24718
24719 function handleStrictParse$1(weekdayName, format, strict) {
24720 var i,
24721 ii,
24722 mom,
24723 llc = weekdayName.toLocaleLowerCase();
24724
24725 if (!this._weekdaysParse) {
24726 this._weekdaysParse = [];
24727 this._shortWeekdaysParse = [];
24728 this._minWeekdaysParse = [];
24729
24730 for (i = 0; i < 7; ++i) {
24731 mom = createUTC([2000, 1]).day(i);
24732 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
24733 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
24734 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
24735 }
24736 }
24737
24738 if (strict) {
24739 if (format === 'dddd') {
24740 ii = indexOf.call(this._weekdaysParse, llc);
24741 return ii !== -1 ? ii : null;
24742 } else if (format === 'ddd') {
24743 ii = indexOf.call(this._shortWeekdaysParse, llc);
24744 return ii !== -1 ? ii : null;
24745 } else {
24746 ii = indexOf.call(this._minWeekdaysParse, llc);
24747 return ii !== -1 ? ii : null;
24748 }
24749 } else {
24750 if (format === 'dddd') {
24751 ii = indexOf.call(this._weekdaysParse, llc);
24752
24753 if (ii !== -1) {
24754 return ii;
24755 }
24756
24757 ii = indexOf.call(this._shortWeekdaysParse, llc);
24758
24759 if (ii !== -1) {
24760 return ii;
24761 }
24762
24763 ii = indexOf.call(this._minWeekdaysParse, llc);
24764 return ii !== -1 ? ii : null;
24765 } else if (format === 'ddd') {
24766 ii = indexOf.call(this._shortWeekdaysParse, llc);
24767
24768 if (ii !== -1) {
24769 return ii;
24770 }
24771
24772 ii = indexOf.call(this._weekdaysParse, llc);
24773
24774 if (ii !== -1) {
24775 return ii;
24776 }
24777
24778 ii = indexOf.call(this._minWeekdaysParse, llc);
24779 return ii !== -1 ? ii : null;
24780 } else {
24781 ii = indexOf.call(this._minWeekdaysParse, llc);
24782
24783 if (ii !== -1) {
24784 return ii;
24785 }
24786
24787 ii = indexOf.call(this._weekdaysParse, llc);
24788
24789 if (ii !== -1) {
24790 return ii;
24791 }
24792
24793 ii = indexOf.call(this._shortWeekdaysParse, llc);
24794 return ii !== -1 ? ii : null;
24795 }
24796 }
24797 }
24798
24799 function localeWeekdaysParse(weekdayName, format, strict) {
24800 var i, mom, regex;
24801
24802 if (this._weekdaysParseExact) {
24803 return handleStrictParse$1.call(this, weekdayName, format, strict);
24804 }
24805
24806 if (!this._weekdaysParse) {
24807 this._weekdaysParse = [];
24808 this._minWeekdaysParse = [];
24809 this._shortWeekdaysParse = [];
24810 this._fullWeekdaysParse = [];
24811 }
24812
24813 for (i = 0; i < 7; i++) {
24814 // make the regex if we don't have it already
24815 mom = createUTC([2000, 1]).day(i);
24816
24817 if (strict && !this._fullWeekdaysParse[i]) {
24818 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
24819 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
24820 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
24821 }
24822
24823 if (!this._weekdaysParse[i]) {
24824 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
24825 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
24826 } // test the regex
24827
24828
24829 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
24830 return i;
24831 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
24832 return i;
24833 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
24834 return i;
24835 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
24836 return i;
24837 }
24838 }
24839 } // MOMENTS
24840
24841
24842 function getSetDayOfWeek(input) {
24843 if (!this.isValid()) {
24844 return input != null ? this : NaN;
24845 }
24846
24847 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
24848
24849 if (input != null) {
24850 input = parseWeekday(input, this.localeData());
24851 return this.add(input - day, 'd');
24852 } else {
24853 return day;
24854 }
24855 }
24856
24857 function getSetLocaleDayOfWeek(input) {
24858 if (!this.isValid()) {
24859 return input != null ? this : NaN;
24860 }
24861
24862 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
24863 return input == null ? weekday : this.add(input - weekday, 'd');
24864 }
24865
24866 function getSetISODayOfWeek(input) {
24867 if (!this.isValid()) {
24868 return input != null ? this : NaN;
24869 } // behaves the same as moment#day except
24870 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
24871 // as a setter, sunday should belong to the previous week.
24872
24873
24874 if (input != null) {
24875 var weekday = parseIsoWeekday(input, this.localeData());
24876 return this.day(this.day() % 7 ? weekday : weekday - 7);
24877 } else {
24878 return this.day() || 7;
24879 }
24880 }
24881
24882 var defaultWeekdaysRegex = matchWord;
24883
24884 function weekdaysRegex(isStrict) {
24885 if (this._weekdaysParseExact) {
24886 if (!hasOwnProp(this, '_weekdaysRegex')) {
24887 computeWeekdaysParse.call(this);
24888 }
24889
24890 if (isStrict) {
24891 return this._weekdaysStrictRegex;
24892 } else {
24893 return this._weekdaysRegex;
24894 }
24895 } else {
24896 if (!hasOwnProp(this, '_weekdaysRegex')) {
24897 this._weekdaysRegex = defaultWeekdaysRegex;
24898 }
24899
24900 return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex;
24901 }
24902 }
24903
24904 var defaultWeekdaysShortRegex = matchWord;
24905
24906 function weekdaysShortRegex(isStrict) {
24907 if (this._weekdaysParseExact) {
24908 if (!hasOwnProp(this, '_weekdaysRegex')) {
24909 computeWeekdaysParse.call(this);
24910 }
24911
24912 if (isStrict) {
24913 return this._weekdaysShortStrictRegex;
24914 } else {
24915 return this._weekdaysShortRegex;
24916 }
24917 } else {
24918 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
24919 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
24920 }
24921
24922 return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
24923 }
24924 }
24925
24926 var defaultWeekdaysMinRegex = matchWord;
24927
24928 function weekdaysMinRegex(isStrict) {
24929 if (this._weekdaysParseExact) {
24930 if (!hasOwnProp(this, '_weekdaysRegex')) {
24931 computeWeekdaysParse.call(this);
24932 }
24933
24934 if (isStrict) {
24935 return this._weekdaysMinStrictRegex;
24936 } else {
24937 return this._weekdaysMinRegex;
24938 }
24939 } else {
24940 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
24941 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
24942 }
24943
24944 return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
24945 }
24946 }
24947
24948 function computeWeekdaysParse() {
24949 function cmpLenRev(a, b) {
24950 return b.length - a.length;
24951 }
24952
24953 var minPieces = [],
24954 shortPieces = [],
24955 longPieces = [],
24956 mixedPieces = [],
24957 i,
24958 mom,
24959 minp,
24960 shortp,
24961 longp;
24962
24963 for (i = 0; i < 7; i++) {
24964 // make the regex if we don't have it already
24965 mom = createUTC([2000, 1]).day(i);
24966 minp = this.weekdaysMin(mom, '');
24967 shortp = this.weekdaysShort(mom, '');
24968 longp = this.weekdays(mom, '');
24969 minPieces.push(minp);
24970 shortPieces.push(shortp);
24971 longPieces.push(longp);
24972 mixedPieces.push(minp);
24973 mixedPieces.push(shortp);
24974 mixedPieces.push(longp);
24975 } // Sorting makes sure if one weekday (or abbr) is a prefix of another it
24976 // will match the longer piece.
24977
24978
24979 minPieces.sort(cmpLenRev);
24980 shortPieces.sort(cmpLenRev);
24981 longPieces.sort(cmpLenRev);
24982 mixedPieces.sort(cmpLenRev);
24983
24984 for (i = 0; i < 7; i++) {
24985 shortPieces[i] = regexEscape(shortPieces[i]);
24986 longPieces[i] = regexEscape(longPieces[i]);
24987 mixedPieces[i] = regexEscape(mixedPieces[i]);
24988 }
24989
24990 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
24991 this._weekdaysShortRegex = this._weekdaysRegex;
24992 this._weekdaysMinRegex = this._weekdaysRegex;
24993 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
24994 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
24995 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
24996 } // FORMATTING
24997
24998
24999 function hFormat() {
25000 return this.hours() % 12 || 12;
25001 }
25002
25003 function kFormat() {
25004 return this.hours() || 24;
25005 }
25006
25007 addFormatToken('H', ['HH', 2], 0, 'hour');
25008 addFormatToken('h', ['hh', 2], 0, hFormat);
25009 addFormatToken('k', ['kk', 2], 0, kFormat);
25010 addFormatToken('hmm', 0, 0, function () {
25011 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
25012 });
25013 addFormatToken('hmmss', 0, 0, function () {
25014 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
25015 });
25016 addFormatToken('Hmm', 0, 0, function () {
25017 return '' + this.hours() + zeroFill(this.minutes(), 2);
25018 });
25019 addFormatToken('Hmmss', 0, 0, function () {
25020 return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2);
25021 });
25022
25023 function meridiem(token, lowercase) {
25024 addFormatToken(token, 0, 0, function () {
25025 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
25026 });
25027 }
25028
25029 meridiem('a', true);
25030 meridiem('A', false); // ALIASES
25031
25032 addUnitAlias('hour', 'h'); // PRIORITY
25033
25034 addUnitPriority('hour', 13); // PARSING
25035
25036 function matchMeridiem(isStrict, locale) {
25037 return locale._meridiemParse;
25038 }
25039
25040 addRegexToken('a', matchMeridiem);
25041 addRegexToken('A', matchMeridiem);
25042 addRegexToken('H', match1to2);
25043 addRegexToken('h', match1to2);
25044 addRegexToken('k', match1to2);
25045 addRegexToken('HH', match1to2, match2);
25046 addRegexToken('hh', match1to2, match2);
25047 addRegexToken('kk', match1to2, match2);
25048 addRegexToken('hmm', match3to4);
25049 addRegexToken('hmmss', match5to6);
25050 addRegexToken('Hmm', match3to4);
25051 addRegexToken('Hmmss', match5to6);
25052 addParseToken(['H', 'HH'], HOUR);
25053 addParseToken(['k', 'kk'], function (input, array, config) {
25054 var kInput = toInt(input);
25055 array[HOUR] = kInput === 24 ? 0 : kInput;
25056 });
25057 addParseToken(['a', 'A'], function (input, array, config) {
25058 config._isPm = config._locale.isPM(input);
25059 config._meridiem = input;
25060 });
25061 addParseToken(['h', 'hh'], function (input, array, config) {
25062 array[HOUR] = toInt(input);
25063 getParsingFlags(config).bigHour = true;
25064 });
25065 addParseToken('hmm', function (input, array, config) {
25066 var pos = input.length - 2;
25067 array[HOUR] = toInt(input.substr(0, pos));
25068 array[MINUTE] = toInt(input.substr(pos));
25069 getParsingFlags(config).bigHour = true;
25070 });
25071 addParseToken('hmmss', function (input, array, config) {
25072 var pos1 = input.length - 4;
25073 var pos2 = input.length - 2;
25074 array[HOUR] = toInt(input.substr(0, pos1));
25075 array[MINUTE] = toInt(input.substr(pos1, 2));
25076 array[SECOND] = toInt(input.substr(pos2));
25077 getParsingFlags(config).bigHour = true;
25078 });
25079 addParseToken('Hmm', function (input, array, config) {
25080 var pos = input.length - 2;
25081 array[HOUR] = toInt(input.substr(0, pos));
25082 array[MINUTE] = toInt(input.substr(pos));
25083 });
25084 addParseToken('Hmmss', function (input, array, config) {
25085 var pos1 = input.length - 4;
25086 var pos2 = input.length - 2;
25087 array[HOUR] = toInt(input.substr(0, pos1));
25088 array[MINUTE] = toInt(input.substr(pos1, 2));
25089 array[SECOND] = toInt(input.substr(pos2));
25090 }); // LOCALES
25091
25092 function localeIsPM(input) {
25093 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
25094 // Using charAt should be more compatible.
25095 return (input + '').toLowerCase().charAt(0) === 'p';
25096 }
25097
25098 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
25099
25100 function localeMeridiem(hours, minutes, isLower) {
25101 if (hours > 11) {
25102 return isLower ? 'pm' : 'PM';
25103 } else {
25104 return isLower ? 'am' : 'AM';
25105 }
25106 } // MOMENTS
25107 // Setting the hour should keep the time, because the user explicitly
25108 // specified which hour they want. So trying to maintain the same hour (in
25109 // a new timezone) makes sense. Adding/subtracting hours does not follow
25110 // this rule.
25111
25112
25113 var getSetHour = makeGetSet('Hours', true);
25114 var baseConfig = {
25115 calendar: defaultCalendar,
25116 longDateFormat: defaultLongDateFormat,
25117 invalidDate: defaultInvalidDate,
25118 ordinal: defaultOrdinal,
25119 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
25120 relativeTime: defaultRelativeTime,
25121 months: defaultLocaleMonths,
25122 monthsShort: defaultLocaleMonthsShort,
25123 week: defaultLocaleWeek,
25124 weekdays: defaultLocaleWeekdays,
25125 weekdaysMin: defaultLocaleWeekdaysMin,
25126 weekdaysShort: defaultLocaleWeekdaysShort,
25127 meridiemParse: defaultLocaleMeridiemParse
25128 }; // internal storage for locale config files
25129
25130 var locales = {};
25131 var localeFamilies = {};
25132 var globalLocale;
25133
25134 function normalizeLocale(key) {
25135 return key ? key.toLowerCase().replace('_', '-') : key;
25136 } // pick the locale from the array
25137 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
25138 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
25139
25140
25141 function chooseLocale(names) {
25142 var i = 0,
25143 j,
25144 next,
25145 locale,
25146 split;
25147
25148 while (i < names.length) {
25149 split = normalizeLocale(names[i]).split('-');
25150 j = split.length;
25151 next = normalizeLocale(names[i + 1]);
25152 next = next ? next.split('-') : null;
25153
25154 while (j > 0) {
25155 locale = loadLocale(split.slice(0, j).join('-'));
25156
25157 if (locale) {
25158 return locale;
25159 }
25160
25161 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
25162 //the next array item is better than a shallower substring of this one
25163 break;
25164 }
25165
25166 j--;
25167 }
25168
25169 i++;
25170 }
25171
25172 return globalLocale;
25173 }
25174
25175 function loadLocale(name) {
25176 var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node
25177
25178 if (!locales[name] && 'object' !== 'undefined' && module && module.exports) {
25179 try {
25180 oldLocale = globalLocale._abbr;
25181 var aliasedRequire = commonjsRequire$1;
25182 aliasedRequire('./locale/' + name);
25183 getSetGlobalLocale(oldLocale);
25184 } catch (e) {}
25185 }
25186
25187 return locales[name];
25188 } // This function will load locale and then set the global locale. If
25189 // no arguments are passed in, it will simply return the current global
25190 // locale key.
25191
25192
25193 function getSetGlobalLocale(key, values) {
25194 var data;
25195
25196 if (key) {
25197 if (isUndefined(values)) {
25198 data = getLocale(key);
25199 } else {
25200 data = defineLocale(key, values);
25201 }
25202
25203 if (data) {
25204 // moment.duration._locale = moment._locale = data;
25205 globalLocale = data;
25206 } else {
25207 if (typeof console !== 'undefined' && console.warn) {
25208 //warn user if arguments are passed but the locale could not be set
25209 console.warn('Locale ' + key + ' not found. Did you forget to load it?');
25210 }
25211 }
25212 }
25213
25214 return globalLocale._abbr;
25215 }
25216
25217 function defineLocale(name, config) {
25218 if (config !== null) {
25219 var locale,
25220 parentConfig = baseConfig;
25221 config.abbr = name;
25222
25223 if (locales[name] != null) {
25224 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.');
25225 parentConfig = locales[name]._config;
25226 } else if (config.parentLocale != null) {
25227 if (locales[config.parentLocale] != null) {
25228 parentConfig = locales[config.parentLocale]._config;
25229 } else {
25230 locale = loadLocale(config.parentLocale);
25231
25232 if (locale != null) {
25233 parentConfig = locale._config;
25234 } else {
25235 if (!localeFamilies[config.parentLocale]) {
25236 localeFamilies[config.parentLocale] = [];
25237 }
25238
25239 localeFamilies[config.parentLocale].push({
25240 name: name,
25241 config: config
25242 });
25243 return null;
25244 }
25245 }
25246 }
25247
25248 locales[name] = new Locale(mergeConfigs(parentConfig, config));
25249
25250 if (localeFamilies[name]) {
25251 localeFamilies[name].forEach(function (x) {
25252 defineLocale(x.name, x.config);
25253 });
25254 } // backwards compat for now: also set the locale
25255 // make sure we set the locale AFTER all child locales have been
25256 // created, so we won't end up with the child locale set.
25257
25258
25259 getSetGlobalLocale(name);
25260 return locales[name];
25261 } else {
25262 // useful for testing
25263 delete locales[name];
25264 return null;
25265 }
25266 }
25267
25268 function updateLocale(name, config) {
25269 if (config != null) {
25270 var locale,
25271 tmpLocale,
25272 parentConfig = baseConfig; // MERGE
25273
25274 tmpLocale = loadLocale(name);
25275
25276 if (tmpLocale != null) {
25277 parentConfig = tmpLocale._config;
25278 }
25279
25280 config = mergeConfigs(parentConfig, config);
25281 locale = new Locale(config);
25282 locale.parentLocale = locales[name];
25283 locales[name] = locale; // backwards compat for now: also set the locale
25284
25285 getSetGlobalLocale(name);
25286 } else {
25287 // pass null for config to unupdate, useful for tests
25288 if (locales[name] != null) {
25289 if (locales[name].parentLocale != null) {
25290 locales[name] = locales[name].parentLocale;
25291 } else if (locales[name] != null) {
25292 delete locales[name];
25293 }
25294 }
25295 }
25296
25297 return locales[name];
25298 } // returns locale data
25299
25300
25301 function getLocale(key) {
25302 var locale;
25303
25304 if (key && key._locale && key._locale._abbr) {
25305 key = key._locale._abbr;
25306 }
25307
25308 if (!key) {
25309 return globalLocale;
25310 }
25311
25312 if (!isArray(key)) {
25313 //short-circuit everything else
25314 locale = loadLocale(key);
25315
25316 if (locale) {
25317 return locale;
25318 }
25319
25320 key = [key];
25321 }
25322
25323 return chooseLocale(key);
25324 }
25325
25326 function listLocales() {
25327 return keys(locales);
25328 }
25329
25330 function checkOverflow(m) {
25331 var overflow;
25332 var a = m._a;
25333
25334 if (a && getParsingFlags(m).overflow === -2) {
25335 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;
25336
25337 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
25338 overflow = DATE;
25339 }
25340
25341 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
25342 overflow = WEEK;
25343 }
25344
25345 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
25346 overflow = WEEKDAY;
25347 }
25348
25349 getParsingFlags(m).overflow = overflow;
25350 }
25351
25352 return m;
25353 } // Pick the first defined of two or three arguments.
25354
25355
25356 function defaults(a, b, c) {
25357 if (a != null) {
25358 return a;
25359 }
25360
25361 if (b != null) {
25362 return b;
25363 }
25364
25365 return c;
25366 }
25367
25368 function currentDateArray(config) {
25369 // hooks is actually the exported moment object
25370 var nowValue = new Date(hooks.now());
25371
25372 if (config._useUTC) {
25373 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
25374 }
25375
25376 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
25377 } // convert an array to a date.
25378 // the array should mirror the parameters below
25379 // note: all values past the year are optional and will default to the lowest possible value.
25380 // [year, month, day , hour, minute, second, millisecond]
25381
25382
25383 function configFromArray(config) {
25384 var i,
25385 date,
25386 input = [],
25387 currentDate,
25388 expectedWeekday,
25389 yearToUse;
25390
25391 if (config._d) {
25392 return;
25393 }
25394
25395 currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays
25396
25397 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
25398 dayOfYearFromWeekInfo(config);
25399 } //if the day of the year is set, figure out what it is
25400
25401
25402 if (config._dayOfYear != null) {
25403 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
25404
25405 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
25406 getParsingFlags(config)._overflowDayOfYear = true;
25407 }
25408
25409 date = createUTCDate(yearToUse, 0, config._dayOfYear);
25410 config._a[MONTH] = date.getUTCMonth();
25411 config._a[DATE] = date.getUTCDate();
25412 } // Default to current date.
25413 // * if no year, month, day of month are given, default to today
25414 // * if day of month is given, default month and year
25415 // * if month is given, default only year
25416 // * if year is given, don't default anything
25417
25418
25419 for (i = 0; i < 3 && config._a[i] == null; ++i) {
25420 config._a[i] = input[i] = currentDate[i];
25421 } // Zero out whatever was not defaulted, including time
25422
25423
25424 for (; i < 7; i++) {
25425 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i];
25426 } // Check for 24:00:00.000
25427
25428
25429 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) {
25430 config._nextDay = true;
25431 config._a[HOUR] = 0;
25432 }
25433
25434 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
25435 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed
25436 // with parseZone.
25437
25438 if (config._tzm != null) {
25439 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
25440 }
25441
25442 if (config._nextDay) {
25443 config._a[HOUR] = 24;
25444 } // check for mismatching day of week
25445
25446
25447 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
25448 getParsingFlags(config).weekdayMismatch = true;
25449 }
25450 }
25451
25452 function dayOfYearFromWeekInfo(config) {
25453 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
25454 w = config._w;
25455
25456 if (w.GG != null || w.W != null || w.E != null) {
25457 dow = 1;
25458 doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on
25459 // how we interpret now (local, utc, fixed offset). So create
25460 // a now version of current config (take local/utc/offset flags, and
25461 // create now).
25462
25463 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
25464 week = defaults(w.W, 1);
25465 weekday = defaults(w.E, 1);
25466
25467 if (weekday < 1 || weekday > 7) {
25468 weekdayOverflow = true;
25469 }
25470 } else {
25471 dow = config._locale._week.dow;
25472 doy = config._locale._week.doy;
25473 var curWeek = weekOfYear(createLocal(), dow, doy);
25474 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week.
25475
25476 week = defaults(w.w, curWeek.week);
25477
25478 if (w.d != null) {
25479 // weekday -- low day numbers are considered next week
25480 weekday = w.d;
25481
25482 if (weekday < 0 || weekday > 6) {
25483 weekdayOverflow = true;
25484 }
25485 } else if (w.e != null) {
25486 // local weekday -- counting starts from beginning of week
25487 weekday = w.e + dow;
25488
25489 if (w.e < 0 || w.e > 6) {
25490 weekdayOverflow = true;
25491 }
25492 } else {
25493 // default to beginning of week
25494 weekday = dow;
25495 }
25496 }
25497
25498 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
25499 getParsingFlags(config)._overflowWeeks = true;
25500 } else if (weekdayOverflow != null) {
25501 getParsingFlags(config)._overflowWeekday = true;
25502 } else {
25503 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
25504 config._a[YEAR] = temp.year;
25505 config._dayOfYear = temp.dayOfYear;
25506 }
25507 } // iso 8601 regex
25508 // 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)
25509
25510
25511 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)?)?$/;
25512 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)?)?$/;
25513 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
25514 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
25515 ['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
25516
25517 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/]];
25518 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format
25519
25520 function configFromISO(config) {
25521 var i,
25522 l,
25523 string = config._i,
25524 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
25525 allowTime,
25526 dateFormat,
25527 timeFormat,
25528 tzFormat;
25529
25530 if (match) {
25531 getParsingFlags(config).iso = true;
25532
25533 for (i = 0, l = isoDates.length; i < l; i++) {
25534 if (isoDates[i][1].exec(match[1])) {
25535 dateFormat = isoDates[i][0];
25536 allowTime = isoDates[i][2] !== false;
25537 break;
25538 }
25539 }
25540
25541 if (dateFormat == null) {
25542 config._isValid = false;
25543 return;
25544 }
25545
25546 if (match[3]) {
25547 for (i = 0, l = isoTimes.length; i < l; i++) {
25548 if (isoTimes[i][1].exec(match[3])) {
25549 // match[2] should be 'T' or space
25550 timeFormat = (match[2] || ' ') + isoTimes[i][0];
25551 break;
25552 }
25553 }
25554
25555 if (timeFormat == null) {
25556 config._isValid = false;
25557 return;
25558 }
25559 }
25560
25561 if (!allowTime && timeFormat != null) {
25562 config._isValid = false;
25563 return;
25564 }
25565
25566 if (match[4]) {
25567 if (tzRegex.exec(match[4])) {
25568 tzFormat = 'Z';
25569 } else {
25570 config._isValid = false;
25571 return;
25572 }
25573 }
25574
25575 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
25576 configFromStringAndFormat(config);
25577 } else {
25578 config._isValid = false;
25579 }
25580 } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
25581
25582
25583 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}))$/;
25584
25585 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
25586 var result = [untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10)];
25587
25588 if (secondStr) {
25589 result.push(parseInt(secondStr, 10));
25590 }
25591
25592 return result;
25593 }
25594
25595 function untruncateYear(yearStr) {
25596 var year = parseInt(yearStr, 10);
25597
25598 if (year <= 49) {
25599 return 2000 + year;
25600 } else if (year <= 999) {
25601 return 1900 + year;
25602 }
25603
25604 return year;
25605 }
25606
25607 function preprocessRFC2822(s) {
25608 // Remove comments and folding whitespace and replace multiple-spaces with a single space
25609 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
25610 }
25611
25612 function checkWeekday(weekdayStr, parsedInput, config) {
25613 if (weekdayStr) {
25614 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
25615 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
25616 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
25617
25618 if (weekdayProvided !== weekdayActual) {
25619 getParsingFlags(config).weekdayMismatch = true;
25620 config._isValid = false;
25621 return false;
25622 }
25623 }
25624
25625 return true;
25626 }
25627
25628 var obsOffsets = {
25629 UT: 0,
25630 GMT: 0,
25631 EDT: -4 * 60,
25632 EST: -5 * 60,
25633 CDT: -5 * 60,
25634 CST: -6 * 60,
25635 MDT: -6 * 60,
25636 MST: -7 * 60,
25637 PDT: -7 * 60,
25638 PST: -8 * 60
25639 };
25640
25641 function calculateOffset(obsOffset, militaryOffset, numOffset) {
25642 if (obsOffset) {
25643 return obsOffsets[obsOffset];
25644 } else if (militaryOffset) {
25645 // the only allowed military tz is Z
25646 return 0;
25647 } else {
25648 var hm = parseInt(numOffset, 10);
25649 var m = hm % 100,
25650 h = (hm - m) / 100;
25651 return h * 60 + m;
25652 }
25653 } // date and time from ref 2822 format
25654
25655
25656 function configFromRFC2822(config) {
25657 var match = rfc2822.exec(preprocessRFC2822(config._i));
25658
25659 if (match) {
25660 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
25661
25662 if (!checkWeekday(match[1], parsedArray, config)) {
25663 return;
25664 }
25665
25666 config._a = parsedArray;
25667 config._tzm = calculateOffset(match[8], match[9], match[10]);
25668 config._d = createUTCDate.apply(null, config._a);
25669
25670 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
25671
25672 getParsingFlags(config).rfc2822 = true;
25673 } else {
25674 config._isValid = false;
25675 }
25676 } // date from iso format or fallback
25677
25678
25679 function configFromString(config) {
25680 var matched = aspNetJsonRegex.exec(config._i);
25681
25682 if (matched !== null) {
25683 config._d = new Date(+matched[1]);
25684 return;
25685 }
25686
25687 configFromISO(config);
25688
25689 if (config._isValid === false) {
25690 delete config._isValid;
25691 } else {
25692 return;
25693 }
25694
25695 configFromRFC2822(config);
25696
25697 if (config._isValid === false) {
25698 delete config._isValid;
25699 } else {
25700 return;
25701 } // Final attempt, use Input Fallback
25702
25703
25704 hooks.createFromInputFallback(config);
25705 }
25706
25707 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) {
25708 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
25709 }); // constant that refers to the ISO standard
25710
25711 hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form
25712
25713
25714 hooks.RFC_2822 = function () {}; // date from string and format string
25715
25716
25717 function configFromStringAndFormat(config) {
25718 // TODO: Move this to another part of the creation flow to prevent circular deps
25719 if (config._f === hooks.ISO_8601) {
25720 configFromISO(config);
25721 return;
25722 }
25723
25724 if (config._f === hooks.RFC_2822) {
25725 configFromRFC2822(config);
25726 return;
25727 }
25728
25729 config._a = [];
25730 getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC`
25731
25732 var string = '' + config._i,
25733 i,
25734 parsedInput,
25735 tokens,
25736 token,
25737 skipped,
25738 stringLength = string.length,
25739 totalParsedInputLength = 0;
25740 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
25741
25742 for (i = 0; i < tokens.length; i++) {
25743 token = tokens[i];
25744 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput,
25745 // 'regex', getParseRegexForToken(token, config));
25746
25747 if (parsedInput) {
25748 skipped = string.substr(0, string.indexOf(parsedInput));
25749
25750 if (skipped.length > 0) {
25751 getParsingFlags(config).unusedInput.push(skipped);
25752 }
25753
25754 string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
25755 totalParsedInputLength += parsedInput.length;
25756 } // don't parse if it's not a known token
25757
25758
25759 if (formatTokenFunctions[token]) {
25760 if (parsedInput) {
25761 getParsingFlags(config).empty = false;
25762 } else {
25763 getParsingFlags(config).unusedTokens.push(token);
25764 }
25765
25766 addTimeToArrayFromToken(token, parsedInput, config);
25767 } else if (config._strict && !parsedInput) {
25768 getParsingFlags(config).unusedTokens.push(token);
25769 }
25770 } // add remaining unparsed input length to the string
25771
25772
25773 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
25774
25775 if (string.length > 0) {
25776 getParsingFlags(config).unusedInput.push(string);
25777 } // clear _12h flag if hour is <= 12
25778
25779
25780 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) {
25781 getParsingFlags(config).bigHour = undefined;
25782 }
25783
25784 getParsingFlags(config).parsedDateParts = config._a.slice(0);
25785 getParsingFlags(config).meridiem = config._meridiem; // handle meridiem
25786
25787 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
25788 configFromArray(config);
25789 checkOverflow(config);
25790 }
25791
25792 function meridiemFixWrap(locale, hour, meridiem) {
25793 var isPm;
25794
25795 if (meridiem == null) {
25796 // nothing to do
25797 return hour;
25798 }
25799
25800 if (locale.meridiemHour != null) {
25801 return locale.meridiemHour(hour, meridiem);
25802 } else if (locale.isPM != null) {
25803 // Fallback
25804 isPm = locale.isPM(meridiem);
25805
25806 if (isPm && hour < 12) {
25807 hour += 12;
25808 }
25809
25810 if (!isPm && hour === 12) {
25811 hour = 0;
25812 }
25813
25814 return hour;
25815 } else {
25816 // this is not supposed to happen
25817 return hour;
25818 }
25819 } // date from string and array of format strings
25820
25821
25822 function configFromStringAndArray(config) {
25823 var tempConfig, bestMoment, scoreToBeat, i, currentScore;
25824
25825 if (config._f.length === 0) {
25826 getParsingFlags(config).invalidFormat = true;
25827 config._d = new Date(NaN);
25828 return;
25829 }
25830
25831 for (i = 0; i < config._f.length; i++) {
25832 currentScore = 0;
25833 tempConfig = copyConfig({}, config);
25834
25835 if (config._useUTC != null) {
25836 tempConfig._useUTC = config._useUTC;
25837 }
25838
25839 tempConfig._f = config._f[i];
25840 configFromStringAndFormat(tempConfig);
25841
25842 if (!isValid(tempConfig)) {
25843 continue;
25844 } // if there is any input that was not parsed add a penalty for that format
25845
25846
25847 currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens
25848
25849 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
25850 getParsingFlags(tempConfig).score = currentScore;
25851
25852 if (scoreToBeat == null || currentScore < scoreToBeat) {
25853 scoreToBeat = currentScore;
25854 bestMoment = tempConfig;
25855 }
25856 }
25857
25858 extend(config, bestMoment || tempConfig);
25859 }
25860
25861 function configFromObject(config) {
25862 if (config._d) {
25863 return;
25864 }
25865
25866 var i = normalizeObjectUnits(config._i);
25867 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
25868 return obj && parseInt(obj, 10);
25869 });
25870 configFromArray(config);
25871 }
25872
25873 function createFromConfig(config) {
25874 var res = new Moment(checkOverflow(prepareConfig(config)));
25875
25876 if (res._nextDay) {
25877 // Adding is smart enough around DST
25878 res.add(1, 'd');
25879 res._nextDay = undefined;
25880 }
25881
25882 return res;
25883 }
25884
25885 function prepareConfig(config) {
25886 var input = config._i,
25887 format = config._f;
25888 config._locale = config._locale || getLocale(config._l);
25889
25890 if (input === null || format === undefined && input === '') {
25891 return createInvalid({
25892 nullInput: true
25893 });
25894 }
25895
25896 if (typeof input === 'string') {
25897 config._i = input = config._locale.preparse(input);
25898 }
25899
25900 if (isMoment(input)) {
25901 return new Moment(checkOverflow(input));
25902 } else if (isDate(input)) {
25903 config._d = input;
25904 } else if (isArray(format)) {
25905 configFromStringAndArray(config);
25906 } else if (format) {
25907 configFromStringAndFormat(config);
25908 } else {
25909 configFromInput(config);
25910 }
25911
25912 if (!isValid(config)) {
25913 config._d = null;
25914 }
25915
25916 return config;
25917 }
25918
25919 function configFromInput(config) {
25920 var input = config._i;
25921
25922 if (isUndefined(input)) {
25923 config._d = new Date(hooks.now());
25924 } else if (isDate(input)) {
25925 config._d = new Date(input.valueOf());
25926 } else if (typeof input === 'string') {
25927 configFromString(config);
25928 } else if (isArray(input)) {
25929 config._a = map(input.slice(0), function (obj) {
25930 return parseInt(obj, 10);
25931 });
25932 configFromArray(config);
25933 } else if (isObject(input)) {
25934 configFromObject(config);
25935 } else if (isNumber(input)) {
25936 // from milliseconds
25937 config._d = new Date(input);
25938 } else {
25939 hooks.createFromInputFallback(config);
25940 }
25941 }
25942
25943 function createLocalOrUTC(input, format, locale, strict, isUTC) {
25944 var c = {};
25945
25946 if (locale === true || locale === false) {
25947 strict = locale;
25948 locale = undefined;
25949 }
25950
25951 if (isObject(input) && isObjectEmpty(input) || isArray(input) && input.length === 0) {
25952 input = undefined;
25953 } // object construction must be done this way.
25954 // https://github.com/moment/moment/issues/1423
25955
25956
25957 c._isAMomentObject = true;
25958 c._useUTC = c._isUTC = isUTC;
25959 c._l = locale;
25960 c._i = input;
25961 c._f = format;
25962 c._strict = strict;
25963 return createFromConfig(c);
25964 }
25965
25966 function createLocal(input, format, locale, strict) {
25967 return createLocalOrUTC(input, format, locale, strict, false);
25968 }
25969
25970 var prototypeMin = deprecate('moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
25971 var other = createLocal.apply(null, arguments);
25972
25973 if (this.isValid() && other.isValid()) {
25974 return other < this ? this : other;
25975 } else {
25976 return createInvalid();
25977 }
25978 });
25979 var prototypeMax = deprecate('moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () {
25980 var other = createLocal.apply(null, arguments);
25981
25982 if (this.isValid() && other.isValid()) {
25983 return other > this ? this : other;
25984 } else {
25985 return createInvalid();
25986 }
25987 }); // Pick a moment m from moments so that m[fn](other) is true for all
25988 // other. This relies on the function fn to be transitive.
25989 //
25990 // moments should either be an array of moment objects or an array, whose
25991 // first element is an array of moment objects.
25992
25993 function pickBy(fn, moments) {
25994 var res, i;
25995
25996 if (moments.length === 1 && isArray(moments[0])) {
25997 moments = moments[0];
25998 }
25999
26000 if (!moments.length) {
26001 return createLocal();
26002 }
26003
26004 res = moments[0];
26005
26006 for (i = 1; i < moments.length; ++i) {
26007 if (!moments[i].isValid() || moments[i][fn](res)) {
26008 res = moments[i];
26009 }
26010 }
26011
26012 return res;
26013 } // TODO: Use [].sort instead?
26014
26015
26016 function min() {
26017 var args = [].slice.call(arguments, 0);
26018 return pickBy('isBefore', args);
26019 }
26020
26021 function max() {
26022 var args = [].slice.call(arguments, 0);
26023 return pickBy('isAfter', args);
26024 }
26025
26026 var now = function () {
26027 return Date.now ? Date.now() : +new Date();
26028 };
26029
26030 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
26031
26032 function isDurationValid(m) {
26033 for (var key in m) {
26034 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
26035 return false;
26036 }
26037 }
26038
26039 var unitHasDecimal = false;
26040
26041 for (var i = 0; i < ordering.length; ++i) {
26042 if (m[ordering[i]]) {
26043 if (unitHasDecimal) {
26044 return false; // only allow non-integers for smallest unit
26045 }
26046
26047 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
26048 unitHasDecimal = true;
26049 }
26050 }
26051 }
26052
26053 return true;
26054 }
26055
26056 function isValid$1() {
26057 return this._isValid;
26058 }
26059
26060 function createInvalid$1() {
26061 return createDuration(NaN);
26062 }
26063
26064 function Duration(duration) {
26065 var normalizedInput = normalizeObjectUnits(duration),
26066 years = normalizedInput.year || 0,
26067 quarters = normalizedInput.quarter || 0,
26068 months = normalizedInput.month || 0,
26069 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
26070 days = normalizedInput.day || 0,
26071 hours = normalizedInput.hour || 0,
26072 minutes = normalizedInput.minute || 0,
26073 seconds = normalizedInput.second || 0,
26074 milliseconds = normalizedInput.millisecond || 0;
26075 this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove
26076
26077 this._milliseconds = +milliseconds + seconds * 1e3 + // 1000
26078 minutes * 6e4 + // 1000 * 60
26079 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
26080 // Because of dateAddRemove treats 24 hours as different from a
26081 // day when working around DST, we need to store them separately
26082
26083 this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing
26084 // which months you are are talking about, so we have to store
26085 // it separately.
26086
26087 this._months = +months + quarters * 3 + years * 12;
26088 this._data = {};
26089 this._locale = getLocale();
26090
26091 this._bubble();
26092 }
26093
26094 function isDuration(obj) {
26095 return obj instanceof Duration;
26096 }
26097
26098 function absRound(number) {
26099 if (number < 0) {
26100 return Math.round(-1 * number) * -1;
26101 } else {
26102 return Math.round(number);
26103 }
26104 } // FORMATTING
26105
26106
26107 function offset(token, separator) {
26108 addFormatToken(token, 0, 0, function () {
26109 var offset = this.utcOffset();
26110 var sign = '+';
26111
26112 if (offset < 0) {
26113 offset = -offset;
26114 sign = '-';
26115 }
26116
26117 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~offset % 60, 2);
26118 });
26119 }
26120
26121 offset('Z', ':');
26122 offset('ZZ', ''); // PARSING
26123
26124 addRegexToken('Z', matchShortOffset);
26125 addRegexToken('ZZ', matchShortOffset);
26126 addParseToken(['Z', 'ZZ'], function (input, array, config) {
26127 config._useUTC = true;
26128 config._tzm = offsetFromString(matchShortOffset, input);
26129 }); // HELPERS
26130 // timezone chunker
26131 // '+10:00' > ['10', '00']
26132 // '-1530' > ['-15', '30']
26133
26134 var chunkOffset = /([\+\-]|\d\d)/gi;
26135
26136 function offsetFromString(matcher, string) {
26137 var matches = (string || '').match(matcher);
26138
26139 if (matches === null) {
26140 return null;
26141 }
26142
26143 var chunk = matches[matches.length - 1] || [];
26144 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
26145 var minutes = +(parts[1] * 60) + toInt(parts[2]);
26146 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
26147 } // Return a moment from input, that is local/utc/zone equivalent to model.
26148
26149
26150 function cloneWithOffset(input, model) {
26151 var res, diff;
26152
26153 if (model._isUTC) {
26154 res = model.clone();
26155 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api.
26156
26157 res._d.setTime(res._d.valueOf() + diff);
26158
26159 hooks.updateOffset(res, false);
26160 return res;
26161 } else {
26162 return createLocal(input).local();
26163 }
26164 }
26165
26166 function getDateOffset(m) {
26167 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
26168 // https://github.com/moment/moment/pull/1871
26169 return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
26170 } // HOOKS
26171 // This function will be called whenever a moment is mutated.
26172 // It is intended to keep the offset in sync with the timezone.
26173
26174
26175 hooks.updateOffset = function () {}; // MOMENTS
26176 // keepLocalTime = true means only change the timezone, without
26177 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
26178 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
26179 // +0200, so we adjust the time as needed, to be valid.
26180 //
26181 // Keeping the time actually adds/subtracts (one hour)
26182 // from the actual represented time. That is why we call updateOffset
26183 // a second time. In case it wants us to change the offset again
26184 // _changeInProgress == true case, then we have to adjust, because
26185 // there is no such time in the given timezone.
26186
26187
26188 function getSetOffset(input, keepLocalTime, keepMinutes) {
26189 var offset = this._offset || 0,
26190 localAdjust;
26191
26192 if (!this.isValid()) {
26193 return input != null ? this : NaN;
26194 }
26195
26196 if (input != null) {
26197 if (typeof input === 'string') {
26198 input = offsetFromString(matchShortOffset, input);
26199
26200 if (input === null) {
26201 return this;
26202 }
26203 } else if (Math.abs(input) < 16 && !keepMinutes) {
26204 input = input * 60;
26205 }
26206
26207 if (!this._isUTC && keepLocalTime) {
26208 localAdjust = getDateOffset(this);
26209 }
26210
26211 this._offset = input;
26212 this._isUTC = true;
26213
26214 if (localAdjust != null) {
26215 this.add(localAdjust, 'm');
26216 }
26217
26218 if (offset !== input) {
26219 if (!keepLocalTime || this._changeInProgress) {
26220 addSubtract(this, createDuration(input - offset, 'm'), 1, false);
26221 } else if (!this._changeInProgress) {
26222 this._changeInProgress = true;
26223 hooks.updateOffset(this, true);
26224 this._changeInProgress = null;
26225 }
26226 }
26227
26228 return this;
26229 } else {
26230 return this._isUTC ? offset : getDateOffset(this);
26231 }
26232 }
26233
26234 function getSetZone(input, keepLocalTime) {
26235 if (input != null) {
26236 if (typeof input !== 'string') {
26237 input = -input;
26238 }
26239
26240 this.utcOffset(input, keepLocalTime);
26241 return this;
26242 } else {
26243 return -this.utcOffset();
26244 }
26245 }
26246
26247 function setOffsetToUTC(keepLocalTime) {
26248 return this.utcOffset(0, keepLocalTime);
26249 }
26250
26251 function setOffsetToLocal(keepLocalTime) {
26252 if (this._isUTC) {
26253 this.utcOffset(0, keepLocalTime);
26254 this._isUTC = false;
26255
26256 if (keepLocalTime) {
26257 this.subtract(getDateOffset(this), 'm');
26258 }
26259 }
26260
26261 return this;
26262 }
26263
26264 function setOffsetToParsedOffset() {
26265 if (this._tzm != null) {
26266 this.utcOffset(this._tzm, false, true);
26267 } else if (typeof this._i === 'string') {
26268 var tZone = offsetFromString(matchOffset, this._i);
26269
26270 if (tZone != null) {
26271 this.utcOffset(tZone);
26272 } else {
26273 this.utcOffset(0, true);
26274 }
26275 }
26276
26277 return this;
26278 }
26279
26280 function hasAlignedHourOffset(input) {
26281 if (!this.isValid()) {
26282 return false;
26283 }
26284
26285 input = input ? createLocal(input).utcOffset() : 0;
26286 return (this.utcOffset() - input) % 60 === 0;
26287 }
26288
26289 function isDaylightSavingTime() {
26290 return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset();
26291 }
26292
26293 function isDaylightSavingTimeShifted() {
26294 if (!isUndefined(this._isDSTShifted)) {
26295 return this._isDSTShifted;
26296 }
26297
26298 var c = {};
26299 copyConfig(c, this);
26300 c = prepareConfig(c);
26301
26302 if (c._a) {
26303 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
26304 this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0;
26305 } else {
26306 this._isDSTShifted = false;
26307 }
26308
26309 return this._isDSTShifted;
26310 }
26311
26312 function isLocal() {
26313 return this.isValid() ? !this._isUTC : false;
26314 }
26315
26316 function isUtcOffset() {
26317 return this.isValid() ? this._isUTC : false;
26318 }
26319
26320 function isUtc() {
26321 return this.isValid() ? this._isUTC && this._offset === 0 : false;
26322 } // ASP.NET json date format regex
26323
26324
26325 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
26326 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
26327 // and further modified to allow for strings containing both week and day
26328
26329 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)?)?$/;
26330
26331 function createDuration(input, key) {
26332 var duration = input,
26333 // matching against regexp is expensive, do it on demand
26334 match = null,
26335 sign,
26336 ret,
26337 diffRes;
26338
26339 if (isDuration(input)) {
26340 duration = {
26341 ms: input._milliseconds,
26342 d: input._days,
26343 M: input._months
26344 };
26345 } else if (isNumber(input)) {
26346 duration = {};
26347
26348 if (key) {
26349 duration[key] = input;
26350 } else {
26351 duration.milliseconds = input;
26352 }
26353 } else if (!!(match = aspNetRegex.exec(input))) {
26354 sign = match[1] === '-' ? -1 : 1;
26355 duration = {
26356 y: 0,
26357 d: toInt(match[DATE]) * sign,
26358 h: toInt(match[HOUR]) * sign,
26359 m: toInt(match[MINUTE]) * sign,
26360 s: toInt(match[SECOND]) * sign,
26361 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
26362
26363 };
26364 } else if (!!(match = isoRegex.exec(input))) {
26365 sign = match[1] === '-' ? -1 : 1;
26366 duration = {
26367 y: parseIso(match[2], sign),
26368 M: parseIso(match[3], sign),
26369 w: parseIso(match[4], sign),
26370 d: parseIso(match[5], sign),
26371 h: parseIso(match[6], sign),
26372 m: parseIso(match[7], sign),
26373 s: parseIso(match[8], sign)
26374 };
26375 } else if (duration == null) {
26376 // checks for null or undefined
26377 duration = {};
26378 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
26379 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
26380 duration = {};
26381 duration.ms = diffRes.milliseconds;
26382 duration.M = diffRes.months;
26383 }
26384
26385 ret = new Duration(duration);
26386
26387 if (isDuration(input) && hasOwnProp(input, '_locale')) {
26388 ret._locale = input._locale;
26389 }
26390
26391 return ret;
26392 }
26393
26394 createDuration.fn = Duration.prototype;
26395 createDuration.invalid = createInvalid$1;
26396
26397 function parseIso(inp, sign) {
26398 // We'd normally use ~~inp for this, but unfortunately it also
26399 // converts floats to ints.
26400 // inp may be undefined, so careful calling replace on it.
26401 var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it
26402
26403 return (isNaN(res) ? 0 : res) * sign;
26404 }
26405
26406 function positiveMomentsDifference(base, other) {
26407 var res = {};
26408 res.months = other.month() - base.month() + (other.year() - base.year()) * 12;
26409
26410 if (base.clone().add(res.months, 'M').isAfter(other)) {
26411 --res.months;
26412 }
26413
26414 res.milliseconds = +other - +base.clone().add(res.months, 'M');
26415 return res;
26416 }
26417
26418 function momentsDifference(base, other) {
26419 var res;
26420
26421 if (!(base.isValid() && other.isValid())) {
26422 return {
26423 milliseconds: 0,
26424 months: 0
26425 };
26426 }
26427
26428 other = cloneWithOffset(other, base);
26429
26430 if (base.isBefore(other)) {
26431 res = positiveMomentsDifference(base, other);
26432 } else {
26433 res = positiveMomentsDifference(other, base);
26434 res.milliseconds = -res.milliseconds;
26435 res.months = -res.months;
26436 }
26437
26438 return res;
26439 } // TODO: remove 'name' arg after deprecation is removed
26440
26441
26442 function createAdder(direction, name) {
26443 return function (val, period) {
26444 var dur, tmp; //invert the arguments, but complain about it
26445
26446 if (period !== null && !isNaN(+period)) {
26447 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.');
26448 tmp = val;
26449 val = period;
26450 period = tmp;
26451 }
26452
26453 val = typeof val === 'string' ? +val : val;
26454 dur = createDuration(val, period);
26455 addSubtract(this, dur, direction);
26456 return this;
26457 };
26458 }
26459
26460 function addSubtract(mom, duration, isAdding, updateOffset) {
26461 var milliseconds = duration._milliseconds,
26462 days = absRound(duration._days),
26463 months = absRound(duration._months);
26464
26465 if (!mom.isValid()) {
26466 // No op
26467 return;
26468 }
26469
26470 updateOffset = updateOffset == null ? true : updateOffset;
26471
26472 if (months) {
26473 setMonth(mom, get(mom, 'Month') + months * isAdding);
26474 }
26475
26476 if (days) {
26477 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
26478 }
26479
26480 if (milliseconds) {
26481 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
26482 }
26483
26484 if (updateOffset) {
26485 hooks.updateOffset(mom, days || months);
26486 }
26487 }
26488
26489 var add = createAdder(1, 'add');
26490 var subtract = createAdder(-1, 'subtract');
26491
26492 function getCalendarFormat(myMoment, now) {
26493 var diff = myMoment.diff(now, 'days', true);
26494 return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse';
26495 }
26496
26497 function calendar$1(time, formats) {
26498 // We want to compare the start of today, vs this.
26499 // Getting start-of-today depends on whether we're local/utc/offset or not.
26500 var now = time || createLocal(),
26501 sod = cloneWithOffset(now, this).startOf('day'),
26502 format = hooks.calendarFormat(this, sod) || 'sameElse';
26503 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
26504 return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
26505 }
26506
26507 function clone() {
26508 return new Moment(this);
26509 }
26510
26511 function isAfter(input, units) {
26512 var localInput = isMoment(input) ? input : createLocal(input);
26513
26514 if (!(this.isValid() && localInput.isValid())) {
26515 return false;
26516 }
26517
26518 units = normalizeUnits(units) || 'millisecond';
26519
26520 if (units === 'millisecond') {
26521 return this.valueOf() > localInput.valueOf();
26522 } else {
26523 return localInput.valueOf() < this.clone().startOf(units).valueOf();
26524 }
26525 }
26526
26527 function isBefore(input, units) {
26528 var localInput = isMoment(input) ? input : createLocal(input);
26529
26530 if (!(this.isValid() && localInput.isValid())) {
26531 return false;
26532 }
26533
26534 units = normalizeUnits(units) || 'millisecond';
26535
26536 if (units === 'millisecond') {
26537 return this.valueOf() < localInput.valueOf();
26538 } else {
26539 return this.clone().endOf(units).valueOf() < localInput.valueOf();
26540 }
26541 }
26542
26543 function isBetween(from, to, units, inclusivity) {
26544 var localFrom = isMoment(from) ? from : createLocal(from),
26545 localTo = isMoment(to) ? to : createLocal(to);
26546
26547 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
26548 return false;
26549 }
26550
26551 inclusivity = inclusivity || '()';
26552 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
26553 }
26554
26555 function isSame(input, units) {
26556 var localInput = isMoment(input) ? input : createLocal(input),
26557 inputMs;
26558
26559 if (!(this.isValid() && localInput.isValid())) {
26560 return false;
26561 }
26562
26563 units = normalizeUnits(units) || 'millisecond';
26564
26565 if (units === 'millisecond') {
26566 return this.valueOf() === localInput.valueOf();
26567 } else {
26568 inputMs = localInput.valueOf();
26569 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
26570 }
26571 }
26572
26573 function isSameOrAfter(input, units) {
26574 return this.isSame(input, units) || this.isAfter(input, units);
26575 }
26576
26577 function isSameOrBefore(input, units) {
26578 return this.isSame(input, units) || this.isBefore(input, units);
26579 }
26580
26581 function diff(input, units, asFloat) {
26582 var that, zoneDelta, output;
26583
26584 if (!this.isValid()) {
26585 return NaN;
26586 }
26587
26588 that = cloneWithOffset(input, this);
26589
26590 if (!that.isValid()) {
26591 return NaN;
26592 }
26593
26594 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
26595 units = normalizeUnits(units);
26596
26597 switch (units) {
26598 case 'year':
26599 output = monthDiff(this, that) / 12;
26600 break;
26601
26602 case 'month':
26603 output = monthDiff(this, that);
26604 break;
26605
26606 case 'quarter':
26607 output = monthDiff(this, that) / 3;
26608 break;
26609
26610 case 'second':
26611 output = (this - that) / 1e3;
26612 break;
26613 // 1000
26614
26615 case 'minute':
26616 output = (this - that) / 6e4;
26617 break;
26618 // 1000 * 60
26619
26620 case 'hour':
26621 output = (this - that) / 36e5;
26622 break;
26623 // 1000 * 60 * 60
26624
26625 case 'day':
26626 output = (this - that - zoneDelta) / 864e5;
26627 break;
26628 // 1000 * 60 * 60 * 24, negate dst
26629
26630 case 'week':
26631 output = (this - that - zoneDelta) / 6048e5;
26632 break;
26633 // 1000 * 60 * 60 * 24 * 7, negate dst
26634
26635 default:
26636 output = this - that;
26637 }
26638
26639 return asFloat ? output : absFloor(output);
26640 }
26641
26642 function monthDiff(a, b) {
26643 // difference in months
26644 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
26645 // b is in (anchor - 1 month, anchor + 1 month)
26646 anchor = a.clone().add(wholeMonthDiff, 'months'),
26647 anchor2,
26648 adjust;
26649
26650 if (b - anchor < 0) {
26651 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month
26652
26653 adjust = (b - anchor) / (anchor - anchor2);
26654 } else {
26655 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month
26656
26657 adjust = (b - anchor) / (anchor2 - anchor);
26658 } //check for negative zero, return zero if negative zero
26659
26660
26661 return -(wholeMonthDiff + adjust) || 0;
26662 }
26663
26664 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
26665 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
26666
26667 function toString() {
26668 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
26669 }
26670
26671 function toISOString(keepOffset) {
26672 if (!this.isValid()) {
26673 return null;
26674 }
26675
26676 var utc = keepOffset !== true;
26677 var m = utc ? this.clone().utc() : this;
26678
26679 if (m.year() < 0 || m.year() > 9999) {
26680 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
26681 }
26682
26683 if (isFunction(Date.prototype.toISOString)) {
26684 // native implementation is ~50x faster, use it when we can
26685 if (utc) {
26686 return this.toDate().toISOString();
26687 } else {
26688 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
26689 }
26690 }
26691
26692 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
26693 }
26694 /**
26695 * Return a human readable representation of a moment that can
26696 * also be evaluated to get a new moment which is the same
26697 *
26698 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
26699 */
26700
26701
26702 function inspect() {
26703 if (!this.isValid()) {
26704 return 'moment.invalid(/* ' + this._i + ' */)';
26705 }
26706
26707 var func = 'moment';
26708 var zone = '';
26709
26710 if (!this.isLocal()) {
26711 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
26712 zone = 'Z';
26713 }
26714
26715 var prefix = '[' + func + '("]';
26716 var year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
26717 var datetime = '-MM-DD[T]HH:mm:ss.SSS';
26718 var suffix = zone + '[")]';
26719 return this.format(prefix + year + datetime + suffix);
26720 }
26721
26722 function format(inputString) {
26723 if (!inputString) {
26724 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
26725 }
26726
26727 var output = formatMoment(this, inputString);
26728 return this.localeData().postformat(output);
26729 }
26730
26731 function from(time, withoutSuffix) {
26732 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
26733 return createDuration({
26734 to: this,
26735 from: time
26736 }).locale(this.locale()).humanize(!withoutSuffix);
26737 } else {
26738 return this.localeData().invalidDate();
26739 }
26740 }
26741
26742 function fromNow(withoutSuffix) {
26743 return this.from(createLocal(), withoutSuffix);
26744 }
26745
26746 function to(time, withoutSuffix) {
26747 if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
26748 return createDuration({
26749 from: this,
26750 to: time
26751 }).locale(this.locale()).humanize(!withoutSuffix);
26752 } else {
26753 return this.localeData().invalidDate();
26754 }
26755 }
26756
26757 function toNow(withoutSuffix) {
26758 return this.to(createLocal(), withoutSuffix);
26759 } // If passed a locale key, it will set the locale for this
26760 // instance. Otherwise, it will return the locale configuration
26761 // variables for this instance.
26762
26763
26764 function locale(key) {
26765 var newLocaleData;
26766
26767 if (key === undefined) {
26768 return this._locale._abbr;
26769 } else {
26770 newLocaleData = getLocale(key);
26771
26772 if (newLocaleData != null) {
26773 this._locale = newLocaleData;
26774 }
26775
26776 return this;
26777 }
26778 }
26779
26780 var lang = deprecate('moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) {
26781 if (key === undefined) {
26782 return this.localeData();
26783 } else {
26784 return this.locale(key);
26785 }
26786 });
26787
26788 function localeData() {
26789 return this._locale;
26790 }
26791
26792 var MS_PER_SECOND = 1000;
26793 var MS_PER_MINUTE = 60 * MS_PER_SECOND;
26794 var MS_PER_HOUR = 60 * MS_PER_MINUTE;
26795 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970):
26796
26797 function mod$1(dividend, divisor) {
26798 return (dividend % divisor + divisor) % divisor;
26799 }
26800
26801 function localStartOfDate(y, m, d) {
26802 // the date constructor remaps years 0-99 to 1900-1999
26803 if (y < 100 && y >= 0) {
26804 // preserve leap years using a full 400 year cycle, then reset
26805 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
26806 } else {
26807 return new Date(y, m, d).valueOf();
26808 }
26809 }
26810
26811 function utcStartOfDate(y, m, d) {
26812 // Date.UTC remaps years 0-99 to 1900-1999
26813 if (y < 100 && y >= 0) {
26814 // preserve leap years using a full 400 year cycle, then reset
26815 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
26816 } else {
26817 return Date.UTC(y, m, d);
26818 }
26819 }
26820
26821 function startOf(units) {
26822 var time;
26823 units = normalizeUnits(units);
26824
26825 if (units === undefined || units === 'millisecond' || !this.isValid()) {
26826 return this;
26827 }
26828
26829 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
26830
26831 switch (units) {
26832 case 'year':
26833 time = startOfDate(this.year(), 0, 1);
26834 break;
26835
26836 case 'quarter':
26837 time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
26838 break;
26839
26840 case 'month':
26841 time = startOfDate(this.year(), this.month(), 1);
26842 break;
26843
26844 case 'week':
26845 time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
26846 break;
26847
26848 case 'isoWeek':
26849 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
26850 break;
26851
26852 case 'day':
26853 case 'date':
26854 time = startOfDate(this.year(), this.month(), this.date());
26855 break;
26856
26857 case 'hour':
26858 time = this._d.valueOf();
26859 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
26860 break;
26861
26862 case 'minute':
26863 time = this._d.valueOf();
26864 time -= mod$1(time, MS_PER_MINUTE);
26865 break;
26866
26867 case 'second':
26868 time = this._d.valueOf();
26869 time -= mod$1(time, MS_PER_SECOND);
26870 break;
26871 }
26872
26873 this._d.setTime(time);
26874
26875 hooks.updateOffset(this, true);
26876 return this;
26877 }
26878
26879 function endOf(units) {
26880 var time;
26881 units = normalizeUnits(units);
26882
26883 if (units === undefined || units === 'millisecond' || !this.isValid()) {
26884 return this;
26885 }
26886
26887 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
26888
26889 switch (units) {
26890 case 'year':
26891 time = startOfDate(this.year() + 1, 0, 1) - 1;
26892 break;
26893
26894 case 'quarter':
26895 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
26896 break;
26897
26898 case 'month':
26899 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
26900 break;
26901
26902 case 'week':
26903 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
26904 break;
26905
26906 case 'isoWeek':
26907 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
26908 break;
26909
26910 case 'day':
26911 case 'date':
26912 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
26913 break;
26914
26915 case 'hour':
26916 time = this._d.valueOf();
26917 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
26918 break;
26919
26920 case 'minute':
26921 time = this._d.valueOf();
26922 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
26923 break;
26924
26925 case 'second':
26926 time = this._d.valueOf();
26927 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
26928 break;
26929 }
26930
26931 this._d.setTime(time);
26932
26933 hooks.updateOffset(this, true);
26934 return this;
26935 }
26936
26937 function valueOf() {
26938 return this._d.valueOf() - (this._offset || 0) * 60000;
26939 }
26940
26941 function unix() {
26942 return Math.floor(this.valueOf() / 1000);
26943 }
26944
26945 function toDate() {
26946 return new Date(this.valueOf());
26947 }
26948
26949 function toArray() {
26950 var m = this;
26951 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
26952 }
26953
26954 function toObject() {
26955 var m = this;
26956 return {
26957 years: m.year(),
26958 months: m.month(),
26959 date: m.date(),
26960 hours: m.hours(),
26961 minutes: m.minutes(),
26962 seconds: m.seconds(),
26963 milliseconds: m.milliseconds()
26964 };
26965 }
26966
26967 function toJSON() {
26968 // new Date(NaN).toJSON() === null
26969 return this.isValid() ? this.toISOString() : null;
26970 }
26971
26972 function isValid$2() {
26973 return isValid(this);
26974 }
26975
26976 function parsingFlags() {
26977 return extend({}, getParsingFlags(this));
26978 }
26979
26980 function invalidAt() {
26981 return getParsingFlags(this).overflow;
26982 }
26983
26984 function creationData() {
26985 return {
26986 input: this._i,
26987 format: this._f,
26988 locale: this._locale,
26989 isUTC: this._isUTC,
26990 strict: this._strict
26991 };
26992 } // FORMATTING
26993
26994
26995 addFormatToken(0, ['gg', 2], 0, function () {
26996 return this.weekYear() % 100;
26997 });
26998 addFormatToken(0, ['GG', 2], 0, function () {
26999 return this.isoWeekYear() % 100;
27000 });
27001
27002 function addWeekYearFormatToken(token, getter) {
27003 addFormatToken(0, [token, token.length], 0, getter);
27004 }
27005
27006 addWeekYearFormatToken('gggg', 'weekYear');
27007 addWeekYearFormatToken('ggggg', 'weekYear');
27008 addWeekYearFormatToken('GGGG', 'isoWeekYear');
27009 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES
27010
27011 addUnitAlias('weekYear', 'gg');
27012 addUnitAlias('isoWeekYear', 'GG'); // PRIORITY
27013
27014 addUnitPriority('weekYear', 1);
27015 addUnitPriority('isoWeekYear', 1); // PARSING
27016
27017 addRegexToken('G', matchSigned);
27018 addRegexToken('g', matchSigned);
27019 addRegexToken('GG', match1to2, match2);
27020 addRegexToken('gg', match1to2, match2);
27021 addRegexToken('GGGG', match1to4, match4);
27022 addRegexToken('gggg', match1to4, match4);
27023 addRegexToken('GGGGG', match1to6, match6);
27024 addRegexToken('ggggg', match1to6, match6);
27025 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
27026 week[token.substr(0, 2)] = toInt(input);
27027 });
27028 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
27029 week[token] = hooks.parseTwoDigitYear(input);
27030 }); // MOMENTS
27031
27032 function getSetWeekYear(input) {
27033 return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy);
27034 }
27035
27036 function getSetISOWeekYear(input) {
27037 return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4);
27038 }
27039
27040 function getISOWeeksInYear() {
27041 return weeksInYear(this.year(), 1, 4);
27042 }
27043
27044 function getWeeksInYear() {
27045 var weekInfo = this.localeData()._week;
27046
27047 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
27048 }
27049
27050 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
27051 var weeksTarget;
27052
27053 if (input == null) {
27054 return weekOfYear(this, dow, doy).year;
27055 } else {
27056 weeksTarget = weeksInYear(input, dow, doy);
27057
27058 if (week > weeksTarget) {
27059 week = weeksTarget;
27060 }
27061
27062 return setWeekAll.call(this, input, week, weekday, dow, doy);
27063 }
27064 }
27065
27066 function setWeekAll(weekYear, week, weekday, dow, doy) {
27067 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
27068 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
27069 this.year(date.getUTCFullYear());
27070 this.month(date.getUTCMonth());
27071 this.date(date.getUTCDate());
27072 return this;
27073 } // FORMATTING
27074
27075
27076 addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES
27077
27078 addUnitAlias('quarter', 'Q'); // PRIORITY
27079
27080 addUnitPriority('quarter', 7); // PARSING
27081
27082 addRegexToken('Q', match1);
27083 addParseToken('Q', function (input, array) {
27084 array[MONTH] = (toInt(input) - 1) * 3;
27085 }); // MOMENTS
27086
27087 function getSetQuarter(input) {
27088 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
27089 } // FORMATTING
27090
27091
27092 addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES
27093
27094 addUnitAlias('date', 'D'); // PRIORITY
27095
27096 addUnitPriority('date', 9); // PARSING
27097
27098 addRegexToken('D', match1to2);
27099 addRegexToken('DD', match1to2, match2);
27100 addRegexToken('Do', function (isStrict, locale) {
27101 // TODO: Remove "ordinalParse" fallback in next major release.
27102 return isStrict ? locale._dayOfMonthOrdinalParse || locale._ordinalParse : locale._dayOfMonthOrdinalParseLenient;
27103 });
27104 addParseToken(['D', 'DD'], DATE);
27105 addParseToken('Do', function (input, array) {
27106 array[DATE] = toInt(input.match(match1to2)[0]);
27107 }); // MOMENTS
27108
27109 var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING
27110
27111 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES
27112
27113 addUnitAlias('dayOfYear', 'DDD'); // PRIORITY
27114
27115 addUnitPriority('dayOfYear', 4); // PARSING
27116
27117 addRegexToken('DDD', match1to3);
27118 addRegexToken('DDDD', match3);
27119 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
27120 config._dayOfYear = toInt(input);
27121 }); // HELPERS
27122 // MOMENTS
27123
27124 function getSetDayOfYear(input) {
27125 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
27126 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
27127 } // FORMATTING
27128
27129
27130 addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES
27131
27132 addUnitAlias('minute', 'm'); // PRIORITY
27133
27134 addUnitPriority('minute', 14); // PARSING
27135
27136 addRegexToken('m', match1to2);
27137 addRegexToken('mm', match1to2, match2);
27138 addParseToken(['m', 'mm'], MINUTE); // MOMENTS
27139
27140 var getSetMinute = makeGetSet('Minutes', false); // FORMATTING
27141
27142 addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES
27143
27144 addUnitAlias('second', 's'); // PRIORITY
27145
27146 addUnitPriority('second', 15); // PARSING
27147
27148 addRegexToken('s', match1to2);
27149 addRegexToken('ss', match1to2, match2);
27150 addParseToken(['s', 'ss'], SECOND); // MOMENTS
27151
27152 var getSetSecond = makeGetSet('Seconds', false); // FORMATTING
27153
27154 addFormatToken('S', 0, 0, function () {
27155 return ~~(this.millisecond() / 100);
27156 });
27157 addFormatToken(0, ['SS', 2], 0, function () {
27158 return ~~(this.millisecond() / 10);
27159 });
27160 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
27161 addFormatToken(0, ['SSSS', 4], 0, function () {
27162 return this.millisecond() * 10;
27163 });
27164 addFormatToken(0, ['SSSSS', 5], 0, function () {
27165 return this.millisecond() * 100;
27166 });
27167 addFormatToken(0, ['SSSSSS', 6], 0, function () {
27168 return this.millisecond() * 1000;
27169 });
27170 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
27171 return this.millisecond() * 10000;
27172 });
27173 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
27174 return this.millisecond() * 100000;
27175 });
27176 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
27177 return this.millisecond() * 1000000;
27178 }); // ALIASES
27179
27180 addUnitAlias('millisecond', 'ms'); // PRIORITY
27181
27182 addUnitPriority('millisecond', 16); // PARSING
27183
27184 addRegexToken('S', match1to3, match1);
27185 addRegexToken('SS', match1to3, match2);
27186 addRegexToken('SSS', match1to3, match3);
27187 var token;
27188
27189 for (token = 'SSSS'; token.length <= 9; token += 'S') {
27190 addRegexToken(token, matchUnsigned);
27191 }
27192
27193 function parseMs(input, array) {
27194 array[MILLISECOND] = toInt(('0.' + input) * 1000);
27195 }
27196
27197 for (token = 'S'; token.length <= 9; token += 'S') {
27198 addParseToken(token, parseMs);
27199 } // MOMENTS
27200
27201
27202 var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING
27203
27204 addFormatToken('z', 0, 0, 'zoneAbbr');
27205 addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS
27206
27207 function getZoneAbbr() {
27208 return this._isUTC ? 'UTC' : '';
27209 }
27210
27211 function getZoneName() {
27212 return this._isUTC ? 'Coordinated Universal Time' : '';
27213 }
27214
27215 var proto = Moment.prototype;
27216 proto.add = add;
27217 proto.calendar = calendar$1;
27218 proto.clone = clone;
27219 proto.diff = diff;
27220 proto.endOf = endOf;
27221 proto.format = format;
27222 proto.from = from;
27223 proto.fromNow = fromNow;
27224 proto.to = to;
27225 proto.toNow = toNow;
27226 proto.get = stringGet;
27227 proto.invalidAt = invalidAt;
27228 proto.isAfter = isAfter;
27229 proto.isBefore = isBefore;
27230 proto.isBetween = isBetween;
27231 proto.isSame = isSame;
27232 proto.isSameOrAfter = isSameOrAfter;
27233 proto.isSameOrBefore = isSameOrBefore;
27234 proto.isValid = isValid$2;
27235 proto.lang = lang;
27236 proto.locale = locale;
27237 proto.localeData = localeData;
27238 proto.max = prototypeMax;
27239 proto.min = prototypeMin;
27240 proto.parsingFlags = parsingFlags;
27241 proto.set = stringSet;
27242 proto.startOf = startOf;
27243 proto.subtract = subtract;
27244 proto.toArray = toArray;
27245 proto.toObject = toObject;
27246 proto.toDate = toDate;
27247 proto.toISOString = toISOString;
27248 proto.inspect = inspect;
27249 proto.toJSON = toJSON;
27250 proto.toString = toString;
27251 proto.unix = unix;
27252 proto.valueOf = valueOf;
27253 proto.creationData = creationData;
27254 proto.year = getSetYear;
27255 proto.isLeapYear = getIsLeapYear;
27256 proto.weekYear = getSetWeekYear;
27257 proto.isoWeekYear = getSetISOWeekYear;
27258 proto.quarter = proto.quarters = getSetQuarter;
27259 proto.month = getSetMonth;
27260 proto.daysInMonth = getDaysInMonth;
27261 proto.week = proto.weeks = getSetWeek;
27262 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
27263 proto.weeksInYear = getWeeksInYear;
27264 proto.isoWeeksInYear = getISOWeeksInYear;
27265 proto.date = getSetDayOfMonth;
27266 proto.day = proto.days = getSetDayOfWeek;
27267 proto.weekday = getSetLocaleDayOfWeek;
27268 proto.isoWeekday = getSetISODayOfWeek;
27269 proto.dayOfYear = getSetDayOfYear;
27270 proto.hour = proto.hours = getSetHour;
27271 proto.minute = proto.minutes = getSetMinute;
27272 proto.second = proto.seconds = getSetSecond;
27273 proto.millisecond = proto.milliseconds = getSetMillisecond;
27274 proto.utcOffset = getSetOffset;
27275 proto.utc = setOffsetToUTC;
27276 proto.local = setOffsetToLocal;
27277 proto.parseZone = setOffsetToParsedOffset;
27278 proto.hasAlignedHourOffset = hasAlignedHourOffset;
27279 proto.isDST = isDaylightSavingTime;
27280 proto.isLocal = isLocal;
27281 proto.isUtcOffset = isUtcOffset;
27282 proto.isUtc = isUtc;
27283 proto.isUTC = isUtc;
27284 proto.zoneAbbr = getZoneAbbr;
27285 proto.zoneName = getZoneName;
27286 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
27287 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
27288 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
27289 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
27290 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
27291
27292 function createUnix(input) {
27293 return createLocal(input * 1000);
27294 }
27295
27296 function createInZone() {
27297 return createLocal.apply(null, arguments).parseZone();
27298 }
27299
27300 function preParsePostFormat(string) {
27301 return string;
27302 }
27303
27304 var proto$1 = Locale.prototype;
27305 proto$1.calendar = calendar;
27306 proto$1.longDateFormat = longDateFormat;
27307 proto$1.invalidDate = invalidDate;
27308 proto$1.ordinal = ordinal;
27309 proto$1.preparse = preParsePostFormat;
27310 proto$1.postformat = preParsePostFormat;
27311 proto$1.relativeTime = relativeTime;
27312 proto$1.pastFuture = pastFuture;
27313 proto$1.set = set;
27314 proto$1.months = localeMonths;
27315 proto$1.monthsShort = localeMonthsShort;
27316 proto$1.monthsParse = localeMonthsParse;
27317 proto$1.monthsRegex = monthsRegex;
27318 proto$1.monthsShortRegex = monthsShortRegex;
27319 proto$1.week = localeWeek;
27320 proto$1.firstDayOfYear = localeFirstDayOfYear;
27321 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
27322 proto$1.weekdays = localeWeekdays;
27323 proto$1.weekdaysMin = localeWeekdaysMin;
27324 proto$1.weekdaysShort = localeWeekdaysShort;
27325 proto$1.weekdaysParse = localeWeekdaysParse;
27326 proto$1.weekdaysRegex = weekdaysRegex;
27327 proto$1.weekdaysShortRegex = weekdaysShortRegex;
27328 proto$1.weekdaysMinRegex = weekdaysMinRegex;
27329 proto$1.isPM = localeIsPM;
27330 proto$1.meridiem = localeMeridiem;
27331
27332 function get$1(format, index, field, setter) {
27333 var locale = getLocale();
27334 var utc = createUTC().set(setter, index);
27335 return locale[field](utc, format);
27336 }
27337
27338 function listMonthsImpl(format, index, field) {
27339 if (isNumber(format)) {
27340 index = format;
27341 format = undefined;
27342 }
27343
27344 format = format || '';
27345
27346 if (index != null) {
27347 return get$1(format, index, field, 'month');
27348 }
27349
27350 var i;
27351 var out = [];
27352
27353 for (i = 0; i < 12; i++) {
27354 out[i] = get$1(format, i, field, 'month');
27355 }
27356
27357 return out;
27358 } // ()
27359 // (5)
27360 // (fmt, 5)
27361 // (fmt)
27362 // (true)
27363 // (true, 5)
27364 // (true, fmt, 5)
27365 // (true, fmt)
27366
27367
27368 function listWeekdaysImpl(localeSorted, format, index, field) {
27369 if (typeof localeSorted === 'boolean') {
27370 if (isNumber(format)) {
27371 index = format;
27372 format = undefined;
27373 }
27374
27375 format = format || '';
27376 } else {
27377 format = localeSorted;
27378 index = format;
27379 localeSorted = false;
27380
27381 if (isNumber(format)) {
27382 index = format;
27383 format = undefined;
27384 }
27385
27386 format = format || '';
27387 }
27388
27389 var locale = getLocale(),
27390 shift = localeSorted ? locale._week.dow : 0;
27391
27392 if (index != null) {
27393 return get$1(format, (index + shift) % 7, field, 'day');
27394 }
27395
27396 var i;
27397 var out = [];
27398
27399 for (i = 0; i < 7; i++) {
27400 out[i] = get$1(format, (i + shift) % 7, field, 'day');
27401 }
27402
27403 return out;
27404 }
27405
27406 function listMonths(format, index) {
27407 return listMonthsImpl(format, index, 'months');
27408 }
27409
27410 function listMonthsShort(format, index) {
27411 return listMonthsImpl(format, index, 'monthsShort');
27412 }
27413
27414 function listWeekdays(localeSorted, format, index) {
27415 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
27416 }
27417
27418 function listWeekdaysShort(localeSorted, format, index) {
27419 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
27420 }
27421
27422 function listWeekdaysMin(localeSorted, format, index) {
27423 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
27424 }
27425
27426 getSetGlobalLocale('en', {
27427 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
27428 ordinal: function (number) {
27429 var b = number % 10,
27430 output = toInt(number % 100 / 10) === 1 ? 'th' : b === 1 ? 'st' : b === 2 ? 'nd' : b === 3 ? 'rd' : 'th';
27431 return number + output;
27432 }
27433 }); // Side effect imports
27434
27435 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
27436 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
27437 var mathAbs = Math.abs;
27438
27439 function abs() {
27440 var data = this._data;
27441 this._milliseconds = mathAbs(this._milliseconds);
27442 this._days = mathAbs(this._days);
27443 this._months = mathAbs(this._months);
27444 data.milliseconds = mathAbs(data.milliseconds);
27445 data.seconds = mathAbs(data.seconds);
27446 data.minutes = mathAbs(data.minutes);
27447 data.hours = mathAbs(data.hours);
27448 data.months = mathAbs(data.months);
27449 data.years = mathAbs(data.years);
27450 return this;
27451 }
27452
27453 function addSubtract$1(duration, input, value, direction) {
27454 var other = createDuration(input, value);
27455 duration._milliseconds += direction * other._milliseconds;
27456 duration._days += direction * other._days;
27457 duration._months += direction * other._months;
27458 return duration._bubble();
27459 } // supports only 2.0-style add(1, 's') or add(duration)
27460
27461
27462 function add$1(input, value) {
27463 return addSubtract$1(this, input, value, 1);
27464 } // supports only 2.0-style subtract(1, 's') or subtract(duration)
27465
27466
27467 function subtract$1(input, value) {
27468 return addSubtract$1(this, input, value, -1);
27469 }
27470
27471 function absCeil(number) {
27472 if (number < 0) {
27473 return Math.floor(number);
27474 } else {
27475 return Math.ceil(number);
27476 }
27477 }
27478
27479 function bubble() {
27480 var milliseconds = this._milliseconds;
27481 var days = this._days;
27482 var months = this._months;
27483 var data = this._data;
27484 var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first
27485 // check: https://github.com/moment/moment/issues/2166
27486
27487 if (!(milliseconds >= 0 && days >= 0 && months >= 0 || milliseconds <= 0 && days <= 0 && months <= 0)) {
27488 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
27489 days = 0;
27490 months = 0;
27491 } // The following code bubbles up values, see the tests for
27492 // examples of what that means.
27493
27494
27495 data.milliseconds = milliseconds % 1000;
27496 seconds = absFloor(milliseconds / 1000);
27497 data.seconds = seconds % 60;
27498 minutes = absFloor(seconds / 60);
27499 data.minutes = minutes % 60;
27500 hours = absFloor(minutes / 60);
27501 data.hours = hours % 24;
27502 days += absFloor(hours / 24); // convert days to months
27503
27504 monthsFromDays = absFloor(daysToMonths(days));
27505 months += monthsFromDays;
27506 days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year
27507
27508 years = absFloor(months / 12);
27509 months %= 12;
27510 data.days = days;
27511 data.months = months;
27512 data.years = years;
27513 return this;
27514 }
27515
27516 function daysToMonths(days) {
27517 // 400 years have 146097 days (taking into account leap year rules)
27518 // 400 years have 12 months === 4800
27519 return days * 4800 / 146097;
27520 }
27521
27522 function monthsToDays(months) {
27523 // the reverse of daysToMonths
27524 return months * 146097 / 4800;
27525 }
27526
27527 function as(units) {
27528 if (!this.isValid()) {
27529 return NaN;
27530 }
27531
27532 var days;
27533 var months;
27534 var milliseconds = this._milliseconds;
27535 units = normalizeUnits(units);
27536
27537 if (units === 'month' || units === 'quarter' || units === 'year') {
27538 days = this._days + milliseconds / 864e5;
27539 months = this._months + daysToMonths(days);
27540
27541 switch (units) {
27542 case 'month':
27543 return months;
27544
27545 case 'quarter':
27546 return months / 3;
27547
27548 case 'year':
27549 return months / 12;
27550 }
27551 } else {
27552 // handle milliseconds separately because of floating point math errors (issue #1867)
27553 days = this._days + Math.round(monthsToDays(this._months));
27554
27555 switch (units) {
27556 case 'week':
27557 return days / 7 + milliseconds / 6048e5;
27558
27559 case 'day':
27560 return days + milliseconds / 864e5;
27561
27562 case 'hour':
27563 return days * 24 + milliseconds / 36e5;
27564
27565 case 'minute':
27566 return days * 1440 + milliseconds / 6e4;
27567
27568 case 'second':
27569 return days * 86400 + milliseconds / 1000;
27570 // Math.floor prevents floating point math errors here
27571
27572 case 'millisecond':
27573 return Math.floor(days * 864e5) + milliseconds;
27574
27575 default:
27576 throw new Error('Unknown unit ' + units);
27577 }
27578 }
27579 } // TODO: Use this.as('ms')?
27580
27581
27582 function valueOf$1() {
27583 if (!this.isValid()) {
27584 return NaN;
27585 }
27586
27587 return this._milliseconds + this._days * 864e5 + this._months % 12 * 2592e6 + toInt(this._months / 12) * 31536e6;
27588 }
27589
27590 function makeAs(alias) {
27591 return function () {
27592 return this.as(alias);
27593 };
27594 }
27595
27596 var asMilliseconds = makeAs('ms');
27597 var asSeconds = makeAs('s');
27598 var asMinutes = makeAs('m');
27599 var asHours = makeAs('h');
27600 var asDays = makeAs('d');
27601 var asWeeks = makeAs('w');
27602 var asMonths = makeAs('M');
27603 var asQuarters = makeAs('Q');
27604 var asYears = makeAs('y');
27605
27606 function clone$1() {
27607 return createDuration(this);
27608 }
27609
27610 function get$2(units) {
27611 units = normalizeUnits(units);
27612 return this.isValid() ? this[units + 's']() : NaN;
27613 }
27614
27615 function makeGetter(name) {
27616 return function () {
27617 return this.isValid() ? this._data[name] : NaN;
27618 };
27619 }
27620
27621 var milliseconds = makeGetter('milliseconds');
27622 var seconds = makeGetter('seconds');
27623 var minutes = makeGetter('minutes');
27624 var hours = makeGetter('hours');
27625 var days = makeGetter('days');
27626 var months = makeGetter('months');
27627 var years = makeGetter('years');
27628
27629 function weeks() {
27630 return absFloor(this.days() / 7);
27631 }
27632
27633 var round = Math.round;
27634 var thresholds = {
27635 ss: 44,
27636 // a few seconds to seconds
27637 s: 45,
27638 // seconds to minute
27639 m: 45,
27640 // minutes to hour
27641 h: 22,
27642 // hours to day
27643 d: 26,
27644 // days to month
27645 M: 11 // months to year
27646
27647 }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
27648
27649 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
27650 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
27651 }
27652
27653 function relativeTime$1(posNegDuration, withoutSuffix, locale) {
27654 var duration = createDuration(posNegDuration).abs();
27655 var seconds = round(duration.as('s'));
27656 var minutes = round(duration.as('m'));
27657 var hours = round(duration.as('h'));
27658 var days = round(duration.as('d'));
27659 var months = round(duration.as('M'));
27660 var years = round(duration.as('y'));
27661 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];
27662 a[2] = withoutSuffix;
27663 a[3] = +posNegDuration > 0;
27664 a[4] = locale;
27665 return substituteTimeAgo.apply(null, a);
27666 } // This function allows you to set the rounding function for relative time strings
27667
27668
27669 function getSetRelativeTimeRounding(roundingFunction) {
27670 if (roundingFunction === undefined) {
27671 return round;
27672 }
27673
27674 if (typeof roundingFunction === 'function') {
27675 round = roundingFunction;
27676 return true;
27677 }
27678
27679 return false;
27680 } // This function allows you to set a threshold for relative time strings
27681
27682
27683 function getSetRelativeTimeThreshold(threshold, limit) {
27684 if (thresholds[threshold] === undefined) {
27685 return false;
27686 }
27687
27688 if (limit === undefined) {
27689 return thresholds[threshold];
27690 }
27691
27692 thresholds[threshold] = limit;
27693
27694 if (threshold === 's') {
27695 thresholds.ss = limit - 1;
27696 }
27697
27698 return true;
27699 }
27700
27701 function humanize(withSuffix) {
27702 if (!this.isValid()) {
27703 return this.localeData().invalidDate();
27704 }
27705
27706 var locale = this.localeData();
27707 var output = relativeTime$1(this, !withSuffix, locale);
27708
27709 if (withSuffix) {
27710 output = locale.pastFuture(+this, output);
27711 }
27712
27713 return locale.postformat(output);
27714 }
27715
27716 var abs$1 = Math.abs;
27717
27718 function sign(x) {
27719 return (x > 0) - (x < 0) || +x;
27720 }
27721
27722 function toISOString$1() {
27723 // for ISO strings we do not use the normal bubbling rules:
27724 // * milliseconds bubble up until they become hours
27725 // * days do not bubble at all
27726 // * months bubble up until they become years
27727 // This is because there is no context-free conversion between hours and days
27728 // (think of clock changes)
27729 // and also not between days and months (28-31 days per month)
27730 if (!this.isValid()) {
27731 return this.localeData().invalidDate();
27732 }
27733
27734 var seconds = abs$1(this._milliseconds) / 1000;
27735 var days = abs$1(this._days);
27736 var months = abs$1(this._months);
27737 var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour
27738
27739 minutes = absFloor(seconds / 60);
27740 hours = absFloor(minutes / 60);
27741 seconds %= 60;
27742 minutes %= 60; // 12 months -> 1 year
27743
27744 years = absFloor(months / 12);
27745 months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
27746
27747 var Y = years;
27748 var M = months;
27749 var D = days;
27750 var h = hours;
27751 var m = minutes;
27752 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
27753 var total = this.asSeconds();
27754
27755 if (!total) {
27756 // this is the same as C#'s (Noda) and python (isodate)...
27757 // but not other JS (goog.date)
27758 return 'P0D';
27759 }
27760
27761 var totalSign = total < 0 ? '-' : '';
27762 var ymSign = sign(this._months) !== sign(total) ? '-' : '';
27763 var daysSign = sign(this._days) !== sign(total) ? '-' : '';
27764 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
27765 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' : '');
27766 }
27767
27768 var proto$2 = Duration.prototype;
27769 proto$2.isValid = isValid$1;
27770 proto$2.abs = abs;
27771 proto$2.add = add$1;
27772 proto$2.subtract = subtract$1;
27773 proto$2.as = as;
27774 proto$2.asMilliseconds = asMilliseconds;
27775 proto$2.asSeconds = asSeconds;
27776 proto$2.asMinutes = asMinutes;
27777 proto$2.asHours = asHours;
27778 proto$2.asDays = asDays;
27779 proto$2.asWeeks = asWeeks;
27780 proto$2.asMonths = asMonths;
27781 proto$2.asQuarters = asQuarters;
27782 proto$2.asYears = asYears;
27783 proto$2.valueOf = valueOf$1;
27784 proto$2._bubble = bubble;
27785 proto$2.clone = clone$1;
27786 proto$2.get = get$2;
27787 proto$2.milliseconds = milliseconds;
27788 proto$2.seconds = seconds;
27789 proto$2.minutes = minutes;
27790 proto$2.hours = hours;
27791 proto$2.days = days;
27792 proto$2.weeks = weeks;
27793 proto$2.months = months;
27794 proto$2.years = years;
27795 proto$2.humanize = humanize;
27796 proto$2.toISOString = toISOString$1;
27797 proto$2.toString = toISOString$1;
27798 proto$2.toJSON = toISOString$1;
27799 proto$2.locale = locale;
27800 proto$2.localeData = localeData;
27801 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
27802 proto$2.lang = lang; // Side effect imports
27803 // FORMATTING
27804
27805 addFormatToken('X', 0, 0, 'unix');
27806 addFormatToken('x', 0, 0, 'valueOf'); // PARSING
27807
27808 addRegexToken('x', matchSigned);
27809 addRegexToken('X', matchTimestamp);
27810 addParseToken('X', function (input, array, config) {
27811 config._d = new Date(parseFloat(input, 10) * 1000);
27812 });
27813 addParseToken('x', function (input, array, config) {
27814 config._d = new Date(toInt(input));
27815 }); // Side effect imports
27816
27817 hooks.version = '2.24.0';
27818 setHookCallback(createLocal);
27819 hooks.fn = proto;
27820 hooks.min = min;
27821 hooks.max = max;
27822 hooks.now = now;
27823 hooks.utc = createUTC;
27824 hooks.unix = createUnix;
27825 hooks.months = listMonths;
27826 hooks.isDate = isDate;
27827 hooks.locale = getSetGlobalLocale;
27828 hooks.invalid = createInvalid;
27829 hooks.duration = createDuration;
27830 hooks.isMoment = isMoment;
27831 hooks.weekdays = listWeekdays;
27832 hooks.parseZone = createInZone;
27833 hooks.localeData = getLocale;
27834 hooks.isDuration = isDuration;
27835 hooks.monthsShort = listMonthsShort;
27836 hooks.weekdaysMin = listWeekdaysMin;
27837 hooks.defineLocale = defineLocale;
27838 hooks.updateLocale = updateLocale;
27839 hooks.locales = listLocales;
27840 hooks.weekdaysShort = listWeekdaysShort;
27841 hooks.normalizeUnits = normalizeUnits;
27842 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
27843 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
27844 hooks.calendarFormat = getCalendarFormat;
27845 hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats
27846
27847 hooks.HTML5_FMT = {
27848 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',
27849 // <input type="datetime-local" />
27850 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',
27851 // <input type="datetime-local" step="1" />
27852 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',
27853 // <input type="datetime-local" step="0.001" />
27854 DATE: 'YYYY-MM-DD',
27855 // <input type="date" />
27856 TIME: 'HH:mm',
27857 // <input type="time" />
27858 TIME_SECONDS: 'HH:mm:ss',
27859 // <input type="time" step="1" />
27860 TIME_MS: 'HH:mm:ss.SSS',
27861 // <input type="time" step="0.001" />
27862 WEEK: 'GGGG-[W]WW',
27863 // <input type="week" />
27864 MONTH: 'YYYY-MM' // <input type="month" />
27865
27866 };
27867 return hooks;
27868 });
27869});
27870
27871// use this instance. Else, load via commonjs.
27872
27873var moment$3 = typeof window !== 'undefined' && window['moment'] || moment$2;
27874
27875var propagating = createCommonjsModule$1(function (module, exports) {
27876
27877 (function (factory) {
27878 {
27879 // Node. Does not work with strict CommonJS, but
27880 // only CommonJS-like environments that support module.exports,
27881 // like Node.
27882 module.exports = factory();
27883 }
27884 })(function () {
27885 var _firstTarget = null; // singleton, will contain the target element where the touch event started
27886
27887 /**
27888 * Extend an Hammer.js instance with event propagation.
27889 *
27890 * Features:
27891 * - Events emitted by hammer will propagate in order from child to parent
27892 * elements.
27893 * - Events are extended with a function `event.stopPropagation()` to stop
27894 * propagation to parent elements.
27895 * - An option `preventDefault` to stop all default browser behavior.
27896 *
27897 * Usage:
27898 * var hammer = propagatingHammer(new Hammer(element));
27899 * var hammer = propagatingHammer(new Hammer(element), {preventDefault: true});
27900 *
27901 * @param {Hammer.Manager} hammer An hammer instance.
27902 * @param {Object} [options] Available options:
27903 * - `preventDefault: true | false | 'mouse' | 'touch' | 'pen'`.
27904 * Enforce preventing the default browser behavior.
27905 * Cannot be set to `false`.
27906 * @return {Hammer.Manager} Returns the same hammer instance with extended
27907 * functionality
27908 */
27909
27910 return function propagating(hammer, options) {
27911 var _options = options || {
27912 preventDefault: false
27913 };
27914
27915 if (hammer.Manager) {
27916 // This looks like the Hammer constructor.
27917 // Overload the constructors with our own.
27918 var Hammer = hammer;
27919
27920 var PropagatingHammer = function (element, options) {
27921 var o = Object.create(_options);
27922 if (options) Hammer.assign(o, options);
27923 return propagating(new Hammer(element, o), o);
27924 };
27925
27926 Hammer.assign(PropagatingHammer, Hammer);
27927
27928 PropagatingHammer.Manager = function (element, options) {
27929 var o = Object.create(_options);
27930 if (options) Hammer.assign(o, options);
27931 return propagating(new Hammer.Manager(element, o), o);
27932 };
27933
27934 return PropagatingHammer;
27935 } // create a wrapper object which will override the functions
27936 // `on`, `off`, `destroy`, and `emit` of the hammer instance
27937
27938
27939 var wrapper = Object.create(hammer); // attach to DOM element
27940
27941 var element = hammer.element;
27942 if (!element.hammer) element.hammer = [];
27943 element.hammer.push(wrapper); // register an event to catch the start of a gesture and store the
27944 // target in a singleton
27945
27946 hammer.on('hammer.input', function (event) {
27947 if (_options.preventDefault === true || _options.preventDefault === event.pointerType) {
27948 event.preventDefault();
27949 }
27950
27951 if (event.isFirst) {
27952 _firstTarget = event.target;
27953 }
27954 });
27955 /** @type {Object.<String, Array.<function>>} */
27956
27957 wrapper._handlers = {};
27958 /**
27959 * Register a handler for one or multiple events
27960 * @param {String} events A space separated string with events
27961 * @param {function} handler A callback function, called as handler(event)
27962 * @returns {Hammer.Manager} Returns the hammer instance
27963 */
27964
27965 wrapper.on = function (events, handler) {
27966 // register the handler
27967 split(events).forEach(function (event) {
27968 var _handlers = wrapper._handlers[event];
27969
27970 if (!_handlers) {
27971 wrapper._handlers[event] = _handlers = []; // register the static, propagated handler
27972
27973 hammer.on(event, propagatedHandler);
27974 }
27975
27976 _handlers.push(handler);
27977 });
27978 return wrapper;
27979 };
27980 /**
27981 * Unregister a handler for one or multiple events
27982 * @param {String} events A space separated string with events
27983 * @param {function} [handler] Optional. The registered handler. If not
27984 * provided, all handlers for given events
27985 * are removed.
27986 * @returns {Hammer.Manager} Returns the hammer instance
27987 */
27988
27989
27990 wrapper.off = function (events, handler) {
27991 // unregister the handler
27992 split(events).forEach(function (event) {
27993 var _handlers = wrapper._handlers[event];
27994
27995 if (_handlers) {
27996 _handlers = handler ? _handlers.filter(function (h) {
27997 return h !== handler;
27998 }) : [];
27999
28000 if (_handlers.length > 0) {
28001 wrapper._handlers[event] = _handlers;
28002 } else {
28003 // remove static, propagated handler
28004 hammer.off(event, propagatedHandler);
28005 delete wrapper._handlers[event];
28006 }
28007 }
28008 });
28009 return wrapper;
28010 };
28011 /**
28012 * Emit to the event listeners
28013 * @param {string} eventType
28014 * @param {Event} event
28015 */
28016
28017
28018 wrapper.emit = function (eventType, event) {
28019 _firstTarget = event.target;
28020 hammer.emit(eventType, event);
28021 };
28022
28023 wrapper.destroy = function () {
28024 // Detach from DOM element
28025 var hammers = hammer.element.hammer;
28026 var idx = hammers.indexOf(wrapper);
28027 if (idx !== -1) hammers.splice(idx, 1);
28028 if (!hammers.length) delete hammer.element.hammer; // clear all handlers
28029
28030 wrapper._handlers = {}; // call original hammer destroy
28031
28032 hammer.destroy();
28033 }; // split a string with space separated words
28034
28035
28036 function split(events) {
28037 return events.match(/[^ ]+/g);
28038 }
28039 /**
28040 * A static event handler, applying event propagation.
28041 * @param {Object} event
28042 */
28043
28044
28045 function propagatedHandler(event) {
28046 // let only a single hammer instance handle this event
28047 if (event.type !== 'hammer.input') {
28048 // it is possible that the same srcEvent is used with multiple hammer events,
28049 // we keep track on which events are handled in an object _handled
28050 if (!event.srcEvent._handled) {
28051 event.srcEvent._handled = {};
28052 }
28053
28054 if (event.srcEvent._handled[event.type]) {
28055 return;
28056 } else {
28057 event.srcEvent._handled[event.type] = true;
28058 }
28059 } // attach a stopPropagation function to the event
28060
28061
28062 var stopped = false;
28063
28064 event.stopPropagation = function () {
28065 stopped = true;
28066 }; //wrap the srcEvent's stopPropagation to also stop hammer propagation:
28067
28068
28069 var srcStop = event.srcEvent.stopPropagation.bind(event.srcEvent);
28070
28071 if (typeof srcStop == "function") {
28072 event.srcEvent.stopPropagation = function () {
28073 srcStop();
28074 event.stopPropagation();
28075 };
28076 } // attach firstTarget property to the event
28077
28078
28079 event.firstTarget = _firstTarget; // propagate over all elements (until stopped)
28080
28081 var elem = _firstTarget;
28082
28083 while (elem && !stopped) {
28084 var elemHammer = elem.hammer;
28085
28086 if (elemHammer) {
28087 var _handlers;
28088
28089 for (var k = 0; k < elemHammer.length; k++) {
28090 _handlers = elemHammer[k]._handlers[event.type];
28091 if (_handlers) for (var i = 0; i < _handlers.length && !stopped; i++) {
28092 _handlers[i](event);
28093 }
28094 }
28095 }
28096
28097 elem = elem.parentNode;
28098 }
28099 }
28100
28101 return wrapper;
28102 };
28103 });
28104});
28105
28106var hammer = createCommonjsModule$1(function (module) {
28107 /*! Hammer.JS - v2.0.7 - 2016-04-22
28108 * http://hammerjs.github.io/
28109 *
28110 * Copyright (c) 2016 Jorik Tangelder;
28111 * Licensed under the MIT license */
28112 (function (window, document, exportName, undefined$1) {
28113
28114 var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
28115 var TEST_ELEMENT = document.createElement('div');
28116 var TYPE_FUNCTION = 'function';
28117 var round = Math.round;
28118 var abs = Math.abs;
28119 var now = Date.now;
28120 /**
28121 * set a timeout with a given scope
28122 * @param {Function} fn
28123 * @param {Number} timeout
28124 * @param {Object} context
28125 * @returns {number}
28126 */
28127
28128 function setTimeoutContext(fn, timeout, context) {
28129 return setTimeout(bindFn(fn, context), timeout);
28130 }
28131 /**
28132 * if the argument is an array, we want to execute the fn on each entry
28133 * if it aint an array we don't want to do a thing.
28134 * this is used by all the methods that accept a single and array argument.
28135 * @param {*|Array} arg
28136 * @param {String} fn
28137 * @param {Object} [context]
28138 * @returns {Boolean}
28139 */
28140
28141
28142 function invokeArrayArg(arg, fn, context) {
28143 if (Array.isArray(arg)) {
28144 each(arg, context[fn], context);
28145 return true;
28146 }
28147
28148 return false;
28149 }
28150 /**
28151 * walk objects and arrays
28152 * @param {Object} obj
28153 * @param {Function} iterator
28154 * @param {Object} context
28155 */
28156
28157
28158 function each(obj, iterator, context) {
28159 var i;
28160
28161 if (!obj) {
28162 return;
28163 }
28164
28165 if (obj.forEach) {
28166 obj.forEach(iterator, context);
28167 } else if (obj.length !== undefined$1) {
28168 i = 0;
28169
28170 while (i < obj.length) {
28171 iterator.call(context, obj[i], i, obj);
28172 i++;
28173 }
28174 } else {
28175 for (i in obj) {
28176 obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
28177 }
28178 }
28179 }
28180 /**
28181 * wrap a method with a deprecation warning and stack trace
28182 * @param {Function} method
28183 * @param {String} name
28184 * @param {String} message
28185 * @returns {Function} A new function wrapping the supplied method.
28186 */
28187
28188
28189 function deprecate(method, name, message) {
28190 var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
28191 return function () {
28192 var e = new Error('get-stack-trace');
28193 var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
28194 var log = window.console && (window.console.warn || window.console.log);
28195
28196 if (log) {
28197 log.call(window.console, deprecationMessage, stack);
28198 }
28199
28200 return method.apply(this, arguments);
28201 };
28202 }
28203 /**
28204 * extend object.
28205 * means that properties in dest will be overwritten by the ones in src.
28206 * @param {Object} target
28207 * @param {...Object} objects_to_assign
28208 * @returns {Object} target
28209 */
28210
28211
28212 var assign;
28213
28214 if (typeof Object.assign !== 'function') {
28215 assign = function assign(target) {
28216 if (target === undefined$1 || target === null) {
28217 throw new TypeError('Cannot convert undefined or null to object');
28218 }
28219
28220 var output = Object(target);
28221
28222 for (var index = 1; index < arguments.length; index++) {
28223 var source = arguments[index];
28224
28225 if (source !== undefined$1 && source !== null) {
28226 for (var nextKey in source) {
28227 if (source.hasOwnProperty(nextKey)) {
28228 output[nextKey] = source[nextKey];
28229 }
28230 }
28231 }
28232 }
28233
28234 return output;
28235 };
28236 } else {
28237 assign = Object.assign;
28238 }
28239 /**
28240 * extend object.
28241 * means that properties in dest will be overwritten by the ones in src.
28242 * @param {Object} dest
28243 * @param {Object} src
28244 * @param {Boolean} [merge=false]
28245 * @returns {Object} dest
28246 */
28247
28248
28249 var extend = deprecate(function extend(dest, src, merge) {
28250 var keys = Object.keys(src);
28251 var i = 0;
28252
28253 while (i < keys.length) {
28254 if (!merge || merge && dest[keys[i]] === undefined$1) {
28255 dest[keys[i]] = src[keys[i]];
28256 }
28257
28258 i++;
28259 }
28260
28261 return dest;
28262 }, 'extend', 'Use `assign`.');
28263 /**
28264 * merge the values from src in the dest.
28265 * means that properties that exist in dest will not be overwritten by src
28266 * @param {Object} dest
28267 * @param {Object} src
28268 * @returns {Object} dest
28269 */
28270
28271 var merge = deprecate(function merge(dest, src) {
28272 return extend(dest, src, true);
28273 }, 'merge', 'Use `assign`.');
28274 /**
28275 * simple class inheritance
28276 * @param {Function} child
28277 * @param {Function} base
28278 * @param {Object} [properties]
28279 */
28280
28281 function inherit(child, base, properties) {
28282 var baseP = base.prototype,
28283 childP;
28284 childP = child.prototype = Object.create(baseP);
28285 childP.constructor = child;
28286 childP._super = baseP;
28287
28288 if (properties) {
28289 assign(childP, properties);
28290 }
28291 }
28292 /**
28293 * simple function bind
28294 * @param {Function} fn
28295 * @param {Object} context
28296 * @returns {Function}
28297 */
28298
28299
28300 function bindFn(fn, context) {
28301 return function boundFn() {
28302 return fn.apply(context, arguments);
28303 };
28304 }
28305 /**
28306 * let a boolean value also be a function that must return a boolean
28307 * this first item in args will be used as the context
28308 * @param {Boolean|Function} val
28309 * @param {Array} [args]
28310 * @returns {Boolean}
28311 */
28312
28313
28314 function boolOrFn(val, args) {
28315 if (typeof val == TYPE_FUNCTION) {
28316 return val.apply(args ? args[0] || undefined$1 : undefined$1, args);
28317 }
28318
28319 return val;
28320 }
28321 /**
28322 * use the val2 when val1 is undefined
28323 * @param {*} val1
28324 * @param {*} val2
28325 * @returns {*}
28326 */
28327
28328
28329 function ifUndefined(val1, val2) {
28330 return val1 === undefined$1 ? val2 : val1;
28331 }
28332 /**
28333 * addEventListener with multiple events at once
28334 * @param {EventTarget} target
28335 * @param {String} types
28336 * @param {Function} handler
28337 */
28338
28339
28340 function addEventListeners(target, types, handler) {
28341 each(splitStr(types), function (type) {
28342 target.addEventListener(type, handler, false);
28343 });
28344 }
28345 /**
28346 * removeEventListener with multiple events at once
28347 * @param {EventTarget} target
28348 * @param {String} types
28349 * @param {Function} handler
28350 */
28351
28352
28353 function removeEventListeners(target, types, handler) {
28354 each(splitStr(types), function (type) {
28355 target.removeEventListener(type, handler, false);
28356 });
28357 }
28358 /**
28359 * find if a node is in the given parent
28360 * @method hasParent
28361 * @param {HTMLElement} node
28362 * @param {HTMLElement} parent
28363 * @return {Boolean} found
28364 */
28365
28366
28367 function hasParent(node, parent) {
28368 while (node) {
28369 if (node == parent) {
28370 return true;
28371 }
28372
28373 node = node.parentNode;
28374 }
28375
28376 return false;
28377 }
28378 /**
28379 * small indexOf wrapper
28380 * @param {String} str
28381 * @param {String} find
28382 * @returns {Boolean} found
28383 */
28384
28385
28386 function inStr(str, find) {
28387 return str.indexOf(find) > -1;
28388 }
28389 /**
28390 * split string on whitespace
28391 * @param {String} str
28392 * @returns {Array} words
28393 */
28394
28395
28396 function splitStr(str) {
28397 return str.trim().split(/\s+/g);
28398 }
28399 /**
28400 * find if a array contains the object using indexOf or a simple polyFill
28401 * @param {Array} src
28402 * @param {String} find
28403 * @param {String} [findByKey]
28404 * @return {Boolean|Number} false when not found, or the index
28405 */
28406
28407
28408 function inArray(src, find, findByKey) {
28409 if (src.indexOf && !findByKey) {
28410 return src.indexOf(find);
28411 } else {
28412 var i = 0;
28413
28414 while (i < src.length) {
28415 if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
28416 return i;
28417 }
28418
28419 i++;
28420 }
28421
28422 return -1;
28423 }
28424 }
28425 /**
28426 * convert array-like objects to real arrays
28427 * @param {Object} obj
28428 * @returns {Array}
28429 */
28430
28431
28432 function toArray(obj) {
28433 return Array.prototype.slice.call(obj, 0);
28434 }
28435 /**
28436 * unique array with objects based on a key (like 'id') or just by the array's value
28437 * @param {Array} src [{id:1},{id:2},{id:1}]
28438 * @param {String} [key]
28439 * @param {Boolean} [sort=False]
28440 * @returns {Array} [{id:1},{id:2}]
28441 */
28442
28443
28444 function uniqueArray(src, key, sort) {
28445 var results = [];
28446 var values = [];
28447 var i = 0;
28448
28449 while (i < src.length) {
28450 var val = key ? src[i][key] : src[i];
28451
28452 if (inArray(values, val) < 0) {
28453 results.push(src[i]);
28454 }
28455
28456 values[i] = val;
28457 i++;
28458 }
28459
28460 if (sort) {
28461 if (!key) {
28462 results = results.sort();
28463 } else {
28464 results = results.sort(function sortUniqueArray(a, b) {
28465 return a[key] > b[key];
28466 });
28467 }
28468 }
28469
28470 return results;
28471 }
28472 /**
28473 * get the prefixed property
28474 * @param {Object} obj
28475 * @param {String} property
28476 * @returns {String|Undefined} prefixed
28477 */
28478
28479
28480 function prefixed(obj, property) {
28481 var prefix, prop;
28482 var camelProp = property[0].toUpperCase() + property.slice(1);
28483 var i = 0;
28484
28485 while (i < VENDOR_PREFIXES.length) {
28486 prefix = VENDOR_PREFIXES[i];
28487 prop = prefix ? prefix + camelProp : property;
28488
28489 if (prop in obj) {
28490 return prop;
28491 }
28492
28493 i++;
28494 }
28495
28496 return undefined$1;
28497 }
28498 /**
28499 * get a unique id
28500 * @returns {number} uniqueId
28501 */
28502
28503
28504 var _uniqueId = 1;
28505
28506 function uniqueId() {
28507 return _uniqueId++;
28508 }
28509 /**
28510 * get the window object of an element
28511 * @param {HTMLElement} element
28512 * @returns {DocumentView|Window}
28513 */
28514
28515
28516 function getWindowForElement(element) {
28517 var doc = element.ownerDocument || element;
28518 return doc.defaultView || doc.parentWindow || window;
28519 }
28520
28521 var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
28522 var SUPPORT_TOUCH = 'ontouchstart' in window;
28523 var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined$1;
28524 var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
28525 var INPUT_TYPE_TOUCH = 'touch';
28526 var INPUT_TYPE_PEN = 'pen';
28527 var INPUT_TYPE_MOUSE = 'mouse';
28528 var INPUT_TYPE_KINECT = 'kinect';
28529 var COMPUTE_INTERVAL = 25;
28530 var INPUT_START = 1;
28531 var INPUT_MOVE = 2;
28532 var INPUT_END = 4;
28533 var INPUT_CANCEL = 8;
28534 var DIRECTION_NONE = 1;
28535 var DIRECTION_LEFT = 2;
28536 var DIRECTION_RIGHT = 4;
28537 var DIRECTION_UP = 8;
28538 var DIRECTION_DOWN = 16;
28539 var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
28540 var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
28541 var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
28542 var PROPS_XY = ['x', 'y'];
28543 var PROPS_CLIENT_XY = ['clientX', 'clientY'];
28544 /**
28545 * create new input type manager
28546 * @param {Manager} manager
28547 * @param {Function} callback
28548 * @returns {Input}
28549 * @constructor
28550 */
28551
28552 function Input(manager, callback) {
28553 var self = this;
28554 this.manager = manager;
28555 this.callback = callback;
28556 this.element = manager.element;
28557 this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager,
28558 // so when disabled the input events are completely bypassed.
28559
28560 this.domHandler = function (ev) {
28561 if (boolOrFn(manager.options.enable, [manager])) {
28562 self.handler(ev);
28563 }
28564 };
28565
28566 this.init();
28567 }
28568
28569 Input.prototype = {
28570 /**
28571 * should handle the inputEvent data and trigger the callback
28572 * @virtual
28573 */
28574 handler: function () {},
28575
28576 /**
28577 * bind the events
28578 */
28579 init: function () {
28580 this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
28581 this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
28582 this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
28583 },
28584
28585 /**
28586 * unbind the events
28587 */
28588 destroy: function () {
28589 this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
28590 this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
28591 this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
28592 }
28593 };
28594 /**
28595 * create new input type manager
28596 * called by the Manager constructor
28597 * @param {Hammer} manager
28598 * @returns {Input}
28599 */
28600
28601 function createInputInstance(manager) {
28602 var Type;
28603 var inputClass = manager.options.inputClass;
28604
28605 if (inputClass) {
28606 Type = inputClass;
28607 } else if (SUPPORT_POINTER_EVENTS) {
28608 Type = PointerEventInput;
28609 } else if (SUPPORT_ONLY_TOUCH) {
28610 Type = TouchInput;
28611 } else if (!SUPPORT_TOUCH) {
28612 Type = MouseInput;
28613 } else {
28614 Type = TouchMouseInput;
28615 }
28616
28617 return new Type(manager, inputHandler);
28618 }
28619 /**
28620 * handle input events
28621 * @param {Manager} manager
28622 * @param {String} eventType
28623 * @param {Object} input
28624 */
28625
28626
28627 function inputHandler(manager, eventType, input) {
28628 var pointersLen = input.pointers.length;
28629 var changedPointersLen = input.changedPointers.length;
28630 var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
28631 var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
28632 input.isFirst = !!isFirst;
28633 input.isFinal = !!isFinal;
28634
28635 if (isFirst) {
28636 manager.session = {};
28637 } // source event is the normalized value of the domEvents
28638 // like 'touchstart, mouseup, pointerdown'
28639
28640
28641 input.eventType = eventType; // compute scale, rotation etc
28642
28643 computeInputData(manager, input); // emit secret event
28644
28645 manager.emit('hammer.input', input);
28646 manager.recognize(input);
28647 manager.session.prevInput = input;
28648 }
28649 /**
28650 * extend the data with some usable properties like scale, rotate, velocity etc
28651 * @param {Object} manager
28652 * @param {Object} input
28653 */
28654
28655
28656 function computeInputData(manager, input) {
28657 var session = manager.session;
28658 var pointers = input.pointers;
28659 var pointersLength = pointers.length; // store the first input to calculate the distance and direction
28660
28661 if (!session.firstInput) {
28662 session.firstInput = simpleCloneInputData(input);
28663 } // to compute scale and rotation we need to store the multiple touches
28664
28665
28666 if (pointersLength > 1 && !session.firstMultiple) {
28667 session.firstMultiple = simpleCloneInputData(input);
28668 } else if (pointersLength === 1) {
28669 session.firstMultiple = false;
28670 }
28671
28672 var firstInput = session.firstInput;
28673 var firstMultiple = session.firstMultiple;
28674 var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
28675 var center = input.center = getCenter(pointers);
28676 input.timeStamp = now();
28677 input.deltaTime = input.timeStamp - firstInput.timeStamp;
28678 input.angle = getAngle(offsetCenter, center);
28679 input.distance = getDistance(offsetCenter, center);
28680 computeDeltaXY(session, input);
28681 input.offsetDirection = getDirection(input.deltaX, input.deltaY);
28682 var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
28683 input.overallVelocityX = overallVelocity.x;
28684 input.overallVelocityY = overallVelocity.y;
28685 input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
28686 input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
28687 input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
28688 input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
28689 computeIntervalInputData(session, input); // find the correct target
28690
28691 var target = manager.element;
28692
28693 if (hasParent(input.srcEvent.target, target)) {
28694 target = input.srcEvent.target;
28695 }
28696
28697 input.target = target;
28698 }
28699
28700 function computeDeltaXY(session, input) {
28701 var center = input.center;
28702 var offset = session.offsetDelta || {};
28703 var prevDelta = session.prevDelta || {};
28704 var prevInput = session.prevInput || {};
28705
28706 if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
28707 prevDelta = session.prevDelta = {
28708 x: prevInput.deltaX || 0,
28709 y: prevInput.deltaY || 0
28710 };
28711 offset = session.offsetDelta = {
28712 x: center.x,
28713 y: center.y
28714 };
28715 }
28716
28717 input.deltaX = prevDelta.x + (center.x - offset.x);
28718 input.deltaY = prevDelta.y + (center.y - offset.y);
28719 }
28720 /**
28721 * velocity is calculated every x ms
28722 * @param {Object} session
28723 * @param {Object} input
28724 */
28725
28726
28727 function computeIntervalInputData(session, input) {
28728 var last = session.lastInterval || input,
28729 deltaTime = input.timeStamp - last.timeStamp,
28730 velocity,
28731 velocityX,
28732 velocityY,
28733 direction;
28734
28735 if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined$1)) {
28736 var deltaX = input.deltaX - last.deltaX;
28737 var deltaY = input.deltaY - last.deltaY;
28738 var v = getVelocity(deltaTime, deltaX, deltaY);
28739 velocityX = v.x;
28740 velocityY = v.y;
28741 velocity = abs(v.x) > abs(v.y) ? v.x : v.y;
28742 direction = getDirection(deltaX, deltaY);
28743 session.lastInterval = input;
28744 } else {
28745 // use latest velocity info if it doesn't overtake a minimum period
28746 velocity = last.velocity;
28747 velocityX = last.velocityX;
28748 velocityY = last.velocityY;
28749 direction = last.direction;
28750 }
28751
28752 input.velocity = velocity;
28753 input.velocityX = velocityX;
28754 input.velocityY = velocityY;
28755 input.direction = direction;
28756 }
28757 /**
28758 * create a simple clone from the input used for storage of firstInput and firstMultiple
28759 * @param {Object} input
28760 * @returns {Object} clonedInputData
28761 */
28762
28763
28764 function simpleCloneInputData(input) {
28765 // make a simple copy of the pointers because we will get a reference if we don't
28766 // we only need clientXY for the calculations
28767 var pointers = [];
28768 var i = 0;
28769
28770 while (i < input.pointers.length) {
28771 pointers[i] = {
28772 clientX: round(input.pointers[i].clientX),
28773 clientY: round(input.pointers[i].clientY)
28774 };
28775 i++;
28776 }
28777
28778 return {
28779 timeStamp: now(),
28780 pointers: pointers,
28781 center: getCenter(pointers),
28782 deltaX: input.deltaX,
28783 deltaY: input.deltaY
28784 };
28785 }
28786 /**
28787 * get the center of all the pointers
28788 * @param {Array} pointers
28789 * @return {Object} center contains `x` and `y` properties
28790 */
28791
28792
28793 function getCenter(pointers) {
28794 var pointersLength = pointers.length; // no need to loop when only one touch
28795
28796 if (pointersLength === 1) {
28797 return {
28798 x: round(pointers[0].clientX),
28799 y: round(pointers[0].clientY)
28800 };
28801 }
28802
28803 var x = 0,
28804 y = 0,
28805 i = 0;
28806
28807 while (i < pointersLength) {
28808 x += pointers[i].clientX;
28809 y += pointers[i].clientY;
28810 i++;
28811 }
28812
28813 return {
28814 x: round(x / pointersLength),
28815 y: round(y / pointersLength)
28816 };
28817 }
28818 /**
28819 * calculate the velocity between two points. unit is in px per ms.
28820 * @param {Number} deltaTime
28821 * @param {Number} x
28822 * @param {Number} y
28823 * @return {Object} velocity `x` and `y`
28824 */
28825
28826
28827 function getVelocity(deltaTime, x, y) {
28828 return {
28829 x: x / deltaTime || 0,
28830 y: y / deltaTime || 0
28831 };
28832 }
28833 /**
28834 * get the direction between two points
28835 * @param {Number} x
28836 * @param {Number} y
28837 * @return {Number} direction
28838 */
28839
28840
28841 function getDirection(x, y) {
28842 if (x === y) {
28843 return DIRECTION_NONE;
28844 }
28845
28846 if (abs(x) >= abs(y)) {
28847 return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
28848 }
28849
28850 return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
28851 }
28852 /**
28853 * calculate the absolute distance between two points
28854 * @param {Object} p1 {x, y}
28855 * @param {Object} p2 {x, y}
28856 * @param {Array} [props] containing x and y keys
28857 * @return {Number} distance
28858 */
28859
28860
28861 function getDistance(p1, p2, props) {
28862 if (!props) {
28863 props = PROPS_XY;
28864 }
28865
28866 var x = p2[props[0]] - p1[props[0]],
28867 y = p2[props[1]] - p1[props[1]];
28868 return Math.sqrt(x * x + y * y);
28869 }
28870 /**
28871 * calculate the angle between two coordinates
28872 * @param {Object} p1
28873 * @param {Object} p2
28874 * @param {Array} [props] containing x and y keys
28875 * @return {Number} angle
28876 */
28877
28878
28879 function getAngle(p1, p2, props) {
28880 if (!props) {
28881 props = PROPS_XY;
28882 }
28883
28884 var x = p2[props[0]] - p1[props[0]],
28885 y = p2[props[1]] - p1[props[1]];
28886 return Math.atan2(y, x) * 180 / Math.PI;
28887 }
28888 /**
28889 * calculate the rotation degrees between two pointersets
28890 * @param {Array} start array of pointers
28891 * @param {Array} end array of pointers
28892 * @return {Number} rotation
28893 */
28894
28895
28896 function getRotation(start, end) {
28897 return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
28898 }
28899 /**
28900 * calculate the scale factor between two pointersets
28901 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
28902 * @param {Array} start array of pointers
28903 * @param {Array} end array of pointers
28904 * @return {Number} scale
28905 */
28906
28907
28908 function getScale(start, end) {
28909 return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
28910 }
28911
28912 var MOUSE_INPUT_MAP = {
28913 mousedown: INPUT_START,
28914 mousemove: INPUT_MOVE,
28915 mouseup: INPUT_END
28916 };
28917 var MOUSE_ELEMENT_EVENTS = 'mousedown';
28918 var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
28919 /**
28920 * Mouse events input
28921 * @constructor
28922 * @extends Input
28923 */
28924
28925 function MouseInput() {
28926 this.evEl = MOUSE_ELEMENT_EVENTS;
28927 this.evWin = MOUSE_WINDOW_EVENTS;
28928 this.pressed = false; // mousedown state
28929
28930 Input.apply(this, arguments);
28931 }
28932
28933 inherit(MouseInput, Input, {
28934 /**
28935 * handle mouse events
28936 * @param {Object} ev
28937 */
28938 handler: function MEhandler(ev) {
28939 var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down
28940
28941 if (eventType & INPUT_START && ev.button === 0) {
28942 this.pressed = true;
28943 }
28944
28945 if (eventType & INPUT_MOVE && ev.which !== 1) {
28946 eventType = INPUT_END;
28947 } // mouse must be down
28948
28949
28950 if (!this.pressed) {
28951 return;
28952 }
28953
28954 if (eventType & INPUT_END) {
28955 this.pressed = false;
28956 }
28957
28958 this.callback(this.manager, eventType, {
28959 pointers: [ev],
28960 changedPointers: [ev],
28961 pointerType: INPUT_TYPE_MOUSE,
28962 srcEvent: ev
28963 });
28964 }
28965 });
28966 var POINTER_INPUT_MAP = {
28967 pointerdown: INPUT_START,
28968 pointermove: INPUT_MOVE,
28969 pointerup: INPUT_END,
28970 pointercancel: INPUT_CANCEL,
28971 pointerout: INPUT_CANCEL
28972 }; // in IE10 the pointer types is defined as an enum
28973
28974 var IE10_POINTER_TYPE_ENUM = {
28975 2: INPUT_TYPE_TOUCH,
28976 3: INPUT_TYPE_PEN,
28977 4: INPUT_TYPE_MOUSE,
28978 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
28979
28980 };
28981 var POINTER_ELEMENT_EVENTS = 'pointerdown';
28982 var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive
28983
28984 if (window.MSPointerEvent && !window.PointerEvent) {
28985 POINTER_ELEMENT_EVENTS = 'MSPointerDown';
28986 POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
28987 }
28988 /**
28989 * Pointer events input
28990 * @constructor
28991 * @extends Input
28992 */
28993
28994
28995 function PointerEventInput() {
28996 this.evEl = POINTER_ELEMENT_EVENTS;
28997 this.evWin = POINTER_WINDOW_EVENTS;
28998 Input.apply(this, arguments);
28999 this.store = this.manager.session.pointerEvents = [];
29000 }
29001
29002 inherit(PointerEventInput, Input, {
29003 /**
29004 * handle mouse events
29005 * @param {Object} ev
29006 */
29007 handler: function PEhandler(ev) {
29008 var store = this.store;
29009 var removePointer = false;
29010 var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
29011 var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
29012 var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
29013 var isTouch = pointerType == INPUT_TYPE_TOUCH; // get index of the event in the store
29014
29015 var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down
29016
29017 if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
29018 if (storeIndex < 0) {
29019 store.push(ev);
29020 storeIndex = store.length - 1;
29021 }
29022 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
29023 removePointer = true;
29024 } // it not found, so the pointer hasn't been down (so it's probably a hover)
29025
29026
29027 if (storeIndex < 0) {
29028 return;
29029 } // update the event in the store
29030
29031
29032 store[storeIndex] = ev;
29033 this.callback(this.manager, eventType, {
29034 pointers: store,
29035 changedPointers: [ev],
29036 pointerType: pointerType,
29037 srcEvent: ev
29038 });
29039
29040 if (removePointer) {
29041 // remove from the store
29042 store.splice(storeIndex, 1);
29043 }
29044 }
29045 });
29046 var SINGLE_TOUCH_INPUT_MAP = {
29047 touchstart: INPUT_START,
29048 touchmove: INPUT_MOVE,
29049 touchend: INPUT_END,
29050 touchcancel: INPUT_CANCEL
29051 };
29052 var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
29053 var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
29054 /**
29055 * Touch events input
29056 * @constructor
29057 * @extends Input
29058 */
29059
29060 function SingleTouchInput() {
29061 this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
29062 this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
29063 this.started = false;
29064 Input.apply(this, arguments);
29065 }
29066
29067 inherit(SingleTouchInput, Input, {
29068 handler: function TEhandler(ev) {
29069 var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events?
29070
29071 if (type === INPUT_START) {
29072 this.started = true;
29073 }
29074
29075 if (!this.started) {
29076 return;
29077 }
29078
29079 var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state
29080
29081 if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
29082 this.started = false;
29083 }
29084
29085 this.callback(this.manager, type, {
29086 pointers: touches[0],
29087 changedPointers: touches[1],
29088 pointerType: INPUT_TYPE_TOUCH,
29089 srcEvent: ev
29090 });
29091 }
29092 });
29093 /**
29094 * @this {TouchInput}
29095 * @param {Object} ev
29096 * @param {Number} type flag
29097 * @returns {undefined|Array} [all, changed]
29098 */
29099
29100 function normalizeSingleTouches(ev, type) {
29101 var all = toArray(ev.touches);
29102 var changed = toArray(ev.changedTouches);
29103
29104 if (type & (INPUT_END | INPUT_CANCEL)) {
29105 all = uniqueArray(all.concat(changed), 'identifier', true);
29106 }
29107
29108 return [all, changed];
29109 }
29110
29111 var TOUCH_INPUT_MAP = {
29112 touchstart: INPUT_START,
29113 touchmove: INPUT_MOVE,
29114 touchend: INPUT_END,
29115 touchcancel: INPUT_CANCEL
29116 };
29117 var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
29118 /**
29119 * Multi-user touch events input
29120 * @constructor
29121 * @extends Input
29122 */
29123
29124 function TouchInput() {
29125 this.evTarget = TOUCH_TARGET_EVENTS;
29126 this.targetIds = {};
29127 Input.apply(this, arguments);
29128 }
29129
29130 inherit(TouchInput, Input, {
29131 handler: function MTEhandler(ev) {
29132 var type = TOUCH_INPUT_MAP[ev.type];
29133 var touches = getTouches.call(this, ev, type);
29134
29135 if (!touches) {
29136 return;
29137 }
29138
29139 this.callback(this.manager, type, {
29140 pointers: touches[0],
29141 changedPointers: touches[1],
29142 pointerType: INPUT_TYPE_TOUCH,
29143 srcEvent: ev
29144 });
29145 }
29146 });
29147 /**
29148 * @this {TouchInput}
29149 * @param {Object} ev
29150 * @param {Number} type flag
29151 * @returns {undefined|Array} [all, changed]
29152 */
29153
29154 function getTouches(ev, type) {
29155 var allTouches = toArray(ev.touches);
29156 var targetIds = this.targetIds; // when there is only one touch, the process can be simplified
29157
29158 if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
29159 targetIds[allTouches[0].identifier] = true;
29160 return [allTouches, allTouches];
29161 }
29162
29163 var i,
29164 targetTouches,
29165 changedTouches = toArray(ev.changedTouches),
29166 changedTargetTouches = [],
29167 target = this.target; // get target touches from touches
29168
29169 targetTouches = allTouches.filter(function (touch) {
29170 return hasParent(touch.target, target);
29171 }); // collect touches
29172
29173 if (type === INPUT_START) {
29174 i = 0;
29175
29176 while (i < targetTouches.length) {
29177 targetIds[targetTouches[i].identifier] = true;
29178 i++;
29179 }
29180 } // filter changed touches to only contain touches that exist in the collected target ids
29181
29182
29183 i = 0;
29184
29185 while (i < changedTouches.length) {
29186 if (targetIds[changedTouches[i].identifier]) {
29187 changedTargetTouches.push(changedTouches[i]);
29188 } // cleanup removed touches
29189
29190
29191 if (type & (INPUT_END | INPUT_CANCEL)) {
29192 delete targetIds[changedTouches[i].identifier];
29193 }
29194
29195 i++;
29196 }
29197
29198 if (!changedTargetTouches.length) {
29199 return;
29200 }
29201
29202 return [// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
29203 uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches];
29204 }
29205 /**
29206 * Combined touch and mouse input
29207 *
29208 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
29209 * This because touch devices also emit mouse events while doing a touch.
29210 *
29211 * @constructor
29212 * @extends Input
29213 */
29214
29215
29216 var DEDUP_TIMEOUT = 2500;
29217 var DEDUP_DISTANCE = 25;
29218
29219 function TouchMouseInput() {
29220 Input.apply(this, arguments);
29221 var handler = bindFn(this.handler, this);
29222 this.touch = new TouchInput(this.manager, handler);
29223 this.mouse = new MouseInput(this.manager, handler);
29224 this.primaryTouch = null;
29225 this.lastTouches = [];
29226 }
29227
29228 inherit(TouchMouseInput, Input, {
29229 /**
29230 * handle mouse and touch events
29231 * @param {Hammer} manager
29232 * @param {String} inputEvent
29233 * @param {Object} inputData
29234 */
29235 handler: function TMEhandler(manager, inputEvent, inputData) {
29236 var isTouch = inputData.pointerType == INPUT_TYPE_TOUCH,
29237 isMouse = inputData.pointerType == INPUT_TYPE_MOUSE;
29238
29239 if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
29240 return;
29241 } // when we're in a touch event, record touches to de-dupe synthetic mouse event
29242
29243
29244 if (isTouch) {
29245 recordTouches.call(this, inputEvent, inputData);
29246 } else if (isMouse && isSyntheticEvent.call(this, inputData)) {
29247 return;
29248 }
29249
29250 this.callback(manager, inputEvent, inputData);
29251 },
29252
29253 /**
29254 * remove the event listeners
29255 */
29256 destroy: function destroy() {
29257 this.touch.destroy();
29258 this.mouse.destroy();
29259 }
29260 });
29261
29262 function recordTouches(eventType, eventData) {
29263 if (eventType & INPUT_START) {
29264 this.primaryTouch = eventData.changedPointers[0].identifier;
29265 setLastTouch.call(this, eventData);
29266 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
29267 setLastTouch.call(this, eventData);
29268 }
29269 }
29270
29271 function setLastTouch(eventData) {
29272 var touch = eventData.changedPointers[0];
29273
29274 if (touch.identifier === this.primaryTouch) {
29275 var lastTouch = {
29276 x: touch.clientX,
29277 y: touch.clientY
29278 };
29279 this.lastTouches.push(lastTouch);
29280 var lts = this.lastTouches;
29281
29282 var removeLastTouch = function () {
29283 var i = lts.indexOf(lastTouch);
29284
29285 if (i > -1) {
29286 lts.splice(i, 1);
29287 }
29288 };
29289
29290 setTimeout(removeLastTouch, DEDUP_TIMEOUT);
29291 }
29292 }
29293
29294 function isSyntheticEvent(eventData) {
29295 var x = eventData.srcEvent.clientX,
29296 y = eventData.srcEvent.clientY;
29297
29298 for (var i = 0; i < this.lastTouches.length; i++) {
29299 var t = this.lastTouches[i];
29300 var dx = Math.abs(x - t.x),
29301 dy = Math.abs(y - t.y);
29302
29303 if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
29304 return true;
29305 }
29306 }
29307
29308 return false;
29309 }
29310
29311 var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
29312 var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined$1; // magical touchAction value
29313
29314 var TOUCH_ACTION_COMPUTE = 'compute';
29315 var TOUCH_ACTION_AUTO = 'auto';
29316 var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
29317
29318 var TOUCH_ACTION_NONE = 'none';
29319 var TOUCH_ACTION_PAN_X = 'pan-x';
29320 var TOUCH_ACTION_PAN_Y = 'pan-y';
29321 var TOUCH_ACTION_MAP = getTouchActionProps();
29322 /**
29323 * Touch Action
29324 * sets the touchAction property or uses the js alternative
29325 * @param {Manager} manager
29326 * @param {String} value
29327 * @constructor
29328 */
29329
29330 function TouchAction(manager, value) {
29331 this.manager = manager;
29332 this.set(value);
29333 }
29334
29335 TouchAction.prototype = {
29336 /**
29337 * set the touchAction value on the element or enable the polyfill
29338 * @param {String} value
29339 */
29340 set: function (value) {
29341 // find out the touch-action by the event handlers
29342 if (value == TOUCH_ACTION_COMPUTE) {
29343 value = this.compute();
29344 }
29345
29346 if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
29347 this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
29348 }
29349
29350 this.actions = value.toLowerCase().trim();
29351 },
29352
29353 /**
29354 * just re-set the touchAction value
29355 */
29356 update: function () {
29357 this.set(this.manager.options.touchAction);
29358 },
29359
29360 /**
29361 * compute the value for the touchAction property based on the recognizer's settings
29362 * @returns {String} value
29363 */
29364 compute: function () {
29365 var actions = [];
29366 each(this.manager.recognizers, function (recognizer) {
29367 if (boolOrFn(recognizer.options.enable, [recognizer])) {
29368 actions = actions.concat(recognizer.getTouchAction());
29369 }
29370 });
29371 return cleanTouchActions(actions.join(' '));
29372 },
29373
29374 /**
29375 * this method is called on each input cycle and provides the preventing of the browser behavior
29376 * @param {Object} input
29377 */
29378 preventDefaults: function (input) {
29379 var srcEvent = input.srcEvent;
29380 var direction = input.offsetDirection; // if the touch action did prevented once this session
29381
29382 if (this.manager.session.prevented) {
29383 srcEvent.preventDefault();
29384 return;
29385 }
29386
29387 var actions = this.actions;
29388 var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
29389 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
29390 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
29391
29392 if (hasNone) {
29393 //do not prevent defaults if this is a tap gesture
29394 var isTapPointer = input.pointers.length === 1;
29395 var isTapMovement = input.distance < 2;
29396 var isTapTouchTime = input.deltaTime < 250;
29397
29398 if (isTapPointer && isTapMovement && isTapTouchTime) {
29399 return;
29400 }
29401 }
29402
29403 if (hasPanX && hasPanY) {
29404 // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
29405 return;
29406 }
29407
29408 if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
29409 return this.preventSrc(srcEvent);
29410 }
29411 },
29412
29413 /**
29414 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
29415 * @param {Object} srcEvent
29416 */
29417 preventSrc: function (srcEvent) {
29418 this.manager.session.prevented = true;
29419 srcEvent.preventDefault();
29420 }
29421 };
29422 /**
29423 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
29424 * @param {String} actions
29425 * @returns {*}
29426 */
29427
29428 function cleanTouchActions(actions) {
29429 // none
29430 if (inStr(actions, TOUCH_ACTION_NONE)) {
29431 return TOUCH_ACTION_NONE;
29432 }
29433
29434 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
29435 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
29436 // for different directions, e.g. horizontal pan but vertical swipe?)
29437 // we need none (as otherwise with pan-x pan-y combined none of these
29438 // recognizers will work, since the browser would handle all panning
29439
29440 if (hasPanX && hasPanY) {
29441 return TOUCH_ACTION_NONE;
29442 } // pan-x OR pan-y
29443
29444
29445 if (hasPanX || hasPanY) {
29446 return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
29447 } // manipulation
29448
29449
29450 if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
29451 return TOUCH_ACTION_MANIPULATION;
29452 }
29453
29454 return TOUCH_ACTION_AUTO;
29455 }
29456
29457 function getTouchActionProps() {
29458 if (!NATIVE_TOUCH_ACTION) {
29459 return false;
29460 }
29461
29462 var touchMap = {};
29463 var cssSupports = window.CSS && window.CSS.supports;
29464 ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
29465 // If css.supports is not supported but there is native touch-action assume it supports
29466 // all values. This is the case for IE 10 and 11.
29467 touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
29468 });
29469 return touchMap;
29470 }
29471 /**
29472 * Recognizer flow explained; *
29473 * All recognizers have the initial state of POSSIBLE when a input session starts.
29474 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
29475 * Example session for mouse-input: mousedown -> mousemove -> mouseup
29476 *
29477 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
29478 * which determines with state it should be.
29479 *
29480 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
29481 * POSSIBLE to give it another change on the next cycle.
29482 *
29483 * Possible
29484 * |
29485 * +-----+---------------+
29486 * | |
29487 * +-----+-----+ |
29488 * | | |
29489 * Failed Cancelled |
29490 * +-------+------+
29491 * | |
29492 * Recognized Began
29493 * |
29494 * Changed
29495 * |
29496 * Ended/Recognized
29497 */
29498
29499
29500 var STATE_POSSIBLE = 1;
29501 var STATE_BEGAN = 2;
29502 var STATE_CHANGED = 4;
29503 var STATE_ENDED = 8;
29504 var STATE_RECOGNIZED = STATE_ENDED;
29505 var STATE_CANCELLED = 16;
29506 var STATE_FAILED = 32;
29507 /**
29508 * Recognizer
29509 * Every recognizer needs to extend from this class.
29510 * @constructor
29511 * @param {Object} options
29512 */
29513
29514 function Recognizer(options) {
29515 this.options = assign({}, this.defaults, options || {});
29516 this.id = uniqueId();
29517 this.manager = null; // default is enable true
29518
29519 this.options.enable = ifUndefined(this.options.enable, true);
29520 this.state = STATE_POSSIBLE;
29521 this.simultaneous = {};
29522 this.requireFail = [];
29523 }
29524
29525 Recognizer.prototype = {
29526 /**
29527 * @virtual
29528 * @type {Object}
29529 */
29530 defaults: {},
29531
29532 /**
29533 * set options
29534 * @param {Object} options
29535 * @return {Recognizer}
29536 */
29537 set: function (options) {
29538 assign(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state
29539
29540 this.manager && this.manager.touchAction.update();
29541 return this;
29542 },
29543
29544 /**
29545 * recognize simultaneous with an other recognizer.
29546 * @param {Recognizer} otherRecognizer
29547 * @returns {Recognizer} this
29548 */
29549 recognizeWith: function (otherRecognizer) {
29550 if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
29551 return this;
29552 }
29553
29554 var simultaneous = this.simultaneous;
29555 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
29556
29557 if (!simultaneous[otherRecognizer.id]) {
29558 simultaneous[otherRecognizer.id] = otherRecognizer;
29559 otherRecognizer.recognizeWith(this);
29560 }
29561
29562 return this;
29563 },
29564
29565 /**
29566 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
29567 * @param {Recognizer} otherRecognizer
29568 * @returns {Recognizer} this
29569 */
29570 dropRecognizeWith: function (otherRecognizer) {
29571 if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
29572 return this;
29573 }
29574
29575 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
29576 delete this.simultaneous[otherRecognizer.id];
29577 return this;
29578 },
29579
29580 /**
29581 * recognizer can only run when an other is failing
29582 * @param {Recognizer} otherRecognizer
29583 * @returns {Recognizer} this
29584 */
29585 requireFailure: function (otherRecognizer) {
29586 if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
29587 return this;
29588 }
29589
29590 var requireFail = this.requireFail;
29591 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
29592
29593 if (inArray(requireFail, otherRecognizer) === -1) {
29594 requireFail.push(otherRecognizer);
29595 otherRecognizer.requireFailure(this);
29596 }
29597
29598 return this;
29599 },
29600
29601 /**
29602 * drop the requireFailure link. it does not remove the link on the other recognizer.
29603 * @param {Recognizer} otherRecognizer
29604 * @returns {Recognizer} this
29605 */
29606 dropRequireFailure: function (otherRecognizer) {
29607 if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
29608 return this;
29609 }
29610
29611 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
29612 var index = inArray(this.requireFail, otherRecognizer);
29613
29614 if (index > -1) {
29615 this.requireFail.splice(index, 1);
29616 }
29617
29618 return this;
29619 },
29620
29621 /**
29622 * has require failures boolean
29623 * @returns {boolean}
29624 */
29625 hasRequireFailures: function () {
29626 return this.requireFail.length > 0;
29627 },
29628
29629 /**
29630 * if the recognizer can recognize simultaneous with an other recognizer
29631 * @param {Recognizer} otherRecognizer
29632 * @returns {Boolean}
29633 */
29634 canRecognizeWith: function (otherRecognizer) {
29635 return !!this.simultaneous[otherRecognizer.id];
29636 },
29637
29638 /**
29639 * You should use `tryEmit` instead of `emit` directly to check
29640 * that all the needed recognizers has failed before emitting.
29641 * @param {Object} input
29642 */
29643 emit: function (input) {
29644 var self = this;
29645 var state = this.state;
29646
29647 function emit(event) {
29648 self.manager.emit(event, input);
29649 } // 'panstart' and 'panmove'
29650
29651
29652 if (state < STATE_ENDED) {
29653 emit(self.options.event + stateStr(state));
29654 }
29655
29656 emit(self.options.event); // simple 'eventName' events
29657
29658 if (input.additionalEvent) {
29659 // additional event(panleft, panright, pinchin, pinchout...)
29660 emit(input.additionalEvent);
29661 } // panend and pancancel
29662
29663
29664 if (state >= STATE_ENDED) {
29665 emit(self.options.event + stateStr(state));
29666 }
29667 },
29668
29669 /**
29670 * Check that all the require failure recognizers has failed,
29671 * if true, it emits a gesture event,
29672 * otherwise, setup the state to FAILED.
29673 * @param {Object} input
29674 */
29675 tryEmit: function (input) {
29676 if (this.canEmit()) {
29677 return this.emit(input);
29678 } // it's failing anyway
29679
29680
29681 this.state = STATE_FAILED;
29682 },
29683
29684 /**
29685 * can we emit?
29686 * @returns {boolean}
29687 */
29688 canEmit: function () {
29689 var i = 0;
29690
29691 while (i < this.requireFail.length) {
29692 if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
29693 return false;
29694 }
29695
29696 i++;
29697 }
29698
29699 return true;
29700 },
29701
29702 /**
29703 * update the recognizer
29704 * @param {Object} inputData
29705 */
29706 recognize: function (inputData) {
29707 // make a new copy of the inputData
29708 // so we can change the inputData without messing up the other recognizers
29709 var inputDataClone = assign({}, inputData); // is is enabled and allow recognizing?
29710
29711 if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
29712 this.reset();
29713 this.state = STATE_FAILED;
29714 return;
29715 } // reset when we've reached the end
29716
29717
29718 if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
29719 this.state = STATE_POSSIBLE;
29720 }
29721
29722 this.state = this.process(inputDataClone); // the recognizer has recognized a gesture
29723 // so trigger an event
29724
29725 if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
29726 this.tryEmit(inputDataClone);
29727 }
29728 },
29729
29730 /**
29731 * return the state of the recognizer
29732 * the actual recognizing happens in this method
29733 * @virtual
29734 * @param {Object} inputData
29735 * @returns {Const} STATE
29736 */
29737 process: function (inputData) {},
29738 // jshint ignore:line
29739
29740 /**
29741 * return the preferred touch-action
29742 * @virtual
29743 * @returns {Array}
29744 */
29745 getTouchAction: function () {},
29746
29747 /**
29748 * called when the gesture isn't allowed to recognize
29749 * like when another is being recognized or it is disabled
29750 * @virtual
29751 */
29752 reset: function () {}
29753 };
29754 /**
29755 * get a usable string, used as event postfix
29756 * @param {Const} state
29757 * @returns {String} state
29758 */
29759
29760 function stateStr(state) {
29761 if (state & STATE_CANCELLED) {
29762 return 'cancel';
29763 } else if (state & STATE_ENDED) {
29764 return 'end';
29765 } else if (state & STATE_CHANGED) {
29766 return 'move';
29767 } else if (state & STATE_BEGAN) {
29768 return 'start';
29769 }
29770
29771 return '';
29772 }
29773 /**
29774 * direction cons to string
29775 * @param {Const} direction
29776 * @returns {String}
29777 */
29778
29779
29780 function directionStr(direction) {
29781 if (direction == DIRECTION_DOWN) {
29782 return 'down';
29783 } else if (direction == DIRECTION_UP) {
29784 return 'up';
29785 } else if (direction == DIRECTION_LEFT) {
29786 return 'left';
29787 } else if (direction == DIRECTION_RIGHT) {
29788 return 'right';
29789 }
29790
29791 return '';
29792 }
29793 /**
29794 * get a recognizer by name if it is bound to a manager
29795 * @param {Recognizer|String} otherRecognizer
29796 * @param {Recognizer} recognizer
29797 * @returns {Recognizer}
29798 */
29799
29800
29801 function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
29802 var manager = recognizer.manager;
29803
29804 if (manager) {
29805 return manager.get(otherRecognizer);
29806 }
29807
29808 return otherRecognizer;
29809 }
29810 /**
29811 * This recognizer is just used as a base for the simple attribute recognizers.
29812 * @constructor
29813 * @extends Recognizer
29814 */
29815
29816
29817 function AttrRecognizer() {
29818 Recognizer.apply(this, arguments);
29819 }
29820
29821 inherit(AttrRecognizer, Recognizer, {
29822 /**
29823 * @namespace
29824 * @memberof AttrRecognizer
29825 */
29826 defaults: {
29827 /**
29828 * @type {Number}
29829 * @default 1
29830 */
29831 pointers: 1
29832 },
29833
29834 /**
29835 * Used to check if it the recognizer receives valid input, like input.distance > 10.
29836 * @memberof AttrRecognizer
29837 * @param {Object} input
29838 * @returns {Boolean} recognized
29839 */
29840 attrTest: function (input) {
29841 var optionPointers = this.options.pointers;
29842 return optionPointers === 0 || input.pointers.length === optionPointers;
29843 },
29844
29845 /**
29846 * Process the input and return the state for the recognizer
29847 * @memberof AttrRecognizer
29848 * @param {Object} input
29849 * @returns {*} State
29850 */
29851 process: function (input) {
29852 var state = this.state;
29853 var eventType = input.eventType;
29854 var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
29855 var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED
29856
29857 if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
29858 return state | STATE_CANCELLED;
29859 } else if (isRecognized || isValid) {
29860 if (eventType & INPUT_END) {
29861 return state | STATE_ENDED;
29862 } else if (!(state & STATE_BEGAN)) {
29863 return STATE_BEGAN;
29864 }
29865
29866 return state | STATE_CHANGED;
29867 }
29868
29869 return STATE_FAILED;
29870 }
29871 });
29872 /**
29873 * Pan
29874 * Recognized when the pointer is down and moved in the allowed direction.
29875 * @constructor
29876 * @extends AttrRecognizer
29877 */
29878
29879 function PanRecognizer() {
29880 AttrRecognizer.apply(this, arguments);
29881 this.pX = null;
29882 this.pY = null;
29883 }
29884
29885 inherit(PanRecognizer, AttrRecognizer, {
29886 /**
29887 * @namespace
29888 * @memberof PanRecognizer
29889 */
29890 defaults: {
29891 event: 'pan',
29892 threshold: 10,
29893 pointers: 1,
29894 direction: DIRECTION_ALL
29895 },
29896 getTouchAction: function () {
29897 var direction = this.options.direction;
29898 var actions = [];
29899
29900 if (direction & DIRECTION_HORIZONTAL) {
29901 actions.push(TOUCH_ACTION_PAN_Y);
29902 }
29903
29904 if (direction & DIRECTION_VERTICAL) {
29905 actions.push(TOUCH_ACTION_PAN_X);
29906 }
29907
29908 return actions;
29909 },
29910 directionTest: function (input) {
29911 var options = this.options;
29912 var hasMoved = true;
29913 var distance = input.distance;
29914 var direction = input.direction;
29915 var x = input.deltaX;
29916 var y = input.deltaY; // lock to axis?
29917
29918 if (!(direction & options.direction)) {
29919 if (options.direction & DIRECTION_HORIZONTAL) {
29920 direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
29921 hasMoved = x != this.pX;
29922 distance = Math.abs(input.deltaX);
29923 } else {
29924 direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
29925 hasMoved = y != this.pY;
29926 distance = Math.abs(input.deltaY);
29927 }
29928 }
29929
29930 input.direction = direction;
29931 return hasMoved && distance > options.threshold && direction & options.direction;
29932 },
29933 attrTest: function (input) {
29934 return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
29935 },
29936 emit: function (input) {
29937 this.pX = input.deltaX;
29938 this.pY = input.deltaY;
29939 var direction = directionStr(input.direction);
29940
29941 if (direction) {
29942 input.additionalEvent = this.options.event + direction;
29943 }
29944
29945 this._super.emit.call(this, input);
29946 }
29947 });
29948 /**
29949 * Pinch
29950 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
29951 * @constructor
29952 * @extends AttrRecognizer
29953 */
29954
29955 function PinchRecognizer() {
29956 AttrRecognizer.apply(this, arguments);
29957 }
29958
29959 inherit(PinchRecognizer, AttrRecognizer, {
29960 /**
29961 * @namespace
29962 * @memberof PinchRecognizer
29963 */
29964 defaults: {
29965 event: 'pinch',
29966 threshold: 0,
29967 pointers: 2
29968 },
29969 getTouchAction: function () {
29970 return [TOUCH_ACTION_NONE];
29971 },
29972 attrTest: function (input) {
29973 return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
29974 },
29975 emit: function (input) {
29976 if (input.scale !== 1) {
29977 var inOut = input.scale < 1 ? 'in' : 'out';
29978 input.additionalEvent = this.options.event + inOut;
29979 }
29980
29981 this._super.emit.call(this, input);
29982 }
29983 });
29984 /**
29985 * Press
29986 * Recognized when the pointer is down for x ms without any movement.
29987 * @constructor
29988 * @extends Recognizer
29989 */
29990
29991 function PressRecognizer() {
29992 Recognizer.apply(this, arguments);
29993 this._timer = null;
29994 this._input = null;
29995 }
29996
29997 inherit(PressRecognizer, Recognizer, {
29998 /**
29999 * @namespace
30000 * @memberof PressRecognizer
30001 */
30002 defaults: {
30003 event: 'press',
30004 pointers: 1,
30005 time: 251,
30006 // minimal time of the pointer to be pressed
30007 threshold: 9 // a minimal movement is ok, but keep it low
30008
30009 },
30010 getTouchAction: function () {
30011 return [TOUCH_ACTION_AUTO];
30012 },
30013 process: function (input) {
30014 var options = this.options;
30015 var validPointers = input.pointers.length === options.pointers;
30016 var validMovement = input.distance < options.threshold;
30017 var validTime = input.deltaTime > options.time;
30018 this._input = input; // we only allow little movement
30019 // and we've reached an end event, so a tap is possible
30020
30021 if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
30022 this.reset();
30023 } else if (input.eventType & INPUT_START) {
30024 this.reset();
30025 this._timer = setTimeoutContext(function () {
30026 this.state = STATE_RECOGNIZED;
30027 this.tryEmit();
30028 }, options.time, this);
30029 } else if (input.eventType & INPUT_END) {
30030 return STATE_RECOGNIZED;
30031 }
30032
30033 return STATE_FAILED;
30034 },
30035 reset: function () {
30036 clearTimeout(this._timer);
30037 },
30038 emit: function (input) {
30039 if (this.state !== STATE_RECOGNIZED) {
30040 return;
30041 }
30042
30043 if (input && input.eventType & INPUT_END) {
30044 this.manager.emit(this.options.event + 'up', input);
30045 } else {
30046 this._input.timeStamp = now();
30047 this.manager.emit(this.options.event, this._input);
30048 }
30049 }
30050 });
30051 /**
30052 * Rotate
30053 * Recognized when two or more pointer are moving in a circular motion.
30054 * @constructor
30055 * @extends AttrRecognizer
30056 */
30057
30058 function RotateRecognizer() {
30059 AttrRecognizer.apply(this, arguments);
30060 }
30061
30062 inherit(RotateRecognizer, AttrRecognizer, {
30063 /**
30064 * @namespace
30065 * @memberof RotateRecognizer
30066 */
30067 defaults: {
30068 event: 'rotate',
30069 threshold: 0,
30070 pointers: 2
30071 },
30072 getTouchAction: function () {
30073 return [TOUCH_ACTION_NONE];
30074 },
30075 attrTest: function (input) {
30076 return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
30077 }
30078 });
30079 /**
30080 * Swipe
30081 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
30082 * @constructor
30083 * @extends AttrRecognizer
30084 */
30085
30086 function SwipeRecognizer() {
30087 AttrRecognizer.apply(this, arguments);
30088 }
30089
30090 inherit(SwipeRecognizer, AttrRecognizer, {
30091 /**
30092 * @namespace
30093 * @memberof SwipeRecognizer
30094 */
30095 defaults: {
30096 event: 'swipe',
30097 threshold: 10,
30098 velocity: 0.3,
30099 direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
30100 pointers: 1
30101 },
30102 getTouchAction: function () {
30103 return PanRecognizer.prototype.getTouchAction.call(this);
30104 },
30105 attrTest: function (input) {
30106 var direction = this.options.direction;
30107 var velocity;
30108
30109 if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
30110 velocity = input.overallVelocity;
30111 } else if (direction & DIRECTION_HORIZONTAL) {
30112 velocity = input.overallVelocityX;
30113 } else if (direction & DIRECTION_VERTICAL) {
30114 velocity = input.overallVelocityY;
30115 }
30116
30117 return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
30118 },
30119 emit: function (input) {
30120 var direction = directionStr(input.offsetDirection);
30121
30122 if (direction) {
30123 this.manager.emit(this.options.event + direction, input);
30124 }
30125
30126 this.manager.emit(this.options.event, input);
30127 }
30128 });
30129 /**
30130 * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
30131 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
30132 * a single tap.
30133 *
30134 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
30135 * multi-taps being recognized.
30136 * @constructor
30137 * @extends Recognizer
30138 */
30139
30140 function TapRecognizer() {
30141 Recognizer.apply(this, arguments); // previous time and center,
30142 // used for tap counting
30143
30144 this.pTime = false;
30145 this.pCenter = false;
30146 this._timer = null;
30147 this._input = null;
30148 this.count = 0;
30149 }
30150
30151 inherit(TapRecognizer, Recognizer, {
30152 /**
30153 * @namespace
30154 * @memberof PinchRecognizer
30155 */
30156 defaults: {
30157 event: 'tap',
30158 pointers: 1,
30159 taps: 1,
30160 interval: 300,
30161 // max time between the multi-tap taps
30162 time: 250,
30163 // max time of the pointer to be down (like finger on the screen)
30164 threshold: 9,
30165 // a minimal movement is ok, but keep it low
30166 posThreshold: 10 // a multi-tap can be a bit off the initial position
30167
30168 },
30169 getTouchAction: function () {
30170 return [TOUCH_ACTION_MANIPULATION];
30171 },
30172 process: function (input) {
30173 var options = this.options;
30174 var validPointers = input.pointers.length === options.pointers;
30175 var validMovement = input.distance < options.threshold;
30176 var validTouchTime = input.deltaTime < options.time;
30177 this.reset();
30178
30179 if (input.eventType & INPUT_START && this.count === 0) {
30180 return this.failTimeout();
30181 } // we only allow little movement
30182 // and we've reached an end event, so a tap is possible
30183
30184
30185 if (validMovement && validTouchTime && validPointers) {
30186 if (input.eventType != INPUT_END) {
30187 return this.failTimeout();
30188 }
30189
30190 var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
30191 var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
30192 this.pTime = input.timeStamp;
30193 this.pCenter = input.center;
30194
30195 if (!validMultiTap || !validInterval) {
30196 this.count = 1;
30197 } else {
30198 this.count += 1;
30199 }
30200
30201 this._input = input; // if tap count matches we have recognized it,
30202 // else it has began recognizing...
30203
30204 var tapCount = this.count % options.taps;
30205
30206 if (tapCount === 0) {
30207 // no failing requirements, immediately trigger the tap event
30208 // or wait as long as the multitap interval to trigger
30209 if (!this.hasRequireFailures()) {
30210 return STATE_RECOGNIZED;
30211 } else {
30212 this._timer = setTimeoutContext(function () {
30213 this.state = STATE_RECOGNIZED;
30214 this.tryEmit();
30215 }, options.interval, this);
30216 return STATE_BEGAN;
30217 }
30218 }
30219 }
30220
30221 return STATE_FAILED;
30222 },
30223 failTimeout: function () {
30224 this._timer = setTimeoutContext(function () {
30225 this.state = STATE_FAILED;
30226 }, this.options.interval, this);
30227 return STATE_FAILED;
30228 },
30229 reset: function () {
30230 clearTimeout(this._timer);
30231 },
30232 emit: function () {
30233 if (this.state == STATE_RECOGNIZED) {
30234 this._input.tapCount = this.count;
30235 this.manager.emit(this.options.event, this._input);
30236 }
30237 }
30238 });
30239 /**
30240 * Simple way to create a manager with a default set of recognizers.
30241 * @param {HTMLElement} element
30242 * @param {Object} [options]
30243 * @constructor
30244 */
30245
30246 function Hammer(element, options) {
30247 options = options || {};
30248 options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
30249 return new Manager(element, options);
30250 }
30251 /**
30252 * @const {string}
30253 */
30254
30255
30256 Hammer.VERSION = '2.0.7';
30257 /**
30258 * default settings
30259 * @namespace
30260 */
30261
30262 Hammer.defaults = {
30263 /**
30264 * set if DOM events are being triggered.
30265 * But this is slower and unused by simple implementations, so disabled by default.
30266 * @type {Boolean}
30267 * @default false
30268 */
30269 domEvents: false,
30270
30271 /**
30272 * The value for the touchAction property/fallback.
30273 * When set to `compute` it will magically set the correct value based on the added recognizers.
30274 * @type {String}
30275 * @default compute
30276 */
30277 touchAction: TOUCH_ACTION_COMPUTE,
30278
30279 /**
30280 * @type {Boolean}
30281 * @default true
30282 */
30283 enable: true,
30284
30285 /**
30286 * EXPERIMENTAL FEATURE -- can be removed/changed
30287 * Change the parent input target element.
30288 * If Null, then it is being set the to main element.
30289 * @type {Null|EventTarget}
30290 * @default null
30291 */
30292 inputTarget: null,
30293
30294 /**
30295 * force an input class
30296 * @type {Null|Function}
30297 * @default null
30298 */
30299 inputClass: null,
30300
30301 /**
30302 * Default recognizer setup when calling `Hammer()`
30303 * When creating a new Manager these will be skipped.
30304 * @type {Array}
30305 */
30306 preset: [// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
30307 [RotateRecognizer, {
30308 enable: false
30309 }], [PinchRecognizer, {
30310 enable: false
30311 }, ['rotate']], [SwipeRecognizer, {
30312 direction: DIRECTION_HORIZONTAL
30313 }], [PanRecognizer, {
30314 direction: DIRECTION_HORIZONTAL
30315 }, ['swipe']], [TapRecognizer], [TapRecognizer, {
30316 event: 'doubletap',
30317 taps: 2
30318 }, ['tap']], [PressRecognizer]],
30319
30320 /**
30321 * Some CSS properties can be used to improve the working of Hammer.
30322 * Add them to this method and they will be set when creating a new Manager.
30323 * @namespace
30324 */
30325 cssProps: {
30326 /**
30327 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
30328 * @type {String}
30329 * @default 'none'
30330 */
30331 userSelect: 'none',
30332
30333 /**
30334 * Disable the Windows Phone grippers when pressing an element.
30335 * @type {String}
30336 * @default 'none'
30337 */
30338 touchSelect: 'none',
30339
30340 /**
30341 * Disables the default callout shown when you touch and hold a touch target.
30342 * On iOS, when you touch and hold a touch target such as a link, Safari displays
30343 * a callout containing information about the link. This property allows you to disable that callout.
30344 * @type {String}
30345 * @default 'none'
30346 */
30347 touchCallout: 'none',
30348
30349 /**
30350 * Specifies whether zooming is enabled. Used by IE10>
30351 * @type {String}
30352 * @default 'none'
30353 */
30354 contentZooming: 'none',
30355
30356 /**
30357 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
30358 * @type {String}
30359 * @default 'none'
30360 */
30361 userDrag: 'none',
30362
30363 /**
30364 * Overrides the highlight color shown when the user taps a link or a JavaScript
30365 * clickable element in iOS. This property obeys the alpha value, if specified.
30366 * @type {String}
30367 * @default 'rgba(0,0,0,0)'
30368 */
30369 tapHighlightColor: 'rgba(0,0,0,0)'
30370 }
30371 };
30372 var STOP = 1;
30373 var FORCED_STOP = 2;
30374 /**
30375 * Manager
30376 * @param {HTMLElement} element
30377 * @param {Object} [options]
30378 * @constructor
30379 */
30380
30381 function Manager(element, options) {
30382 this.options = assign({}, Hammer.defaults, options || {});
30383 this.options.inputTarget = this.options.inputTarget || element;
30384 this.handlers = {};
30385 this.session = {};
30386 this.recognizers = [];
30387 this.oldCssProps = {};
30388 this.element = element;
30389 this.input = createInputInstance(this);
30390 this.touchAction = new TouchAction(this, this.options.touchAction);
30391 toggleCssProps(this, true);
30392 each(this.options.recognizers, function (item) {
30393 var recognizer = this.add(new item[0](item[1]));
30394 item[2] && recognizer.recognizeWith(item[2]);
30395 item[3] && recognizer.requireFailure(item[3]);
30396 }, this);
30397 }
30398
30399 Manager.prototype = {
30400 /**
30401 * set options
30402 * @param {Object} options
30403 * @returns {Manager}
30404 */
30405 set: function (options) {
30406 assign(this.options, options); // Options that need a little more setup
30407
30408 if (options.touchAction) {
30409 this.touchAction.update();
30410 }
30411
30412 if (options.inputTarget) {
30413 // Clean up existing event listeners and reinitialize
30414 this.input.destroy();
30415 this.input.target = options.inputTarget;
30416 this.input.init();
30417 }
30418
30419 return this;
30420 },
30421
30422 /**
30423 * stop recognizing for this session.
30424 * This session will be discarded, when a new [input]start event is fired.
30425 * When forced, the recognizer cycle is stopped immediately.
30426 * @param {Boolean} [force]
30427 */
30428 stop: function (force) {
30429 this.session.stopped = force ? FORCED_STOP : STOP;
30430 },
30431
30432 /**
30433 * run the recognizers!
30434 * called by the inputHandler function on every movement of the pointers (touches)
30435 * it walks through all the recognizers and tries to detect the gesture that is being made
30436 * @param {Object} inputData
30437 */
30438 recognize: function (inputData) {
30439 var session = this.session;
30440
30441 if (session.stopped) {
30442 return;
30443 } // run the touch-action polyfill
30444
30445
30446 this.touchAction.preventDefaults(inputData);
30447 var recognizer;
30448 var recognizers = this.recognizers; // this holds the recognizer that is being recognized.
30449 // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
30450 // if no recognizer is detecting a thing, it is set to `null`
30451
30452 var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized
30453 // or when we're in a new session
30454
30455 if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
30456 curRecognizer = session.curRecognizer = null;
30457 }
30458
30459 var i = 0;
30460
30461 while (i < recognizers.length) {
30462 recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one.
30463 // 1. allow if the session is NOT forced stopped (see the .stop() method)
30464 // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
30465 // that is being recognized.
30466 // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
30467 // this can be setup with the `recognizeWith()` method on the recognizer.
30468
30469 if (session.stopped !== FORCED_STOP && ( // 1
30470 !curRecognizer || recognizer == curRecognizer || // 2
30471 recognizer.canRecognizeWith(curRecognizer))) {
30472 // 3
30473 recognizer.recognize(inputData);
30474 } else {
30475 recognizer.reset();
30476 } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
30477 // current active recognizer. but only if we don't already have an active recognizer
30478
30479
30480 if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
30481 curRecognizer = session.curRecognizer = recognizer;
30482 }
30483
30484 i++;
30485 }
30486 },
30487
30488 /**
30489 * get a recognizer by its event name.
30490 * @param {Recognizer|String} recognizer
30491 * @returns {Recognizer|Null}
30492 */
30493 get: function (recognizer) {
30494 if (recognizer instanceof Recognizer) {
30495 return recognizer;
30496 }
30497
30498 var recognizers = this.recognizers;
30499
30500 for (var i = 0; i < recognizers.length; i++) {
30501 if (recognizers[i].options.event == recognizer) {
30502 return recognizers[i];
30503 }
30504 }
30505
30506 return null;
30507 },
30508
30509 /**
30510 * add a recognizer to the manager
30511 * existing recognizers with the same event name will be removed
30512 * @param {Recognizer} recognizer
30513 * @returns {Recognizer|Manager}
30514 */
30515 add: function (recognizer) {
30516 if (invokeArrayArg(recognizer, 'add', this)) {
30517 return this;
30518 } // remove existing
30519
30520
30521 var existing = this.get(recognizer.options.event);
30522
30523 if (existing) {
30524 this.remove(existing);
30525 }
30526
30527 this.recognizers.push(recognizer);
30528 recognizer.manager = this;
30529 this.touchAction.update();
30530 return recognizer;
30531 },
30532
30533 /**
30534 * remove a recognizer by name or instance
30535 * @param {Recognizer|String} recognizer
30536 * @returns {Manager}
30537 */
30538 remove: function (recognizer) {
30539 if (invokeArrayArg(recognizer, 'remove', this)) {
30540 return this;
30541 }
30542
30543 recognizer = this.get(recognizer); // let's make sure this recognizer exists
30544
30545 if (recognizer) {
30546 var recognizers = this.recognizers;
30547 var index = inArray(recognizers, recognizer);
30548
30549 if (index !== -1) {
30550 recognizers.splice(index, 1);
30551 this.touchAction.update();
30552 }
30553 }
30554
30555 return this;
30556 },
30557
30558 /**
30559 * bind event
30560 * @param {String} events
30561 * @param {Function} handler
30562 * @returns {EventEmitter} this
30563 */
30564 on: function (events, handler) {
30565 if (events === undefined$1) {
30566 return;
30567 }
30568
30569 if (handler === undefined$1) {
30570 return;
30571 }
30572
30573 var handlers = this.handlers;
30574 each(splitStr(events), function (event) {
30575 handlers[event] = handlers[event] || [];
30576 handlers[event].push(handler);
30577 });
30578 return this;
30579 },
30580
30581 /**
30582 * unbind event, leave emit blank to remove all handlers
30583 * @param {String} events
30584 * @param {Function} [handler]
30585 * @returns {EventEmitter} this
30586 */
30587 off: function (events, handler) {
30588 if (events === undefined$1) {
30589 return;
30590 }
30591
30592 var handlers = this.handlers;
30593 each(splitStr(events), function (event) {
30594 if (!handler) {
30595 delete handlers[event];
30596 } else {
30597 handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
30598 }
30599 });
30600 return this;
30601 },
30602
30603 /**
30604 * emit event to the listeners
30605 * @param {String} event
30606 * @param {Object} data
30607 */
30608 emit: function (event, data) {
30609 // we also want to trigger dom events
30610 if (this.options.domEvents) {
30611 triggerDomEvent(event, data);
30612 } // no handlers, so skip it all
30613
30614
30615 var handlers = this.handlers[event] && this.handlers[event].slice();
30616
30617 if (!handlers || !handlers.length) {
30618 return;
30619 }
30620
30621 data.type = event;
30622
30623 data.preventDefault = function () {
30624 data.srcEvent.preventDefault();
30625 };
30626
30627 var i = 0;
30628
30629 while (i < handlers.length) {
30630 handlers[i](data);
30631 i++;
30632 }
30633 },
30634
30635 /**
30636 * destroy the manager and unbinds all events
30637 * it doesn't unbind dom events, that is the user own responsibility
30638 */
30639 destroy: function () {
30640 this.element && toggleCssProps(this, false);
30641 this.handlers = {};
30642 this.session = {};
30643 this.input.destroy();
30644 this.element = null;
30645 }
30646 };
30647 /**
30648 * add/remove the css properties as defined in manager.options.cssProps
30649 * @param {Manager} manager
30650 * @param {Boolean} add
30651 */
30652
30653 function toggleCssProps(manager, add) {
30654 var element = manager.element;
30655
30656 if (!element.style) {
30657 return;
30658 }
30659
30660 var prop;
30661 each(manager.options.cssProps, function (value, name) {
30662 prop = prefixed(element.style, name);
30663
30664 if (add) {
30665 manager.oldCssProps[prop] = element.style[prop];
30666 element.style[prop] = value;
30667 } else {
30668 element.style[prop] = manager.oldCssProps[prop] || '';
30669 }
30670 });
30671
30672 if (!add) {
30673 manager.oldCssProps = {};
30674 }
30675 }
30676 /**
30677 * trigger dom event
30678 * @param {String} event
30679 * @param {Object} data
30680 */
30681
30682
30683 function triggerDomEvent(event, data) {
30684 var gestureEvent = document.createEvent('Event');
30685 gestureEvent.initEvent(event, true, true);
30686 gestureEvent.gesture = data;
30687 data.target.dispatchEvent(gestureEvent);
30688 }
30689
30690 assign(Hammer, {
30691 INPUT_START: INPUT_START,
30692 INPUT_MOVE: INPUT_MOVE,
30693 INPUT_END: INPUT_END,
30694 INPUT_CANCEL: INPUT_CANCEL,
30695 STATE_POSSIBLE: STATE_POSSIBLE,
30696 STATE_BEGAN: STATE_BEGAN,
30697 STATE_CHANGED: STATE_CHANGED,
30698 STATE_ENDED: STATE_ENDED,
30699 STATE_RECOGNIZED: STATE_RECOGNIZED,
30700 STATE_CANCELLED: STATE_CANCELLED,
30701 STATE_FAILED: STATE_FAILED,
30702 DIRECTION_NONE: DIRECTION_NONE,
30703 DIRECTION_LEFT: DIRECTION_LEFT,
30704 DIRECTION_RIGHT: DIRECTION_RIGHT,
30705 DIRECTION_UP: DIRECTION_UP,
30706 DIRECTION_DOWN: DIRECTION_DOWN,
30707 DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
30708 DIRECTION_VERTICAL: DIRECTION_VERTICAL,
30709 DIRECTION_ALL: DIRECTION_ALL,
30710 Manager: Manager,
30711 Input: Input,
30712 TouchAction: TouchAction,
30713 TouchInput: TouchInput,
30714 MouseInput: MouseInput,
30715 PointerEventInput: PointerEventInput,
30716 TouchMouseInput: TouchMouseInput,
30717 SingleTouchInput: SingleTouchInput,
30718 Recognizer: Recognizer,
30719 AttrRecognizer: AttrRecognizer,
30720 Tap: TapRecognizer,
30721 Pan: PanRecognizer,
30722 Swipe: SwipeRecognizer,
30723 Pinch: PinchRecognizer,
30724 Rotate: RotateRecognizer,
30725 Press: PressRecognizer,
30726 on: addEventListeners,
30727 off: removeEventListeners,
30728 each: each,
30729 merge: merge,
30730 extend: extend,
30731 assign: assign,
30732 inherit: inherit,
30733 bindFn: bindFn,
30734 prefixed: prefixed
30735 }); // this prevents errors when Hammer is loaded in the presence of an AMD
30736 // style loader but by script tag, not by the loader.
30737
30738 var freeGlobal = typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}; // jshint ignore:line
30739
30740 freeGlobal.Hammer = Hammer;
30741
30742 if (typeof undefined$1 === 'function' && undefined$1.amd) {
30743 undefined$1(function () {
30744 return Hammer;
30745 });
30746 } else if ( module.exports) {
30747 module.exports = Hammer;
30748 } else {
30749 window[exportName] = Hammer;
30750 }
30751 })(window, document, 'Hammer');
30752});
30753
30754var hammer$1 = createCommonjsModule$1(function (module) {
30755 /**
30756 * Setup a mock hammer.js object, for unit testing.
30757 *
30758 * Inspiration: https://github.com/uber/deck.gl/pull/658
30759 *
30760 * @returns {{on: noop, off: noop, destroy: noop, emit: noop, get: get}}
30761 */
30762 function hammerMock() {
30763 var noop = function noop() {};
30764
30765 return {
30766 on: noop,
30767 off: noop,
30768 destroy: noop,
30769 emit: noop,
30770 get: function get(m) {
30771 //eslint-disable-line no-unused-vars
30772 return {
30773 set: noop
30774 };
30775 }
30776 };
30777 }
30778
30779 if (typeof window !== 'undefined') {
30780 var propagating$1 = propagating;
30781 var Hammer = window['Hammer'] || hammer;
30782 module.exports = propagating$1(Hammer, {
30783 preventDefault: 'mouse'
30784 });
30785 } else {
30786 module.exports = function () {
30787 // hammer.js is only available in a browser, not in node.js. Replacing it with a mock object.
30788 return hammerMock();
30789 };
30790 }
30791});
30792
30793var keycharm = createCommonjsModule$1(function (module, exports) {
30794 /**
30795 * Created by Alex on 11/6/2014.
30796 */
30797 // https://github.com/umdjs/umd/blob/master/returnExports.js#L40-L60
30798 // if the module has no dependencies, the above pattern can be simplified to
30799
30800 (function (root, factory) {
30801 {
30802 // Node. Does not work with strict CommonJS, but
30803 // only CommonJS-like environments that support module.exports,
30804 // like Node.
30805 module.exports = factory();
30806 }
30807 })(commonjsGlobal$1, function () {
30808 function keycharm(options) {
30809 var preventDefault = options && options.preventDefault || false;
30810 var container = options && options.container || window;
30811 var _exportFunctions = {};
30812 var _bound = {
30813 keydown: {},
30814 keyup: {}
30815 };
30816 var _keys = {};
30817 var i; // a - z
30818
30819 for (i = 97; i <= 122; i++) {
30820 _keys[String.fromCharCode(i)] = {
30821 code: 65 + (i - 97),
30822 shift: false
30823 };
30824 } // A - Z
30825
30826
30827 for (i = 65; i <= 90; i++) {
30828 _keys[String.fromCharCode(i)] = {
30829 code: i,
30830 shift: true
30831 };
30832 } // 0 - 9
30833
30834
30835 for (i = 0; i <= 9; i++) {
30836 _keys['' + i] = {
30837 code: 48 + i,
30838 shift: false
30839 };
30840 } // F1 - F12
30841
30842
30843 for (i = 1; i <= 12; i++) {
30844 _keys['F' + i] = {
30845 code: 111 + i,
30846 shift: false
30847 };
30848 } // num0 - num9
30849
30850
30851 for (i = 0; i <= 9; i++) {
30852 _keys['num' + i] = {
30853 code: 96 + i,
30854 shift: false
30855 };
30856 } // numpad misc
30857
30858
30859 _keys['num*'] = {
30860 code: 106,
30861 shift: false
30862 };
30863 _keys['num+'] = {
30864 code: 107,
30865 shift: false
30866 };
30867 _keys['num-'] = {
30868 code: 109,
30869 shift: false
30870 };
30871 _keys['num/'] = {
30872 code: 111,
30873 shift: false
30874 };
30875 _keys['num.'] = {
30876 code: 110,
30877 shift: false
30878 }; // arrows
30879
30880 _keys['left'] = {
30881 code: 37,
30882 shift: false
30883 };
30884 _keys['up'] = {
30885 code: 38,
30886 shift: false
30887 };
30888 _keys['right'] = {
30889 code: 39,
30890 shift: false
30891 };
30892 _keys['down'] = {
30893 code: 40,
30894 shift: false
30895 }; // extra keys
30896
30897 _keys['space'] = {
30898 code: 32,
30899 shift: false
30900 };
30901 _keys['enter'] = {
30902 code: 13,
30903 shift: false
30904 };
30905 _keys['shift'] = {
30906 code: 16,
30907 shift: undefined
30908 };
30909 _keys['esc'] = {
30910 code: 27,
30911 shift: false
30912 };
30913 _keys['backspace'] = {
30914 code: 8,
30915 shift: false
30916 };
30917 _keys['tab'] = {
30918 code: 9,
30919 shift: false
30920 };
30921 _keys['ctrl'] = {
30922 code: 17,
30923 shift: false
30924 };
30925 _keys['alt'] = {
30926 code: 18,
30927 shift: false
30928 };
30929 _keys['delete'] = {
30930 code: 46,
30931 shift: false
30932 };
30933 _keys['pageup'] = {
30934 code: 33,
30935 shift: false
30936 };
30937 _keys['pagedown'] = {
30938 code: 34,
30939 shift: false
30940 }; // symbols
30941
30942 _keys['='] = {
30943 code: 187,
30944 shift: false
30945 };
30946 _keys['-'] = {
30947 code: 189,
30948 shift: false
30949 };
30950 _keys[']'] = {
30951 code: 221,
30952 shift: false
30953 };
30954 _keys['['] = {
30955 code: 219,
30956 shift: false
30957 };
30958
30959 var down = function (event) {
30960 handleEvent(event, 'keydown');
30961 };
30962
30963 var up = function (event) {
30964 handleEvent(event, 'keyup');
30965 }; // handle the actualy bound key with the event
30966
30967
30968 var handleEvent = function (event, type) {
30969 if (_bound[type][event.keyCode] !== undefined) {
30970 var bound = _bound[type][event.keyCode];
30971
30972 for (var i = 0; i < bound.length; i++) {
30973 if (bound[i].shift === undefined) {
30974 bound[i].fn(event);
30975 } else if (bound[i].shift == true && event.shiftKey == true) {
30976 bound[i].fn(event);
30977 } else if (bound[i].shift == false && event.shiftKey == false) {
30978 bound[i].fn(event);
30979 }
30980 }
30981
30982 if (preventDefault == true) {
30983 event.preventDefault();
30984 }
30985 }
30986 }; // bind a key to a callback
30987
30988
30989 _exportFunctions.bind = function (key, callback, type) {
30990 if (type === undefined) {
30991 type = 'keydown';
30992 }
30993
30994 if (_keys[key] === undefined) {
30995 throw new Error("unsupported key: " + key);
30996 }
30997
30998 if (_bound[type][_keys[key].code] === undefined) {
30999 _bound[type][_keys[key].code] = [];
31000 }
31001
31002 _bound[type][_keys[key].code].push({
31003 fn: callback,
31004 shift: _keys[key].shift
31005 });
31006 }; // bind all keys to a call back (demo purposes)
31007
31008
31009 _exportFunctions.bindAll = function (callback, type) {
31010 if (type === undefined) {
31011 type = 'keydown';
31012 }
31013
31014 for (var key in _keys) {
31015 if (_keys.hasOwnProperty(key)) {
31016 _exportFunctions.bind(key, callback, type);
31017 }
31018 }
31019 }; // get the key label from an event
31020
31021
31022 _exportFunctions.getKey = function (event) {
31023 for (var key in _keys) {
31024 if (_keys.hasOwnProperty(key)) {
31025 if (event.shiftKey == true && _keys[key].shift == true && event.keyCode == _keys[key].code) {
31026 return key;
31027 } else if (event.shiftKey == false && _keys[key].shift == false && event.keyCode == _keys[key].code) {
31028 return key;
31029 } else if (event.keyCode == _keys[key].code && key == 'shift') {
31030 return key;
31031 }
31032 }
31033 }
31034
31035 return "unknown key, currently not supported";
31036 }; // unbind either a specific callback from a key or all of them (by leaving callback undefined)
31037
31038
31039 _exportFunctions.unbind = function (key, callback, type) {
31040 if (type === undefined) {
31041 type = 'keydown';
31042 }
31043
31044 if (_keys[key] === undefined) {
31045 throw new Error("unsupported key: " + key);
31046 }
31047
31048 if (callback !== undefined) {
31049 var newBindings = [];
31050 var bound = _bound[type][_keys[key].code];
31051
31052 if (bound !== undefined) {
31053 for (var i = 0; i < bound.length; i++) {
31054 if (!(bound[i].fn == callback && bound[i].shift == _keys[key].shift)) {
31055 newBindings.push(_bound[type][_keys[key].code][i]);
31056 }
31057 }
31058 }
31059
31060 _bound[type][_keys[key].code] = newBindings;
31061 } else {
31062 _bound[type][_keys[key].code] = [];
31063 }
31064 }; // reset all bound variables.
31065
31066
31067 _exportFunctions.reset = function () {
31068 _bound = {
31069 keydown: {},
31070 keyup: {}
31071 };
31072 }; // unbind all listeners and reset all variables.
31073
31074
31075 _exportFunctions.destroy = function () {
31076 _bound = {
31077 keydown: {},
31078 keyup: {}
31079 };
31080 container.removeEventListener('keydown', down, true);
31081 container.removeEventListener('keyup', up, true);
31082 }; // create listeners.
31083
31084
31085 container.addEventListener('keydown', down, true);
31086 container.addEventListener('keyup', up, true); // return the public functions.
31087
31088 return _exportFunctions;
31089 }
31090
31091 return keycharm;
31092 });
31093});
31094
31095var util_1 = util;
31096var DOMutil$1 = DOMutil; // data
31097
31098var DataSet$2 = index.DataSet,
31099 DataView$3 = index.DataView,
31100 Queue$1 = index.Queue;
31101var DataSet_1 = DataSet$2;
31102var DataView_1 = DataView$3;
31103var Queue_1 = Queue$1; // Graph3d
31104
31105var Graph3d$1 = Graph3d_1;
31106var graph3d = {
31107 Camera: Camera_1,
31108 Filter: Filter_1,
31109 Point2d: Point2d_1,
31110 Point3d: Point3d_1,
31111 Slider: Slider_1,
31112 StepNumber: StepNumber_1
31113}; // bundled external libraries
31114
31115var moment$4 = moment$3;
31116var Hammer = hammer$1;
31117var keycharm$1 = keycharm;
31118var repo = {
31119 util: util_1,
31120 DOMutil: DOMutil$1,
31121 DataSet: DataSet_1,
31122 DataView: DataView_1,
31123 Queue: Queue_1,
31124 Graph3d: Graph3d$1,
31125 graph3d: graph3d,
31126 moment: moment$4,
31127 Hammer: Hammer,
31128 keycharm: keycharm$1
31129};
31130
31131export default repo;
31132export { DOMutil$1 as DOMutil, DataSet_1 as DataSet, DataView_1 as DataView, Graph3d$1 as Graph3d, Hammer, Queue_1 as Queue, graph3d, keycharm$1 as keycharm, moment$4 as moment, util_1 as util };