PageSourceSearch

https://www.daltile.com/-/media/Base-Themes/Core-Libraries/scripts/moment.js

js daltile.com collected 2026-09-24 19:02:39 UTC 174,011 bytes, 5,669 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.