UNPKG

176 kBJavaScriptView Raw
1//! moment.js
2//! version : 2.30.1
3//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4//! license : MIT
5//! momentjs.com
6
7;(function (global, factory) {
8 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
9 typeof define === 'function' && define.amd ? define(factory) :
10 global.moment = factory()
11}(this, (function () { 'use strict';
12
13 var hookCallback;
14
15 function hooks() {
16 return hookCallback.apply(null, arguments);
17 }
18
19 // This is done to register the method called with moment()
20 // without creating circular dependencies.
21 function setHookCallback(callback) {
22 hookCallback = callback;
23 }
24
25 function isArray(input) {
26 return (
27 input instanceof Array ||
28 Object.prototype.toString.call(input) === '[object Array]'
29 );
30 }
31
32 function isObject(input) {
33 // IE8 will treat undefined and null as object if it wasn't for
34 // input != null
35 return (
36 input != null &&
37 Object.prototype.toString.call(input) === '[object Object]'
38 );
39 }
40
41 function hasOwnProp(a, b) {
42 return Object.prototype.hasOwnProperty.call(a, b);
43 }
44
45 function isObjectEmpty(obj) {
46 if (Object.getOwnPropertyNames) {
47 return Object.getOwnPropertyNames(obj).length === 0;
48 } else {
49 var k;
50 for (k in obj) {
51 if (hasOwnProp(obj, k)) {
52 return false;
53 }
54 }
55 return true;
56 }
57 }
58
59 function isUndefined(input) {
60 return input === void 0;
61 }
62
63 function isNumber(input) {
64 return (
65 typeof input === 'number' ||
66 Object.prototype.toString.call(input) === '[object Number]'
67 );
68 }
69
70 function isDate(input) {
71 return (
72 input instanceof Date ||
73 Object.prototype.toString.call(input) === '[object Date]'
74 );
75 }
76
77 function map(arr, fn) {
78 var res = [],
79 i,
80 arrLen = arr.length;
81 for (i = 0; i < arrLen; ++i) {
82 res.push(fn(arr[i], i));
83 }
84 return res;
85 }
86
87 function extend(a, b) {
88 for (var i in b) {
89 if (hasOwnProp(b, i)) {
90 a[i] = b[i];
91 }
92 }
93
94 if (hasOwnProp(b, 'toString')) {
95 a.toString = b.toString;
96 }
97
98 if (hasOwnProp(b, 'valueOf')) {
99 a.valueOf = b.valueOf;
100 }
101
102 return a;
103 }
104
105 function createUTC(input, format, locale, strict) {
106 return createLocalOrUTC(input, format, locale, strict, true).utc();
107 }
108
109 function defaultParsingFlags() {
110 // We need to deep clone this object.
111 return {
112 empty: false,
113 unusedTokens: [],
114 unusedInput: [],
115 overflow: -2,
116 charsLeftOver: 0,
117 nullInput: false,
118 invalidEra: null,
119 invalidMonth: null,
120 invalidFormat: false,
121 userInvalidated: false,
122 iso: false,
123 parsedDateParts: [],
124 era: null,
125 meridiem: null,
126 rfc2822: false,
127 weekdayMismatch: false,
128 };
129 }
130
131 function getParsingFlags(m) {
132 if (m._pf == null) {
133 m._pf = defaultParsingFlags();
134 }
135 return m._pf;
136 }
137
138 var some;
139 if (Array.prototype.some) {
140 some = Array.prototype.some;
141 } else {
142 some = function (fun) {
143 var t = Object(this),
144 len = t.length >>> 0,
145 i;
146
147 for (i = 0; i < len; i++) {
148 if (i in t && fun.call(this, t[i], i, t)) {
149 return true;
150 }
151 }
152
153 return false;
154 };
155 }
156
157 function isValid(m) {
158 var flags = null,
159 parsedParts = false,
160 isNowValid = m._d && !isNaN(m._d.getTime());
161 if (isNowValid) {
162 flags = getParsingFlags(m);
163 parsedParts = some.call(flags.parsedDateParts, function (i) {
164 return i != null;
165 });
166 isNowValid =
167 flags.overflow < 0 &&
168 !flags.empty &&
169 !flags.invalidEra &&
170 !flags.invalidMonth &&
171 !flags.invalidWeekday &&
172 !flags.weekdayMismatch &&
173 !flags.nullInput &&
174 !flags.invalidFormat &&
175 !flags.userInvalidated &&
176 (!flags.meridiem || (flags.meridiem && parsedParts));
177 if (m._strict) {
178 isNowValid =
179 isNowValid &&
180 flags.charsLeftOver === 0 &&
181 flags.unusedTokens.length === 0 &&
182 flags.bigHour === undefined;
183 }
184 }
185 if (Object.isFrozen == null || !Object.isFrozen(m)) {
186 m._isValid = isNowValid;
187 } else {
188 return isNowValid;
189 }
190 return m._isValid;
191 }
192
193 function createInvalid(flags) {
194 var m = createUTC(NaN);
195 if (flags != null) {
196 extend(getParsingFlags(m), flags);
197 } else {
198 getParsingFlags(m).userInvalidated = true;
199 }
200
201 return m;
202 }
203
204 // Plugins that add properties should also add the key here (null value),
205 // so we can properly clone ourselves.
206 var momentProperties = (hooks.momentProperties = []),
207 updateInProgress = false;
208
209 function copyConfig(to, from) {
210 var i,
211 prop,
212 val,
213 momentPropertiesLen = momentProperties.length;
214
215 if (!isUndefined(from._isAMomentObject)) {
216 to._isAMomentObject = from._isAMomentObject;
217 }
218 if (!isUndefined(from._i)) {
219 to._i = from._i;
220 }
221 if (!isUndefined(from._f)) {
222 to._f = from._f;
223 }
224 if (!isUndefined(from._l)) {
225 to._l = from._l;
226 }
227 if (!isUndefined(from._strict)) {
228 to._strict = from._strict;
229 }
230 if (!isUndefined(from._tzm)) {
231 to._tzm = from._tzm;
232 }
233 if (!isUndefined(from._isUTC)) {
234 to._isUTC = from._isUTC;
235 }
236 if (!isUndefined(from._offset)) {
237 to._offset = from._offset;
238 }
239 if (!isUndefined(from._pf)) {
240 to._pf = getParsingFlags(from);
241 }
242 if (!isUndefined(from._locale)) {
243 to._locale = from._locale;
244 }
245
246 if (momentPropertiesLen > 0) {
247 for (i = 0; i < momentPropertiesLen; i++) {
248 prop = momentProperties[i];
249 val = from[prop];
250 if (!isUndefined(val)) {
251 to[prop] = val;
252 }
253 }
254 }
255
256 return to;
257 }
258
259 // Moment prototype object
260 function Moment(config) {
261 copyConfig(this, config);
262 this._d = new Date(config._d != null ? config._d.getTime() : NaN);
263 if (!this.isValid()) {
264 this._d = new Date(NaN);
265 }
266 // Prevent infinite loop in case updateOffset creates new moment
267 // objects.
268 if (updateInProgress === false) {
269 updateInProgress = true;
270 hooks.updateOffset(this);
271 updateInProgress = false;
272 }
273 }
274
275 function isMoment(obj) {
276 return (
277 obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
278 );
279 }
280
281 function warn(msg) {
282 if (
283 hooks.suppressDeprecationWarnings === false &&
284 typeof console !== 'undefined' &&
285 console.warn
286 ) {
287 console.warn('Deprecation warning: ' + msg);
288 }
289 }
290
291 function deprecate(msg, fn) {
292 var firstTime = true;
293
294 return extend(function () {
295 if (hooks.deprecationHandler != null) {
296 hooks.deprecationHandler(null, msg);
297 }
298 if (firstTime) {
299 var args = [],
300 arg,
301 i,
302 key,
303 argLen = arguments.length;
304 for (i = 0; i < argLen; i++) {
305 arg = '';
306 if (typeof arguments[i] === 'object') {
307 arg += '\n[' + i + '] ';
308 for (key in arguments[0]) {
309 if (hasOwnProp(arguments[0], key)) {
310 arg += key + ': ' + arguments[0][key] + ', ';
311 }
312 }
313 arg = arg.slice(0, -2); // Remove trailing comma and space
314 } else {
315 arg = arguments[i];
316 }
317 args.push(arg);
318 }
319 warn(
320 msg +
321 '\nArguments: ' +
322 Array.prototype.slice.call(args).join('') +
323 '\n' +
324 new Error().stack
325 );
326 firstTime = false;
327 }
328 return fn.apply(this, arguments);
329 }, fn);
330 }
331
332 var deprecations = {};
333
334 function deprecateSimple(name, msg) {
335 if (hooks.deprecationHandler != null) {
336 hooks.deprecationHandler(name, msg);
337 }
338 if (!deprecations[name]) {
339 warn(msg);
340 deprecations[name] = true;
341 }
342 }
343
344 hooks.suppressDeprecationWarnings = false;
345 hooks.deprecationHandler = null;
346
347 function isFunction(input) {
348 return (
349 (typeof Function !== 'undefined' && input instanceof Function) ||
350 Object.prototype.toString.call(input) === '[object Function]'
351 );
352 }
353
354 function set(config) {
355 var prop, i;
356 for (i in config) {
357 if (hasOwnProp(config, i)) {
358 prop = config[i];
359 if (isFunction(prop)) {
360 this[i] = prop;
361 } else {
362 this['_' + i] = prop;
363 }
364 }
365 }
366 this._config = config;
367 // Lenient ordinal parsing accepts just a number in addition to
368 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
369 // TODO: Remove "ordinalParse" fallback in next major release.
370 this._dayOfMonthOrdinalParseLenient = new RegExp(
371 (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
372 '|' +
373 /\d{1,2}/.source
374 );
375 }
376
377 function mergeConfigs(parentConfig, childConfig) {
378 var res = extend({}, parentConfig),
379 prop;
380 for (prop in childConfig) {
381 if (hasOwnProp(childConfig, prop)) {
382 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
383 res[prop] = {};
384 extend(res[prop], parentConfig[prop]);
385 extend(res[prop], childConfig[prop]);
386 } else if (childConfig[prop] != null) {
387 res[prop] = childConfig[prop];
388 } else {
389 delete res[prop];
390 }
391 }
392 }
393 for (prop in parentConfig) {
394 if (
395 hasOwnProp(parentConfig, prop) &&
396 !hasOwnProp(childConfig, prop) &&
397 isObject(parentConfig[prop])
398 ) {
399 // make sure changes to properties don't modify parent config
400 res[prop] = extend({}, res[prop]);
401 }
402 }
403 return res;
404 }
405
406 function Locale(config) {
407 if (config != null) {
408 this.set(config);
409 }
410 }
411
412 var keys;
413
414 if (Object.keys) {
415 keys = Object.keys;
416 } else {
417 keys = function (obj) {
418 var i,
419 res = [];
420 for (i in obj) {
421 if (hasOwnProp(obj, i)) {
422 res.push(i);
423 }
424 }
425 return res;
426 };
427 }
428
429 var defaultCalendar = {
430 sameDay: '[Today at] LT',
431 nextDay: '[Tomorrow at] LT',
432 nextWeek: 'dddd [at] LT',
433 lastDay: '[Yesterday at] LT',
434 lastWeek: '[Last] dddd [at] LT',
435 sameElse: 'L',
436 };
437
438 function calendar(key, mom, now) {
439 var output = this._calendar[key] || this._calendar['sameElse'];
440 return isFunction(output) ? output.call(mom, now) : output;
441 }
442
443 function zeroFill(number, targetLength, forceSign) {
444 var absNumber = '' + Math.abs(number),
445 zerosToFill = targetLength - absNumber.length,
446 sign = number >= 0;
447 return (
448 (sign ? (forceSign ? '+' : '') : '-') +
449 Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
450 absNumber
451 );
452 }
453
454 var formattingTokens =
455 /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
456 localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
457 formatFunctions = {},
458 formatTokenFunctions = {};
459
460 // token: 'M'
461 // padded: ['MM', 2]
462 // ordinal: 'Mo'
463 // callback: function () { this.month() + 1 }
464 function addFormatToken(token, padded, ordinal, callback) {
465 var func = callback;
466 if (typeof callback === 'string') {
467 func = function () {
468 return this[callback]();
469 };
470 }
471 if (token) {
472 formatTokenFunctions[token] = func;
473 }
474 if (padded) {
475 formatTokenFunctions[padded[0]] = function () {
476 return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
477 };
478 }
479 if (ordinal) {
480 formatTokenFunctions[ordinal] = function () {
481 return this.localeData().ordinal(
482 func.apply(this, arguments),
483 token
484 );
485 };
486 }
487 }
488
489 function removeFormattingTokens(input) {
490 if (input.match(/\[[\s\S]/)) {
491 return input.replace(/^\[|\]$/g, '');
492 }
493 return input.replace(/\\/g, '');
494 }
495
496 function makeFormatFunction(format) {
497 var array = format.match(formattingTokens),
498 i,
499 length;
500
501 for (i = 0, length = array.length; i < length; i++) {
502 if (formatTokenFunctions[array[i]]) {
503 array[i] = formatTokenFunctions[array[i]];
504 } else {
505 array[i] = removeFormattingTokens(array[i]);
506 }
507 }
508
509 return function (mom) {
510 var output = '',
511 i;
512 for (i = 0; i < length; i++) {
513 output += isFunction(array[i])
514 ? array[i].call(mom, format)
515 : array[i];
516 }
517 return output;
518 };
519 }
520
521 // format date using native date object
522 function formatMoment(m, format) {
523 if (!m.isValid()) {
524 return m.localeData().invalidDate();
525 }
526
527 format = expandFormat(format, m.localeData());
528 formatFunctions[format] =
529 formatFunctions[format] || makeFormatFunction(format);
530
531 return formatFunctions[format](m);
532 }
533
534 function expandFormat(format, locale) {
535 var i = 5;
536
537 function replaceLongDateFormatTokens(input) {
538 return locale.longDateFormat(input) || input;
539 }
540
541 localFormattingTokens.lastIndex = 0;
542 while (i >= 0 && localFormattingTokens.test(format)) {
543 format = format.replace(
544 localFormattingTokens,
545 replaceLongDateFormatTokens
546 );
547 localFormattingTokens.lastIndex = 0;
548 i -= 1;
549 }
550
551 return format;
552 }
553
554 var defaultLongDateFormat = {
555 LTS: 'h:mm:ss A',
556 LT: 'h:mm A',
557 L: 'MM/DD/YYYY',
558 LL: 'MMMM D, YYYY',
559 LLL: 'MMMM D, YYYY h:mm A',
560 LLLL: 'dddd, MMMM D, YYYY h:mm A',
561 };
562
563 function longDateFormat(key) {
564 var format = this._longDateFormat[key],
565 formatUpper = this._longDateFormat[key.toUpperCase()];
566
567 if (format || !formatUpper) {
568 return format;
569 }
570
571 this._longDateFormat[key] = formatUpper
572 .match(formattingTokens)
573 .map(function (tok) {
574 if (
575 tok === 'MMMM' ||
576 tok === 'MM' ||
577 tok === 'DD' ||
578 tok === 'dddd'
579 ) {
580 return tok.slice(1);
581 }
582 return tok;
583 })
584 .join('');
585
586 return this._longDateFormat[key];
587 }
588
589 var defaultInvalidDate = 'Invalid date';
590
591 function invalidDate() {
592 return this._invalidDate;
593 }
594
595 var defaultOrdinal = '%d',
596 defaultDayOfMonthOrdinalParse = /\d{1,2}/;
597
598 function ordinal(number) {
599 return this._ordinal.replace('%d', number);
600 }
601
602 var defaultRelativeTime = {
603 future: 'in %s',
604 past: '%s ago',
605 s: 'a few seconds',
606 ss: '%d seconds',
607 m: 'a minute',
608 mm: '%d minutes',
609 h: 'an hour',
610 hh: '%d hours',
611 d: 'a day',
612 dd: '%d days',
613 w: 'a week',
614 ww: '%d weeks',
615 M: 'a month',
616 MM: '%d months',
617 y: 'a year',
618 yy: '%d years',
619 };
620
621 function relativeTime(number, withoutSuffix, string, isFuture) {
622 var output = this._relativeTime[string];
623 return isFunction(output)
624 ? output(number, withoutSuffix, string, isFuture)
625 : output.replace(/%d/i, number);
626 }
627
628 function pastFuture(diff, output) {
629 var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
630 return isFunction(format) ? format(output) : format.replace(/%s/i, output);
631 }
632
633 var aliases = {
634 D: 'date',
635 dates: 'date',
636 date: 'date',
637 d: 'day',
638 days: 'day',
639 day: 'day',
640 e: 'weekday',
641 weekdays: 'weekday',
642 weekday: 'weekday',
643 E: 'isoWeekday',
644 isoweekdays: 'isoWeekday',
645 isoweekday: 'isoWeekday',
646 DDD: 'dayOfYear',
647 dayofyears: 'dayOfYear',
648 dayofyear: 'dayOfYear',
649 h: 'hour',
650 hours: 'hour',
651 hour: 'hour',
652 ms: 'millisecond',
653 milliseconds: 'millisecond',
654 millisecond: 'millisecond',
655 m: 'minute',
656 minutes: 'minute',
657 minute: 'minute',
658 M: 'month',
659 months: 'month',
660 month: 'month',
661 Q: 'quarter',
662 quarters: 'quarter',
663 quarter: 'quarter',
664 s: 'second',
665 seconds: 'second',
666 second: 'second',
667 gg: 'weekYear',
668 weekyears: 'weekYear',
669 weekyear: 'weekYear',
670 GG: 'isoWeekYear',
671 isoweekyears: 'isoWeekYear',
672 isoweekyear: 'isoWeekYear',
673 w: 'week',
674 weeks: 'week',
675 week: 'week',
676 W: 'isoWeek',
677 isoweeks: 'isoWeek',
678 isoweek: 'isoWeek',
679 y: 'year',
680 years: 'year',
681 year: 'year',
682 };
683
684 function normalizeUnits(units) {
685 return typeof units === 'string'
686 ? aliases[units] || aliases[units.toLowerCase()]
687 : undefined;
688 }
689
690 function normalizeObjectUnits(inputObject) {
691 var normalizedInput = {},
692 normalizedProp,
693 prop;
694
695 for (prop in inputObject) {
696 if (hasOwnProp(inputObject, prop)) {
697 normalizedProp = normalizeUnits(prop);
698 if (normalizedProp) {
699 normalizedInput[normalizedProp] = inputObject[prop];
700 }
701 }
702 }
703
704 return normalizedInput;
705 }
706
707 var priorities = {
708 date: 9,
709 day: 11,
710 weekday: 11,
711 isoWeekday: 11,
712 dayOfYear: 4,
713 hour: 13,
714 millisecond: 16,
715 minute: 14,
716 month: 8,
717 quarter: 7,
718 second: 15,
719 weekYear: 1,
720 isoWeekYear: 1,
721 week: 5,
722 isoWeek: 5,
723 year: 1,
724 };
725
726 function getPrioritizedUnits(unitsObj) {
727 var units = [],
728 u;
729 for (u in unitsObj) {
730 if (hasOwnProp(unitsObj, u)) {
731 units.push({ unit: u, priority: priorities[u] });
732 }
733 }
734 units.sort(function (a, b) {
735 return a.priority - b.priority;
736 });
737 return units;
738 }
739
740 var match1 = /\d/, // 0 - 9
741 match2 = /\d\d/, // 00 - 99
742 match3 = /\d{3}/, // 000 - 999
743 match4 = /\d{4}/, // 0000 - 9999
744 match6 = /[+-]?\d{6}/, // -999999 - 999999
745 match1to2 = /\d\d?/, // 0 - 99
746 match3to4 = /\d\d\d\d?/, // 999 - 9999
747 match5to6 = /\d\d\d\d\d\d?/, // 99999 - 999999
748 match1to3 = /\d{1,3}/, // 0 - 999
749 match1to4 = /\d{1,4}/, // 0 - 9999
750 match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
751 matchUnsigned = /\d+/, // 0 - inf
752 matchSigned = /[+-]?\d+/, // -inf - inf
753 matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
754 matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
755 matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
756 // any word (or two) characters or numbers including two/three word month in arabic.
757 // includes scottish gaelic two word and hyphenated months
758 matchWord =
759 /[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,
760 match1to2NoLeadingZero = /^[1-9]\d?/, // 1-99
761 match1to2HasZero = /^([1-9]\d|\d)/, // 0-99
762 regexes;
763
764 regexes = {};
765
766 function addRegexToken(token, regex, strictRegex) {
767 regexes[token] = isFunction(regex)
768 ? regex
769 : function (isStrict, localeData) {
770 return isStrict && strictRegex ? strictRegex : regex;
771 };
772 }
773
774 function getParseRegexForToken(token, config) {
775 if (!hasOwnProp(regexes, token)) {
776 return new RegExp(unescapeFormat(token));
777 }
778
779 return regexes[token](config._strict, config._locale);
780 }
781
782 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
783 function unescapeFormat(s) {
784 return regexEscape(
785 s
786 .replace('\\', '')
787 .replace(
788 /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,
789 function (matched, p1, p2, p3, p4) {
790 return p1 || p2 || p3 || p4;
791 }
792 )
793 );
794 }
795
796 function regexEscape(s) {
797 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
798 }
799
800 function absFloor(number) {
801 if (number < 0) {
802 // -0 -> 0
803 return Math.ceil(number) || 0;
804 } else {
805 return Math.floor(number);
806 }
807 }
808
809 function toInt(argumentForCoercion) {
810 var coercedNumber = +argumentForCoercion,
811 value = 0;
812
813 if (coercedNumber !== 0 && isFinite(coercedNumber)) {
814 value = absFloor(coercedNumber);
815 }
816
817 return value;
818 }
819
820 var tokens = {};
821
822 function addParseToken(token, callback) {
823 var i,
824 func = callback,
825 tokenLen;
826 if (typeof token === 'string') {
827 token = [token];
828 }
829 if (isNumber(callback)) {
830 func = function (input, array) {
831 array[callback] = toInt(input);
832 };
833 }
834 tokenLen = token.length;
835 for (i = 0; i < tokenLen; i++) {
836 tokens[token[i]] = func;
837 }
838 }
839
840 function addWeekParseToken(token, callback) {
841 addParseToken(token, function (input, array, config, token) {
842 config._w = config._w || {};
843 callback(input, config._w, config, token);
844 });
845 }
846
847 function addTimeToArrayFromToken(token, input, config) {
848 if (input != null && hasOwnProp(tokens, token)) {
849 tokens[token](input, config._a, config, token);
850 }
851 }
852
853 function isLeapYear(year) {
854 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
855 }
856
857 var YEAR = 0,
858 MONTH = 1,
859 DATE = 2,
860 HOUR = 3,
861 MINUTE = 4,
862 SECOND = 5,
863 MILLISECOND = 6,
864 WEEK = 7,
865 WEEKDAY = 8;
866
867 // FORMATTING
868
869 addFormatToken('Y', 0, 0, function () {
870 var y = this.year();
871 return y <= 9999 ? zeroFill(y, 4) : '+' + y;
872 });
873
874 addFormatToken(0, ['YY', 2], 0, function () {
875 return this.year() % 100;
876 });
877
878 addFormatToken(0, ['YYYY', 4], 0, 'year');
879 addFormatToken(0, ['YYYYY', 5], 0, 'year');
880 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
881
882 // PARSING
883
884 addRegexToken('Y', matchSigned);
885 addRegexToken('YY', match1to2, match2);
886 addRegexToken('YYYY', match1to4, match4);
887 addRegexToken('YYYYY', match1to6, match6);
888 addRegexToken('YYYYYY', match1to6, match6);
889
890 addParseToken(['YYYYY', 'YYYYYY'], YEAR);
891 addParseToken('YYYY', function (input, array) {
892 array[YEAR] =
893 input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
894 });
895 addParseToken('YY', function (input, array) {
896 array[YEAR] = hooks.parseTwoDigitYear(input);
897 });
898 addParseToken('Y', function (input, array) {
899 array[YEAR] = parseInt(input, 10);
900 });
901
902 // HELPERS
903
904 function daysInYear(year) {
905 return isLeapYear(year) ? 366 : 365;
906 }
907
908 // HOOKS
909
910 hooks.parseTwoDigitYear = function (input) {
911 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
912 };
913
914 // MOMENTS
915
916 var getSetYear = makeGetSet('FullYear', true);
917
918 function getIsLeapYear() {
919 return isLeapYear(this.year());
920 }
921
922 function makeGetSet(unit, keepTime) {
923 return function (value) {
924 if (value != null) {
925 set$1(this, unit, value);
926 hooks.updateOffset(this, keepTime);
927 return this;
928 } else {
929 return get(this, unit);
930 }
931 };
932 }
933
934 function get(mom, unit) {
935 if (!mom.isValid()) {
936 return NaN;
937 }
938
939 var d = mom._d,
940 isUTC = mom._isUTC;
941
942 switch (unit) {
943 case 'Milliseconds':
944 return isUTC ? d.getUTCMilliseconds() : d.getMilliseconds();
945 case 'Seconds':
946 return isUTC ? d.getUTCSeconds() : d.getSeconds();
947 case 'Minutes':
948 return isUTC ? d.getUTCMinutes() : d.getMinutes();
949 case 'Hours':
950 return isUTC ? d.getUTCHours() : d.getHours();
951 case 'Date':
952 return isUTC ? d.getUTCDate() : d.getDate();
953 case 'Day':
954 return isUTC ? d.getUTCDay() : d.getDay();
955 case 'Month':
956 return isUTC ? d.getUTCMonth() : d.getMonth();
957 case 'FullYear':
958 return isUTC ? d.getUTCFullYear() : d.getFullYear();
959 default:
960 return NaN; // Just in case
961 }
962 }
963
964 function set$1(mom, unit, value) {
965 var d, isUTC, year, month, date;
966
967 if (!mom.isValid() || isNaN(value)) {
968 return;
969 }
970
971 d = mom._d;
972 isUTC = mom._isUTC;
973
974 switch (unit) {
975 case 'Milliseconds':
976 return void (isUTC
977 ? d.setUTCMilliseconds(value)
978 : d.setMilliseconds(value));
979 case 'Seconds':
980 return void (isUTC ? d.setUTCSeconds(value) : d.setSeconds(value));
981 case 'Minutes':
982 return void (isUTC ? d.setUTCMinutes(value) : d.setMinutes(value));
983 case 'Hours':
984 return void (isUTC ? d.setUTCHours(value) : d.setHours(value));
985 case 'Date':
986 return void (isUTC ? d.setUTCDate(value) : d.setDate(value));
987 // case 'Day': // Not real
988 // return void (isUTC ? d.setUTCDay(value) : d.setDay(value));
989 // case 'Month': // Not used because we need to pass two variables
990 // return void (isUTC ? d.setUTCMonth(value) : d.setMonth(value));
991 case 'FullYear':
992 break; // See below ...
993 default:
994 return; // Just in case
995 }
996
997 year = value;
998 month = mom.month();
999 date = mom.date();
1000 date = date === 29 && month === 1 && !isLeapYear(year) ? 28 : date;
1001 void (isUTC
1002 ? d.setUTCFullYear(year, month, date)
1003 : d.setFullYear(year, month, date));
1004 }
1005
1006 // MOMENTS
1007
1008 function stringGet(units) {
1009 units = normalizeUnits(units);
1010 if (isFunction(this[units])) {
1011 return this[units]();
1012 }
1013 return this;
1014 }
1015
1016 function stringSet(units, value) {
1017 if (typeof units === 'object') {
1018 units = normalizeObjectUnits(units);
1019 var prioritized = getPrioritizedUnits(units),
1020 i,
1021 prioritizedLen = prioritized.length;
1022 for (i = 0; i < prioritizedLen; i++) {
1023 this[prioritized[i].unit](units[prioritized[i].unit]);
1024 }
1025 } else {
1026 units = normalizeUnits(units);
1027 if (isFunction(this[units])) {
1028 return this[units](value);
1029 }
1030 }
1031 return this;
1032 }
1033
1034 function mod(n, x) {
1035 return ((n % x) + x) % x;
1036 }
1037
1038 var indexOf;
1039
1040 if (Array.prototype.indexOf) {
1041 indexOf = Array.prototype.indexOf;
1042 } else {
1043 indexOf = function (o) {
1044 // I know
1045 var i;
1046 for (i = 0; i < this.length; ++i) {
1047 if (this[i] === o) {
1048 return i;
1049 }
1050 }
1051 return -1;
1052 };
1053 }
1054
1055 function daysInMonth(year, month) {
1056 if (isNaN(year) || isNaN(month)) {
1057 return NaN;
1058 }
1059 var modMonth = mod(month, 12);
1060 year += (month - modMonth) / 12;
1061 return modMonth === 1
1062 ? isLeapYear(year)
1063 ? 29
1064 : 28
1065 : 31 - ((modMonth % 7) % 2);
1066 }
1067
1068 // FORMATTING
1069
1070 addFormatToken('M', ['MM', 2], 'Mo', function () {
1071 return this.month() + 1;
1072 });
1073
1074 addFormatToken('MMM', 0, 0, function (format) {
1075 return this.localeData().monthsShort(this, format);
1076 });
1077
1078 addFormatToken('MMMM', 0, 0, function (format) {
1079 return this.localeData().months(this, format);
1080 });
1081
1082 // PARSING
1083
1084 addRegexToken('M', match1to2, match1to2NoLeadingZero);
1085 addRegexToken('MM', match1to2, match2);
1086 addRegexToken('MMM', function (isStrict, locale) {
1087 return locale.monthsShortRegex(isStrict);
1088 });
1089 addRegexToken('MMMM', function (isStrict, locale) {
1090 return locale.monthsRegex(isStrict);
1091 });
1092
1093 addParseToken(['M', 'MM'], function (input, array) {
1094 array[MONTH] = toInt(input) - 1;
1095 });
1096
1097 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
1098 var month = config._locale.monthsParse(input, token, config._strict);
1099 // if we didn't find a month name, mark the date as invalid.
1100 if (month != null) {
1101 array[MONTH] = month;
1102 } else {
1103 getParsingFlags(config).invalidMonth = input;
1104 }
1105 });
1106
1107 // LOCALES
1108
1109 var defaultLocaleMonths =
1110 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
1111 '_'
1112 ),
1113 defaultLocaleMonthsShort =
1114 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
1115 MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
1116 defaultMonthsShortRegex = matchWord,
1117 defaultMonthsRegex = matchWord;
1118
1119 function localeMonths(m, format) {
1120 if (!m) {
1121 return isArray(this._months)
1122 ? this._months
1123 : this._months['standalone'];
1124 }
1125 return isArray(this._months)
1126 ? this._months[m.month()]
1127 : this._months[
1128 (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
1129 ? 'format'
1130 : 'standalone'
1131 ][m.month()];
1132 }
1133
1134 function localeMonthsShort(m, format) {
1135 if (!m) {
1136 return isArray(this._monthsShort)
1137 ? this._monthsShort
1138 : this._monthsShort['standalone'];
1139 }
1140 return isArray(this._monthsShort)
1141 ? this._monthsShort[m.month()]
1142 : this._monthsShort[
1143 MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
1144 ][m.month()];
1145 }
1146
1147 function handleStrictParse(monthName, format, strict) {
1148 var i,
1149 ii,
1150 mom,
1151 llc = monthName.toLocaleLowerCase();
1152 if (!this._monthsParse) {
1153 // this is not used
1154 this._monthsParse = [];
1155 this._longMonthsParse = [];
1156 this._shortMonthsParse = [];
1157 for (i = 0; i < 12; ++i) {
1158 mom = createUTC([2000, i]);
1159 this._shortMonthsParse[i] = this.monthsShort(
1160 mom,
1161 ''
1162 ).toLocaleLowerCase();
1163 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
1164 }
1165 }
1166
1167 if (strict) {
1168 if (format === 'MMM') {
1169 ii = indexOf.call(this._shortMonthsParse, llc);
1170 return ii !== -1 ? ii : null;
1171 } else {
1172 ii = indexOf.call(this._longMonthsParse, llc);
1173 return ii !== -1 ? ii : null;
1174 }
1175 } else {
1176 if (format === 'MMM') {
1177 ii = indexOf.call(this._shortMonthsParse, llc);
1178 if (ii !== -1) {
1179 return ii;
1180 }
1181 ii = indexOf.call(this._longMonthsParse, llc);
1182 return ii !== -1 ? ii : null;
1183 } else {
1184 ii = indexOf.call(this._longMonthsParse, llc);
1185 if (ii !== -1) {
1186 return ii;
1187 }
1188 ii = indexOf.call(this._shortMonthsParse, llc);
1189 return ii !== -1 ? ii : null;
1190 }
1191 }
1192 }
1193
1194 function localeMonthsParse(monthName, format, strict) {
1195 var i, mom, regex;
1196
1197 if (this._monthsParseExact) {
1198 return handleStrictParse.call(this, monthName, format, strict);
1199 }
1200
1201 if (!this._monthsParse) {
1202 this._monthsParse = [];
1203 this._longMonthsParse = [];
1204 this._shortMonthsParse = [];
1205 }
1206
1207 // TODO: add sorting
1208 // Sorting makes sure if one month (or abbr) is a prefix of another
1209 // see sorting in computeMonthsParse
1210 for (i = 0; i < 12; i++) {
1211 // make the regex if we don't have it already
1212 mom = createUTC([2000, i]);
1213 if (strict && !this._longMonthsParse[i]) {
1214 this._longMonthsParse[i] = new RegExp(
1215 '^' + this.months(mom, '').replace('.', '') + '$',
1216 'i'
1217 );
1218 this._shortMonthsParse[i] = new RegExp(
1219 '^' + this.monthsShort(mom, '').replace('.', '') + '$',
1220 'i'
1221 );
1222 }
1223 if (!strict && !this._monthsParse[i]) {
1224 regex =
1225 '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
1226 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
1227 }
1228 // test the regex
1229 if (
1230 strict &&
1231 format === 'MMMM' &&
1232 this._longMonthsParse[i].test(monthName)
1233 ) {
1234 return i;
1235 } else if (
1236 strict &&
1237 format === 'MMM' &&
1238 this._shortMonthsParse[i].test(monthName)
1239 ) {
1240 return i;
1241 } else if (!strict && this._monthsParse[i].test(monthName)) {
1242 return i;
1243 }
1244 }
1245 }
1246
1247 // MOMENTS
1248
1249 function setMonth(mom, value) {
1250 if (!mom.isValid()) {
1251 // No op
1252 return mom;
1253 }
1254
1255 if (typeof value === 'string') {
1256 if (/^\d+$/.test(value)) {
1257 value = toInt(value);
1258 } else {
1259 value = mom.localeData().monthsParse(value);
1260 // TODO: Another silent failure?
1261 if (!isNumber(value)) {
1262 return mom;
1263 }
1264 }
1265 }
1266
1267 var month = value,
1268 date = mom.date();
1269
1270 date = date < 29 ? date : Math.min(date, daysInMonth(mom.year(), month));
1271 void (mom._isUTC
1272 ? mom._d.setUTCMonth(month, date)
1273 : mom._d.setMonth(month, date));
1274 return mom;
1275 }
1276
1277 function getSetMonth(value) {
1278 if (value != null) {
1279 setMonth(this, value);
1280 hooks.updateOffset(this, true);
1281 return this;
1282 } else {
1283 return get(this, 'Month');
1284 }
1285 }
1286
1287 function getDaysInMonth() {
1288 return daysInMonth(this.year(), this.month());
1289 }
1290
1291 function monthsShortRegex(isStrict) {
1292 if (this._monthsParseExact) {
1293 if (!hasOwnProp(this, '_monthsRegex')) {
1294 computeMonthsParse.call(this);
1295 }
1296 if (isStrict) {
1297 return this._monthsShortStrictRegex;
1298 } else {
1299 return this._monthsShortRegex;
1300 }
1301 } else {
1302 if (!hasOwnProp(this, '_monthsShortRegex')) {
1303 this._monthsShortRegex = defaultMonthsShortRegex;
1304 }
1305 return this._monthsShortStrictRegex && isStrict
1306 ? this._monthsShortStrictRegex
1307 : this._monthsShortRegex;
1308 }
1309 }
1310
1311 function monthsRegex(isStrict) {
1312 if (this._monthsParseExact) {
1313 if (!hasOwnProp(this, '_monthsRegex')) {
1314 computeMonthsParse.call(this);
1315 }
1316 if (isStrict) {
1317 return this._monthsStrictRegex;
1318 } else {
1319 return this._monthsRegex;
1320 }
1321 } else {
1322 if (!hasOwnProp(this, '_monthsRegex')) {
1323 this._monthsRegex = defaultMonthsRegex;
1324 }
1325 return this._monthsStrictRegex && isStrict
1326 ? this._monthsStrictRegex
1327 : this._monthsRegex;
1328 }
1329 }
1330
1331 function computeMonthsParse() {
1332 function cmpLenRev(a, b) {
1333 return b.length - a.length;
1334 }
1335
1336 var shortPieces = [],
1337 longPieces = [],
1338 mixedPieces = [],
1339 i,
1340 mom,
1341 shortP,
1342 longP;
1343 for (i = 0; i < 12; i++) {
1344 // make the regex if we don't have it already
1345 mom = createUTC([2000, i]);
1346 shortP = regexEscape(this.monthsShort(mom, ''));
1347 longP = regexEscape(this.months(mom, ''));
1348 shortPieces.push(shortP);
1349 longPieces.push(longP);
1350 mixedPieces.push(longP);
1351 mixedPieces.push(shortP);
1352 }
1353 // Sorting makes sure if one month (or abbr) is a prefix of another it
1354 // will match the longer piece.
1355 shortPieces.sort(cmpLenRev);
1356 longPieces.sort(cmpLenRev);
1357 mixedPieces.sort(cmpLenRev);
1358
1359 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1360 this._monthsShortRegex = this._monthsRegex;
1361 this._monthsStrictRegex = new RegExp(
1362 '^(' + longPieces.join('|') + ')',
1363 'i'
1364 );
1365 this._monthsShortStrictRegex = new RegExp(
1366 '^(' + shortPieces.join('|') + ')',
1367 'i'
1368 );
1369 }
1370
1371 function createDate(y, m, d, h, M, s, ms) {
1372 // can't just apply() to create a date:
1373 // https://stackoverflow.com/q/181348
1374 var date;
1375 // the date constructor remaps years 0-99 to 1900-1999
1376 if (y < 100 && y >= 0) {
1377 // preserve leap years using a full 400 year cycle, then reset
1378 date = new Date(y + 400, m, d, h, M, s, ms);
1379 if (isFinite(date.getFullYear())) {
1380 date.setFullYear(y);
1381 }
1382 } else {
1383 date = new Date(y, m, d, h, M, s, ms);
1384 }
1385
1386 return date;
1387 }
1388
1389 function createUTCDate(y) {
1390 var date, args;
1391 // the Date.UTC function remaps years 0-99 to 1900-1999
1392 if (y < 100 && y >= 0) {
1393 args = Array.prototype.slice.call(arguments);
1394 // preserve leap years using a full 400 year cycle, then reset
1395 args[0] = y + 400;
1396 date = new Date(Date.UTC.apply(null, args));
1397 if (isFinite(date.getUTCFullYear())) {
1398 date.setUTCFullYear(y);
1399 }
1400 } else {
1401 date = new Date(Date.UTC.apply(null, arguments));
1402 }
1403
1404 return date;
1405 }
1406
1407 // start-of-first-week - start-of-year
1408 function firstWeekOffset(year, dow, doy) {
1409 var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
1410 fwd = 7 + dow - doy,
1411 // first-week day local weekday -- which local weekday is fwd
1412 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
1413
1414 return -fwdlw + fwd - 1;
1415 }
1416
1417 // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1418 function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
1419 var localWeekday = (7 + weekday - dow) % 7,
1420 weekOffset = firstWeekOffset(year, dow, doy),
1421 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
1422 resYear,
1423 resDayOfYear;
1424
1425 if (dayOfYear <= 0) {
1426 resYear = year - 1;
1427 resDayOfYear = daysInYear(resYear) + dayOfYear;
1428 } else if (dayOfYear > daysInYear(year)) {
1429 resYear = year + 1;
1430 resDayOfYear = dayOfYear - daysInYear(year);
1431 } else {
1432 resYear = year;
1433 resDayOfYear = dayOfYear;
1434 }
1435
1436 return {
1437 year: resYear,
1438 dayOfYear: resDayOfYear,
1439 };
1440 }
1441
1442 function weekOfYear(mom, dow, doy) {
1443 var weekOffset = firstWeekOffset(mom.year(), dow, doy),
1444 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
1445 resWeek,
1446 resYear;
1447
1448 if (week < 1) {
1449 resYear = mom.year() - 1;
1450 resWeek = week + weeksInYear(resYear, dow, doy);
1451 } else if (week > weeksInYear(mom.year(), dow, doy)) {
1452 resWeek = week - weeksInYear(mom.year(), dow, doy);
1453 resYear = mom.year() + 1;
1454 } else {
1455 resYear = mom.year();
1456 resWeek = week;
1457 }
1458
1459 return {
1460 week: resWeek,
1461 year: resYear,
1462 };
1463 }
1464
1465 function weeksInYear(year, dow, doy) {
1466 var weekOffset = firstWeekOffset(year, dow, doy),
1467 weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
1468 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1469 }
1470
1471 // FORMATTING
1472
1473 addFormatToken('w', ['ww', 2], 'wo', 'week');
1474 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
1475
1476 // PARSING
1477
1478 addRegexToken('w', match1to2, match1to2NoLeadingZero);
1479 addRegexToken('ww', match1to2, match2);
1480 addRegexToken('W', match1to2, match1to2NoLeadingZero);
1481 addRegexToken('WW', match1to2, match2);
1482
1483 addWeekParseToken(
1484 ['w', 'ww', 'W', 'WW'],
1485 function (input, week, config, token) {
1486 week[token.substr(0, 1)] = toInt(input);
1487 }
1488 );
1489
1490 // HELPERS
1491
1492 // LOCALES
1493
1494 function localeWeek(mom) {
1495 return weekOfYear(mom, this._week.dow, this._week.doy).week;
1496 }
1497
1498 var defaultLocaleWeek = {
1499 dow: 0, // Sunday is the first day of the week.
1500 doy: 6, // The week that contains Jan 6th is the first week of the year.
1501 };
1502
1503 function localeFirstDayOfWeek() {
1504 return this._week.dow;
1505 }
1506
1507 function localeFirstDayOfYear() {
1508 return this._week.doy;
1509 }
1510
1511 // MOMENTS
1512
1513 function getSetWeek(input) {
1514 var week = this.localeData().week(this);
1515 return input == null ? week : this.add((input - week) * 7, 'd');
1516 }
1517
1518 function getSetISOWeek(input) {
1519 var week = weekOfYear(this, 1, 4).week;
1520 return input == null ? week : this.add((input - week) * 7, 'd');
1521 }
1522
1523 // FORMATTING
1524
1525 addFormatToken('d', 0, 'do', 'day');
1526
1527 addFormatToken('dd', 0, 0, function (format) {
1528 return this.localeData().weekdaysMin(this, format);
1529 });
1530
1531 addFormatToken('ddd', 0, 0, function (format) {
1532 return this.localeData().weekdaysShort(this, format);
1533 });
1534
1535 addFormatToken('dddd', 0, 0, function (format) {
1536 return this.localeData().weekdays(this, format);
1537 });
1538
1539 addFormatToken('e', 0, 0, 'weekday');
1540 addFormatToken('E', 0, 0, 'isoWeekday');
1541
1542 // PARSING
1543
1544 addRegexToken('d', match1to2);
1545 addRegexToken('e', match1to2);
1546 addRegexToken('E', match1to2);
1547 addRegexToken('dd', function (isStrict, locale) {
1548 return locale.weekdaysMinRegex(isStrict);
1549 });
1550 addRegexToken('ddd', function (isStrict, locale) {
1551 return locale.weekdaysShortRegex(isStrict);
1552 });
1553 addRegexToken('dddd', function (isStrict, locale) {
1554 return locale.weekdaysRegex(isStrict);
1555 });
1556
1557 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
1558 var weekday = config._locale.weekdaysParse(input, token, config._strict);
1559 // if we didn't get a weekday name, mark the date as invalid
1560 if (weekday != null) {
1561 week.d = weekday;
1562 } else {
1563 getParsingFlags(config).invalidWeekday = input;
1564 }
1565 });
1566
1567 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
1568 week[token] = toInt(input);
1569 });
1570
1571 // HELPERS
1572
1573 function parseWeekday(input, locale) {
1574 if (typeof input !== 'string') {
1575 return input;
1576 }
1577
1578 if (!isNaN(input)) {
1579 return parseInt(input, 10);
1580 }
1581
1582 input = locale.weekdaysParse(input);
1583 if (typeof input === 'number') {
1584 return input;
1585 }
1586
1587 return null;
1588 }
1589
1590 function parseIsoWeekday(input, locale) {
1591 if (typeof input === 'string') {
1592 return locale.weekdaysParse(input) % 7 || 7;
1593 }
1594 return isNaN(input) ? null : input;
1595 }
1596
1597 // LOCALES
1598 function shiftWeekdays(ws, n) {
1599 return ws.slice(n, 7).concat(ws.slice(0, n));
1600 }
1601
1602 var defaultLocaleWeekdays =
1603 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
1604 defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
1605 defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
1606 defaultWeekdaysRegex = matchWord,
1607 defaultWeekdaysShortRegex = matchWord,
1608 defaultWeekdaysMinRegex = matchWord;
1609
1610 function localeWeekdays(m, format) {
1611 var weekdays = isArray(this._weekdays)
1612 ? this._weekdays
1613 : this._weekdays[
1614 m && m !== true && this._weekdays.isFormat.test(format)
1615 ? 'format'
1616 : 'standalone'
1617 ];
1618 return m === true
1619 ? shiftWeekdays(weekdays, this._week.dow)
1620 : m
1621 ? weekdays[m.day()]
1622 : weekdays;
1623 }
1624
1625 function localeWeekdaysShort(m) {
1626 return m === true
1627 ? shiftWeekdays(this._weekdaysShort, this._week.dow)
1628 : m
1629 ? this._weekdaysShort[m.day()]
1630 : this._weekdaysShort;
1631 }
1632
1633 function localeWeekdaysMin(m) {
1634 return m === true
1635 ? shiftWeekdays(this._weekdaysMin, this._week.dow)
1636 : m
1637 ? this._weekdaysMin[m.day()]
1638 : this._weekdaysMin;
1639 }
1640
1641 function handleStrictParse$1(weekdayName, format, strict) {
1642 var i,
1643 ii,
1644 mom,
1645 llc = weekdayName.toLocaleLowerCase();
1646 if (!this._weekdaysParse) {
1647 this._weekdaysParse = [];
1648 this._shortWeekdaysParse = [];
1649 this._minWeekdaysParse = [];
1650
1651 for (i = 0; i < 7; ++i) {
1652 mom = createUTC([2000, 1]).day(i);
1653 this._minWeekdaysParse[i] = this.weekdaysMin(
1654 mom,
1655 ''
1656 ).toLocaleLowerCase();
1657 this._shortWeekdaysParse[i] = this.weekdaysShort(
1658 mom,
1659 ''
1660 ).toLocaleLowerCase();
1661 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
1662 }
1663 }
1664
1665 if (strict) {
1666 if (format === 'dddd') {
1667 ii = indexOf.call(this._weekdaysParse, llc);
1668 return ii !== -1 ? ii : null;
1669 } else if (format === 'ddd') {
1670 ii = indexOf.call(this._shortWeekdaysParse, llc);
1671 return ii !== -1 ? ii : null;
1672 } else {
1673 ii = indexOf.call(this._minWeekdaysParse, llc);
1674 return ii !== -1 ? ii : null;
1675 }
1676 } else {
1677 if (format === 'dddd') {
1678 ii = indexOf.call(this._weekdaysParse, llc);
1679 if (ii !== -1) {
1680 return ii;
1681 }
1682 ii = indexOf.call(this._shortWeekdaysParse, llc);
1683 if (ii !== -1) {
1684 return ii;
1685 }
1686 ii = indexOf.call(this._minWeekdaysParse, llc);
1687 return ii !== -1 ? ii : null;
1688 } else if (format === 'ddd') {
1689 ii = indexOf.call(this._shortWeekdaysParse, llc);
1690 if (ii !== -1) {
1691 return ii;
1692 }
1693 ii = indexOf.call(this._weekdaysParse, llc);
1694 if (ii !== -1) {
1695 return ii;
1696 }
1697 ii = indexOf.call(this._minWeekdaysParse, llc);
1698 return ii !== -1 ? ii : null;
1699 } else {
1700 ii = indexOf.call(this._minWeekdaysParse, llc);
1701 if (ii !== -1) {
1702 return ii;
1703 }
1704 ii = indexOf.call(this._weekdaysParse, llc);
1705 if (ii !== -1) {
1706 return ii;
1707 }
1708 ii = indexOf.call(this._shortWeekdaysParse, llc);
1709 return ii !== -1 ? ii : null;
1710 }
1711 }
1712 }
1713
1714 function localeWeekdaysParse(weekdayName, format, strict) {
1715 var i, mom, regex;
1716
1717 if (this._weekdaysParseExact) {
1718 return handleStrictParse$1.call(this, weekdayName, format, strict);
1719 }
1720
1721 if (!this._weekdaysParse) {
1722 this._weekdaysParse = [];
1723 this._minWeekdaysParse = [];
1724 this._shortWeekdaysParse = [];
1725 this._fullWeekdaysParse = [];
1726 }
1727
1728 for (i = 0; i < 7; i++) {
1729 // make the regex if we don't have it already
1730
1731 mom = createUTC([2000, 1]).day(i);
1732 if (strict && !this._fullWeekdaysParse[i]) {
1733 this._fullWeekdaysParse[i] = new RegExp(
1734 '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
1735 'i'
1736 );
1737 this._shortWeekdaysParse[i] = new RegExp(
1738 '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
1739 'i'
1740 );
1741 this._minWeekdaysParse[i] = new RegExp(
1742 '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
1743 'i'
1744 );
1745 }
1746 if (!this._weekdaysParse[i]) {
1747 regex =
1748 '^' +
1749 this.weekdays(mom, '') +
1750 '|^' +
1751 this.weekdaysShort(mom, '') +
1752 '|^' +
1753 this.weekdaysMin(mom, '');
1754 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
1755 }
1756 // test the regex
1757 if (
1758 strict &&
1759 format === 'dddd' &&
1760 this._fullWeekdaysParse[i].test(weekdayName)
1761 ) {
1762 return i;
1763 } else if (
1764 strict &&
1765 format === 'ddd' &&
1766 this._shortWeekdaysParse[i].test(weekdayName)
1767 ) {
1768 return i;
1769 } else if (
1770 strict &&
1771 format === 'dd' &&
1772 this._minWeekdaysParse[i].test(weekdayName)
1773 ) {
1774 return i;
1775 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
1776 return i;
1777 }
1778 }
1779 }
1780
1781 // MOMENTS
1782
1783 function getSetDayOfWeek(input) {
1784 if (!this.isValid()) {
1785 return input != null ? this : NaN;
1786 }
1787
1788 var day = get(this, 'Day');
1789 if (input != null) {
1790 input = parseWeekday(input, this.localeData());
1791 return this.add(input - day, 'd');
1792 } else {
1793 return day;
1794 }
1795 }
1796
1797 function getSetLocaleDayOfWeek(input) {
1798 if (!this.isValid()) {
1799 return input != null ? this : NaN;
1800 }
1801 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
1802 return input == null ? weekday : this.add(input - weekday, 'd');
1803 }
1804
1805 function getSetISODayOfWeek(input) {
1806 if (!this.isValid()) {
1807 return input != null ? this : NaN;
1808 }
1809
1810 // behaves the same as moment#day except
1811 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1812 // as a setter, sunday should belong to the previous week.
1813
1814 if (input != null) {
1815 var weekday = parseIsoWeekday(input, this.localeData());
1816 return this.day(this.day() % 7 ? weekday : weekday - 7);
1817 } else {
1818 return this.day() || 7;
1819 }
1820 }
1821
1822 function weekdaysRegex(isStrict) {
1823 if (this._weekdaysParseExact) {
1824 if (!hasOwnProp(this, '_weekdaysRegex')) {
1825 computeWeekdaysParse.call(this);
1826 }
1827 if (isStrict) {
1828 return this._weekdaysStrictRegex;
1829 } else {
1830 return this._weekdaysRegex;
1831 }
1832 } else {
1833 if (!hasOwnProp(this, '_weekdaysRegex')) {
1834 this._weekdaysRegex = defaultWeekdaysRegex;
1835 }
1836 return this._weekdaysStrictRegex && isStrict
1837 ? this._weekdaysStrictRegex
1838 : this._weekdaysRegex;
1839 }
1840 }
1841
1842 function weekdaysShortRegex(isStrict) {
1843 if (this._weekdaysParseExact) {
1844 if (!hasOwnProp(this, '_weekdaysRegex')) {
1845 computeWeekdaysParse.call(this);
1846 }
1847 if (isStrict) {
1848 return this._weekdaysShortStrictRegex;
1849 } else {
1850 return this._weekdaysShortRegex;
1851 }
1852 } else {
1853 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
1854 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
1855 }
1856 return this._weekdaysShortStrictRegex && isStrict
1857 ? this._weekdaysShortStrictRegex
1858 : this._weekdaysShortRegex;
1859 }
1860 }
1861
1862 function weekdaysMinRegex(isStrict) {
1863 if (this._weekdaysParseExact) {
1864 if (!hasOwnProp(this, '_weekdaysRegex')) {
1865 computeWeekdaysParse.call(this);
1866 }
1867 if (isStrict) {
1868 return this._weekdaysMinStrictRegex;
1869 } else {
1870 return this._weekdaysMinRegex;
1871 }
1872 } else {
1873 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
1874 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
1875 }
1876 return this._weekdaysMinStrictRegex && isStrict
1877 ? this._weekdaysMinStrictRegex
1878 : this._weekdaysMinRegex;
1879 }
1880 }
1881
1882 function computeWeekdaysParse() {
1883 function cmpLenRev(a, b) {
1884 return b.length - a.length;
1885 }
1886
1887 var minPieces = [],
1888 shortPieces = [],
1889 longPieces = [],
1890 mixedPieces = [],
1891 i,
1892 mom,
1893 minp,
1894 shortp,
1895 longp;
1896 for (i = 0; i < 7; i++) {
1897 // make the regex if we don't have it already
1898 mom = createUTC([2000, 1]).day(i);
1899 minp = regexEscape(this.weekdaysMin(mom, ''));
1900 shortp = regexEscape(this.weekdaysShort(mom, ''));
1901 longp = regexEscape(this.weekdays(mom, ''));
1902 minPieces.push(minp);
1903 shortPieces.push(shortp);
1904 longPieces.push(longp);
1905 mixedPieces.push(minp);
1906 mixedPieces.push(shortp);
1907 mixedPieces.push(longp);
1908 }
1909 // Sorting makes sure if one weekday (or abbr) is a prefix of another it
1910 // will match the longer piece.
1911 minPieces.sort(cmpLenRev);
1912 shortPieces.sort(cmpLenRev);
1913 longPieces.sort(cmpLenRev);
1914 mixedPieces.sort(cmpLenRev);
1915
1916 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1917 this._weekdaysShortRegex = this._weekdaysRegex;
1918 this._weekdaysMinRegex = this._weekdaysRegex;
1919
1920 this._weekdaysStrictRegex = new RegExp(
1921 '^(' + longPieces.join('|') + ')',
1922 'i'
1923 );
1924 this._weekdaysShortStrictRegex = new RegExp(
1925 '^(' + shortPieces.join('|') + ')',
1926 'i'
1927 );
1928 this._weekdaysMinStrictRegex = new RegExp(
1929 '^(' + minPieces.join('|') + ')',
1930 'i'
1931 );
1932 }
1933
1934 // FORMATTING
1935
1936 function hFormat() {
1937 return this.hours() % 12 || 12;
1938 }
1939
1940 function kFormat() {
1941 return this.hours() || 24;
1942 }
1943
1944 addFormatToken('H', ['HH', 2], 0, 'hour');
1945 addFormatToken('h', ['hh', 2], 0, hFormat);
1946 addFormatToken('k', ['kk', 2], 0, kFormat);
1947
1948 addFormatToken('hmm', 0, 0, function () {
1949 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
1950 });
1951
1952 addFormatToken('hmmss', 0, 0, function () {
1953 return (
1954 '' +
1955 hFormat.apply(this) +
1956 zeroFill(this.minutes(), 2) +
1957 zeroFill(this.seconds(), 2)
1958 );
1959 });
1960
1961 addFormatToken('Hmm', 0, 0, function () {
1962 return '' + this.hours() + zeroFill(this.minutes(), 2);
1963 });
1964
1965 addFormatToken('Hmmss', 0, 0, function () {
1966 return (
1967 '' +
1968 this.hours() +
1969 zeroFill(this.minutes(), 2) +
1970 zeroFill(this.seconds(), 2)
1971 );
1972 });
1973
1974 function meridiem(token, lowercase) {
1975 addFormatToken(token, 0, 0, function () {
1976 return this.localeData().meridiem(
1977 this.hours(),
1978 this.minutes(),
1979 lowercase
1980 );
1981 });
1982 }
1983
1984 meridiem('a', true);
1985 meridiem('A', false);
1986
1987 // PARSING
1988
1989 function matchMeridiem(isStrict, locale) {
1990 return locale._meridiemParse;
1991 }
1992
1993 addRegexToken('a', matchMeridiem);
1994 addRegexToken('A', matchMeridiem);
1995 addRegexToken('H', match1to2, match1to2HasZero);
1996 addRegexToken('h', match1to2, match1to2NoLeadingZero);
1997 addRegexToken('k', match1to2, match1to2NoLeadingZero);
1998 addRegexToken('HH', match1to2, match2);
1999 addRegexToken('hh', match1to2, match2);
2000 addRegexToken('kk', match1to2, match2);
2001
2002 addRegexToken('hmm', match3to4);
2003 addRegexToken('hmmss', match5to6);
2004 addRegexToken('Hmm', match3to4);
2005 addRegexToken('Hmmss', match5to6);
2006
2007 addParseToken(['H', 'HH'], HOUR);
2008 addParseToken(['k', 'kk'], function (input, array, config) {
2009 var kInput = toInt(input);
2010 array[HOUR] = kInput === 24 ? 0 : kInput;
2011 });
2012 addParseToken(['a', 'A'], function (input, array, config) {
2013 config._isPm = config._locale.isPM(input);
2014 config._meridiem = input;
2015 });
2016 addParseToken(['h', 'hh'], function (input, array, config) {
2017 array[HOUR] = toInt(input);
2018 getParsingFlags(config).bigHour = true;
2019 });
2020 addParseToken('hmm', function (input, array, config) {
2021 var pos = input.length - 2;
2022 array[HOUR] = toInt(input.substr(0, pos));
2023 array[MINUTE] = toInt(input.substr(pos));
2024 getParsingFlags(config).bigHour = true;
2025 });
2026 addParseToken('hmmss', function (input, array, config) {
2027 var pos1 = input.length - 4,
2028 pos2 = input.length - 2;
2029 array[HOUR] = toInt(input.substr(0, pos1));
2030 array[MINUTE] = toInt(input.substr(pos1, 2));
2031 array[SECOND] = toInt(input.substr(pos2));
2032 getParsingFlags(config).bigHour = true;
2033 });
2034 addParseToken('Hmm', function (input, array, config) {
2035 var pos = input.length - 2;
2036 array[HOUR] = toInt(input.substr(0, pos));
2037 array[MINUTE] = toInt(input.substr(pos));
2038 });
2039 addParseToken('Hmmss', function (input, array, config) {
2040 var pos1 = input.length - 4,
2041 pos2 = input.length - 2;
2042 array[HOUR] = toInt(input.substr(0, pos1));
2043 array[MINUTE] = toInt(input.substr(pos1, 2));
2044 array[SECOND] = toInt(input.substr(pos2));
2045 });
2046
2047 // LOCALES
2048
2049 function localeIsPM(input) {
2050 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
2051 // Using charAt should be more compatible.
2052 return (input + '').toLowerCase().charAt(0) === 'p';
2053 }
2054
2055 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
2056 // Setting the hour should keep the time, because the user explicitly
2057 // specified which hour they want. So trying to maintain the same hour (in
2058 // a new timezone) makes sense. Adding/subtracting hours does not follow
2059 // this rule.
2060 getSetHour = makeGetSet('Hours', true);
2061
2062 function localeMeridiem(hours, minutes, isLower) {
2063 if (hours > 11) {
2064 return isLower ? 'pm' : 'PM';
2065 } else {
2066 return isLower ? 'am' : 'AM';
2067 }
2068 }
2069
2070 var baseConfig = {
2071 calendar: defaultCalendar,
2072 longDateFormat: defaultLongDateFormat,
2073 invalidDate: defaultInvalidDate,
2074 ordinal: defaultOrdinal,
2075 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
2076 relativeTime: defaultRelativeTime,
2077
2078 months: defaultLocaleMonths,
2079 monthsShort: defaultLocaleMonthsShort,
2080
2081 week: defaultLocaleWeek,
2082
2083 weekdays: defaultLocaleWeekdays,
2084 weekdaysMin: defaultLocaleWeekdaysMin,
2085 weekdaysShort: defaultLocaleWeekdaysShort,
2086
2087 meridiemParse: defaultLocaleMeridiemParse,
2088 };
2089
2090 // internal storage for locale config files
2091 var locales = {},
2092 localeFamilies = {},
2093 globalLocale;
2094
2095 function commonPrefix(arr1, arr2) {
2096 var i,
2097 minl = Math.min(arr1.length, arr2.length);
2098 for (i = 0; i < minl; i += 1) {
2099 if (arr1[i] !== arr2[i]) {
2100 return i;
2101 }
2102 }
2103 return minl;
2104 }
2105
2106 function normalizeLocale(key) {
2107 return key ? key.toLowerCase().replace('_', '-') : key;
2108 }
2109
2110 // pick the locale from the array
2111 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
2112 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
2113 function chooseLocale(names) {
2114 var i = 0,
2115 j,
2116 next,
2117 locale,
2118 split;
2119
2120 while (i < names.length) {
2121 split = normalizeLocale(names[i]).split('-');
2122 j = split.length;
2123 next = normalizeLocale(names[i + 1]);
2124 next = next ? next.split('-') : null;
2125 while (j > 0) {
2126 locale = loadLocale(split.slice(0, j).join('-'));
2127 if (locale) {
2128 return locale;
2129 }
2130 if (
2131 next &&
2132 next.length >= j &&
2133 commonPrefix(split, next) >= j - 1
2134 ) {
2135 //the next array item is better than a shallower substring of this one
2136 break;
2137 }
2138 j--;
2139 }
2140 i++;
2141 }
2142 return globalLocale;
2143 }
2144
2145 function isLocaleNameSane(name) {
2146 // Prevent names that look like filesystem paths, i.e contain '/' or '\'
2147 // Ensure name is available and function returns boolean
2148 return !!(name && name.match('^[^/\\\\]*$'));
2149 }
2150
2151 function loadLocale(name) {
2152 var oldLocale = null,
2153 aliasedRequire;
2154 // TODO: Find a better way to register and load all the locales in Node
2155 if (
2156 locales[name] === undefined &&
2157 typeof module !== 'undefined' &&
2158 module &&
2159 module.exports &&
2160 isLocaleNameSane(name)
2161 ) {
2162 try {
2163 oldLocale = globalLocale._abbr;
2164 aliasedRequire = require;
2165 aliasedRequire('./locale/' + name);
2166 getSetGlobalLocale(oldLocale);
2167 } catch (e) {
2168 // mark as not found to avoid repeating expensive file require call causing high CPU
2169 // when trying to find en-US, en_US, en-us for every format call
2170 locales[name] = null; // null means not found
2171 }
2172 }
2173 return locales[name];
2174 }
2175
2176 // This function will load locale and then set the global locale. If
2177 // no arguments are passed in, it will simply return the current global
2178 // locale key.
2179 function getSetGlobalLocale(key, values) {
2180 var data;
2181 if (key) {
2182 if (isUndefined(values)) {
2183 data = getLocale(key);
2184 } else {
2185 data = defineLocale(key, values);
2186 }
2187
2188 if (data) {
2189 // moment.duration._locale = moment._locale = data;
2190 globalLocale = data;
2191 } else {
2192 if (typeof console !== 'undefined' && console.warn) {
2193 //warn user if arguments are passed but the locale could not be set
2194 console.warn(
2195 'Locale ' + key + ' not found. Did you forget to load it?'
2196 );
2197 }
2198 }
2199 }
2200
2201 return globalLocale._abbr;
2202 }
2203
2204 function defineLocale(name, config) {
2205 if (config !== null) {
2206 var locale,
2207 parentConfig = baseConfig;
2208 config.abbr = name;
2209 if (locales[name] != null) {
2210 deprecateSimple(
2211 'defineLocaleOverride',
2212 'use moment.updateLocale(localeName, config) to change ' +
2213 'an existing locale. moment.defineLocale(localeName, ' +
2214 'config) should only be used for creating a new locale ' +
2215 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
2216 );
2217 parentConfig = locales[name]._config;
2218 } else if (config.parentLocale != null) {
2219 if (locales[config.parentLocale] != null) {
2220 parentConfig = locales[config.parentLocale]._config;
2221 } else {
2222 locale = loadLocale(config.parentLocale);
2223 if (locale != null) {
2224 parentConfig = locale._config;
2225 } else {
2226 if (!localeFamilies[config.parentLocale]) {
2227 localeFamilies[config.parentLocale] = [];
2228 }
2229 localeFamilies[config.parentLocale].push({
2230 name: name,
2231 config: config,
2232 });
2233 return null;
2234 }
2235 }
2236 }
2237 locales[name] = new Locale(mergeConfigs(parentConfig, config));
2238
2239 if (localeFamilies[name]) {
2240 localeFamilies[name].forEach(function (x) {
2241 defineLocale(x.name, x.config);
2242 });
2243 }
2244
2245 // backwards compat for now: also set the locale
2246 // make sure we set the locale AFTER all child locales have been
2247 // created, so we won't end up with the child locale set.
2248 getSetGlobalLocale(name);
2249
2250 return locales[name];
2251 } else {
2252 // useful for testing
2253 delete locales[name];
2254 return null;
2255 }
2256 }
2257
2258 function updateLocale(name, config) {
2259 if (config != null) {
2260 var locale,
2261 tmpLocale,
2262 parentConfig = baseConfig;
2263
2264 if (locales[name] != null && locales[name].parentLocale != null) {
2265 // Update existing child locale in-place to avoid memory-leaks
2266 locales[name].set(mergeConfigs(locales[name]._config, config));
2267 } else {
2268 // MERGE
2269 tmpLocale = loadLocale(name);
2270 if (tmpLocale != null) {
2271 parentConfig = tmpLocale._config;
2272 }
2273 config = mergeConfigs(parentConfig, config);
2274 if (tmpLocale == null) {
2275 // updateLocale is called for creating a new locale
2276 // Set abbr so it will have a name (getters return
2277 // undefined otherwise).
2278 config.abbr = name;
2279 }
2280 locale = new Locale(config);
2281 locale.parentLocale = locales[name];
2282 locales[name] = locale;
2283 }
2284
2285 // backwards compat for now: also set the locale
2286 getSetGlobalLocale(name);
2287 } else {
2288 // pass null for config to unupdate, useful for tests
2289 if (locales[name] != null) {
2290 if (locales[name].parentLocale != null) {
2291 locales[name] = locales[name].parentLocale;
2292 if (name === getSetGlobalLocale()) {
2293 getSetGlobalLocale(name);
2294 }
2295 } else if (locales[name] != null) {
2296 delete locales[name];
2297 }
2298 }
2299 }
2300 return locales[name];
2301 }
2302
2303 // returns locale data
2304 function getLocale(key) {
2305 var locale;
2306
2307 if (key && key._locale && key._locale._abbr) {
2308 key = key._locale._abbr;
2309 }
2310
2311 if (!key) {
2312 return globalLocale;
2313 }
2314
2315 if (!isArray(key)) {
2316 //short-circuit everything else
2317 locale = loadLocale(key);
2318 if (locale) {
2319 return locale;
2320 }
2321 key = [key];
2322 }
2323
2324 return chooseLocale(key);
2325 }
2326
2327 function listLocales() {
2328 return keys(locales);
2329 }
2330
2331 function checkOverflow(m) {
2332 var overflow,
2333 a = m._a;
2334
2335 if (a && getParsingFlags(m).overflow === -2) {
2336 overflow =
2337 a[MONTH] < 0 || a[MONTH] > 11
2338 ? MONTH
2339 : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
2340 ? DATE
2341 : a[HOUR] < 0 ||
2342 a[HOUR] > 24 ||
2343 (a[HOUR] === 24 &&
2344 (a[MINUTE] !== 0 ||
2345 a[SECOND] !== 0 ||
2346 a[MILLISECOND] !== 0))
2347 ? HOUR
2348 : a[MINUTE] < 0 || a[MINUTE] > 59
2349 ? MINUTE
2350 : a[SECOND] < 0 || a[SECOND] > 59
2351 ? SECOND
2352 : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
2353 ? MILLISECOND
2354 : -1;
2355
2356 if (
2357 getParsingFlags(m)._overflowDayOfYear &&
2358 (overflow < YEAR || overflow > DATE)
2359 ) {
2360 overflow = DATE;
2361 }
2362 if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
2363 overflow = WEEK;
2364 }
2365 if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
2366 overflow = WEEKDAY;
2367 }
2368
2369 getParsingFlags(m).overflow = overflow;
2370 }
2371
2372 return m;
2373 }
2374
2375 // iso 8601 regex
2376 // 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)
2377 var extendedIsoRegex =
2378 /^\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)?)?$/,
2379 basicIsoRegex =
2380 /^\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)?)?$/,
2381 tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
2382 isoDates = [
2383 ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
2384 ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
2385 ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
2386 ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
2387 ['YYYY-DDD', /\d{4}-\d{3}/],
2388 ['YYYY-MM', /\d{4}-\d\d/, false],
2389 ['YYYYYYMMDD', /[+-]\d{10}/],
2390 ['YYYYMMDD', /\d{8}/],
2391 ['GGGG[W]WWE', /\d{4}W\d{3}/],
2392 ['GGGG[W]WW', /\d{4}W\d{2}/, false],
2393 ['YYYYDDD', /\d{7}/],
2394 ['YYYYMM', /\d{6}/, false],
2395 ['YYYY', /\d{4}/, false],
2396 ],
2397 // iso time formats and regexes
2398 isoTimes = [
2399 ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
2400 ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
2401 ['HH:mm:ss', /\d\d:\d\d:\d\d/],
2402 ['HH:mm', /\d\d:\d\d/],
2403 ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
2404 ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
2405 ['HHmmss', /\d\d\d\d\d\d/],
2406 ['HHmm', /\d\d\d\d/],
2407 ['HH', /\d\d/],
2408 ],
2409 aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
2410 // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
2411 rfc2822 =
2412 /^(?:(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}))$/,
2413 obsOffsets = {
2414 UT: 0,
2415 GMT: 0,
2416 EDT: -4 * 60,
2417 EST: -5 * 60,
2418 CDT: -5 * 60,
2419 CST: -6 * 60,
2420 MDT: -6 * 60,
2421 MST: -7 * 60,
2422 PDT: -7 * 60,
2423 PST: -8 * 60,
2424 };
2425
2426 // date from iso format
2427 function configFromISO(config) {
2428 var i,
2429 l,
2430 string = config._i,
2431 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
2432 allowTime,
2433 dateFormat,
2434 timeFormat,
2435 tzFormat,
2436 isoDatesLen = isoDates.length,
2437 isoTimesLen = isoTimes.length;
2438
2439 if (match) {
2440 getParsingFlags(config).iso = true;
2441 for (i = 0, l = isoDatesLen; i < l; i++) {
2442 if (isoDates[i][1].exec(match[1])) {
2443 dateFormat = isoDates[i][0];
2444 allowTime = isoDates[i][2] !== false;
2445 break;
2446 }
2447 }
2448 if (dateFormat == null) {
2449 config._isValid = false;
2450 return;
2451 }
2452 if (match[3]) {
2453 for (i = 0, l = isoTimesLen; i < l; i++) {
2454 if (isoTimes[i][1].exec(match[3])) {
2455 // match[2] should be 'T' or space
2456 timeFormat = (match[2] || ' ') + isoTimes[i][0];
2457 break;
2458 }
2459 }
2460 if (timeFormat == null) {
2461 config._isValid = false;
2462 return;
2463 }
2464 }
2465 if (!allowTime && timeFormat != null) {
2466 config._isValid = false;
2467 return;
2468 }
2469 if (match[4]) {
2470 if (tzRegex.exec(match[4])) {
2471 tzFormat = 'Z';
2472 } else {
2473 config._isValid = false;
2474 return;
2475 }
2476 }
2477 config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
2478 configFromStringAndFormat(config);
2479 } else {
2480 config._isValid = false;
2481 }
2482 }
2483
2484 function extractFromRFC2822Strings(
2485 yearStr,
2486 monthStr,
2487 dayStr,
2488 hourStr,
2489 minuteStr,
2490 secondStr
2491 ) {
2492 var result = [
2493 untruncateYear(yearStr),
2494 defaultLocaleMonthsShort.indexOf(monthStr),
2495 parseInt(dayStr, 10),
2496 parseInt(hourStr, 10),
2497 parseInt(minuteStr, 10),
2498 ];
2499
2500 if (secondStr) {
2501 result.push(parseInt(secondStr, 10));
2502 }
2503
2504 return result;
2505 }
2506
2507 function untruncateYear(yearStr) {
2508 var year = parseInt(yearStr, 10);
2509 if (year <= 49) {
2510 return 2000 + year;
2511 } else if (year <= 999) {
2512 return 1900 + year;
2513 }
2514 return year;
2515 }
2516
2517 function preprocessRFC2822(s) {
2518 // Remove comments and folding whitespace and replace multiple-spaces with a single space
2519 return s
2520 .replace(/\([^()]*\)|[\n\t]/g, ' ')
2521 .replace(/(\s\s+)/g, ' ')
2522 .replace(/^\s\s*/, '')
2523 .replace(/\s\s*$/, '');
2524 }
2525
2526 function checkWeekday(weekdayStr, parsedInput, config) {
2527 if (weekdayStr) {
2528 // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
2529 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
2530 weekdayActual = new Date(
2531 parsedInput[0],
2532 parsedInput[1],
2533 parsedInput[2]
2534 ).getDay();
2535 if (weekdayProvided !== weekdayActual) {
2536 getParsingFlags(config).weekdayMismatch = true;
2537 config._isValid = false;
2538 return false;
2539 }
2540 }
2541 return true;
2542 }
2543
2544 function calculateOffset(obsOffset, militaryOffset, numOffset) {
2545 if (obsOffset) {
2546 return obsOffsets[obsOffset];
2547 } else if (militaryOffset) {
2548 // the only allowed military tz is Z
2549 return 0;
2550 } else {
2551 var hm = parseInt(numOffset, 10),
2552 m = hm % 100,
2553 h = (hm - m) / 100;
2554 return h * 60 + m;
2555 }
2556 }
2557
2558 // date and time from ref 2822 format
2559 function configFromRFC2822(config) {
2560 var match = rfc2822.exec(preprocessRFC2822(config._i)),
2561 parsedArray;
2562 if (match) {
2563 parsedArray = extractFromRFC2822Strings(
2564 match[4],
2565 match[3],
2566 match[2],
2567 match[5],
2568 match[6],
2569 match[7]
2570 );
2571 if (!checkWeekday(match[1], parsedArray, config)) {
2572 return;
2573 }
2574
2575 config._a = parsedArray;
2576 config._tzm = calculateOffset(match[8], match[9], match[10]);
2577
2578 config._d = createUTCDate.apply(null, config._a);
2579 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2580
2581 getParsingFlags(config).rfc2822 = true;
2582 } else {
2583 config._isValid = false;
2584 }
2585 }
2586
2587 // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
2588 function configFromString(config) {
2589 var matched = aspNetJsonRegex.exec(config._i);
2590 if (matched !== null) {
2591 config._d = new Date(+matched[1]);
2592 return;
2593 }
2594
2595 configFromISO(config);
2596 if (config._isValid === false) {
2597 delete config._isValid;
2598 } else {
2599 return;
2600 }
2601
2602 configFromRFC2822(config);
2603 if (config._isValid === false) {
2604 delete config._isValid;
2605 } else {
2606 return;
2607 }
2608
2609 if (config._strict) {
2610 config._isValid = false;
2611 } else {
2612 // Final attempt, use Input Fallback
2613 hooks.createFromInputFallback(config);
2614 }
2615 }
2616
2617 hooks.createFromInputFallback = deprecate(
2618 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
2619 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
2620 'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
2621 function (config) {
2622 config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
2623 }
2624 );
2625
2626 // Pick the first defined of two or three arguments.
2627 function defaults(a, b, c) {
2628 if (a != null) {
2629 return a;
2630 }
2631 if (b != null) {
2632 return b;
2633 }
2634 return c;
2635 }
2636
2637 function currentDateArray(config) {
2638 // hooks is actually the exported moment object
2639 var nowValue = new Date(hooks.now());
2640 if (config._useUTC) {
2641 return [
2642 nowValue.getUTCFullYear(),
2643 nowValue.getUTCMonth(),
2644 nowValue.getUTCDate(),
2645 ];
2646 }
2647 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
2648 }
2649
2650 // convert an array to a date.
2651 // the array should mirror the parameters below
2652 // note: all values past the year are optional and will default to the lowest possible value.
2653 // [year, month, day , hour, minute, second, millisecond]
2654 function configFromArray(config) {
2655 var i,
2656 date,
2657 input = [],
2658 currentDate,
2659 expectedWeekday,
2660 yearToUse;
2661
2662 if (config._d) {
2663 return;
2664 }
2665
2666 currentDate = currentDateArray(config);
2667
2668 //compute day of the year from weeks and weekdays
2669 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
2670 dayOfYearFromWeekInfo(config);
2671 }
2672
2673 //if the day of the year is set, figure out what it is
2674 if (config._dayOfYear != null) {
2675 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
2676
2677 if (
2678 config._dayOfYear > daysInYear(yearToUse) ||
2679 config._dayOfYear === 0
2680 ) {
2681 getParsingFlags(config)._overflowDayOfYear = true;
2682 }
2683
2684 date = createUTCDate(yearToUse, 0, config._dayOfYear);
2685 config._a[MONTH] = date.getUTCMonth();
2686 config._a[DATE] = date.getUTCDate();
2687 }
2688
2689 // Default to current date.
2690 // * if no year, month, day of month are given, default to today
2691 // * if day of month is given, default month and year
2692 // * if month is given, default only year
2693 // * if year is given, don't default anything
2694 for (i = 0; i < 3 && config._a[i] == null; ++i) {
2695 config._a[i] = input[i] = currentDate[i];
2696 }
2697
2698 // Zero out whatever was not defaulted, including time
2699 for (; i < 7; i++) {
2700 config._a[i] = input[i] =
2701 config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
2702 }
2703
2704 // Check for 24:00:00.000
2705 if (
2706 config._a[HOUR] === 24 &&
2707 config._a[MINUTE] === 0 &&
2708 config._a[SECOND] === 0 &&
2709 config._a[MILLISECOND] === 0
2710 ) {
2711 config._nextDay = true;
2712 config._a[HOUR] = 0;
2713 }
2714
2715 config._d = (config._useUTC ? createUTCDate : createDate).apply(
2716 null,
2717 input
2718 );
2719 expectedWeekday = config._useUTC
2720 ? config._d.getUTCDay()
2721 : config._d.getDay();
2722
2723 // Apply timezone offset from input. The actual utcOffset can be changed
2724 // with parseZone.
2725 if (config._tzm != null) {
2726 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2727 }
2728
2729 if (config._nextDay) {
2730 config._a[HOUR] = 24;
2731 }
2732
2733 // check for mismatching day of week
2734 if (
2735 config._w &&
2736 typeof config._w.d !== 'undefined' &&
2737 config._w.d !== expectedWeekday
2738 ) {
2739 getParsingFlags(config).weekdayMismatch = true;
2740 }
2741 }
2742
2743 function dayOfYearFromWeekInfo(config) {
2744 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
2745
2746 w = config._w;
2747 if (w.GG != null || w.W != null || w.E != null) {
2748 dow = 1;
2749 doy = 4;
2750
2751 // TODO: We need to take the current isoWeekYear, but that depends on
2752 // how we interpret now (local, utc, fixed offset). So create
2753 // a now version of current config (take local/utc/offset flags, and
2754 // create now).
2755 weekYear = defaults(
2756 w.GG,
2757 config._a[YEAR],
2758 weekOfYear(createLocal(), 1, 4).year
2759 );
2760 week = defaults(w.W, 1);
2761 weekday = defaults(w.E, 1);
2762 if (weekday < 1 || weekday > 7) {
2763 weekdayOverflow = true;
2764 }
2765 } else {
2766 dow = config._locale._week.dow;
2767 doy = config._locale._week.doy;
2768
2769 curWeek = weekOfYear(createLocal(), dow, doy);
2770
2771 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
2772
2773 // Default to current week.
2774 week = defaults(w.w, curWeek.week);
2775
2776 if (w.d != null) {
2777 // weekday -- low day numbers are considered next week
2778 weekday = w.d;
2779 if (weekday < 0 || weekday > 6) {
2780 weekdayOverflow = true;
2781 }
2782 } else if (w.e != null) {
2783 // local weekday -- counting starts from beginning of week
2784 weekday = w.e + dow;
2785 if (w.e < 0 || w.e > 6) {
2786 weekdayOverflow = true;
2787 }
2788 } else {
2789 // default to beginning of week
2790 weekday = dow;
2791 }
2792 }
2793 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
2794 getParsingFlags(config)._overflowWeeks = true;
2795 } else if (weekdayOverflow != null) {
2796 getParsingFlags(config)._overflowWeekday = true;
2797 } else {
2798 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
2799 config._a[YEAR] = temp.year;
2800 config._dayOfYear = temp.dayOfYear;
2801 }
2802 }
2803
2804 // constant that refers to the ISO standard
2805 hooks.ISO_8601 = function () {};
2806
2807 // constant that refers to the RFC 2822 form
2808 hooks.RFC_2822 = function () {};
2809
2810 // date from string and format string
2811 function configFromStringAndFormat(config) {
2812 // TODO: Move this to another part of the creation flow to prevent circular deps
2813 if (config._f === hooks.ISO_8601) {
2814 configFromISO(config);
2815 return;
2816 }
2817 if (config._f === hooks.RFC_2822) {
2818 configFromRFC2822(config);
2819 return;
2820 }
2821 config._a = [];
2822 getParsingFlags(config).empty = true;
2823
2824 // This array is used to make a Date, either with `new Date` or `Date.UTC`
2825 var string = '' + config._i,
2826 i,
2827 parsedInput,
2828 tokens,
2829 token,
2830 skipped,
2831 stringLength = string.length,
2832 totalParsedInputLength = 0,
2833 era,
2834 tokenLen;
2835
2836 tokens =
2837 expandFormat(config._f, config._locale).match(formattingTokens) || [];
2838 tokenLen = tokens.length;
2839 for (i = 0; i < tokenLen; i++) {
2840 token = tokens[i];
2841 parsedInput = (string.match(getParseRegexForToken(token, config)) ||
2842 [])[0];
2843 if (parsedInput) {
2844 skipped = string.substr(0, string.indexOf(parsedInput));
2845 if (skipped.length > 0) {
2846 getParsingFlags(config).unusedInput.push(skipped);
2847 }
2848 string = string.slice(
2849 string.indexOf(parsedInput) + parsedInput.length
2850 );
2851 totalParsedInputLength += parsedInput.length;
2852 }
2853 // don't parse if it's not a known token
2854 if (formatTokenFunctions[token]) {
2855 if (parsedInput) {
2856 getParsingFlags(config).empty = false;
2857 } else {
2858 getParsingFlags(config).unusedTokens.push(token);
2859 }
2860 addTimeToArrayFromToken(token, parsedInput, config);
2861 } else if (config._strict && !parsedInput) {
2862 getParsingFlags(config).unusedTokens.push(token);
2863 }
2864 }
2865
2866 // add remaining unparsed input length to the string
2867 getParsingFlags(config).charsLeftOver =
2868 stringLength - totalParsedInputLength;
2869 if (string.length > 0) {
2870 getParsingFlags(config).unusedInput.push(string);
2871 }
2872
2873 // clear _12h flag if hour is <= 12
2874 if (
2875 config._a[HOUR] <= 12 &&
2876 getParsingFlags(config).bigHour === true &&
2877 config._a[HOUR] > 0
2878 ) {
2879 getParsingFlags(config).bigHour = undefined;
2880 }
2881
2882 getParsingFlags(config).parsedDateParts = config._a.slice(0);
2883 getParsingFlags(config).meridiem = config._meridiem;
2884 // handle meridiem
2885 config._a[HOUR] = meridiemFixWrap(
2886 config._locale,
2887 config._a[HOUR],
2888 config._meridiem
2889 );
2890
2891 // handle era
2892 era = getParsingFlags(config).era;
2893 if (era !== null) {
2894 config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
2895 }
2896
2897 configFromArray(config);
2898 checkOverflow(config);
2899 }
2900
2901 function meridiemFixWrap(locale, hour, meridiem) {
2902 var isPm;
2903
2904 if (meridiem == null) {
2905 // nothing to do
2906 return hour;
2907 }
2908 if (locale.meridiemHour != null) {
2909 return locale.meridiemHour(hour, meridiem);
2910 } else if (locale.isPM != null) {
2911 // Fallback
2912 isPm = locale.isPM(meridiem);
2913 if (isPm && hour < 12) {
2914 hour += 12;
2915 }
2916 if (!isPm && hour === 12) {
2917 hour = 0;
2918 }
2919 return hour;
2920 } else {
2921 // this is not supposed to happen
2922 return hour;
2923 }
2924 }
2925
2926 // date from string and array of format strings
2927 function configFromStringAndArray(config) {
2928 var tempConfig,
2929 bestMoment,
2930 scoreToBeat,
2931 i,
2932 currentScore,
2933 validFormatFound,
2934 bestFormatIsValid = false,
2935 configfLen = config._f.length;
2936
2937 if (configfLen === 0) {
2938 getParsingFlags(config).invalidFormat = true;
2939 config._d = new Date(NaN);
2940 return;
2941 }
2942
2943 for (i = 0; i < configfLen; i++) {
2944 currentScore = 0;
2945 validFormatFound = false;
2946 tempConfig = copyConfig({}, config);
2947 if (config._useUTC != null) {
2948 tempConfig._useUTC = config._useUTC;
2949 }
2950 tempConfig._f = config._f[i];
2951 configFromStringAndFormat(tempConfig);
2952
2953 if (isValid(tempConfig)) {
2954 validFormatFound = true;
2955 }
2956
2957 // if there is any input that was not parsed add a penalty for that format
2958 currentScore += getParsingFlags(tempConfig).charsLeftOver;
2959
2960 //or tokens
2961 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
2962
2963 getParsingFlags(tempConfig).score = currentScore;
2964
2965 if (!bestFormatIsValid) {
2966 if (
2967 scoreToBeat == null ||
2968 currentScore < scoreToBeat ||
2969 validFormatFound
2970 ) {
2971 scoreToBeat = currentScore;
2972 bestMoment = tempConfig;
2973 if (validFormatFound) {
2974 bestFormatIsValid = true;
2975 }
2976 }
2977 } else {
2978 if (currentScore < scoreToBeat) {
2979 scoreToBeat = currentScore;
2980 bestMoment = tempConfig;
2981 }
2982 }
2983 }
2984
2985 extend(config, bestMoment || tempConfig);
2986 }
2987
2988 function configFromObject(config) {
2989 if (config._d) {
2990 return;
2991 }
2992
2993 var i = normalizeObjectUnits(config._i),
2994 dayOrDate = i.day === undefined ? i.date : i.day;
2995 config._a = map(
2996 [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
2997 function (obj) {
2998 return obj && parseInt(obj, 10);
2999 }
3000 );
3001
3002 configFromArray(config);
3003 }
3004
3005 function createFromConfig(config) {
3006 var res = new Moment(checkOverflow(prepareConfig(config)));
3007 if (res._nextDay) {
3008 // Adding is smart enough around DST
3009 res.add(1, 'd');
3010 res._nextDay = undefined;
3011 }
3012
3013 return res;
3014 }
3015
3016 function prepareConfig(config) {
3017 var input = config._i,
3018 format = config._f;
3019
3020 config._locale = config._locale || getLocale(config._l);
3021
3022 if (input === null || (format === undefined && input === '')) {
3023 return createInvalid({ nullInput: true });
3024 }
3025
3026 if (typeof input === 'string') {
3027 config._i = input = config._locale.preparse(input);
3028 }
3029
3030 if (isMoment(input)) {
3031 return new Moment(checkOverflow(input));
3032 } else if (isDate(input)) {
3033 config._d = input;
3034 } else if (isArray(format)) {
3035 configFromStringAndArray(config);
3036 } else if (format) {
3037 configFromStringAndFormat(config);
3038 } else {
3039 configFromInput(config);
3040 }
3041
3042 if (!isValid(config)) {
3043 config._d = null;
3044 }
3045
3046 return config;
3047 }
3048
3049 function configFromInput(config) {
3050 var input = config._i;
3051 if (isUndefined(input)) {
3052 config._d = new Date(hooks.now());
3053 } else if (isDate(input)) {
3054 config._d = new Date(input.valueOf());
3055 } else if (typeof input === 'string') {
3056 configFromString(config);
3057 } else if (isArray(input)) {
3058 config._a = map(input.slice(0), function (obj) {
3059 return parseInt(obj, 10);
3060 });
3061 configFromArray(config);
3062 } else if (isObject(input)) {
3063 configFromObject(config);
3064 } else if (isNumber(input)) {
3065 // from milliseconds
3066 config._d = new Date(input);
3067 } else {
3068 hooks.createFromInputFallback(config);
3069 }
3070 }
3071
3072 function createLocalOrUTC(input, format, locale, strict, isUTC) {
3073 var c = {};
3074
3075 if (format === true || format === false) {
3076 strict = format;
3077 format = undefined;
3078 }
3079
3080 if (locale === true || locale === false) {
3081 strict = locale;
3082 locale = undefined;
3083 }
3084
3085 if (
3086 (isObject(input) && isObjectEmpty(input)) ||
3087 (isArray(input) && input.length === 0)
3088 ) {
3089 input = undefined;
3090 }
3091 // object construction must be done this way.
3092 // https://github.com/moment/moment/issues/1423
3093 c._isAMomentObject = true;
3094 c._useUTC = c._isUTC = isUTC;
3095 c._l = locale;
3096 c._i = input;
3097 c._f = format;
3098 c._strict = strict;
3099
3100 return createFromConfig(c);
3101 }
3102
3103 function createLocal(input, format, locale, strict) {
3104 return createLocalOrUTC(input, format, locale, strict, false);
3105 }
3106
3107 var prototypeMin = deprecate(
3108 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
3109 function () {
3110 var other = createLocal.apply(null, arguments);
3111 if (this.isValid() && other.isValid()) {
3112 return other < this ? this : other;
3113 } else {
3114 return createInvalid();
3115 }
3116 }
3117 ),
3118 prototypeMax = deprecate(
3119 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
3120 function () {
3121 var other = createLocal.apply(null, arguments);
3122 if (this.isValid() && other.isValid()) {
3123 return other > this ? this : other;
3124 } else {
3125 return createInvalid();
3126 }
3127 }
3128 );
3129
3130 // Pick a moment m from moments so that m[fn](other) is true for all
3131 // other. This relies on the function fn to be transitive.
3132 //
3133 // moments should either be an array of moment objects or an array, whose
3134 // first element is an array of moment objects.
3135 function pickBy(fn, moments) {
3136 var res, i;
3137 if (moments.length === 1 && isArray(moments[0])) {
3138 moments = moments[0];
3139 }
3140 if (!moments.length) {
3141 return createLocal();
3142 }
3143 res = moments[0];
3144 for (i = 1; i < moments.length; ++i) {
3145 if (!moments[i].isValid() || moments[i][fn](res)) {
3146 res = moments[i];
3147 }
3148 }
3149 return res;
3150 }
3151
3152 // TODO: Use [].sort instead?
3153 function min() {
3154 var args = [].slice.call(arguments, 0);
3155
3156 return pickBy('isBefore', args);
3157 }
3158
3159 function max() {
3160 var args = [].slice.call(arguments, 0);
3161
3162 return pickBy('isAfter', args);
3163 }
3164
3165 var now = function () {
3166 return Date.now ? Date.now() : +new Date();
3167 };
3168
3169 var ordering = [
3170 'year',
3171 'quarter',
3172 'month',
3173 'week',
3174 'day',
3175 'hour',
3176 'minute',
3177 'second',
3178 'millisecond',
3179 ];
3180
3181 function isDurationValid(m) {
3182 var key,
3183 unitHasDecimal = false,
3184 i,
3185 orderLen = ordering.length;
3186 for (key in m) {
3187 if (
3188 hasOwnProp(m, key) &&
3189 !(
3190 indexOf.call(ordering, key) !== -1 &&
3191 (m[key] == null || !isNaN(m[key]))
3192 )
3193 ) {
3194 return false;
3195 }
3196 }
3197
3198 for (i = 0; i < orderLen; ++i) {
3199 if (m[ordering[i]]) {
3200 if (unitHasDecimal) {
3201 return false; // only allow non-integers for smallest unit
3202 }
3203 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
3204 unitHasDecimal = true;
3205 }
3206 }
3207 }
3208
3209 return true;
3210 }
3211
3212 function isValid$1() {
3213 return this._isValid;
3214 }
3215
3216 function createInvalid$1() {
3217 return createDuration(NaN);
3218 }
3219
3220 function Duration(duration) {
3221 var normalizedInput = normalizeObjectUnits(duration),
3222 years = normalizedInput.year || 0,
3223 quarters = normalizedInput.quarter || 0,
3224 months = normalizedInput.month || 0,
3225 weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
3226 days = normalizedInput.day || 0,
3227 hours = normalizedInput.hour || 0,
3228 minutes = normalizedInput.minute || 0,
3229 seconds = normalizedInput.second || 0,
3230 milliseconds = normalizedInput.millisecond || 0;
3231
3232 this._isValid = isDurationValid(normalizedInput);
3233
3234 // representation for dateAddRemove
3235 this._milliseconds =
3236 +milliseconds +
3237 seconds * 1e3 + // 1000
3238 minutes * 6e4 + // 1000 * 60
3239 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
3240 // Because of dateAddRemove treats 24 hours as different from a
3241 // day when working around DST, we need to store them separately
3242 this._days = +days + weeks * 7;
3243 // It is impossible to translate months into days without knowing
3244 // which months you are are talking about, so we have to store
3245 // it separately.
3246 this._months = +months + quarters * 3 + years * 12;
3247
3248 this._data = {};
3249
3250 this._locale = getLocale();
3251
3252 this._bubble();
3253 }
3254
3255 function isDuration(obj) {
3256 return obj instanceof Duration;
3257 }
3258
3259 function absRound(number) {
3260 if (number < 0) {
3261 return Math.round(-1 * number) * -1;
3262 } else {
3263 return Math.round(number);
3264 }
3265 }
3266
3267 // compare two arrays, return the number of differences
3268 function compareArrays(array1, array2, dontConvert) {
3269 var len = Math.min(array1.length, array2.length),
3270 lengthDiff = Math.abs(array1.length - array2.length),
3271 diffs = 0,
3272 i;
3273 for (i = 0; i < len; i++) {
3274 if (
3275 (dontConvert && array1[i] !== array2[i]) ||
3276 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
3277 ) {
3278 diffs++;
3279 }
3280 }
3281 return diffs + lengthDiff;
3282 }
3283
3284 // FORMATTING
3285
3286 function offset(token, separator) {
3287 addFormatToken(token, 0, 0, function () {
3288 var offset = this.utcOffset(),
3289 sign = '+';
3290 if (offset < 0) {
3291 offset = -offset;
3292 sign = '-';
3293 }
3294 return (
3295 sign +
3296 zeroFill(~~(offset / 60), 2) +
3297 separator +
3298 zeroFill(~~offset % 60, 2)
3299 );
3300 });
3301 }
3302
3303 offset('Z', ':');
3304 offset('ZZ', '');
3305
3306 // PARSING
3307
3308 addRegexToken('Z', matchShortOffset);
3309 addRegexToken('ZZ', matchShortOffset);
3310 addParseToken(['Z', 'ZZ'], function (input, array, config) {
3311 config._useUTC = true;
3312 config._tzm = offsetFromString(matchShortOffset, input);
3313 });
3314
3315 // HELPERS
3316
3317 // timezone chunker
3318 // '+10:00' > ['10', '00']
3319 // '-1530' > ['-15', '30']
3320 var chunkOffset = /([\+\-]|\d\d)/gi;
3321
3322 function offsetFromString(matcher, string) {
3323 var matches = (string || '').match(matcher),
3324 chunk,
3325 parts,
3326 minutes;
3327
3328 if (matches === null) {
3329 return null;
3330 }
3331
3332 chunk = matches[matches.length - 1] || [];
3333 parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
3334 minutes = +(parts[1] * 60) + toInt(parts[2]);
3335
3336 return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
3337 }
3338
3339 // Return a moment from input, that is local/utc/zone equivalent to model.
3340 function cloneWithOffset(input, model) {
3341 var res, diff;
3342 if (model._isUTC) {
3343 res = model.clone();
3344 diff =
3345 (isMoment(input) || isDate(input)
3346 ? input.valueOf()
3347 : createLocal(input).valueOf()) - res.valueOf();
3348 // Use low-level api, because this fn is low-level api.
3349 res._d.setTime(res._d.valueOf() + diff);
3350 hooks.updateOffset(res, false);
3351 return res;
3352 } else {
3353 return createLocal(input).local();
3354 }
3355 }
3356
3357 function getDateOffset(m) {
3358 // On Firefox.24 Date#getTimezoneOffset returns a floating point.
3359 // https://github.com/moment/moment/pull/1871
3360 return -Math.round(m._d.getTimezoneOffset());
3361 }
3362
3363 // HOOKS
3364
3365 // This function will be called whenever a moment is mutated.
3366 // It is intended to keep the offset in sync with the timezone.
3367 hooks.updateOffset = function () {};
3368
3369 // MOMENTS
3370
3371 // keepLocalTime = true means only change the timezone, without
3372 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
3373 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
3374 // +0200, so we adjust the time as needed, to be valid.
3375 //
3376 // Keeping the time actually adds/subtracts (one hour)
3377 // from the actual represented time. That is why we call updateOffset
3378 // a second time. In case it wants us to change the offset again
3379 // _changeInProgress == true case, then we have to adjust, because
3380 // there is no such time in the given timezone.
3381 function getSetOffset(input, keepLocalTime, keepMinutes) {
3382 var offset = this._offset || 0,
3383 localAdjust;
3384 if (!this.isValid()) {
3385 return input != null ? this : NaN;
3386 }
3387 if (input != null) {
3388 if (typeof input === 'string') {
3389 input = offsetFromString(matchShortOffset, input);
3390 if (input === null) {
3391 return this;
3392 }
3393 } else if (Math.abs(input) < 16 && !keepMinutes) {
3394 input = input * 60;
3395 }
3396 if (!this._isUTC && keepLocalTime) {
3397 localAdjust = getDateOffset(this);
3398 }
3399 this._offset = input;
3400 this._isUTC = true;
3401 if (localAdjust != null) {
3402 this.add(localAdjust, 'm');
3403 }
3404 if (offset !== input) {
3405 if (!keepLocalTime || this._changeInProgress) {
3406 addSubtract(
3407 this,
3408 createDuration(input - offset, 'm'),
3409 1,
3410 false
3411 );
3412 } else if (!this._changeInProgress) {
3413 this._changeInProgress = true;
3414 hooks.updateOffset(this, true);
3415 this._changeInProgress = null;
3416 }
3417 }
3418 return this;
3419 } else {
3420 return this._isUTC ? offset : getDateOffset(this);
3421 }
3422 }
3423
3424 function getSetZone(input, keepLocalTime) {
3425 if (input != null) {
3426 if (typeof input !== 'string') {
3427 input = -input;
3428 }
3429
3430 this.utcOffset(input, keepLocalTime);
3431
3432 return this;
3433 } else {
3434 return -this.utcOffset();
3435 }
3436 }
3437
3438 function setOffsetToUTC(keepLocalTime) {
3439 return this.utcOffset(0, keepLocalTime);
3440 }
3441
3442 function setOffsetToLocal(keepLocalTime) {
3443 if (this._isUTC) {
3444 this.utcOffset(0, keepLocalTime);
3445 this._isUTC = false;
3446
3447 if (keepLocalTime) {
3448 this.subtract(getDateOffset(this), 'm');
3449 }
3450 }
3451 return this;
3452 }
3453
3454 function setOffsetToParsedOffset() {
3455 if (this._tzm != null) {
3456 this.utcOffset(this._tzm, false, true);
3457 } else if (typeof this._i === 'string') {
3458 var tZone = offsetFromString(matchOffset, this._i);
3459 if (tZone != null) {
3460 this.utcOffset(tZone);
3461 } else {
3462 this.utcOffset(0, true);
3463 }
3464 }
3465 return this;
3466 }
3467
3468 function hasAlignedHourOffset(input) {
3469 if (!this.isValid()) {
3470 return false;
3471 }
3472 input = input ? createLocal(input).utcOffset() : 0;
3473
3474 return (this.utcOffset() - input) % 60 === 0;
3475 }
3476
3477 function isDaylightSavingTime() {
3478 return (
3479 this.utcOffset() > this.clone().month(0).utcOffset() ||
3480 this.utcOffset() > this.clone().month(5).utcOffset()
3481 );
3482 }
3483
3484 function isDaylightSavingTimeShifted() {
3485 if (!isUndefined(this._isDSTShifted)) {
3486 return this._isDSTShifted;
3487 }
3488
3489 var c = {},
3490 other;
3491
3492 copyConfig(c, this);
3493 c = prepareConfig(c);
3494
3495 if (c._a) {
3496 other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
3497 this._isDSTShifted =
3498 this.isValid() && compareArrays(c._a, other.toArray()) > 0;
3499 } else {
3500 this._isDSTShifted = false;
3501 }
3502
3503 return this._isDSTShifted;
3504 }
3505
3506 function isLocal() {
3507 return this.isValid() ? !this._isUTC : false;
3508 }
3509
3510 function isUtcOffset() {
3511 return this.isValid() ? this._isUTC : false;
3512 }
3513
3514 function isUtc() {
3515 return this.isValid() ? this._isUTC && this._offset === 0 : false;
3516 }
3517
3518 // ASP.NET json date format regex
3519 var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
3520 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
3521 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
3522 // and further modified to allow for strings containing both week and day
3523 isoRegex =
3524 /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
3525
3526 function createDuration(input, key) {
3527 var duration = input,
3528 // matching against regexp is expensive, do it on demand
3529 match = null,
3530 sign,
3531 ret,
3532 diffRes;
3533
3534 if (isDuration(input)) {
3535 duration = {
3536 ms: input._milliseconds,
3537 d: input._days,
3538 M: input._months,
3539 };
3540 } else if (isNumber(input) || !isNaN(+input)) {
3541 duration = {};
3542 if (key) {
3543 duration[key] = +input;
3544 } else {
3545 duration.milliseconds = +input;
3546 }
3547 } else if ((match = aspNetRegex.exec(input))) {
3548 sign = match[1] === '-' ? -1 : 1;
3549 duration = {
3550 y: 0,
3551 d: toInt(match[DATE]) * sign,
3552 h: toInt(match[HOUR]) * sign,
3553 m: toInt(match[MINUTE]) * sign,
3554 s: toInt(match[SECOND]) * sign,
3555 ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
3556 };
3557 } else if ((match = isoRegex.exec(input))) {
3558 sign = match[1] === '-' ? -1 : 1;
3559 duration = {
3560 y: parseIso(match[2], sign),
3561 M: parseIso(match[3], sign),
3562 w: parseIso(match[4], sign),
3563 d: parseIso(match[5], sign),
3564 h: parseIso(match[6], sign),
3565 m: parseIso(match[7], sign),
3566 s: parseIso(match[8], sign),
3567 };
3568 } else if (duration == null) {
3569 // checks for null or undefined
3570 duration = {};
3571 } else if (
3572 typeof duration === 'object' &&
3573 ('from' in duration || 'to' in duration)
3574 ) {
3575 diffRes = momentsDifference(
3576 createLocal(duration.from),
3577 createLocal(duration.to)
3578 );
3579
3580 duration = {};
3581 duration.ms = diffRes.milliseconds;
3582 duration.M = diffRes.months;
3583 }
3584
3585 ret = new Duration(duration);
3586
3587 if (isDuration(input) && hasOwnProp(input, '_locale')) {
3588 ret._locale = input._locale;
3589 }
3590
3591 if (isDuration(input) && hasOwnProp(input, '_isValid')) {
3592 ret._isValid = input._isValid;
3593 }
3594
3595 return ret;
3596 }
3597
3598 createDuration.fn = Duration.prototype;
3599 createDuration.invalid = createInvalid$1;
3600
3601 function parseIso(inp, sign) {
3602 // We'd normally use ~~inp for this, but unfortunately it also
3603 // converts floats to ints.
3604 // inp may be undefined, so careful calling replace on it.
3605 var res = inp && parseFloat(inp.replace(',', '.'));
3606 // apply sign while we're at it
3607 return (isNaN(res) ? 0 : res) * sign;
3608 }
3609
3610 function positiveMomentsDifference(base, other) {
3611 var res = {};
3612
3613 res.months =
3614 other.month() - base.month() + (other.year() - base.year()) * 12;
3615 if (base.clone().add(res.months, 'M').isAfter(other)) {
3616 --res.months;
3617 }
3618
3619 res.milliseconds = +other - +base.clone().add(res.months, 'M');
3620
3621 return res;
3622 }
3623
3624 function momentsDifference(base, other) {
3625 var res;
3626 if (!(base.isValid() && other.isValid())) {
3627 return { milliseconds: 0, months: 0 };
3628 }
3629
3630 other = cloneWithOffset(other, base);
3631 if (base.isBefore(other)) {
3632 res = positiveMomentsDifference(base, other);
3633 } else {
3634 res = positiveMomentsDifference(other, base);
3635 res.milliseconds = -res.milliseconds;
3636 res.months = -res.months;
3637 }
3638
3639 return res;
3640 }
3641
3642 // TODO: remove 'name' arg after deprecation is removed
3643 function createAdder(direction, name) {
3644 return function (val, period) {
3645 var dur, tmp;
3646 //invert the arguments, but complain about it
3647 if (period !== null && !isNaN(+period)) {
3648 deprecateSimple(
3649 name,
3650 'moment().' +
3651 name +
3652 '(period, number) is deprecated. Please use moment().' +
3653 name +
3654 '(number, period). ' +
3655 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
3656 );
3657 tmp = val;
3658 val = period;
3659 period = tmp;
3660 }
3661
3662 dur = createDuration(val, period);
3663 addSubtract(this, dur, direction);
3664 return this;
3665 };
3666 }
3667
3668 function addSubtract(mom, duration, isAdding, updateOffset) {
3669 var milliseconds = duration._milliseconds,
3670 days = absRound(duration._days),
3671 months = absRound(duration._months);
3672
3673 if (!mom.isValid()) {
3674 // No op
3675 return;
3676 }
3677
3678 updateOffset = updateOffset == null ? true : updateOffset;
3679
3680 if (months) {
3681 setMonth(mom, get(mom, 'Month') + months * isAdding);
3682 }
3683 if (days) {
3684 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
3685 }
3686 if (milliseconds) {
3687 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
3688 }
3689 if (updateOffset) {
3690 hooks.updateOffset(mom, days || months);
3691 }
3692 }
3693
3694 var add = createAdder(1, 'add'),
3695 subtract = createAdder(-1, 'subtract');
3696
3697 function isString(input) {
3698 return typeof input === 'string' || input instanceof String;
3699 }
3700
3701 // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
3702 function isMomentInput(input) {
3703 return (
3704 isMoment(input) ||
3705 isDate(input) ||
3706 isString(input) ||
3707 isNumber(input) ||
3708 isNumberOrStringArray(input) ||
3709 isMomentInputObject(input) ||
3710 input === null ||
3711 input === undefined
3712 );
3713 }
3714
3715 function isMomentInputObject(input) {
3716 var objectTest = isObject(input) && !isObjectEmpty(input),
3717 propertyTest = false,
3718 properties = [
3719 'years',
3720 'year',
3721 'y',
3722 'months',
3723 'month',
3724 'M',
3725 'days',
3726 'day',
3727 'd',
3728 'dates',
3729 'date',
3730 'D',
3731 'hours',
3732 'hour',
3733 'h',
3734 'minutes',
3735 'minute',
3736 'm',
3737 'seconds',
3738 'second',
3739 's',
3740 'milliseconds',
3741 'millisecond',
3742 'ms',
3743 ],
3744 i,
3745 property,
3746 propertyLen = properties.length;
3747
3748 for (i = 0; i < propertyLen; i += 1) {
3749 property = properties[i];
3750 propertyTest = propertyTest || hasOwnProp(input, property);
3751 }
3752
3753 return objectTest && propertyTest;
3754 }
3755
3756 function isNumberOrStringArray(input) {
3757 var arrayTest = isArray(input),
3758 dataTypeTest = false;
3759 if (arrayTest) {
3760 dataTypeTest =
3761 input.filter(function (item) {
3762 return !isNumber(item) && isString(input);
3763 }).length === 0;
3764 }
3765 return arrayTest && dataTypeTest;
3766 }
3767
3768 function isCalendarSpec(input) {
3769 var objectTest = isObject(input) && !isObjectEmpty(input),
3770 propertyTest = false,
3771 properties = [
3772 'sameDay',
3773 'nextDay',
3774 'lastDay',
3775 'nextWeek',
3776 'lastWeek',
3777 'sameElse',
3778 ],
3779 i,
3780 property;
3781
3782 for (i = 0; i < properties.length; i += 1) {
3783 property = properties[i];
3784 propertyTest = propertyTest || hasOwnProp(input, property);
3785 }
3786
3787 return objectTest && propertyTest;
3788 }
3789
3790 function getCalendarFormat(myMoment, now) {
3791 var diff = myMoment.diff(now, 'days', true);
3792 return diff < -6
3793 ? 'sameElse'
3794 : diff < -1
3795 ? 'lastWeek'
3796 : diff < 0
3797 ? 'lastDay'
3798 : diff < 1
3799 ? 'sameDay'
3800 : diff < 2
3801 ? 'nextDay'
3802 : diff < 7
3803 ? 'nextWeek'
3804 : 'sameElse';
3805 }
3806
3807 function calendar$1(time, formats) {
3808 // Support for single parameter, formats only overload to the calendar function
3809 if (arguments.length === 1) {
3810 if (!arguments[0]) {
3811 time = undefined;
3812 formats = undefined;
3813 } else if (isMomentInput(arguments[0])) {
3814 time = arguments[0];
3815 formats = undefined;
3816 } else if (isCalendarSpec(arguments[0])) {
3817 formats = arguments[0];
3818 time = undefined;
3819 }
3820 }
3821 // We want to compare the start of today, vs this.
3822 // Getting start-of-today depends on whether we're local/utc/offset or not.
3823 var now = time || createLocal(),
3824 sod = cloneWithOffset(now, this).startOf('day'),
3825 format = hooks.calendarFormat(this, sod) || 'sameElse',
3826 output =
3827 formats &&
3828 (isFunction(formats[format])
3829 ? formats[format].call(this, now)
3830 : formats[format]);
3831
3832 return this.format(
3833 output || this.localeData().calendar(format, this, createLocal(now))
3834 );
3835 }
3836
3837 function clone() {
3838 return new Moment(this);
3839 }
3840
3841 function isAfter(input, units) {
3842 var localInput = isMoment(input) ? input : createLocal(input);
3843 if (!(this.isValid() && localInput.isValid())) {
3844 return false;
3845 }
3846 units = normalizeUnits(units) || 'millisecond';
3847 if (units === 'millisecond') {
3848 return this.valueOf() > localInput.valueOf();
3849 } else {
3850 return localInput.valueOf() < this.clone().startOf(units).valueOf();
3851 }
3852 }
3853
3854 function isBefore(input, units) {
3855 var localInput = isMoment(input) ? input : createLocal(input);
3856 if (!(this.isValid() && localInput.isValid())) {
3857 return false;
3858 }
3859 units = normalizeUnits(units) || 'millisecond';
3860 if (units === 'millisecond') {
3861 return this.valueOf() < localInput.valueOf();
3862 } else {
3863 return this.clone().endOf(units).valueOf() < localInput.valueOf();
3864 }
3865 }
3866
3867 function isBetween(from, to, units, inclusivity) {
3868 var localFrom = isMoment(from) ? from : createLocal(from),
3869 localTo = isMoment(to) ? to : createLocal(to);
3870 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
3871 return false;
3872 }
3873 inclusivity = inclusivity || '()';
3874 return (
3875 (inclusivity[0] === '('
3876 ? this.isAfter(localFrom, units)
3877 : !this.isBefore(localFrom, units)) &&
3878 (inclusivity[1] === ')'
3879 ? this.isBefore(localTo, units)
3880 : !this.isAfter(localTo, units))
3881 );
3882 }
3883
3884 function isSame(input, units) {
3885 var localInput = isMoment(input) ? input : createLocal(input),
3886 inputMs;
3887 if (!(this.isValid() && localInput.isValid())) {
3888 return false;
3889 }
3890 units = normalizeUnits(units) || 'millisecond';
3891 if (units === 'millisecond') {
3892 return this.valueOf() === localInput.valueOf();
3893 } else {
3894 inputMs = localInput.valueOf();
3895 return (
3896 this.clone().startOf(units).valueOf() <= inputMs &&
3897 inputMs <= this.clone().endOf(units).valueOf()
3898 );
3899 }
3900 }
3901
3902 function isSameOrAfter(input, units) {
3903 return this.isSame(input, units) || this.isAfter(input, units);
3904 }
3905
3906 function isSameOrBefore(input, units) {
3907 return this.isSame(input, units) || this.isBefore(input, units);
3908 }
3909
3910 function diff(input, units, asFloat) {
3911 var that, zoneDelta, output;
3912
3913 if (!this.isValid()) {
3914 return NaN;
3915 }
3916
3917 that = cloneWithOffset(input, this);
3918
3919 if (!that.isValid()) {
3920 return NaN;
3921 }
3922
3923 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
3924
3925 units = normalizeUnits(units);
3926
3927 switch (units) {
3928 case 'year':
3929 output = monthDiff(this, that) / 12;
3930 break;
3931 case 'month':
3932 output = monthDiff(this, that);
3933 break;
3934 case 'quarter':
3935 output = monthDiff(this, that) / 3;
3936 break;
3937 case 'second':
3938 output = (this - that) / 1e3;
3939 break; // 1000
3940 case 'minute':
3941 output = (this - that) / 6e4;
3942 break; // 1000 * 60
3943 case 'hour':
3944 output = (this - that) / 36e5;
3945 break; // 1000 * 60 * 60
3946 case 'day':
3947 output = (this - that - zoneDelta) / 864e5;
3948 break; // 1000 * 60 * 60 * 24, negate dst
3949 case 'week':
3950 output = (this - that - zoneDelta) / 6048e5;
3951 break; // 1000 * 60 * 60 * 24 * 7, negate dst
3952 default:
3953 output = this - that;
3954 }
3955
3956 return asFloat ? output : absFloor(output);
3957 }
3958
3959 function monthDiff(a, b) {
3960 if (a.date() < b.date()) {
3961 // end-of-month calculations work correct when the start month has more
3962 // days than the end month.
3963 return -monthDiff(b, a);
3964 }
3965 // difference in months
3966 var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
3967 // b is in (anchor - 1 month, anchor + 1 month)
3968 anchor = a.clone().add(wholeMonthDiff, 'months'),
3969 anchor2,
3970 adjust;
3971
3972 if (b - anchor < 0) {
3973 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
3974 // linear across the month
3975 adjust = (b - anchor) / (anchor - anchor2);
3976 } else {
3977 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
3978 // linear across the month
3979 adjust = (b - anchor) / (anchor2 - anchor);
3980 }
3981
3982 //check for negative zero, return zero if negative zero
3983 return -(wholeMonthDiff + adjust) || 0;
3984 }
3985
3986 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
3987 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
3988
3989 function toString() {
3990 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
3991 }
3992
3993 function toISOString(keepOffset) {
3994 if (!this.isValid()) {
3995 return null;
3996 }
3997 var utc = keepOffset !== true,
3998 m = utc ? this.clone().utc() : this;
3999 if (m.year() < 0 || m.year() > 9999) {
4000 return formatMoment(
4001 m,
4002 utc
4003 ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
4004 : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
4005 );
4006 }
4007 if (isFunction(Date.prototype.toISOString)) {
4008 // native implementation is ~50x faster, use it when we can
4009 if (utc) {
4010 return this.toDate().toISOString();
4011 } else {
4012 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
4013 .toISOString()
4014 .replace('Z', formatMoment(m, 'Z'));
4015 }
4016 }
4017 return formatMoment(
4018 m,
4019 utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
4020 );
4021 }
4022
4023 /**
4024 * Return a human readable representation of a moment that can
4025 * also be evaluated to get a new moment which is the same
4026 *
4027 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
4028 */
4029 function inspect() {
4030 if (!this.isValid()) {
4031 return 'moment.invalid(/* ' + this._i + ' */)';
4032 }
4033 var func = 'moment',
4034 zone = '',
4035 prefix,
4036 year,
4037 datetime,
4038 suffix;
4039 if (!this.isLocal()) {
4040 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
4041 zone = 'Z';
4042 }
4043 prefix = '[' + func + '("]';
4044 year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
4045 datetime = '-MM-DD[T]HH:mm:ss.SSS';
4046 suffix = zone + '[")]';
4047
4048 return this.format(prefix + year + datetime + suffix);
4049 }
4050
4051 function format(inputString) {
4052 if (!inputString) {
4053 inputString = this.isUtc()
4054 ? hooks.defaultFormatUtc
4055 : hooks.defaultFormat;
4056 }
4057 var output = formatMoment(this, inputString);
4058 return this.localeData().postformat(output);
4059 }
4060
4061 function from(time, withoutSuffix) {
4062 if (
4063 this.isValid() &&
4064 ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
4065 ) {
4066 return createDuration({ to: this, from: time })
4067 .locale(this.locale())
4068 .humanize(!withoutSuffix);
4069 } else {
4070 return this.localeData().invalidDate();
4071 }
4072 }
4073
4074 function fromNow(withoutSuffix) {
4075 return this.from(createLocal(), withoutSuffix);
4076 }
4077
4078 function to(time, withoutSuffix) {
4079 if (
4080 this.isValid() &&
4081 ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
4082 ) {
4083 return createDuration({ from: this, to: time })
4084 .locale(this.locale())
4085 .humanize(!withoutSuffix);
4086 } else {
4087 return this.localeData().invalidDate();
4088 }
4089 }
4090
4091 function toNow(withoutSuffix) {
4092 return this.to(createLocal(), withoutSuffix);
4093 }
4094
4095 // If passed a locale key, it will set the locale for this
4096 // instance. Otherwise, it will return the locale configuration
4097 // variables for this instance.
4098 function locale(key) {
4099 var newLocaleData;
4100
4101 if (key === undefined) {
4102 return this._locale._abbr;
4103 } else {
4104 newLocaleData = getLocale(key);
4105 if (newLocaleData != null) {
4106 this._locale = newLocaleData;
4107 }
4108 return this;
4109 }
4110 }
4111
4112 var lang = deprecate(
4113 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
4114 function (key) {
4115 if (key === undefined) {
4116 return this.localeData();
4117 } else {
4118 return this.locale(key);
4119 }
4120 }
4121 );
4122
4123 function localeData() {
4124 return this._locale;
4125 }
4126
4127 var MS_PER_SECOND = 1000,
4128 MS_PER_MINUTE = 60 * MS_PER_SECOND,
4129 MS_PER_HOUR = 60 * MS_PER_MINUTE,
4130 MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
4131
4132 // actual modulo - handles negative numbers (for dates before 1970):
4133 function mod$1(dividend, divisor) {
4134 return ((dividend % divisor) + divisor) % divisor;
4135 }
4136
4137 function localStartOfDate(y, m, d) {
4138 // the date constructor remaps years 0-99 to 1900-1999
4139 if (y < 100 && y >= 0) {
4140 // preserve leap years using a full 400 year cycle, then reset
4141 return new Date(y + 400, m, d) - MS_PER_400_YEARS;
4142 } else {
4143 return new Date(y, m, d).valueOf();
4144 }
4145 }
4146
4147 function utcStartOfDate(y, m, d) {
4148 // Date.UTC remaps years 0-99 to 1900-1999
4149 if (y < 100 && y >= 0) {
4150 // preserve leap years using a full 400 year cycle, then reset
4151 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
4152 } else {
4153 return Date.UTC(y, m, d);
4154 }
4155 }
4156
4157 function startOf(units) {
4158 var time, startOfDate;
4159 units = normalizeUnits(units);
4160 if (units === undefined || units === 'millisecond' || !this.isValid()) {
4161 return this;
4162 }
4163
4164 startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
4165
4166 switch (units) {
4167 case 'year':
4168 time = startOfDate(this.year(), 0, 1);
4169 break;
4170 case 'quarter':
4171 time = startOfDate(
4172 this.year(),
4173 this.month() - (this.month() % 3),
4174 1
4175 );
4176 break;
4177 case 'month':
4178 time = startOfDate(this.year(), this.month(), 1);
4179 break;
4180 case 'week':
4181 time = startOfDate(
4182 this.year(),
4183 this.month(),
4184 this.date() - this.weekday()
4185 );
4186 break;
4187 case 'isoWeek':
4188 time = startOfDate(
4189 this.year(),
4190 this.month(),
4191 this.date() - (this.isoWeekday() - 1)
4192 );
4193 break;
4194 case 'day':
4195 case 'date':
4196 time = startOfDate(this.year(), this.month(), this.date());
4197 break;
4198 case 'hour':
4199 time = this._d.valueOf();
4200 time -= mod$1(
4201 time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
4202 MS_PER_HOUR
4203 );
4204 break;
4205 case 'minute':
4206 time = this._d.valueOf();
4207 time -= mod$1(time, MS_PER_MINUTE);
4208 break;
4209 case 'second':
4210 time = this._d.valueOf();
4211 time -= mod$1(time, MS_PER_SECOND);
4212 break;
4213 }
4214
4215 this._d.setTime(time);
4216 hooks.updateOffset(this, true);
4217 return this;
4218 }
4219
4220 function endOf(units) {
4221 var time, startOfDate;
4222 units = normalizeUnits(units);
4223 if (units === undefined || units === 'millisecond' || !this.isValid()) {
4224 return this;
4225 }
4226
4227 startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
4228
4229 switch (units) {
4230 case 'year':
4231 time = startOfDate(this.year() + 1, 0, 1) - 1;
4232 break;
4233 case 'quarter':
4234 time =
4235 startOfDate(
4236 this.year(),
4237 this.month() - (this.month() % 3) + 3,
4238 1
4239 ) - 1;
4240 break;
4241 case 'month':
4242 time = startOfDate(this.year(), this.month() + 1, 1) - 1;
4243 break;
4244 case 'week':
4245 time =
4246 startOfDate(
4247 this.year(),
4248 this.month(),
4249 this.date() - this.weekday() + 7
4250 ) - 1;
4251 break;
4252 case 'isoWeek':
4253 time =
4254 startOfDate(
4255 this.year(),
4256 this.month(),
4257 this.date() - (this.isoWeekday() - 1) + 7
4258 ) - 1;
4259 break;
4260 case 'day':
4261 case 'date':
4262 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
4263 break;
4264 case 'hour':
4265 time = this._d.valueOf();
4266 time +=
4267 MS_PER_HOUR -
4268 mod$1(
4269 time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
4270 MS_PER_HOUR
4271 ) -
4272 1;
4273 break;
4274 case 'minute':
4275 time = this._d.valueOf();
4276 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
4277 break;
4278 case 'second':
4279 time = this._d.valueOf();
4280 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
4281 break;
4282 }
4283
4284 this._d.setTime(time);
4285 hooks.updateOffset(this, true);
4286 return this;
4287 }
4288
4289 function valueOf() {
4290 return this._d.valueOf() - (this._offset || 0) * 60000;
4291 }
4292
4293 function unix() {
4294 return Math.floor(this.valueOf() / 1000);
4295 }
4296
4297 function toDate() {
4298 return new Date(this.valueOf());
4299 }
4300
4301 function toArray() {
4302 var m = this;
4303 return [
4304 m.year(),
4305 m.month(),
4306 m.date(),
4307 m.hour(),
4308 m.minute(),
4309 m.second(),
4310 m.millisecond(),
4311 ];
4312 }
4313
4314 function toObject() {
4315 var m = this;
4316 return {
4317 years: m.year(),
4318 months: m.month(),
4319 date: m.date(),
4320 hours: m.hours(),
4321 minutes: m.minutes(),
4322 seconds: m.seconds(),
4323 milliseconds: m.milliseconds(),
4324 };
4325 }
4326
4327 function toJSON() {
4328 // new Date(NaN).toJSON() === null
4329 return this.isValid() ? this.toISOString() : null;
4330 }
4331
4332 function isValid$2() {
4333 return isValid(this);
4334 }
4335
4336 function parsingFlags() {
4337 return extend({}, getParsingFlags(this));
4338 }
4339
4340 function invalidAt() {
4341 return getParsingFlags(this).overflow;
4342 }
4343
4344 function creationData() {
4345 return {
4346 input: this._i,
4347 format: this._f,
4348 locale: this._locale,
4349 isUTC: this._isUTC,
4350 strict: this._strict,
4351 };
4352 }
4353
4354 addFormatToken('N', 0, 0, 'eraAbbr');
4355 addFormatToken('NN', 0, 0, 'eraAbbr');
4356 addFormatToken('NNN', 0, 0, 'eraAbbr');
4357 addFormatToken('NNNN', 0, 0, 'eraName');
4358 addFormatToken('NNNNN', 0, 0, 'eraNarrow');
4359
4360 addFormatToken('y', ['y', 1], 'yo', 'eraYear');
4361 addFormatToken('y', ['yy', 2], 0, 'eraYear');
4362 addFormatToken('y', ['yyy', 3], 0, 'eraYear');
4363 addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
4364
4365 addRegexToken('N', matchEraAbbr);
4366 addRegexToken('NN', matchEraAbbr);
4367 addRegexToken('NNN', matchEraAbbr);
4368 addRegexToken('NNNN', matchEraName);
4369 addRegexToken('NNNNN', matchEraNarrow);
4370
4371 addParseToken(
4372 ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
4373 function (input, array, config, token) {
4374 var era = config._locale.erasParse(input, token, config._strict);
4375 if (era) {
4376 getParsingFlags(config).era = era;
4377 } else {
4378 getParsingFlags(config).invalidEra = input;
4379 }
4380 }
4381 );
4382
4383 addRegexToken('y', matchUnsigned);
4384 addRegexToken('yy', matchUnsigned);
4385 addRegexToken('yyy', matchUnsigned);
4386 addRegexToken('yyyy', matchUnsigned);
4387 addRegexToken('yo', matchEraYearOrdinal);
4388
4389 addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
4390 addParseToken(['yo'], function (input, array, config, token) {
4391 var match;
4392 if (config._locale._eraYearOrdinalRegex) {
4393 match = input.match(config._locale._eraYearOrdinalRegex);
4394 }
4395
4396 if (config._locale.eraYearOrdinalParse) {
4397 array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
4398 } else {
4399 array[YEAR] = parseInt(input, 10);
4400 }
4401 });
4402
4403 function localeEras(m, format) {
4404 var i,
4405 l,
4406 date,
4407 eras = this._eras || getLocale('en')._eras;
4408 for (i = 0, l = eras.length; i < l; ++i) {
4409 switch (typeof eras[i].since) {
4410 case 'string':
4411 // truncate time
4412 date = hooks(eras[i].since).startOf('day');
4413 eras[i].since = date.valueOf();
4414 break;
4415 }
4416
4417 switch (typeof eras[i].until) {
4418 case 'undefined':
4419 eras[i].until = +Infinity;
4420 break;
4421 case 'string':
4422 // truncate time
4423 date = hooks(eras[i].until).startOf('day').valueOf();
4424 eras[i].until = date.valueOf();
4425 break;
4426 }
4427 }
4428 return eras;
4429 }
4430
4431 function localeErasParse(eraName, format, strict) {
4432 var i,
4433 l,
4434 eras = this.eras(),
4435 name,
4436 abbr,
4437 narrow;
4438 eraName = eraName.toUpperCase();
4439
4440 for (i = 0, l = eras.length; i < l; ++i) {
4441 name = eras[i].name.toUpperCase();
4442 abbr = eras[i].abbr.toUpperCase();
4443 narrow = eras[i].narrow.toUpperCase();
4444
4445 if (strict) {
4446 switch (format) {
4447 case 'N':
4448 case 'NN':
4449 case 'NNN':
4450 if (abbr === eraName) {
4451 return eras[i];
4452 }
4453 break;
4454
4455 case 'NNNN':
4456 if (name === eraName) {
4457 return eras[i];
4458 }
4459 break;
4460
4461 case 'NNNNN':
4462 if (narrow === eraName) {
4463 return eras[i];
4464 }
4465 break;
4466 }
4467 } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
4468 return eras[i];
4469 }
4470 }
4471 }
4472
4473 function localeErasConvertYear(era, year) {
4474 var dir = era.since <= era.until ? +1 : -1;
4475 if (year === undefined) {
4476 return hooks(era.since).year();
4477 } else {
4478 return hooks(era.since).year() + (year - era.offset) * dir;
4479 }
4480 }
4481
4482 function getEraName() {
4483 var i,
4484 l,
4485 val,
4486 eras = this.localeData().eras();
4487 for (i = 0, l = eras.length; i < l; ++i) {
4488 // truncate time
4489 val = this.clone().startOf('day').valueOf();
4490
4491 if (eras[i].since <= val && val <= eras[i].until) {
4492 return eras[i].name;
4493 }
4494 if (eras[i].until <= val && val <= eras[i].since) {
4495 return eras[i].name;
4496 }
4497 }
4498
4499 return '';
4500 }
4501
4502 function getEraNarrow() {
4503 var i,
4504 l,
4505 val,
4506 eras = this.localeData().eras();
4507 for (i = 0, l = eras.length; i < l; ++i) {
4508 // truncate time
4509 val = this.clone().startOf('day').valueOf();
4510
4511 if (eras[i].since <= val && val <= eras[i].until) {
4512 return eras[i].narrow;
4513 }
4514 if (eras[i].until <= val && val <= eras[i].since) {
4515 return eras[i].narrow;
4516 }
4517 }
4518
4519 return '';
4520 }
4521
4522 function getEraAbbr() {
4523 var i,
4524 l,
4525 val,
4526 eras = this.localeData().eras();
4527 for (i = 0, l = eras.length; i < l; ++i) {
4528 // truncate time
4529 val = this.clone().startOf('day').valueOf();
4530
4531 if (eras[i].since <= val && val <= eras[i].until) {
4532 return eras[i].abbr;
4533 }
4534 if (eras[i].until <= val && val <= eras[i].since) {
4535 return eras[i].abbr;
4536 }
4537 }
4538
4539 return '';
4540 }
4541
4542 function getEraYear() {
4543 var i,
4544 l,
4545 dir,
4546 val,
4547 eras = this.localeData().eras();
4548 for (i = 0, l = eras.length; i < l; ++i) {
4549 dir = eras[i].since <= eras[i].until ? +1 : -1;
4550
4551 // truncate time
4552 val = this.clone().startOf('day').valueOf();
4553
4554 if (
4555 (eras[i].since <= val && val <= eras[i].until) ||
4556 (eras[i].until <= val && val <= eras[i].since)
4557 ) {
4558 return (
4559 (this.year() - hooks(eras[i].since).year()) * dir +
4560 eras[i].offset
4561 );
4562 }
4563 }
4564
4565 return this.year();
4566 }
4567
4568 function erasNameRegex(isStrict) {
4569 if (!hasOwnProp(this, '_erasNameRegex')) {
4570 computeErasParse.call(this);
4571 }
4572 return isStrict ? this._erasNameRegex : this._erasRegex;
4573 }
4574
4575 function erasAbbrRegex(isStrict) {
4576 if (!hasOwnProp(this, '_erasAbbrRegex')) {
4577 computeErasParse.call(this);
4578 }
4579 return isStrict ? this._erasAbbrRegex : this._erasRegex;
4580 }
4581
4582 function erasNarrowRegex(isStrict) {
4583 if (!hasOwnProp(this, '_erasNarrowRegex')) {
4584 computeErasParse.call(this);
4585 }
4586 return isStrict ? this._erasNarrowRegex : this._erasRegex;
4587 }
4588
4589 function matchEraAbbr(isStrict, locale) {
4590 return locale.erasAbbrRegex(isStrict);
4591 }
4592
4593 function matchEraName(isStrict, locale) {
4594 return locale.erasNameRegex(isStrict);
4595 }
4596
4597 function matchEraNarrow(isStrict, locale) {
4598 return locale.erasNarrowRegex(isStrict);
4599 }
4600
4601 function matchEraYearOrdinal(isStrict, locale) {
4602 return locale._eraYearOrdinalRegex || matchUnsigned;
4603 }
4604
4605 function computeErasParse() {
4606 var abbrPieces = [],
4607 namePieces = [],
4608 narrowPieces = [],
4609 mixedPieces = [],
4610 i,
4611 l,
4612 erasName,
4613 erasAbbr,
4614 erasNarrow,
4615 eras = this.eras();
4616
4617 for (i = 0, l = eras.length; i < l; ++i) {
4618 erasName = regexEscape(eras[i].name);
4619 erasAbbr = regexEscape(eras[i].abbr);
4620 erasNarrow = regexEscape(eras[i].narrow);
4621
4622 namePieces.push(erasName);
4623 abbrPieces.push(erasAbbr);
4624 narrowPieces.push(erasNarrow);
4625 mixedPieces.push(erasName);
4626 mixedPieces.push(erasAbbr);
4627 mixedPieces.push(erasNarrow);
4628 }
4629
4630 this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
4631 this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
4632 this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
4633 this._erasNarrowRegex = new RegExp(
4634 '^(' + narrowPieces.join('|') + ')',
4635 'i'
4636 );
4637 }
4638
4639 // FORMATTING
4640
4641 addFormatToken(0, ['gg', 2], 0, function () {
4642 return this.weekYear() % 100;
4643 });
4644
4645 addFormatToken(0, ['GG', 2], 0, function () {
4646 return this.isoWeekYear() % 100;
4647 });
4648
4649 function addWeekYearFormatToken(token, getter) {
4650 addFormatToken(0, [token, token.length], 0, getter);
4651 }
4652
4653 addWeekYearFormatToken('gggg', 'weekYear');
4654 addWeekYearFormatToken('ggggg', 'weekYear');
4655 addWeekYearFormatToken('GGGG', 'isoWeekYear');
4656 addWeekYearFormatToken('GGGGG', 'isoWeekYear');
4657
4658 // ALIASES
4659
4660 // PARSING
4661
4662 addRegexToken('G', matchSigned);
4663 addRegexToken('g', matchSigned);
4664 addRegexToken('GG', match1to2, match2);
4665 addRegexToken('gg', match1to2, match2);
4666 addRegexToken('GGGG', match1to4, match4);
4667 addRegexToken('gggg', match1to4, match4);
4668 addRegexToken('GGGGG', match1to6, match6);
4669 addRegexToken('ggggg', match1to6, match6);
4670
4671 addWeekParseToken(
4672 ['gggg', 'ggggg', 'GGGG', 'GGGGG'],
4673 function (input, week, config, token) {
4674 week[token.substr(0, 2)] = toInt(input);
4675 }
4676 );
4677
4678 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
4679 week[token] = hooks.parseTwoDigitYear(input);
4680 });
4681
4682 // MOMENTS
4683
4684 function getSetWeekYear(input) {
4685 return getSetWeekYearHelper.call(
4686 this,
4687 input,
4688 this.week(),
4689 this.weekday() + this.localeData()._week.dow,
4690 this.localeData()._week.dow,
4691 this.localeData()._week.doy
4692 );
4693 }
4694
4695 function getSetISOWeekYear(input) {
4696 return getSetWeekYearHelper.call(
4697 this,
4698 input,
4699 this.isoWeek(),
4700 this.isoWeekday(),
4701 1,
4702 4
4703 );
4704 }
4705
4706 function getISOWeeksInYear() {
4707 return weeksInYear(this.year(), 1, 4);
4708 }
4709
4710 function getISOWeeksInISOWeekYear() {
4711 return weeksInYear(this.isoWeekYear(), 1, 4);
4712 }
4713
4714 function getWeeksInYear() {
4715 var weekInfo = this.localeData()._week;
4716 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
4717 }
4718
4719 function getWeeksInWeekYear() {
4720 var weekInfo = this.localeData()._week;
4721 return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
4722 }
4723
4724 function getSetWeekYearHelper(input, week, weekday, dow, doy) {
4725 var weeksTarget;
4726 if (input == null) {
4727 return weekOfYear(this, dow, doy).year;
4728 } else {
4729 weeksTarget = weeksInYear(input, dow, doy);
4730 if (week > weeksTarget) {
4731 week = weeksTarget;
4732 }
4733 return setWeekAll.call(this, input, week, weekday, dow, doy);
4734 }
4735 }
4736
4737 function setWeekAll(weekYear, week, weekday, dow, doy) {
4738 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
4739 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
4740
4741 this.year(date.getUTCFullYear());
4742 this.month(date.getUTCMonth());
4743 this.date(date.getUTCDate());
4744 return this;
4745 }
4746
4747 // FORMATTING
4748
4749 addFormatToken('Q', 0, 'Qo', 'quarter');
4750
4751 // PARSING
4752
4753 addRegexToken('Q', match1);
4754 addParseToken('Q', function (input, array) {
4755 array[MONTH] = (toInt(input) - 1) * 3;
4756 });
4757
4758 // MOMENTS
4759
4760 function getSetQuarter(input) {
4761 return input == null
4762 ? Math.ceil((this.month() + 1) / 3)
4763 : this.month((input - 1) * 3 + (this.month() % 3));
4764 }
4765
4766 // FORMATTING
4767
4768 addFormatToken('D', ['DD', 2], 'Do', 'date');
4769
4770 // PARSING
4771
4772 addRegexToken('D', match1to2, match1to2NoLeadingZero);
4773 addRegexToken('DD', match1to2, match2);
4774 addRegexToken('Do', function (isStrict, locale) {
4775 // TODO: Remove "ordinalParse" fallback in next major release.
4776 return isStrict
4777 ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
4778 : locale._dayOfMonthOrdinalParseLenient;
4779 });
4780
4781 addParseToken(['D', 'DD'], DATE);
4782 addParseToken('Do', function (input, array) {
4783 array[DATE] = toInt(input.match(match1to2)[0]);
4784 });
4785
4786 // MOMENTS
4787
4788 var getSetDayOfMonth = makeGetSet('Date', true);
4789
4790 // FORMATTING
4791
4792 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
4793
4794 // PARSING
4795
4796 addRegexToken('DDD', match1to3);
4797 addRegexToken('DDDD', match3);
4798 addParseToken(['DDD', 'DDDD'], function (input, array, config) {
4799 config._dayOfYear = toInt(input);
4800 });
4801
4802 // HELPERS
4803
4804 // MOMENTS
4805
4806 function getSetDayOfYear(input) {
4807 var dayOfYear =
4808 Math.round(
4809 (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
4810 ) + 1;
4811 return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
4812 }
4813
4814 // FORMATTING
4815
4816 addFormatToken('m', ['mm', 2], 0, 'minute');
4817
4818 // PARSING
4819
4820 addRegexToken('m', match1to2, match1to2HasZero);
4821 addRegexToken('mm', match1to2, match2);
4822 addParseToken(['m', 'mm'], MINUTE);
4823
4824 // MOMENTS
4825
4826 var getSetMinute = makeGetSet('Minutes', false);
4827
4828 // FORMATTING
4829
4830 addFormatToken('s', ['ss', 2], 0, 'second');
4831
4832 // PARSING
4833
4834 addRegexToken('s', match1to2, match1to2HasZero);
4835 addRegexToken('ss', match1to2, match2);
4836 addParseToken(['s', 'ss'], SECOND);
4837
4838 // MOMENTS
4839
4840 var getSetSecond = makeGetSet('Seconds', false);
4841
4842 // FORMATTING
4843
4844 addFormatToken('S', 0, 0, function () {
4845 return ~~(this.millisecond() / 100);
4846 });
4847
4848 addFormatToken(0, ['SS', 2], 0, function () {
4849 return ~~(this.millisecond() / 10);
4850 });
4851
4852 addFormatToken(0, ['SSS', 3], 0, 'millisecond');
4853 addFormatToken(0, ['SSSS', 4], 0, function () {
4854 return this.millisecond() * 10;
4855 });
4856 addFormatToken(0, ['SSSSS', 5], 0, function () {
4857 return this.millisecond() * 100;
4858 });
4859 addFormatToken(0, ['SSSSSS', 6], 0, function () {
4860 return this.millisecond() * 1000;
4861 });
4862 addFormatToken(0, ['SSSSSSS', 7], 0, function () {
4863 return this.millisecond() * 10000;
4864 });
4865 addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
4866 return this.millisecond() * 100000;
4867 });
4868 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
4869 return this.millisecond() * 1000000;
4870 });
4871
4872 // PARSING
4873
4874 addRegexToken('S', match1to3, match1);
4875 addRegexToken('SS', match1to3, match2);
4876 addRegexToken('SSS', match1to3, match3);
4877
4878 var token, getSetMillisecond;
4879 for (token = 'SSSS'; token.length <= 9; token += 'S') {
4880 addRegexToken(token, matchUnsigned);
4881 }
4882
4883 function parseMs(input, array) {
4884 array[MILLISECOND] = toInt(('0.' + input) * 1000);
4885 }
4886
4887 for (token = 'S'; token.length <= 9; token += 'S') {
4888 addParseToken(token, parseMs);
4889 }
4890
4891 getSetMillisecond = makeGetSet('Milliseconds', false);
4892
4893 // FORMATTING
4894
4895 addFormatToken('z', 0, 0, 'zoneAbbr');
4896 addFormatToken('zz', 0, 0, 'zoneName');
4897
4898 // MOMENTS
4899
4900 function getZoneAbbr() {
4901 return this._isUTC ? 'UTC' : '';
4902 }
4903
4904 function getZoneName() {
4905 return this._isUTC ? 'Coordinated Universal Time' : '';
4906 }
4907
4908 var proto = Moment.prototype;
4909
4910 proto.add = add;
4911 proto.calendar = calendar$1;
4912 proto.clone = clone;
4913 proto.diff = diff;
4914 proto.endOf = endOf;
4915 proto.format = format;
4916 proto.from = from;
4917 proto.fromNow = fromNow;
4918 proto.to = to;
4919 proto.toNow = toNow;
4920 proto.get = stringGet;
4921 proto.invalidAt = invalidAt;
4922 proto.isAfter = isAfter;
4923 proto.isBefore = isBefore;
4924 proto.isBetween = isBetween;
4925 proto.isSame = isSame;
4926 proto.isSameOrAfter = isSameOrAfter;
4927 proto.isSameOrBefore = isSameOrBefore;
4928 proto.isValid = isValid$2;
4929 proto.lang = lang;
4930 proto.locale = locale;
4931 proto.localeData = localeData;
4932 proto.max = prototypeMax;
4933 proto.min = prototypeMin;
4934 proto.parsingFlags = parsingFlags;
4935 proto.set = stringSet;
4936 proto.startOf = startOf;
4937 proto.subtract = subtract;
4938 proto.toArray = toArray;
4939 proto.toObject = toObject;
4940 proto.toDate = toDate;
4941 proto.toISOString = toISOString;
4942 proto.inspect = inspect;
4943 if (typeof Symbol !== 'undefined' && Symbol.for != null) {
4944 proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
4945 return 'Moment<' + this.format() + '>';
4946 };
4947 }
4948 proto.toJSON = toJSON;
4949 proto.toString = toString;
4950 proto.unix = unix;
4951 proto.valueOf = valueOf;
4952 proto.creationData = creationData;
4953 proto.eraName = getEraName;
4954 proto.eraNarrow = getEraNarrow;
4955 proto.eraAbbr = getEraAbbr;
4956 proto.eraYear = getEraYear;
4957 proto.year = getSetYear;
4958 proto.isLeapYear = getIsLeapYear;
4959 proto.weekYear = getSetWeekYear;
4960 proto.isoWeekYear = getSetISOWeekYear;
4961 proto.quarter = proto.quarters = getSetQuarter;
4962 proto.month = getSetMonth;
4963 proto.daysInMonth = getDaysInMonth;
4964 proto.week = proto.weeks = getSetWeek;
4965 proto.isoWeek = proto.isoWeeks = getSetISOWeek;
4966 proto.weeksInYear = getWeeksInYear;
4967 proto.weeksInWeekYear = getWeeksInWeekYear;
4968 proto.isoWeeksInYear = getISOWeeksInYear;
4969 proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
4970 proto.date = getSetDayOfMonth;
4971 proto.day = proto.days = getSetDayOfWeek;
4972 proto.weekday = getSetLocaleDayOfWeek;
4973 proto.isoWeekday = getSetISODayOfWeek;
4974 proto.dayOfYear = getSetDayOfYear;
4975 proto.hour = proto.hours = getSetHour;
4976 proto.minute = proto.minutes = getSetMinute;
4977 proto.second = proto.seconds = getSetSecond;
4978 proto.millisecond = proto.milliseconds = getSetMillisecond;
4979 proto.utcOffset = getSetOffset;
4980 proto.utc = setOffsetToUTC;
4981 proto.local = setOffsetToLocal;
4982 proto.parseZone = setOffsetToParsedOffset;
4983 proto.hasAlignedHourOffset = hasAlignedHourOffset;
4984 proto.isDST = isDaylightSavingTime;
4985 proto.isLocal = isLocal;
4986 proto.isUtcOffset = isUtcOffset;
4987 proto.isUtc = isUtc;
4988 proto.isUTC = isUtc;
4989 proto.zoneAbbr = getZoneAbbr;
4990 proto.zoneName = getZoneName;
4991 proto.dates = deprecate(
4992 'dates accessor is deprecated. Use date instead.',
4993 getSetDayOfMonth
4994 );
4995 proto.months = deprecate(
4996 'months accessor is deprecated. Use month instead',
4997 getSetMonth
4998 );
4999 proto.years = deprecate(
5000 'years accessor is deprecated. Use year instead',
5001 getSetYear
5002 );
5003 proto.zone = deprecate(
5004 'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
5005 getSetZone
5006 );
5007 proto.isDSTShifted = deprecate(
5008 'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
5009 isDaylightSavingTimeShifted
5010 );
5011
5012 function createUnix(input) {
5013 return createLocal(input * 1000);
5014 }
5015
5016 function createInZone() {
5017 return createLocal.apply(null, arguments).parseZone();
5018 }
5019
5020 function preParsePostFormat(string) {
5021 return string;
5022 }
5023
5024 var proto$1 = Locale.prototype;
5025
5026 proto$1.calendar = calendar;
5027 proto$1.longDateFormat = longDateFormat;
5028 proto$1.invalidDate = invalidDate;
5029 proto$1.ordinal = ordinal;
5030 proto$1.preparse = preParsePostFormat;
5031 proto$1.postformat = preParsePostFormat;
5032 proto$1.relativeTime = relativeTime;
5033 proto$1.pastFuture = pastFuture;
5034 proto$1.set = set;
5035 proto$1.eras = localeEras;
5036 proto$1.erasParse = localeErasParse;
5037 proto$1.erasConvertYear = localeErasConvertYear;
5038 proto$1.erasAbbrRegex = erasAbbrRegex;
5039 proto$1.erasNameRegex = erasNameRegex;
5040 proto$1.erasNarrowRegex = erasNarrowRegex;
5041
5042 proto$1.months = localeMonths;
5043 proto$1.monthsShort = localeMonthsShort;
5044 proto$1.monthsParse = localeMonthsParse;
5045 proto$1.monthsRegex = monthsRegex;
5046 proto$1.monthsShortRegex = monthsShortRegex;
5047 proto$1.week = localeWeek;
5048 proto$1.firstDayOfYear = localeFirstDayOfYear;
5049 proto$1.firstDayOfWeek = localeFirstDayOfWeek;
5050
5051 proto$1.weekdays = localeWeekdays;
5052 proto$1.weekdaysMin = localeWeekdaysMin;
5053 proto$1.weekdaysShort = localeWeekdaysShort;
5054 proto$1.weekdaysParse = localeWeekdaysParse;
5055
5056 proto$1.weekdaysRegex = weekdaysRegex;
5057 proto$1.weekdaysShortRegex = weekdaysShortRegex;
5058 proto$1.weekdaysMinRegex = weekdaysMinRegex;
5059
5060 proto$1.isPM = localeIsPM;
5061 proto$1.meridiem = localeMeridiem;
5062
5063 function get$1(format, index, field, setter) {
5064 var locale = getLocale(),
5065 utc = createUTC().set(setter, index);
5066 return locale[field](utc, format);
5067 }
5068
5069 function listMonthsImpl(format, index, field) {
5070 if (isNumber(format)) {
5071 index = format;
5072 format = undefined;
5073 }
5074
5075 format = format || '';
5076
5077 if (index != null) {
5078 return get$1(format, index, field, 'month');
5079 }
5080
5081 var i,
5082 out = [];
5083 for (i = 0; i < 12; i++) {
5084 out[i] = get$1(format, i, field, 'month');
5085 }
5086 return out;
5087 }
5088
5089 // ()
5090 // (5)
5091 // (fmt, 5)
5092 // (fmt)
5093 // (true)
5094 // (true, 5)
5095 // (true, fmt, 5)
5096 // (true, fmt)
5097 function listWeekdaysImpl(localeSorted, format, index, field) {
5098 if (typeof localeSorted === 'boolean') {
5099 if (isNumber(format)) {
5100 index = format;
5101 format = undefined;
5102 }
5103
5104 format = format || '';
5105 } else {
5106 format = localeSorted;
5107 index = format;
5108 localeSorted = false;
5109
5110 if (isNumber(format)) {
5111 index = format;
5112 format = undefined;
5113 }
5114
5115 format = format || '';
5116 }
5117
5118 var locale = getLocale(),
5119 shift = localeSorted ? locale._week.dow : 0,
5120 i,
5121 out = [];
5122
5123 if (index != null) {
5124 return get$1(format, (index + shift) % 7, field, 'day');
5125 }
5126
5127 for (i = 0; i < 7; i++) {
5128 out[i] = get$1(format, (i + shift) % 7, field, 'day');
5129 }
5130 return out;
5131 }
5132
5133 function listMonths(format, index) {
5134 return listMonthsImpl(format, index, 'months');
5135 }
5136
5137 function listMonthsShort(format, index) {
5138 return listMonthsImpl(format, index, 'monthsShort');
5139 }
5140
5141 function listWeekdays(localeSorted, format, index) {
5142 return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
5143 }
5144
5145 function listWeekdaysShort(localeSorted, format, index) {
5146 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
5147 }
5148
5149 function listWeekdaysMin(localeSorted, format, index) {
5150 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
5151 }
5152
5153 getSetGlobalLocale('en', {
5154 eras: [
5155 {
5156 since: '0001-01-01',
5157 until: +Infinity,
5158 offset: 1,
5159 name: 'Anno Domini',
5160 narrow: 'AD',
5161 abbr: 'AD',
5162 },
5163 {
5164 since: '0000-12-31',
5165 until: -Infinity,
5166 offset: 1,
5167 name: 'Before Christ',
5168 narrow: 'BC',
5169 abbr: 'BC',
5170 },
5171 ],
5172 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
5173 ordinal: function (number) {
5174 var b = number % 10,
5175 output =
5176 toInt((number % 100) / 10) === 1
5177 ? 'th'
5178 : b === 1
5179 ? 'st'
5180 : b === 2
5181 ? 'nd'
5182 : b === 3
5183 ? 'rd'
5184 : 'th';
5185 return number + output;
5186 },
5187 });
5188
5189 // Side effect imports
5190
5191 hooks.lang = deprecate(
5192 'moment.lang is deprecated. Use moment.locale instead.',
5193 getSetGlobalLocale
5194 );
5195 hooks.langData = deprecate(
5196 'moment.langData is deprecated. Use moment.localeData instead.',
5197 getLocale
5198 );
5199
5200 var mathAbs = Math.abs;
5201
5202 function abs() {
5203 var data = this._data;
5204
5205 this._milliseconds = mathAbs(this._milliseconds);
5206 this._days = mathAbs(this._days);
5207 this._months = mathAbs(this._months);
5208
5209 data.milliseconds = mathAbs(data.milliseconds);
5210 data.seconds = mathAbs(data.seconds);
5211 data.minutes = mathAbs(data.minutes);
5212 data.hours = mathAbs(data.hours);
5213 data.months = mathAbs(data.months);
5214 data.years = mathAbs(data.years);
5215
5216 return this;
5217 }
5218
5219 function addSubtract$1(duration, input, value, direction) {
5220 var other = createDuration(input, value);
5221
5222 duration._milliseconds += direction * other._milliseconds;
5223 duration._days += direction * other._days;
5224 duration._months += direction * other._months;
5225
5226 return duration._bubble();
5227 }
5228
5229 // supports only 2.0-style add(1, 's') or add(duration)
5230 function add$1(input, value) {
5231 return addSubtract$1(this, input, value, 1);
5232 }
5233
5234 // supports only 2.0-style subtract(1, 's') or subtract(duration)
5235 function subtract$1(input, value) {
5236 return addSubtract$1(this, input, value, -1);
5237 }
5238
5239 function absCeil(number) {
5240 if (number < 0) {
5241 return Math.floor(number);
5242 } else {
5243 return Math.ceil(number);
5244 }
5245 }
5246
5247 function bubble() {
5248 var milliseconds = this._milliseconds,
5249 days = this._days,
5250 months = this._months,
5251 data = this._data,
5252 seconds,
5253 minutes,
5254 hours,
5255 years,
5256 monthsFromDays;
5257
5258 // if we have a mix of positive and negative values, bubble down first
5259 // check: https://github.com/moment/moment/issues/2166
5260 if (
5261 !(
5262 (milliseconds >= 0 && days >= 0 && months >= 0) ||
5263 (milliseconds <= 0 && days <= 0 && months <= 0)
5264 )
5265 ) {
5266 milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
5267 days = 0;
5268 months = 0;
5269 }
5270
5271 // The following code bubbles up values, see the tests for
5272 // examples of what that means.
5273 data.milliseconds = milliseconds % 1000;
5274
5275 seconds = absFloor(milliseconds / 1000);
5276 data.seconds = seconds % 60;
5277
5278 minutes = absFloor(seconds / 60);
5279 data.minutes = minutes % 60;
5280
5281 hours = absFloor(minutes / 60);
5282 data.hours = hours % 24;
5283
5284 days += absFloor(hours / 24);
5285
5286 // convert days to months
5287 monthsFromDays = absFloor(daysToMonths(days));
5288 months += monthsFromDays;
5289 days -= absCeil(monthsToDays(monthsFromDays));
5290
5291 // 12 months -> 1 year
5292 years = absFloor(months / 12);
5293 months %= 12;
5294
5295 data.days = days;
5296 data.months = months;
5297 data.years = years;
5298
5299 return this;
5300 }
5301
5302 function daysToMonths(days) {
5303 // 400 years have 146097 days (taking into account leap year rules)
5304 // 400 years have 12 months === 4800
5305 return (days * 4800) / 146097;
5306 }
5307
5308 function monthsToDays(months) {
5309 // the reverse of daysToMonths
5310 return (months * 146097) / 4800;
5311 }
5312
5313 function as(units) {
5314 if (!this.isValid()) {
5315 return NaN;
5316 }
5317 var days,
5318 months,
5319 milliseconds = this._milliseconds;
5320
5321 units = normalizeUnits(units);
5322
5323 if (units === 'month' || units === 'quarter' || units === 'year') {
5324 days = this._days + milliseconds / 864e5;
5325 months = this._months + daysToMonths(days);
5326 switch (units) {
5327 case 'month':
5328 return months;
5329 case 'quarter':
5330 return months / 3;
5331 case 'year':
5332 return months / 12;
5333 }
5334 } else {
5335 // handle milliseconds separately because of floating point math errors (issue #1867)
5336 days = this._days + Math.round(monthsToDays(this._months));
5337 switch (units) {
5338 case 'week':
5339 return days / 7 + milliseconds / 6048e5;
5340 case 'day':
5341 return days + milliseconds / 864e5;
5342 case 'hour':
5343 return days * 24 + milliseconds / 36e5;
5344 case 'minute':
5345 return days * 1440 + milliseconds / 6e4;
5346 case 'second':
5347 return days * 86400 + milliseconds / 1000;
5348 // Math.floor prevents floating point math errors here
5349 case 'millisecond':
5350 return Math.floor(days * 864e5) + milliseconds;
5351 default:
5352 throw new Error('Unknown unit ' + units);
5353 }
5354 }
5355 }
5356
5357 function makeAs(alias) {
5358 return function () {
5359 return this.as(alias);
5360 };
5361 }
5362
5363 var asMilliseconds = makeAs('ms'),
5364 asSeconds = makeAs('s'),
5365 asMinutes = makeAs('m'),
5366 asHours = makeAs('h'),
5367 asDays = makeAs('d'),
5368 asWeeks = makeAs('w'),
5369 asMonths = makeAs('M'),
5370 asQuarters = makeAs('Q'),
5371 asYears = makeAs('y'),
5372 valueOf$1 = asMilliseconds;
5373
5374 function clone$1() {
5375 return createDuration(this);
5376 }
5377
5378 function get$2(units) {
5379 units = normalizeUnits(units);
5380 return this.isValid() ? this[units + 's']() : NaN;
5381 }
5382
5383 function makeGetter(name) {
5384 return function () {
5385 return this.isValid() ? this._data[name] : NaN;
5386 };
5387 }
5388
5389 var milliseconds = makeGetter('milliseconds'),
5390 seconds = makeGetter('seconds'),
5391 minutes = makeGetter('minutes'),
5392 hours = makeGetter('hours'),
5393 days = makeGetter('days'),
5394 months = makeGetter('months'),
5395 years = makeGetter('years');
5396
5397 function weeks() {
5398 return absFloor(this.days() / 7);
5399 }
5400
5401 var round = Math.round,
5402 thresholds = {
5403 ss: 44, // a few seconds to seconds
5404 s: 45, // seconds to minute
5405 m: 45, // minutes to hour
5406 h: 22, // hours to day
5407 d: 26, // days to month/week
5408 w: null, // weeks to month
5409 M: 11, // months to year
5410 };
5411
5412 // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
5413 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
5414 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
5415 }
5416
5417 function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
5418 var duration = createDuration(posNegDuration).abs(),
5419 seconds = round(duration.as('s')),
5420 minutes = round(duration.as('m')),
5421 hours = round(duration.as('h')),
5422 days = round(duration.as('d')),
5423 months = round(duration.as('M')),
5424 weeks = round(duration.as('w')),
5425 years = round(duration.as('y')),
5426 a =
5427 (seconds <= thresholds.ss && ['s', seconds]) ||
5428 (seconds < thresholds.s && ['ss', seconds]) ||
5429 (minutes <= 1 && ['m']) ||
5430 (minutes < thresholds.m && ['mm', minutes]) ||
5431 (hours <= 1 && ['h']) ||
5432 (hours < thresholds.h && ['hh', hours]) ||
5433 (days <= 1 && ['d']) ||
5434 (days < thresholds.d && ['dd', days]);
5435
5436 if (thresholds.w != null) {
5437 a =
5438 a ||
5439 (weeks <= 1 && ['w']) ||
5440 (weeks < thresholds.w && ['ww', weeks]);
5441 }
5442 a = a ||
5443 (months <= 1 && ['M']) ||
5444 (months < thresholds.M && ['MM', months]) ||
5445 (years <= 1 && ['y']) || ['yy', years];
5446
5447 a[2] = withoutSuffix;
5448 a[3] = +posNegDuration > 0;
5449 a[4] = locale;
5450 return substituteTimeAgo.apply(null, a);
5451 }
5452
5453 // This function allows you to set the rounding function for relative time strings
5454 function getSetRelativeTimeRounding(roundingFunction) {
5455 if (roundingFunction === undefined) {
5456 return round;
5457 }
5458 if (typeof roundingFunction === 'function') {
5459 round = roundingFunction;
5460 return true;
5461 }
5462 return false;
5463 }
5464
5465 // This function allows you to set a threshold for relative time strings
5466 function getSetRelativeTimeThreshold(threshold, limit) {
5467 if (thresholds[threshold] === undefined) {
5468 return false;
5469 }
5470 if (limit === undefined) {
5471 return thresholds[threshold];
5472 }
5473 thresholds[threshold] = limit;
5474 if (threshold === 's') {
5475 thresholds.ss = limit - 1;
5476 }
5477 return true;
5478 }
5479
5480 function humanize(argWithSuffix, argThresholds) {
5481 if (!this.isValid()) {
5482 return this.localeData().invalidDate();
5483 }
5484
5485 var withSuffix = false,
5486 th = thresholds,
5487 locale,
5488 output;
5489
5490 if (typeof argWithSuffix === 'object') {
5491 argThresholds = argWithSuffix;
5492 argWithSuffix = false;
5493 }
5494 if (typeof argWithSuffix === 'boolean') {
5495 withSuffix = argWithSuffix;
5496 }
5497 if (typeof argThresholds === 'object') {
5498 th = Object.assign({}, thresholds, argThresholds);
5499 if (argThresholds.s != null && argThresholds.ss == null) {
5500 th.ss = argThresholds.s - 1;
5501 }
5502 }
5503
5504 locale = this.localeData();
5505 output = relativeTime$1(this, !withSuffix, th, locale);
5506
5507 if (withSuffix) {
5508 output = locale.pastFuture(+this, output);
5509 }
5510
5511 return locale.postformat(output);
5512 }
5513
5514 var abs$1 = Math.abs;
5515
5516 function sign(x) {
5517 return (x > 0) - (x < 0) || +x;
5518 }
5519
5520 function toISOString$1() {
5521 // for ISO strings we do not use the normal bubbling rules:
5522 // * milliseconds bubble up until they become hours
5523 // * days do not bubble at all
5524 // * months bubble up until they become years
5525 // This is because there is no context-free conversion between hours and days
5526 // (think of clock changes)
5527 // and also not between days and months (28-31 days per month)
5528 if (!this.isValid()) {
5529 return this.localeData().invalidDate();
5530 }
5531
5532 var seconds = abs$1(this._milliseconds) / 1000,
5533 days = abs$1(this._days),
5534 months = abs$1(this._months),
5535 minutes,
5536 hours,
5537 years,
5538 s,
5539 total = this.asSeconds(),
5540 totalSign,
5541 ymSign,
5542 daysSign,
5543 hmsSign;
5544
5545 if (!total) {
5546 // this is the same as C#'s (Noda) and python (isodate)...
5547 // but not other JS (goog.date)
5548 return 'P0D';
5549 }
5550
5551 // 3600 seconds -> 60 minutes -> 1 hour
5552 minutes = absFloor(seconds / 60);
5553 hours = absFloor(minutes / 60);
5554 seconds %= 60;
5555 minutes %= 60;
5556
5557 // 12 months -> 1 year
5558 years = absFloor(months / 12);
5559 months %= 12;
5560
5561 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
5562 s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
5563
5564 totalSign = total < 0 ? '-' : '';
5565 ymSign = sign(this._months) !== sign(total) ? '-' : '';
5566 daysSign = sign(this._days) !== sign(total) ? '-' : '';
5567 hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
5568
5569 return (
5570 totalSign +
5571 'P' +
5572 (years ? ymSign + years + 'Y' : '') +
5573 (months ? ymSign + months + 'M' : '') +
5574 (days ? daysSign + days + 'D' : '') +
5575 (hours || minutes || seconds ? 'T' : '') +
5576 (hours ? hmsSign + hours + 'H' : '') +
5577 (minutes ? hmsSign + minutes + 'M' : '') +
5578 (seconds ? hmsSign + s + 'S' : '')
5579 );
5580 }
5581
5582 var proto$2 = Duration.prototype;
5583
5584 proto$2.isValid = isValid$1;
5585 proto$2.abs = abs;
5586 proto$2.add = add$1;
5587 proto$2.subtract = subtract$1;
5588 proto$2.as = as;
5589 proto$2.asMilliseconds = asMilliseconds;
5590 proto$2.asSeconds = asSeconds;
5591 proto$2.asMinutes = asMinutes;
5592 proto$2.asHours = asHours;
5593 proto$2.asDays = asDays;
5594 proto$2.asWeeks = asWeeks;
5595 proto$2.asMonths = asMonths;
5596 proto$2.asQuarters = asQuarters;
5597 proto$2.asYears = asYears;
5598 proto$2.valueOf = valueOf$1;
5599 proto$2._bubble = bubble;
5600 proto$2.clone = clone$1;
5601 proto$2.get = get$2;
5602 proto$2.milliseconds = milliseconds;
5603 proto$2.seconds = seconds;
5604 proto$2.minutes = minutes;
5605 proto$2.hours = hours;
5606 proto$2.days = days;
5607 proto$2.weeks = weeks;
5608 proto$2.months = months;
5609 proto$2.years = years;
5610 proto$2.humanize = humanize;
5611 proto$2.toISOString = toISOString$1;
5612 proto$2.toString = toISOString$1;
5613 proto$2.toJSON = toISOString$1;
5614 proto$2.locale = locale;
5615 proto$2.localeData = localeData;
5616
5617 proto$2.toIsoString = deprecate(
5618 'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
5619 toISOString$1
5620 );
5621 proto$2.lang = lang;
5622
5623 // FORMATTING
5624
5625 addFormatToken('X', 0, 0, 'unix');
5626 addFormatToken('x', 0, 0, 'valueOf');
5627
5628 // PARSING
5629
5630 addRegexToken('x', matchSigned);
5631 addRegexToken('X', matchTimestamp);
5632 addParseToken('X', function (input, array, config) {
5633 config._d = new Date(parseFloat(input) * 1000);
5634 });
5635 addParseToken('x', function (input, array, config) {
5636 config._d = new Date(toInt(input));
5637 });
5638
5639 //! moment.js
5640
5641 hooks.version = '2.30.1';
5642
5643 setHookCallback(createLocal);
5644
5645 hooks.fn = proto;
5646 hooks.min = min;
5647 hooks.max = max;
5648 hooks.now = now;
5649 hooks.utc = createUTC;
5650 hooks.unix = createUnix;
5651 hooks.months = listMonths;
5652 hooks.isDate = isDate;
5653 hooks.locale = getSetGlobalLocale;
5654 hooks.invalid = createInvalid;
5655 hooks.duration = createDuration;
5656 hooks.isMoment = isMoment;
5657 hooks.weekdays = listWeekdays;
5658 hooks.parseZone = createInZone;
5659 hooks.localeData = getLocale;
5660 hooks.isDuration = isDuration;
5661 hooks.monthsShort = listMonthsShort;
5662 hooks.weekdaysMin = listWeekdaysMin;
5663 hooks.defineLocale = defineLocale;
5664 hooks.updateLocale = updateLocale;
5665 hooks.locales = listLocales;
5666 hooks.weekdaysShort = listWeekdaysShort;
5667 hooks.normalizeUnits = normalizeUnits;
5668 hooks.relativeTimeRounding = getSetRelativeTimeRounding;
5669 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
5670 hooks.calendarFormat = getCalendarFormat;
5671 hooks.prototype = proto;
5672
5673 // currently HTML5 input type only supports 24-hour formats
5674 hooks.HTML5_FMT = {
5675 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
5676 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
5677 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
5678 DATE: 'YYYY-MM-DD', // <input type="date" />
5679 TIME: 'HH:mm', // <input type="time" />
5680 TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
5681 TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
5682 WEEK: 'GGGG-[W]WW', // <input type="week" />
5683 MONTH: 'YYYY-MM', // <input type="month" />
5684 };
5685
5686 return hooks;
5687
5688})));