cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

moment.js (156326B)


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