PageSourceSearch

https://payments.neiwpcc.org/wp-content/plugins/fooevents-calendar/js/moment.js?ver=2.29.3

js neiwpcc.org collected 2026-09-24 18:18:06 UTC 180,287 bytes, 5,685 lines download raw bytes

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

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.