PageSourceSearch

https://marc-bloch.ehess.fr/js/lib/moment/moment.js

js ehess.fr collected 2026-09-24 08:39:46 UTC 182,123 bytes, 5,688 lines download raw bytes

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

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.