GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

third-party/js-tools/moment.js/2.24.0/moment.js   F
last analyzed

Complexity

Total Complexity 878
Complexity/F 2.61

Size

Lines of Code 4600
Function Count 336

Duplication

Duplicated Lines 96
Ratio 2.09 %

Importance

Changes 0
Metric Value
eloc 2816
dl 96
loc 4600
rs 0.8
c 0
b 0
f 0
wmc 878
mnd 542
bc 542
fnc 336
bpm 1.613
cpm 2.613
noi 51

246 Functions

Rating   Name   Duplication   Size   Complexity  
A moment.js ➔ defaults 0 9 3
A moment.js ➔ hasOwnProp 0 3 1
A moment.js ➔ isUtcOffset 0 3 2
A moment.js ➔ unix 0 3 1
A moment.js ➔ valueOf$1 0 11 2
A moment.js ➔ createLocalOrUTC 0 23 3
A moment.js ➔ mod 0 3 1
A moment.js ➔ toNow 0 3 1
A moment.js ➔ parseIsoWeekday 0 6 3
C moment.js ➔ dayOfYearFromWeekInfo 0 56 9
A moment.js ➔ ordinal 0 3 1
A moment.js ➔ isLeapYear 0 3 1
A moment.js ➔ from 0 9 2
F moment.js ➔ copyConfig 0 46 14
A moment.js ➔ normalizeUnits 0 3 2
A moment.js ➔ shiftWeekdays 0 3 1
A moment.js ➔ createUTCDate 0 17 3
A moment.js ➔ Moment 0 14 4
A moment.js ➔ isSame 0 14 4
C moment.js ➔ isDurationValid 0 21 9
A moment.js ➔ createUTC 0 3 1
A moment.js ➔ getDaysInMonth 0 3 1
A moment.js ➔ clone$1 0 3 1
F moment.js ➔ handleStrictParse$1 33 63 20
A moment.js ➔ fromNow 0 3 1
F moment.js ➔ configFromArray 0 68 15
A moment.js ➔ isUtc 0 3 2
A moment.js ➔ daysToMonths 0 5 1
A moment.js ➔ regexEscape 0 3 1
A moment.js ➔ isLocal 0 3 2
A moment.js ➔ isMoment 0 3 1
A moment.js ➔ matchMeridiem 0 3 1
A moment.js ➔ preParsePostFormat 0 3 1
A moment.js ➔ createAdder 0 16 4
A moment.js ➔ getZoneAbbr 0 3 3
A moment.js ➔ set 0 18 3
A moment.js ➔ normalizeObjectUnits 0 16 4
A moment.js ➔ makeGetter 0 5 3
A moment.js ➔ cloneWithOffset 0 13 3
A moment.js ➔ isSameOrBefore 0 3 1
A moment.js ➔ utcStartOfDate 0 9 2
A moment.js ➔ absFloor 0 8 2
A moment.js ➔ configFromObject 0 12 3
B moment.js ➔ listWeekdaysImpl 0 35 7
A moment.js ➔ setOffsetToUTC 0 3 1
A moment.js ➔ listMonthsShort 0 3 1
A moment.js ➔ setOffsetToLocal 0 11 3
A moment.js ➔ isAfter 0 12 4
A moment.js ➔ positiveMomentsDifference 0 13 2
A moment.js ➔ localeWeek 0 3 2
A moment.js ➔ get$2 0 4 2
A moment.js ➔ createLocal 0 3 1
B moment.js ➔ getCalendarFormat 0 9 7
A moment.js ➔ creationData 0 9 1
A moment.js ➔ expandFormat 0 16 3
A moment.js ➔ toObject 0 12 1
A moment.js ➔ addTimeToArrayFromToken 0 5 2
A moment.js ➔ isFunction 0 3 1
A moment.js ➔ getSetDayOfWeek 0 12 5
A moment.js ➔ setOffsetToParsedOffset 0 14 4
A moment.js ➔ getSetWeek 0 4 2
B moment.js ➔ computeMonthsParse 0 33 5
B moment.js ➔ makeFormatFunction 0 19 6
A moment.js ➔ addWeekYearFormatToken 0 3 3
A moment.js ➔ getPrioritizedUnits 0 10 3
A moment.js ➔ invalidDate 0 3 1
C moment.js ➔ localeIsPM 0 5 9
B moment.js ➔ as 0 33 5
A moment.js ➔ getZoneName 0 3 2
A moment.js ➔ get$1 0 5 1
A moment.js ➔ untruncateYear 0 9 3
A moment.js ➔ getSetISOWeekYear 0 4 1
A moment.js ➔ parsingFlags 0 3 1
A moment.js ➔ map 0 7 2
A moment.js ➔ stringSet 0 15 4
B moment.js ➔ daysInMonth 0 8 8
A moment.js ➔ extend 0 17 5
A moment.js ➔ currentDateArray 0 8 2
A moment.js ➔ mod$1 0 3 1
A moment.js ➔ calendar$1 0 11 2
A moment.js ➔ listWeekdays 0 3 1
A moment.js ➔ isValid$1 0 3 1
A moment.js ➔ createUnix 0 3 1
A moment.js ➔ locale 0 13 3
A moment.js ➔ isSameOrAfter 0 3 1
B moment.js ➔ addFormatToken 0 21 8
A moment.js ➔ getSetWeekYearHelper 0 12 3
A moment.js ➔ checkWeekday 0 13 3
A moment.js ➔ subtract$1 0 3 1
B moment.js ➔ setMonth 0 24 6
A moment.js ➔ createInZone 0 3 1
A moment.js ➔ localeWeekdays 0 6 5
A moment.js ➔ add$1 0 3 1
B moment.js ➔ configFromStringAndArray 0 43 6
B moment.js ➔ meridiemFixWrap 0 24 6
A moment.js ➔ absRound 0 7 2
C moment.js ➔ defineLocale 0 51 9
A moment.js ➔ get 0 4 3
A moment.js ➔ weeksInYear 0 5 1
C moment.js ➔ createDuration 0 60 11
B moment.js ➔ monthsRegex 0 18 6
A moment.js ➔ localStartOfDate 0 9 2
A moment.js ➔ relativeTime 0 6 2
A moment.js ➔ getLocale 0 22 5
A moment.js ➔ stringGet 0 7 2
D moment.js ➔ configFromISO 0 51 12
A moment.js ➔ configFromString 0 25 4
A moment.js ➔ getSetISOWeek 0 4 2
A moment.js ➔ sign 0 3 1
A moment.js ➔ absCeil 0 7 2
A moment.js ➔ listWeekdaysMin 0 3 1
A moment.js ➔ listWeekdaysShort 0 3 1
A moment.js ➔ bubble 0 46 2
A moment.js ➔ toArray 0 4 1
A moment.js ➔ localeMeridiem 0 7 4
A moment.js ➔ zeroFill 0 7 3
B moment.js ➔ startOf 0 47 5
F moment.js ➔ configFromStringAndFormat 27 70 15
A moment.js ➔ monthDiff 0 20 2
C moment.js ➔ localeWeekdaysParse 0 39 10
A moment.js ➔ localeWeekdaysShort 0 4 3
A moment.js ➔ parseIso 0 8 2
A moment.js ➔ toJSON 0 4 2
A moment.js ➔ min 0 5 1
A moment.js ➔ to 0 9 2
A moment.js ➔ calculateOffset 0 12 3
B moment.js ➔ updateLocale 0 27 6
A moment.js ➔ inspect 0 17 5
B moment.js ➔ chooseLocale 23 23 6
A moment.js ➔ momentsDifference 0 17 3
A moment.js ➔ getSetRelativeTimeRounding 0 10 3
A moment.js ➔ hasAlignedHourOffset 0 8 3
A moment.js ➔ listMonthsImpl 0 19 4
B moment.js ➔ toISOString 0 19 8
A moment.js ➔ getSetQuarter 0 3 3
D moment.js ➔ localeMonths 0 8 13
A moment.js ➔ localeData 0 3 3
D moment.js ➔ handleStrictParse 0 40 12
A moment.js ➔ Locale 0 5 2
A moment.js ➔ offset 0 11 3
B moment.js ➔ addSubtract 0 25 7
B moment.js ➔ deprecate 0 29 7
A moment.js ➔ isArray 0 3 1
B moment.js ➔ abs 0 16 6
A moment.js ➔ listMonths 0 3 1
A moment.js ➔ max 0 5 1
B moment.js ➔ monthsShortRegex 0 18 6
B moment.js ➔ meridiem 0 5 6
A moment.js ➔ hooks 0 3 5
A moment.js ➔ preprocessRFC2822 0 4 1
A moment.js ➔ getSetGlobalLocale 0 24 5
A moment.js ➔ isNumber 0 3 1
A moment.js ➔ dayOfYearFromWeeks 0 22 3
A moment.js ➔ pastFuture 0 4 3
B moment.js ➔ endOf 0 47 5
A moment.js ➔ isDaylightSavingTime 0 6 1
A moment.js ➔ getIsLeapYear 0 3 3
A moment.js ➔ normalizeLocale 0 3 2
A moment.js ➔ addParseToken 0 14 5
A moment.js ➔ deprecateSimple 0 9 3
A moment.js ➔ getParsingFlags 0 6 2
A moment.js ➔ clone 0 3 1
A moment.js ➔ isDuration 0 3 1
B moment.js ➔ mergeConfigs 0 25 7
B moment.js ➔ weekdaysMinRegex 0 18 6
C moment.js ➔ isValid 0 33 9
A moment.js ➔ createInvalid 0 11 2
C moment.js ➔ checkOverflow 0 29 11
A moment.js ➔ addSubtract$1 0 9 1
A moment.js ➔ getDateOffset 0 5 1
A moment.js ➔ extractFromRFC2822Strings 0 15 2
A moment.js ➔ isUndefined 0 3 1
A moment.js ➔ setHookCallback 0 3 1
A moment.js ➔ unescapeFormat 0 5 2
A moment.js ➔ Duration 0 36 1
A moment.js ➔ setWeekAll 0 9 1
A moment.js ➔ toInt 0 10 2
B moment.js ➔ diff 0 33 5
A moment.js ➔ longDateFormat 0 14 3
D moment.js ➔ parseWeekday 0 16 13
A moment.js ➔ isDate 0 3 1
A moment.js ➔ compareArrays 13 13 3
A moment.js ➔ computeWeekdaysParse 0 40 4
A moment.js ➔ createInvalid$1 0 3 1
A moment.js ➔ format 0 7 3
A moment.js ➔ toDate 0 3 1
F moment.js ➔ toISOString$1 0 57 15
A moment.js ➔ humanize 0 14 3
A moment.js ➔ localeMonthsShort 0 8 5
B moment.js ➔ configFromInput 0 22 8
A moment.js ➔ createFromConfig 0 10 2
B moment.js ➔ weekdaysShortRegex 0 18 6
A moment.js ➔ getISOWeeksInYear 0 3 1
A moment.js ➔ formatMoment 0 10 2
A moment.js ➔ isObjectEmpty 0 13 4
A moment.js ➔ weeks 0 3 1
B moment.js ➔ isBetween 0 10 6
A moment.js ➔ toString 0 3 1
B moment.js ➔ weekdaysRegex 0 18 6
A moment.js ➔ kFormat 0 3 1
F moment.js ➔ getSetOffset 0 37 14
A moment.js ➔ makeAs 0 5 2
A moment.js ➔ loadLocale 0 14 3
A moment.js ➔ isDaylightSavingTimeShifted 0 20 4
A moment.js ➔ warn 0 6 2
A moment.js ➔ isObject 0 5 1
A moment.js ➔ valueOf 0 3 1
A moment.js ➔ invalidAt 0 3 1
C moment.js ➔ daysInYear 0 3 9
A moment.js ➔ offsetFromString 0 15 5
A moment.js ➔ getSetISODayOfWeek 0 16 5
A moment.js ➔ removeFormattingTokens 0 6 2
A moment.js ➔ addUnitPriority 0 3 1
A moment.js ➔ getSetWeekYear 0 8 3
C moment.js ➔ localeMonthsParse 0 37 9
A moment.js ➔ addRegexToken 0 5 4
A moment.js ➔ substituteTimeAgo 0 3 1
A moment.js ➔ isValid$2 0 3 1
A moment.js ➔ firstWeekOffset 0 8 1
A moment.js ➔ addUnitAlias 0 4 1
A moment.js ➔ getParseRegexForToken 0 7 2
A moment.js ➔ monthsToDays 0 4 1
B moment.js ➔ prepareConfig 0 32 8
A moment.js ➔ getSetLocaleDayOfWeek 0 7 4
A moment.js ➔ set$1 0 10 5
A moment.js ➔ getSetMonth 0 9 2
A moment.js ➔ hFormat 0 3 1
A moment.js ➔ localeFirstDayOfWeek 0 3 1
A moment.js ➔ listLocales 0 3 1
A moment.js ➔ makeGetSet 0 11 3
A moment.js ➔ isBefore 0 12 4
C moment.js ➔ pickBy 0 16 11
A moment.js ➔ defaultParsingFlags 0 19 1
C moment.js ➔ parseMs 0 3 10
A moment.js ➔ createDate 0 17 3
A moment.js ➔ getSetZone 0 13 3
B moment.js ➔ getSetDayOfYear 0 4 6
A moment.js ➔ relativeTime$1 0 26 1
A moment.js ➔ getSetRelativeTimeThreshold 0 13 4
A moment.js ➔ configFromRFC2822 0 19 3
A moment.js ➔ addWeekParseToken 0 6 2
A moment.js ➔ localeFirstDayOfYear 0 3 1
A moment.js ➔ localeWeekdaysMin 0 4 3
A moment.js ➔ getWeeksInYear 0 4 1
A moment.js ➔ weekOfYear 0 21 3
B moment.js ➔ calendar 0 4 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like third-party/js-tools/moment.js/2.24.0/moment.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
//! moment.js
2
3
;(function (global, factory) {
4
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
5
    typeof define === 'function' && define.amd ? define(factory) :
6
    global.moment = factory()
7
}(this, (function () { 'use strict';
8
9
    var hookCallback;
10
11
    function hooks () {
12
        return hookCallback.apply(null, arguments);
13
    }
14
15
    // This is done to register the method called with moment()
16
    // without creating circular dependencies.
17
    function setHookCallback (callback) {
18
        hookCallback = callback;
19
    }
20
21
    function isArray(input) {
22
        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
23
    }
24
25
    function isObject(input) {
26
        // IE8 will treat undefined and null as object if it wasn't for
27
        // input != null
28
        return input != null && Object.prototype.toString.call(input) === '[object Object]';
29
    }
30
31
    function isObjectEmpty(obj) {
32
        if (Object.getOwnPropertyNames) {
33
            return (Object.getOwnPropertyNames(obj).length === 0);
34
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
35
            var k;
36
            for (k in obj) {
37
                if (obj.hasOwnProperty(k)) {
38
                    return false;
39
                }
40
            }
41
            return true;
42
        }
43
    }
44
45
    function isUndefined(input) {
46
        return input === void 0;
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
47
    }
48
49
    function isNumber(input) {
50
        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
51
    }
52
53
    function isDate(input) {
54
        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
55
    }
56
57
    function map(arr, fn) {
58
        var res = [], i;
59
        for (i = 0; i < arr.length; ++i) {
60
            res.push(fn(arr[i], i));
61
        }
62
        return res;
63
    }
64
65
    function hasOwnProp(a, b) {
66
        return Object.prototype.hasOwnProperty.call(a, b);
67
    }
68
69
    function extend(a, b) {
70
        for (var i in b) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
71
            if (hasOwnProp(b, i)) {
72
                a[i] = b[i];
73
            }
74
        }
75
76
        if (hasOwnProp(b, 'toString')) {
77
            a.toString = b.toString;
78
        }
79
80
        if (hasOwnProp(b, 'valueOf')) {
81
            a.valueOf = b.valueOf;
82
        }
83
84
        return a;
85
    }
86
87
    function createUTC (input, format, locale, strict) {
88
        return createLocalOrUTC(input, format, locale, strict, true).utc();
89
    }
90
91
    function defaultParsingFlags() {
92
        // We need to deep clone this object.
93
        return {
94
            empty           : false,
95
            unusedTokens    : [],
96
            unusedInput     : [],
97
            overflow        : -2,
98
            charsLeftOver   : 0,
99
            nullInput       : false,
100
            invalidMonth    : null,
101
            invalidFormat   : false,
102
            userInvalidated : false,
103
            iso             : false,
104
            parsedDateParts : [],
105
            meridiem        : null,
106
            rfc2822         : false,
107
            weekdayMismatch : false
108
        };
109
    }
110
111
    function getParsingFlags(m) {
112
        if (m._pf == null) {
113
            m._pf = defaultParsingFlags();
114
        }
115
        return m._pf;
116
    }
117
118
    var some;
119
    if (Array.prototype.some) {
120
        some = Array.prototype.some;
121
    } else {
122
        some = function (fun) {
123
            var t = Object(this);
124
            var len = t.length >>> 0;
125
126
            for (var i = 0; i < len; i++) {
127
                if (i in t && fun.call(this, t[i], i, t)) {
128
                    return true;
129
                }
130
            }
131
132
            return false;
133
        };
134
    }
135
136
    function isValid(m) {
137
        if (m._isValid == null) {
138
            var flags = getParsingFlags(m);
139
            var parsedParts = some.call(flags.parsedDateParts, function (i) {
140
                return i != null;
141
            });
142
            var isNowValid = !isNaN(m._d.getTime()) &&
143
                flags.overflow < 0 &&
144
                !flags.empty &&
145
                !flags.invalidMonth &&
146
                !flags.invalidWeekday &&
147
                !flags.weekdayMismatch &&
148
                !flags.nullInput &&
149
                !flags.invalidFormat &&
150
                !flags.userInvalidated &&
151
                (!flags.meridiem || (flags.meridiem && parsedParts));
152
153
            if (m._strict) {
154
                isNowValid = isNowValid &&
155
                    flags.charsLeftOver === 0 &&
156
                    flags.unusedTokens.length === 0 &&
157
                    flags.bigHour === undefined;
158
            }
159
160
            if (Object.isFrozen == null || !Object.isFrozen(m)) {
161
                m._isValid = isNowValid;
162
            }
163
            else {
164
                return isNowValid;
165
            }
166
        }
167
        return m._isValid;
168
    }
169
170
    function createInvalid (flags) {
171
        var m = createUTC(NaN);
172
        if (flags != null) {
173
            extend(getParsingFlags(m), flags);
174
        }
175
        else {
176
            getParsingFlags(m).userInvalidated = true;
177
        }
178
179
        return m;
180
    }
181
182
    // Plugins that add properties should also add the key here (null value),
183
    // so we can properly clone ourselves.
184
    var momentProperties = hooks.momentProperties = [];
185
186
    function copyConfig(to, from) {
187
        var i, prop, val;
188
189
        if (!isUndefined(from._isAMomentObject)) {
190
            to._isAMomentObject = from._isAMomentObject;
191
        }
192
        if (!isUndefined(from._i)) {
193
            to._i = from._i;
194
        }
195
        if (!isUndefined(from._f)) {
196
            to._f = from._f;
197
        }
198
        if (!isUndefined(from._l)) {
199
            to._l = from._l;
200
        }
201
        if (!isUndefined(from._strict)) {
202
            to._strict = from._strict;
203
        }
204
        if (!isUndefined(from._tzm)) {
205
            to._tzm = from._tzm;
206
        }
207
        if (!isUndefined(from._isUTC)) {
208
            to._isUTC = from._isUTC;
209
        }
210
        if (!isUndefined(from._offset)) {
211
            to._offset = from._offset;
212
        }
213
        if (!isUndefined(from._pf)) {
214
            to._pf = getParsingFlags(from);
215
        }
216
        if (!isUndefined(from._locale)) {
217
            to._locale = from._locale;
218
        }
219
220
        if (momentProperties.length > 0) {
221
            for (i = 0; i < momentProperties.length; i++) {
222
                prop = momentProperties[i];
223
                val = from[prop];
224
                if (!isUndefined(val)) {
225
                    to[prop] = val;
226
                }
227
            }
228
        }
229
230
        return to;
231
    }
232
233
    var updateInProgress = false;
234
235
    // Moment prototype object
236
    function Moment(config) {
237
        copyConfig(this, config);
238
        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
239
        if (!this.isValid()) {
240
            this._d = new Date(NaN);
241
        }
242
        // Prevent infinite loop in case updateOffset creates new moment
243
        // objects.
244
        if (updateInProgress === false) {
245
            updateInProgress = true;
246
            hooks.updateOffset(this);
247
            updateInProgress = false;
248
        }
249
    }
250
251
    function isMoment (obj) {
252
        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
253
    }
254
255
    function absFloor (number) {
256
        if (number < 0) {
257
            // -0 -> 0
258
            return Math.ceil(number) || 0;
259
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
260
            return Math.floor(number);
261
        }
262
    }
263
264
    function toInt(argumentForCoercion) {
265
        var coercedNumber = +argumentForCoercion,
266
            value = 0;
267
268
        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
269
            value = absFloor(coercedNumber);
270
        }
271
272
        return value;
273
    }
274
275
    // compare two arrays, return the number of differences
276 View Code Duplication
    function compareArrays(array1, array2, dontConvert) {
277
        var len = Math.min(array1.length, array2.length),
278
            lengthDiff = Math.abs(array1.length - array2.length),
279
            diffs = 0,
280
            i;
281
        for (i = 0; i < len; i++) {
282
            if ((dontConvert && array1[i] !== array2[i]) ||
283
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
284
                diffs++;
285
            }
286
        }
287
        return diffs + lengthDiff;
288
    }
289
290
    function warn(msg) {
291
        if (hooks.suppressDeprecationWarnings === false &&
292
                (typeof console !==  'undefined') && console.warn) {
293
            console.warn('Deprecation warning: ' + msg);
294
        }
295
    }
296
297
    function deprecate(msg, fn) {
298
        var firstTime = true;
299
300
        return extend(function () {
301
            if (hooks.deprecationHandler != null) {
302
                hooks.deprecationHandler(null, msg);
303
            }
304
            if (firstTime) {
305
                var args = [];
306
                var arg;
307
                for (var i = 0; i < arguments.length; i++) {
308
                    arg = '';
309
                    if (typeof arguments[i] === 'object') {
310
                        arg += '\n[' + i + '] ';
311
                        for (var key in arguments[0]) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
312
                            arg += key + ': ' + arguments[0][key] + ', ';
313
                        }
314
                        arg = arg.slice(0, -2); // Remove trailing comma and space
315
                    } else {
316
                        arg = arguments[i];
317
                    }
318
                    args.push(arg);
319
                }
320
                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
321
                firstTime = false;
322
            }
323
            return fn.apply(this, arguments);
324
        }, fn);
325
    }
326
327
    var deprecations = {};
328
329
    function deprecateSimple(name, msg) {
330
        if (hooks.deprecationHandler != null) {
331
            hooks.deprecationHandler(name, msg);
332
        }
333
        if (!deprecations[name]) {
334
            warn(msg);
335
            deprecations[name] = true;
336
        }
337
    }
338
339
    hooks.suppressDeprecationWarnings = false;
340
    hooks.deprecationHandler = null;
341
342
    function isFunction(input) {
343
        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
344
    }
345
346
    function set (config) {
347
        var prop, i;
348
        for (i in config) {
349
            prop = config[i];
350
            if (isFunction(prop)) {
351
                this[i] = prop;
352
            } else {
353
                this['_' + i] = prop;
354
            }
355
        }
356
        this._config = config;
357
        // Lenient ordinal parsing accepts just a number in addition to
358
        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
359
        // TODO: Remove "ordinalParse" fallback in next major release.
360
        this._dayOfMonthOrdinalParseLenient = new RegExp(
361
            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
362
                '|' + (/\d{1,2}/).source);
363
    }
364
365
    function mergeConfigs(parentConfig, childConfig) {
366
        var res = extend({}, parentConfig), prop;
367
        for (prop in childConfig) {
368
            if (hasOwnProp(childConfig, prop)) {
369
                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
370
                    res[prop] = {};
371
                    extend(res[prop], parentConfig[prop]);
372
                    extend(res[prop], childConfig[prop]);
373
                } else if (childConfig[prop] != null) {
374
                    res[prop] = childConfig[prop];
375
                } else {
376
                    delete res[prop];
377
                }
378
            }
379
        }
380
        for (prop in parentConfig) {
381
            if (hasOwnProp(parentConfig, prop) &&
382
                    !hasOwnProp(childConfig, prop) &&
383
                    isObject(parentConfig[prop])) {
384
                // make sure changes to properties don't modify parent config
385
                res[prop] = extend({}, res[prop]);
386
            }
387
        }
388
        return res;
389
    }
390
391
    function Locale(config) {
392
        if (config != null) {
393
            this.set(config);
394
        }
395
    }
396
397
    var keys;
398
399
    if (Object.keys) {
400
        keys = Object.keys;
401
    } else {
402
        keys = function (obj) {
403
            var i, res = [];
404
            for (i in obj) {
405
                if (hasOwnProp(obj, i)) {
406
                    res.push(i);
407
                }
408
            }
409
            return res;
410
        };
411
    }
412
413
    var defaultCalendar = {
414
        sameDay : '[Today at] LT',
415
        nextDay : '[Tomorrow at] LT',
416
        nextWeek : 'dddd [at] LT',
417
        lastDay : '[Yesterday at] LT',
418
        lastWeek : '[Last] dddd [at] LT',
419
        sameElse : 'L'
420
    };
421
422
    function calendar (key, mom, now) {
423
        var output = this._calendar[key] || this._calendar['sameElse'];
424
        return isFunction(output) ? output.call(mom, now) : output;
425
    }
426
427
    var defaultLongDateFormat = {
428
        LTS  : 'h:mm:ss A',
429
        LT   : 'h:mm A',
430
        L    : 'MM/DD/YYYY',
431
        LL   : 'MMMM D, YYYY',
432
        LLL  : 'MMMM D, YYYY h:mm A',
433
        LLLL : 'dddd, MMMM D, YYYY h:mm A'
434
    };
435
436
    function longDateFormat (key) {
437
        var format = this._longDateFormat[key],
438
            formatUpper = this._longDateFormat[key.toUpperCase()];
439
440
        if (format || !formatUpper) {
441
            return format;
442
        }
443
444
        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
445
            return val.slice(1);
446
        });
447
448
        return this._longDateFormat[key];
449
    }
450
451
    var defaultInvalidDate = 'Invalid date';
452
453
    function invalidDate () {
454
        return this._invalidDate;
455
    }
456
457
    var defaultOrdinal = '%d';
458
    var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
459
460
    function ordinal (number) {
461
        return this._ordinal.replace('%d', number);
462
    }
463
464
    var defaultRelativeTime = {
465
        future : 'in %s',
466
        past   : '%s ago',
467
        s  : 'a few seconds',
468
        ss : '%d seconds',
469
        m  : 'a minute',
470
        mm : '%d minutes',
471
        h  : 'an hour',
472
        hh : '%d hours',
473
        d  : 'a day',
474
        dd : '%d days',
475
        M  : 'a month',
476
        MM : '%d months',
477
        y  : 'a year',
478
        yy : '%d years'
479
    };
480
481
    function relativeTime (number, withoutSuffix, string, isFuture) {
482
        var output = this._relativeTime[string];
483
        return (isFunction(output)) ?
484
            output(number, withoutSuffix, string, isFuture) :
485
            output.replace(/%d/i, number);
486
    }
487
488
    function pastFuture (diff, output) {
489
        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
490
        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
491
    }
492
493
    var aliases = {};
494
495
    function addUnitAlias (unit, shorthand) {
496
        var lowerCase = unit.toLowerCase();
497
        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
498
    }
499
500
    function normalizeUnits(units) {
501
        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
502
    }
503
504
    function normalizeObjectUnits(inputObject) {
505
        var normalizedInput = {},
506
            normalizedProp,
507
            prop;
508
509
        for (prop in inputObject) {
510
            if (hasOwnProp(inputObject, prop)) {
511
                normalizedProp = normalizeUnits(prop);
512
                if (normalizedProp) {
513
                    normalizedInput[normalizedProp] = inputObject[prop];
514
                }
515
            }
516
        }
517
518
        return normalizedInput;
519
    }
520
521
    var priorities = {};
522
523
    function addUnitPriority(unit, priority) {
524
        priorities[unit] = priority;
525
    }
526
527
    function getPrioritizedUnits(unitsObj) {
528
        var units = [];
529
        for (var u in unitsObj) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
530
            units.push({unit: u, priority: priorities[u]});
531
        }
532
        units.sort(function (a, b) {
533
            return a.priority - b.priority;
534
        });
535
        return units;
536
    }
537
538
    function zeroFill(number, targetLength, forceSign) {
539
        var absNumber = '' + Math.abs(number),
540
            zerosToFill = targetLength - absNumber.length,
541
            sign = number >= 0;
542
        return (sign ? (forceSign ? '+' : '') : '-') +
543
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
544
    }
545
546
    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
547
548
    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
549
550
    var formatFunctions = {};
551
552
    var formatTokenFunctions = {};
553
554
    // token:    'M'
555
    // padded:   ['MM', 2]
556
    // ordinal:  'Mo'
557
    // callback: function () { this.month() + 1 }
558
    function addFormatToken (token, padded, ordinal, callback) {
559
        var func = callback;
560
        if (typeof callback === 'string') {
561
            func = function () {
562
                return this[callback]();
563
            };
564
        }
565
        if (token) {
566
            formatTokenFunctions[token] = func;
567
        }
568
        if (padded) {
569
            formatTokenFunctions[padded[0]] = function () {
570
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
571
            };
572
        }
573
        if (ordinal) {
574
            formatTokenFunctions[ordinal] = function () {
575
                return this.localeData().ordinal(func.apply(this, arguments), token);
576
            };
577
        }
578
    }
579
580
    function removeFormattingTokens(input) {
581
        if (input.match(/\[[\s\S]/)) {
582
            return input.replace(/^\[|\]$/g, '');
583
        }
584
        return input.replace(/\\/g, '');
585
    }
586
587
    function makeFormatFunction(format) {
588
        var array = format.match(formattingTokens), i, length;
589
590
        for (i = 0, length = array.length; i < length; i++) {
591
            if (formatTokenFunctions[array[i]]) {
592
                array[i] = formatTokenFunctions[array[i]];
593
            } else {
594
                array[i] = removeFormattingTokens(array[i]);
595
            }
596
        }
597
598
        return function (mom) {
599
            var output = '', i;
600
            for (i = 0; i < length; i++) {
601
                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
602
            }
603
            return output;
604
        };
605
    }
606
607
    // format date using native date object
608
    function formatMoment(m, format) {
609
        if (!m.isValid()) {
610
            return m.localeData().invalidDate();
611
        }
612
613
        format = expandFormat(format, m.localeData());
614
        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
615
616
        return formatFunctions[format](m);
617
    }
618
619
    function expandFormat(format, locale) {
620
        var i = 5;
621
622
        function replaceLongDateFormatTokens(input) {
623
            return locale.longDateFormat(input) || input;
624
        }
625
626
        localFormattingTokens.lastIndex = 0;
627
        while (i >= 0 && localFormattingTokens.test(format)) {
628
            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
629
            localFormattingTokens.lastIndex = 0;
630
            i -= 1;
631
        }
632
633
        return format;
634
    }
635
636
    var match1         = /\d/;            //       0 - 9
637
    var match2         = /\d\d/;          //      00 - 99
638
    var match3         = /\d{3}/;         //     000 - 999
639
    var match4         = /\d{4}/;         //    0000 - 9999
640
    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
641
    var match1to2      = /\d\d?/;         //       0 - 99
642
    var match3to4      = /\d\d\d\d?/;     //     999 - 9999
643
    var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
644
    var match1to3      = /\d{1,3}/;       //       0 - 999
645
    var match1to4      = /\d{1,4}/;       //       0 - 9999
646
    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
647
648
    var matchUnsigned  = /\d+/;           //       0 - inf
649
    var matchSigned    = /[+-]?\d+/;      //    -inf - inf
650
651
    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
652
    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
653
654
    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
655
656
    // any word (or two) characters or numbers including two/three word month in arabic.
657
    // includes scottish gaelic two word and hyphenated months
658
    var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
659
660
    var regexes = {};
661
662
    function addRegexToken (token, regex, strictRegex) {
663
        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
664
            return (isStrict && strictRegex) ? strictRegex : regex;
665
        };
666
    }
667
668
    function getParseRegexForToken (token, config) {
669
        if (!hasOwnProp(regexes, token)) {
670
            return new RegExp(unescapeFormat(token));
671
        }
672
673
        return regexes[token](config._strict, config._locale);
674
    }
675
676
    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
677
    function unescapeFormat(s) {
678
        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
679
            return p1 || p2 || p3 || p4;
680
        }));
681
    }
682
683
    function regexEscape(s) {
684
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
685
    }
686
687
    var tokens = {};
688
689
    function addParseToken (token, callback) {
690
        var i, func = callback;
691
        if (typeof token === 'string') {
692
            token = [token];
693
        }
694
        if (isNumber(callback)) {
695
            func = function (input, array) {
696
                array[callback] = toInt(input);
697
            };
698
        }
699
        for (i = 0; i < token.length; i++) {
700
            tokens[token[i]] = func;
701
        }
702
    }
703
704
    function addWeekParseToken (token, callback) {
705
        addParseToken(token, function (input, array, config, token) {
706
            config._w = config._w || {};
707
            callback(input, config._w, config, token);
708
        });
709
    }
710
711
    function addTimeToArrayFromToken(token, input, config) {
712
        if (input != null && hasOwnProp(tokens, token)) {
713
            tokens[token](input, config._a, config, token);
714
        }
715
    }
716
717
    var YEAR = 0;
718
    var MONTH = 1;
719
    var DATE = 2;
720
    var HOUR = 3;
721
    var MINUTE = 4;
722
    var SECOND = 5;
723
    var MILLISECOND = 6;
724
    var WEEK = 7;
725
    var WEEKDAY = 8;
726
727
    // FORMATTING
728
729
    addFormatToken('Y', 0, 0, function () {
730
        var y = this.year();
731
        return y <= 9999 ? '' + y : '+' + y;
732
    });
733
734
    addFormatToken(0, ['YY', 2], 0, function () {
735
        return this.year() % 100;
736
    });
737
738
    addFormatToken(0, ['YYYY',   4],       0, 'year');
739
    addFormatToken(0, ['YYYYY',  5],       0, 'year');
740
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
741
742
    // ALIASES
743
744
    addUnitAlias('year', 'y');
745
746
    // PRIORITIES
747
748
    addUnitPriority('year', 1);
749
750
    // PARSING
751
752
    addRegexToken('Y',      matchSigned);
753
    addRegexToken('YY',     match1to2, match2);
754
    addRegexToken('YYYY',   match1to4, match4);
755
    addRegexToken('YYYYY',  match1to6, match6);
756
    addRegexToken('YYYYYY', match1to6, match6);
757
758
    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
759
    addParseToken('YYYY', function (input, array) {
760
        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
761
    });
762
    addParseToken('YY', function (input, array) {
763
        array[YEAR] = hooks.parseTwoDigitYear(input);
764
    });
765
    addParseToken('Y', function (input, array) {
766
        array[YEAR] = parseInt(input, 10);
767
    });
768
769
    // HELPERS
770
771
    function daysInYear(year) {
772
        return isLeapYear(year) ? 366 : 365;
773
    }
774
775
    function isLeapYear(year) {
776
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
777
    }
778
779
    // HOOKS
780
781
    hooks.parseTwoDigitYear = function (input) {
782
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
783
    };
784
785
    // MOMENTS
786
787
    var getSetYear = makeGetSet('FullYear', true);
788
789
    function getIsLeapYear () {
790
        return isLeapYear(this.year());
791
    }
792
793
    function makeGetSet (unit, keepTime) {
794
        return function (value) {
795
            if (value != null) {
796
                set$1(this, unit, value);
797
                hooks.updateOffset(this, keepTime);
798
                return this;
799
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
800
                return get(this, unit);
801
            }
802
        };
803
    }
804
805
    function get (mom, unit) {
806
        return mom.isValid() ?
807
            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
808
    }
809
810
    function set$1 (mom, unit, value) {
811
        if (mom.isValid() && !isNaN(value)) {
812
            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
813
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
814
            }
815
            else {
816
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
817
            }
818
        }
819
    }
820
821
    // MOMENTS
822
823
    function stringGet (units) {
824
        units = normalizeUnits(units);
825
        if (isFunction(this[units])) {
826
            return this[units]();
827
        }
828
        return this;
829
    }
830
831
832
    function stringSet (units, value) {
833
        if (typeof units === 'object') {
834
            units = normalizeObjectUnits(units);
835
            var prioritized = getPrioritizedUnits(units);
836
            for (var i = 0; i < prioritized.length; i++) {
837
                this[prioritized[i].unit](units[prioritized[i].unit]);
838
            }
839
        } else {
840
            units = normalizeUnits(units);
841
            if (isFunction(this[units])) {
842
                return this[units](value);
843
            }
844
        }
845
        return this;
846
    }
847
848
    function mod(n, x) {
849
        return ((n % x) + x) % x;
850
    }
851
852
    var indexOf;
853
854
    if (Array.prototype.indexOf) {
855
        indexOf = Array.prototype.indexOf;
856
    } else {
857
        indexOf = function (o) {
858
            // I know
859
            var i;
860
            for (i = 0; i < this.length; ++i) {
861
                if (this[i] === o) {
862
                    return i;
863
                }
864
            }
865
            return -1;
866
        };
867
    }
868
869
    function daysInMonth(year, month) {
870
        if (isNaN(year) || isNaN(month)) {
871
            return NaN;
872
        }
873
        var modMonth = mod(month, 12);
874
        year += (month - modMonth) / 12;
875
        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
876
    }
877
878
    // FORMATTING
879
880
    addFormatToken('M', ['MM', 2], 'Mo', function () {
881
        return this.month() + 1;
882
    });
883
884
    addFormatToken('MMM', 0, 0, function (format) {
885
        return this.localeData().monthsShort(this, format);
886
    });
887
888
    addFormatToken('MMMM', 0, 0, function (format) {
889
        return this.localeData().months(this, format);
890
    });
891
892
    // ALIASES
893
894
    addUnitAlias('month', 'M');
895
896
    // PRIORITY
897
898
    addUnitPriority('month', 8);
899
900
    // PARSING
901
902
    addRegexToken('M',    match1to2);
903
    addRegexToken('MM',   match1to2, match2);
904
    addRegexToken('MMM',  function (isStrict, locale) {
905
        return locale.monthsShortRegex(isStrict);
906
    });
907
    addRegexToken('MMMM', function (isStrict, locale) {
908
        return locale.monthsRegex(isStrict);
909
    });
910
911
    addParseToken(['M', 'MM'], function (input, array) {
912
        array[MONTH] = toInt(input) - 1;
913
    });
914
915
    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
916
        var month = config._locale.monthsParse(input, token, config._strict);
917
        // if we didn't find a month name, mark the date as invalid.
918
        if (month != null) {
919
            array[MONTH] = month;
920
        } else {
921
            getParsingFlags(config).invalidMonth = input;
922
        }
923
    });
924
925
    // LOCALES
926
927
    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
928
    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
929
    function localeMonths (m, format) {
930
        if (!m) {
931
            return isArray(this._months) ? this._months :
932
                this._months['standalone'];
933
        }
934
        return isArray(this._months) ? this._months[m.month()] :
935
            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
936
    }
937
938
    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
939
    function localeMonthsShort (m, format) {
940
        if (!m) {
941
            return isArray(this._monthsShort) ? this._monthsShort :
942
                this._monthsShort['standalone'];
943
        }
944
        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
945
            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
946
    }
947
948
    function handleStrictParse(monthName, format, strict) {
949
        var i, ii, mom, llc = monthName.toLocaleLowerCase();
950
        if (!this._monthsParse) {
951
            // this is not used
952
            this._monthsParse = [];
953
            this._longMonthsParse = [];
954
            this._shortMonthsParse = [];
955
            for (i = 0; i < 12; ++i) {
956
                mom = createUTC([2000, i]);
957
                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
958
                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
959
            }
960
        }
961
962
        if (strict) {
963
            if (format === 'MMM') {
964
                ii = indexOf.call(this._shortMonthsParse, llc);
965
                return ii !== -1 ? ii : null;
966
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
967
                ii = indexOf.call(this._longMonthsParse, llc);
968
                return ii !== -1 ? ii : null;
969
            }
970
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
971
            if (format === 'MMM') {
972
                ii = indexOf.call(this._shortMonthsParse, llc);
973
                if (ii !== -1) {
974
                    return ii;
975
                }
976
                ii = indexOf.call(this._longMonthsParse, llc);
977
                return ii !== -1 ? ii : null;
978
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
979
                ii = indexOf.call(this._longMonthsParse, llc);
980
                if (ii !== -1) {
981
                    return ii;
982
                }
983
                ii = indexOf.call(this._shortMonthsParse, llc);
984
                return ii !== -1 ? ii : null;
985
            }
986
        }
987
    }
988
989
    function localeMonthsParse (monthName, format, strict) {
990
        var i, mom, regex;
991
992
        if (this._monthsParseExact) {
993
            return handleStrictParse.call(this, monthName, format, strict);
994
        }
995
996
        if (!this._monthsParse) {
997
            this._monthsParse = [];
998
            this._longMonthsParse = [];
999
            this._shortMonthsParse = [];
1000
        }
1001
1002
        // TODO: add sorting
1003
        // Sorting makes sure if one month (or abbr) is a prefix of another
1004
        // see sorting in computeMonthsParse
1005
        for (i = 0; i < 12; i++) {
1006
            // make the regex if we don't have it already
1007
            mom = createUTC([2000, i]);
1008
            if (strict && !this._longMonthsParse[i]) {
1009
                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
1010
                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
1011
            }
1012
            if (!strict && !this._monthsParse[i]) {
1013
                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
1014
                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
1015
            }
1016
            // test the regex
1017
            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
1018
                return i;
1019
            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
1020
                return i;
1021
            } else if (!strict && this._monthsParse[i].test(monthName)) {
1022
                return i;
1023
            }
1024
        }
1025
    }
1026
1027
    // MOMENTS
1028
1029
    function setMonth (mom, value) {
1030
        var dayOfMonth;
1031
1032
        if (!mom.isValid()) {
1033
            // No op
1034
            return mom;
1035
        }
1036
1037
        if (typeof value === 'string') {
1038
            if (/^\d+$/.test(value)) {
1039
                value = toInt(value);
1040
            } else {
1041
                value = mom.localeData().monthsParse(value);
1042
                // TODO: Another silent failure?
1043
                if (!isNumber(value)) {
1044
                    return mom;
1045
                }
1046
            }
1047
        }
1048
1049
        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
1050
        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
1051
        return mom;
1052
    }
1053
1054
    function getSetMonth (value) {
1055
        if (value != null) {
1056
            setMonth(this, value);
1057
            hooks.updateOffset(this, true);
1058
            return this;
1059
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1060
            return get(this, 'Month');
1061
        }
1062
    }
1063
1064
    function getDaysInMonth () {
1065
        return daysInMonth(this.year(), this.month());
1066
    }
1067
1068
    var defaultMonthsShortRegex = matchWord;
1069
    function monthsShortRegex (isStrict) {
1070
        if (this._monthsParseExact) {
1071
            if (!hasOwnProp(this, '_monthsRegex')) {
1072
                computeMonthsParse.call(this);
1073
            }
1074
            if (isStrict) {
1075
                return this._monthsShortStrictRegex;
1076
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1077
                return this._monthsShortRegex;
1078
            }
1079
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1080
            if (!hasOwnProp(this, '_monthsShortRegex')) {
1081
                this._monthsShortRegex = defaultMonthsShortRegex;
1082
            }
1083
            return this._monthsShortStrictRegex && isStrict ?
1084
                this._monthsShortStrictRegex : this._monthsShortRegex;
1085
        }
1086
    }
1087
1088
    var defaultMonthsRegex = matchWord;
1089
    function monthsRegex (isStrict) {
1090
        if (this._monthsParseExact) {
1091
            if (!hasOwnProp(this, '_monthsRegex')) {
1092
                computeMonthsParse.call(this);
1093
            }
1094
            if (isStrict) {
1095
                return this._monthsStrictRegex;
1096
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1097
                return this._monthsRegex;
1098
            }
1099
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1100
            if (!hasOwnProp(this, '_monthsRegex')) {
1101
                this._monthsRegex = defaultMonthsRegex;
1102
            }
1103
            return this._monthsStrictRegex && isStrict ?
1104
                this._monthsStrictRegex : this._monthsRegex;
1105
        }
1106
    }
1107
1108
    function computeMonthsParse () {
1109
        function cmpLenRev(a, b) {
1110
            return b.length - a.length;
1111
        }
1112
1113
        var shortPieces = [], longPieces = [], mixedPieces = [],
1114
            i, mom;
1115
        for (i = 0; i < 12; i++) {
1116
            // make the regex if we don't have it already
1117
            mom = createUTC([2000, i]);
1118
            shortPieces.push(this.monthsShort(mom, ''));
1119
            longPieces.push(this.months(mom, ''));
1120
            mixedPieces.push(this.months(mom, ''));
1121
            mixedPieces.push(this.monthsShort(mom, ''));
1122
        }
1123
        // Sorting makes sure if one month (or abbr) is a prefix of another it
1124
        // will match the longer piece.
1125
        shortPieces.sort(cmpLenRev);
1126
        longPieces.sort(cmpLenRev);
1127
        mixedPieces.sort(cmpLenRev);
1128
        for (i = 0; i < 12; i++) {
1129
            shortPieces[i] = regexEscape(shortPieces[i]);
1130
            longPieces[i] = regexEscape(longPieces[i]);
1131
        }
1132
        for (i = 0; i < 24; i++) {
1133
            mixedPieces[i] = regexEscape(mixedPieces[i]);
1134
        }
1135
1136
        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1137
        this._monthsShortRegex = this._monthsRegex;
1138
        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
1139
        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
1140
    }
1141
1142
    function createDate (y, m, d, h, M, s, ms) {
1143
        // can't just apply() to create a date:
1144
        // https://stackoverflow.com/q/181348
1145
        var date;
1146
        // the date constructor remaps years 0-99 to 1900-1999
1147
        if (y < 100 && y >= 0) {
1148
            // preserve leap years using a full 400 year cycle, then reset
1149
            date = new Date(y + 400, m, d, h, M, s, ms);
1150
            if (isFinite(date.getFullYear())) {
1151
                date.setFullYear(y);
1152
            }
1153
        } else {
1154
            date = new Date(y, m, d, h, M, s, ms);
1155
        }
1156
1157
        return date;
1158
    }
1159
1160
    function createUTCDate (y) {
1161
        var date;
1162
        // the Date.UTC function remaps years 0-99 to 1900-1999
1163
        if (y < 100 && y >= 0) {
1164
            var args = Array.prototype.slice.call(arguments);
1165
            // preserve leap years using a full 400 year cycle, then reset
1166
            args[0] = y + 400;
1167
            date = new Date(Date.UTC.apply(null, args));
1168
            if (isFinite(date.getUTCFullYear())) {
1169
                date.setUTCFullYear(y);
1170
            }
1171
        } else {
1172
            date = new Date(Date.UTC.apply(null, arguments));
1173
        }
1174
1175
        return date;
1176
    }
1177
1178
    // start-of-first-week - start-of-year
1179
    function firstWeekOffset(year, dow, doy) {
1180
        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
1181
            fwd = 7 + dow - doy,
1182
            // first-week day local weekday -- which local weekday is fwd
1183
            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
1184
1185
        return -fwdlw + fwd - 1;
1186
    }
1187
1188
    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1189
    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
1190
        var localWeekday = (7 + weekday - dow) % 7,
1191
            weekOffset = firstWeekOffset(year, dow, doy),
1192
            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
1193
            resYear, resDayOfYear;
1194
1195
        if (dayOfYear <= 0) {
1196
            resYear = year - 1;
1197
            resDayOfYear = daysInYear(resYear) + dayOfYear;
1198
        } else if (dayOfYear > daysInYear(year)) {
1199
            resYear = year + 1;
1200
            resDayOfYear = dayOfYear - daysInYear(year);
1201
        } else {
1202
            resYear = year;
1203
            resDayOfYear = dayOfYear;
1204
        }
1205
1206
        return {
1207
            year: resYear,
1208
            dayOfYear: resDayOfYear
1209
        };
1210
    }
1211
1212
    function weekOfYear(mom, dow, doy) {
1213
        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
1214
            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
1215
            resWeek, resYear;
1216
1217
        if (week < 1) {
1218
            resYear = mom.year() - 1;
1219
            resWeek = week + weeksInYear(resYear, dow, doy);
1220
        } else if (week > weeksInYear(mom.year(), dow, doy)) {
1221
            resWeek = week - weeksInYear(mom.year(), dow, doy);
1222
            resYear = mom.year() + 1;
1223
        } else {
1224
            resYear = mom.year();
1225
            resWeek = week;
1226
        }
1227
1228
        return {
1229
            week: resWeek,
1230
            year: resYear
1231
        };
1232
    }
1233
1234
    function weeksInYear(year, dow, doy) {
1235
        var weekOffset = firstWeekOffset(year, dow, doy),
1236
            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
1237
        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1238
    }
1239
1240
    // FORMATTING
1241
1242
    addFormatToken('w', ['ww', 2], 'wo', 'week');
1243
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
1244
1245
    // ALIASES
1246
1247
    addUnitAlias('week', 'w');
1248
    addUnitAlias('isoWeek', 'W');
1249
1250
    // PRIORITIES
1251
1252
    addUnitPriority('week', 5);
1253
    addUnitPriority('isoWeek', 5);
1254
1255
    // PARSING
1256
1257
    addRegexToken('w',  match1to2);
1258
    addRegexToken('ww', match1to2, match2);
1259
    addRegexToken('W',  match1to2);
1260
    addRegexToken('WW', match1to2, match2);
1261
1262
    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
1263
        week[token.substr(0, 1)] = toInt(input);
1264
    });
1265
1266
    // HELPERS
1267
1268
    // LOCALES
1269
1270
    function localeWeek (mom) {
1271
        return weekOfYear(mom, this._week.dow, this._week.doy).week;
1272
    }
1273
1274
    var defaultLocaleWeek = {
1275
        dow : 0, // Sunday is the first day of the week.
1276
        doy : 6  // The week that contains Jan 6th is the first week of the year.
1277
    };
1278
1279
    function localeFirstDayOfWeek () {
1280
        return this._week.dow;
1281
    }
1282
1283
    function localeFirstDayOfYear () {
1284
        return this._week.doy;
1285
    }
1286
1287
    // MOMENTS
1288
1289
    function getSetWeek (input) {
1290
        var week = this.localeData().week(this);
1291
        return input == null ? week : this.add((input - week) * 7, 'd');
1292
    }
1293
1294
    function getSetISOWeek (input) {
1295
        var week = weekOfYear(this, 1, 4).week;
1296
        return input == null ? week : this.add((input - week) * 7, 'd');
1297
    }
1298
1299
    // FORMATTING
1300
1301
    addFormatToken('d', 0, 'do', 'day');
1302
1303
    addFormatToken('dd', 0, 0, function (format) {
1304
        return this.localeData().weekdaysMin(this, format);
1305
    });
1306
1307
    addFormatToken('ddd', 0, 0, function (format) {
1308
        return this.localeData().weekdaysShort(this, format);
1309
    });
1310
1311
    addFormatToken('dddd', 0, 0, function (format) {
1312
        return this.localeData().weekdays(this, format);
1313
    });
1314
1315
    addFormatToken('e', 0, 0, 'weekday');
1316
    addFormatToken('E', 0, 0, 'isoWeekday');
1317
1318
    // ALIASES
1319
1320
    addUnitAlias('day', 'd');
1321
    addUnitAlias('weekday', 'e');
1322
    addUnitAlias('isoWeekday', 'E');
1323
1324
    // PRIORITY
1325
    addUnitPriority('day', 11);
1326
    addUnitPriority('weekday', 11);
1327
    addUnitPriority('isoWeekday', 11);
1328
1329
    // PARSING
1330
1331
    addRegexToken('d',    match1to2);
1332
    addRegexToken('e',    match1to2);
1333
    addRegexToken('E',    match1to2);
1334
    addRegexToken('dd',   function (isStrict, locale) {
1335
        return locale.weekdaysMinRegex(isStrict);
1336
    });
1337
    addRegexToken('ddd',   function (isStrict, locale) {
1338
        return locale.weekdaysShortRegex(isStrict);
1339
    });
1340
    addRegexToken('dddd',   function (isStrict, locale) {
1341
        return locale.weekdaysRegex(isStrict);
1342
    });
1343
1344
    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
1345
        var weekday = config._locale.weekdaysParse(input, token, config._strict);
1346
        // if we didn't get a weekday name, mark the date as invalid
1347
        if (weekday != null) {
1348
            week.d = weekday;
1349
        } else {
1350
            getParsingFlags(config).invalidWeekday = input;
1351
        }
1352
    });
1353
1354
    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
1355
        week[token] = toInt(input);
1356
    });
1357
1358
    // HELPERS
1359
1360
    function parseWeekday(input, locale) {
1361
        if (typeof input !== 'string') {
1362
            return input;
1363
        }
1364
1365
        if (!isNaN(input)) {
1366
            return parseInt(input, 10);
1367
        }
1368
1369
        input = locale.weekdaysParse(input);
1370
        if (typeof input === 'number') {
1371
            return input;
1372
        }
1373
1374
        return null;
1375
    }
1376
1377
    function parseIsoWeekday(input, locale) {
1378
        if (typeof input === 'string') {
1379
            return locale.weekdaysParse(input) % 7 || 7;
1380
        }
1381
        return isNaN(input) ? null : input;
1382
    }
1383
1384
    // LOCALES
1385
    function shiftWeekdays (ws, n) {
1386
        return ws.slice(n, 7).concat(ws.slice(0, n));
1387
    }
1388
1389
    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
1390
    function localeWeekdays (m, format) {
1391
        var weekdays = isArray(this._weekdays) ? this._weekdays :
1392
            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];
1393
        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)
1394
            : (m) ? weekdays[m.day()] : weekdays;
1395
    }
1396
1397
    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
1398
    function localeWeekdaysShort (m) {
1399
        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)
1400
            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
1401
    }
1402
1403
    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
1404
    function localeWeekdaysMin (m) {
1405
        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)
1406
            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
1407
    }
1408
1409
    function handleStrictParse$1(weekdayName, format, strict) {
1410
        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
1411
        if (!this._weekdaysParse) {
1412
            this._weekdaysParse = [];
1413
            this._shortWeekdaysParse = [];
1414
            this._minWeekdaysParse = [];
1415
1416
            for (i = 0; i < 7; ++i) {
1417
                mom = createUTC([2000, 1]).day(i);
1418
                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
1419
                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
1420
                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
1421
            }
1422
        }
1423
1424
        if (strict) {
1425 View Code Duplication
            if (format === 'dddd') {
1426
                ii = indexOf.call(this._weekdaysParse, llc);
1427
                return ii !== -1 ? ii : null;
1428
            } else if (format === 'ddd') {
1429
                ii = indexOf.call(this._shortWeekdaysParse, llc);
1430
                return ii !== -1 ? ii : null;
1431
            } else {
1432
                ii = indexOf.call(this._minWeekdaysParse, llc);
1433
                return ii !== -1 ? ii : null;
1434
            }
1435
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1436
            if (format === 'dddd') {
1437
                ii = indexOf.call(this._weekdaysParse, llc);
1438
                if (ii !== -1) {
1439
                    return ii;
1440
                }
1441
                ii = indexOf.call(this._shortWeekdaysParse, llc);
1442
                if (ii !== -1) {
1443
                    return ii;
1444
                }
1445
                ii = indexOf.call(this._minWeekdaysParse, llc);
1446
                return ii !== -1 ? ii : null;
1447 View Code Duplication
            } else if (format === 'ddd') {
1448
                ii = indexOf.call(this._shortWeekdaysParse, llc);
1449
                if (ii !== -1) {
1450
                    return ii;
1451
                }
1452
                ii = indexOf.call(this._weekdaysParse, llc);
1453
                if (ii !== -1) {
1454
                    return ii;
1455
                }
1456
                ii = indexOf.call(this._minWeekdaysParse, llc);
1457
                return ii !== -1 ? ii : null;
1458
            } else {
1459
                ii = indexOf.call(this._minWeekdaysParse, llc);
1460
                if (ii !== -1) {
1461
                    return ii;
1462
                }
1463
                ii = indexOf.call(this._weekdaysParse, llc);
1464
                if (ii !== -1) {
1465
                    return ii;
1466
                }
1467
                ii = indexOf.call(this._shortWeekdaysParse, llc);
1468
                return ii !== -1 ? ii : null;
1469
            }
1470
        }
1471
    }
1472
1473
    function localeWeekdaysParse (weekdayName, format, strict) {
1474
        var i, mom, regex;
1475
1476
        if (this._weekdaysParseExact) {
1477
            return handleStrictParse$1.call(this, weekdayName, format, strict);
1478
        }
1479
1480
        if (!this._weekdaysParse) {
1481
            this._weekdaysParse = [];
1482
            this._minWeekdaysParse = [];
1483
            this._shortWeekdaysParse = [];
1484
            this._fullWeekdaysParse = [];
1485
        }
1486
1487
        for (i = 0; i < 7; i++) {
1488
            // make the regex if we don't have it already
1489
1490
            mom = createUTC([2000, 1]).day(i);
1491
            if (strict && !this._fullWeekdaysParse[i]) {
1492
                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
1493
                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
1494
                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
1495
            }
1496
            if (!this._weekdaysParse[i]) {
1497
                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
1498
                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
1499
            }
1500
            // test the regex
1501
            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
1502
                return i;
1503
            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
1504
                return i;
1505
            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
1506
                return i;
1507
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
1508
                return i;
1509
            }
1510
        }
1511
    }
1512
1513
    // MOMENTS
1514
1515
    function getSetDayOfWeek (input) {
1516
        if (!this.isValid()) {
1517
            return input != null ? this : NaN;
1518
        }
1519
        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1520
        if (input != null) {
1521
            input = parseWeekday(input, this.localeData());
1522
            return this.add(input - day, 'd');
1523
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1524
            return day;
1525
        }
1526
    }
1527
1528
    function getSetLocaleDayOfWeek (input) {
1529
        if (!this.isValid()) {
1530
            return input != null ? this : NaN;
1531
        }
1532
        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
1533
        return input == null ? weekday : this.add(input - weekday, 'd');
1534
    }
1535
1536
    function getSetISODayOfWeek (input) {
1537
        if (!this.isValid()) {
1538
            return input != null ? this : NaN;
1539
        }
1540
1541
        // behaves the same as moment#day except
1542
        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1543
        // as a setter, sunday should belong to the previous week.
1544
1545
        if (input != null) {
1546
            var weekday = parseIsoWeekday(input, this.localeData());
1547
            return this.day(this.day() % 7 ? weekday : weekday - 7);
1548
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1549
            return this.day() || 7;
1550
        }
1551
    }
1552
1553
    var defaultWeekdaysRegex = matchWord;
1554
    function weekdaysRegex (isStrict) {
1555
        if (this._weekdaysParseExact) {
1556
            if (!hasOwnProp(this, '_weekdaysRegex')) {
1557
                computeWeekdaysParse.call(this);
1558
            }
1559
            if (isStrict) {
1560
                return this._weekdaysStrictRegex;
1561
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1562
                return this._weekdaysRegex;
1563
            }
1564
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1565
            if (!hasOwnProp(this, '_weekdaysRegex')) {
1566
                this._weekdaysRegex = defaultWeekdaysRegex;
1567
            }
1568
            return this._weekdaysStrictRegex && isStrict ?
1569
                this._weekdaysStrictRegex : this._weekdaysRegex;
1570
        }
1571
    }
1572
1573
    var defaultWeekdaysShortRegex = matchWord;
1574
    function weekdaysShortRegex (isStrict) {
1575
        if (this._weekdaysParseExact) {
1576
            if (!hasOwnProp(this, '_weekdaysRegex')) {
1577
                computeWeekdaysParse.call(this);
1578
            }
1579
            if (isStrict) {
1580
                return this._weekdaysShortStrictRegex;
1581
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1582
                return this._weekdaysShortRegex;
1583
            }
1584
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1585
            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
1586
                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
1587
            }
1588
            return this._weekdaysShortStrictRegex && isStrict ?
1589
                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
1590
        }
1591
    }
1592
1593
    var defaultWeekdaysMinRegex = matchWord;
1594
    function weekdaysMinRegex (isStrict) {
1595
        if (this._weekdaysParseExact) {
1596
            if (!hasOwnProp(this, '_weekdaysRegex')) {
1597
                computeWeekdaysParse.call(this);
1598
            }
1599
            if (isStrict) {
1600
                return this._weekdaysMinStrictRegex;
1601
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1602
                return this._weekdaysMinRegex;
1603
            }
1604
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1605
            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
1606
                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
1607
            }
1608
            return this._weekdaysMinStrictRegex && isStrict ?
1609
                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
1610
        }
1611
    }
1612
1613
1614
    function computeWeekdaysParse () {
1615
        function cmpLenRev(a, b) {
1616
            return b.length - a.length;
1617
        }
1618
1619
        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
1620
            i, mom, minp, shortp, longp;
1621
        for (i = 0; i < 7; i++) {
1622
            // make the regex if we don't have it already
1623
            mom = createUTC([2000, 1]).day(i);
1624
            minp = this.weekdaysMin(mom, '');
1625
            shortp = this.weekdaysShort(mom, '');
1626
            longp = this.weekdays(mom, '');
1627
            minPieces.push(minp);
1628
            shortPieces.push(shortp);
1629
            longPieces.push(longp);
1630
            mixedPieces.push(minp);
1631
            mixedPieces.push(shortp);
1632
            mixedPieces.push(longp);
1633
        }
1634
        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
1635
        // will match the longer piece.
1636
        minPieces.sort(cmpLenRev);
1637
        shortPieces.sort(cmpLenRev);
1638
        longPieces.sort(cmpLenRev);
1639
        mixedPieces.sort(cmpLenRev);
1640
        for (i = 0; i < 7; i++) {
1641
            shortPieces[i] = regexEscape(shortPieces[i]);
1642
            longPieces[i] = regexEscape(longPieces[i]);
1643
            mixedPieces[i] = regexEscape(mixedPieces[i]);
1644
        }
1645
1646
        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1647
        this._weekdaysShortRegex = this._weekdaysRegex;
1648
        this._weekdaysMinRegex = this._weekdaysRegex;
1649
1650
        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
1651
        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
1652
        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
1653
    }
1654
1655
    // FORMATTING
1656
1657
    function hFormat() {
1658
        return this.hours() % 12 || 12;
1659
    }
1660
1661
    function kFormat() {
1662
        return this.hours() || 24;
1663
    }
1664
1665
    addFormatToken('H', ['HH', 2], 0, 'hour');
1666
    addFormatToken('h', ['hh', 2], 0, hFormat);
1667
    addFormatToken('k', ['kk', 2], 0, kFormat);
1668
1669
    addFormatToken('hmm', 0, 0, function () {
1670
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
1671
    });
1672
1673
    addFormatToken('hmmss', 0, 0, function () {
1674
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
1675
            zeroFill(this.seconds(), 2);
1676
    });
1677
1678
    addFormatToken('Hmm', 0, 0, function () {
1679
        return '' + this.hours() + zeroFill(this.minutes(), 2);
1680
    });
1681
1682
    addFormatToken('Hmmss', 0, 0, function () {
1683
        return '' + this.hours() + zeroFill(this.minutes(), 2) +
1684
            zeroFill(this.seconds(), 2);
1685
    });
1686
1687
    function meridiem (token, lowercase) {
1688
        addFormatToken(token, 0, 0, function () {
1689
            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
1690
        });
1691
    }
1692
1693
    meridiem('a', true);
1694
    meridiem('A', false);
1695
1696
    // ALIASES
1697
1698
    addUnitAlias('hour', 'h');
1699
1700
    // PRIORITY
1701
    addUnitPriority('hour', 13);
1702
1703
    // PARSING
1704
1705
    function matchMeridiem (isStrict, locale) {
1706
        return locale._meridiemParse;
1707
    }
1708
1709
    addRegexToken('a',  matchMeridiem);
1710
    addRegexToken('A',  matchMeridiem);
1711
    addRegexToken('H',  match1to2);
1712
    addRegexToken('h',  match1to2);
1713
    addRegexToken('k',  match1to2);
1714
    addRegexToken('HH', match1to2, match2);
1715
    addRegexToken('hh', match1to2, match2);
1716
    addRegexToken('kk', match1to2, match2);
1717
1718
    addRegexToken('hmm', match3to4);
1719
    addRegexToken('hmmss', match5to6);
1720
    addRegexToken('Hmm', match3to4);
1721
    addRegexToken('Hmmss', match5to6);
1722
1723
    addParseToken(['H', 'HH'], HOUR);
1724
    addParseToken(['k', 'kk'], function (input, array, config) {
1725
        var kInput = toInt(input);
1726
        array[HOUR] = kInput === 24 ? 0 : kInput;
1727
    });
1728
    addParseToken(['a', 'A'], function (input, array, config) {
1729
        config._isPm = config._locale.isPM(input);
1730
        config._meridiem = input;
1731
    });
1732
    addParseToken(['h', 'hh'], function (input, array, config) {
1733
        array[HOUR] = toInt(input);
1734
        getParsingFlags(config).bigHour = true;
1735
    });
1736
    addParseToken('hmm', function (input, array, config) {
1737
        var pos = input.length - 2;
1738
        array[HOUR] = toInt(input.substr(0, pos));
1739
        array[MINUTE] = toInt(input.substr(pos));
1740
        getParsingFlags(config).bigHour = true;
1741
    });
1742
    addParseToken('hmmss', function (input, array, config) {
1743
        var pos1 = input.length - 4;
1744
        var pos2 = input.length - 2;
1745
        array[HOUR] = toInt(input.substr(0, pos1));
1746
        array[MINUTE] = toInt(input.substr(pos1, 2));
1747
        array[SECOND] = toInt(input.substr(pos2));
1748
        getParsingFlags(config).bigHour = true;
1749
    });
1750
    addParseToken('Hmm', function (input, array, config) {
1751
        var pos = input.length - 2;
1752
        array[HOUR] = toInt(input.substr(0, pos));
1753
        array[MINUTE] = toInt(input.substr(pos));
1754
    });
1755
    addParseToken('Hmmss', function (input, array, config) {
1756
        var pos1 = input.length - 4;
1757
        var pos2 = input.length - 2;
1758
        array[HOUR] = toInt(input.substr(0, pos1));
1759
        array[MINUTE] = toInt(input.substr(pos1, 2));
1760
        array[SECOND] = toInt(input.substr(pos2));
1761
    });
1762
1763
    // LOCALES
1764
1765
    function localeIsPM (input) {
1766
        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
1767
        // Using charAt should be more compatible.
1768
        return ((input + '').toLowerCase().charAt(0) === 'p');
1769
    }
1770
1771
    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
1772
    function localeMeridiem (hours, minutes, isLower) {
1773
        if (hours > 11) {
1774
            return isLower ? 'pm' : 'PM';
1775
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1776
            return isLower ? 'am' : 'AM';
1777
        }
1778
    }
1779
1780
1781
    // MOMENTS
1782
1783
    // Setting the hour should keep the time, because the user explicitly
1784
    // specified which hour they want. So trying to maintain the same hour (in
1785
    // a new timezone) makes sense. Adding/subtracting hours does not follow
1786
    // this rule.
1787
    var getSetHour = makeGetSet('Hours', true);
1788
1789
    var baseConfig = {
1790
        calendar: defaultCalendar,
1791
        longDateFormat: defaultLongDateFormat,
1792
        invalidDate: defaultInvalidDate,
1793
        ordinal: defaultOrdinal,
1794
        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
1795
        relativeTime: defaultRelativeTime,
1796
1797
        months: defaultLocaleMonths,
1798
        monthsShort: defaultLocaleMonthsShort,
1799
1800
        week: defaultLocaleWeek,
1801
1802
        weekdays: defaultLocaleWeekdays,
1803
        weekdaysMin: defaultLocaleWeekdaysMin,
1804
        weekdaysShort: defaultLocaleWeekdaysShort,
1805
1806
        meridiemParse: defaultLocaleMeridiemParse
1807
    };
1808
1809
    // internal storage for locale config files
1810
    var locales = {};
1811
    var localeFamilies = {};
1812
    var globalLocale;
1813
1814
    function normalizeLocale(key) {
1815
        return key ? key.toLowerCase().replace('_', '-') : key;
1816
    }
1817
1818
    // pick the locale from the array
1819
    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
1820
    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
1821 View Code Duplication
    function chooseLocale(names) {
1822
        var i = 0, j, next, locale, split;
1823
1824
        while (i < names.length) {
1825
            split = normalizeLocale(names[i]).split('-');
1826
            j = split.length;
1827
            next = normalizeLocale(names[i + 1]);
1828
            next = next ? next.split('-') : null;
1829
            while (j > 0) {
1830
                locale = loadLocale(split.slice(0, j).join('-'));
1831
                if (locale) {
1832
                    return locale;
1833
                }
1834
                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
1835
                    //the next array item is better than a shallower substring of this one
1836
                    break;
1837
                }
1838
                j--;
1839
            }
1840
            i++;
1841
        }
1842
        return globalLocale;
1843
    }
1844
1845
    function loadLocale(name) {
1846
        var oldLocale = null;
0 ignored issues
show
Unused Code introduced by
The assignment to oldLocale seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1847
        // TODO: Find a better way to register and load all the locales in Node
1848
        if (!locales[name] && (typeof module !== 'undefined') &&
1849
                module && module.exports) {
1850
            try {
1851
                oldLocale = globalLocale._abbr;
1852
                var aliasedRequire = require;
1853
                aliasedRequire('./locale/' + name);
1854
                getSetGlobalLocale(oldLocale);
1855
            } catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
1856
        }
1857
        return locales[name];
1858
    }
1859
1860
    // This function will load locale and then set the global locale.  If
1861
    // no arguments are passed in, it will simply return the current global
1862
    // locale key.
1863
    function getSetGlobalLocale (key, values) {
1864
        var data;
1865
        if (key) {
1866
            if (isUndefined(values)) {
1867
                data = getLocale(key);
1868
            }
1869
            else {
1870
                data = defineLocale(key, values);
1871
            }
1872
1873
            if (data) {
1874
                // moment.duration._locale = moment._locale = data;
1875
                globalLocale = data;
1876
            }
1877
            else {
1878
                if ((typeof console !==  'undefined') && console.warn) {
1879
                    //warn user if arguments are passed but the locale could not be set
1880
                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
1881
                }
1882
            }
1883
        }
1884
1885
        return globalLocale._abbr;
1886
    }
1887
1888
    function defineLocale (name, config) {
1889
        if (config !== null) {
1890
            var locale, parentConfig = baseConfig;
1891
            config.abbr = name;
1892
            if (locales[name] != null) {
1893
                deprecateSimple('defineLocaleOverride',
1894
                        'use moment.updateLocale(localeName, config) to change ' +
1895
                        'an existing locale. moment.defineLocale(localeName, ' +
1896
                        'config) should only be used for creating a new locale ' +
1897
                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
1898
                parentConfig = locales[name]._config;
1899
            } else if (config.parentLocale != null) {
1900
                if (locales[config.parentLocale] != null) {
1901
                    parentConfig = locales[config.parentLocale]._config;
1902
                } else {
1903
                    locale = loadLocale(config.parentLocale);
1904
                    if (locale != null) {
1905
                        parentConfig = locale._config;
1906
                    } else {
1907
                        if (!localeFamilies[config.parentLocale]) {
1908
                            localeFamilies[config.parentLocale] = [];
1909
                        }
1910
                        localeFamilies[config.parentLocale].push({
1911
                            name: name,
1912
                            config: config
1913
                        });
1914
                        return null;
1915
                    }
1916
                }
1917
            }
1918
            locales[name] = new Locale(mergeConfigs(parentConfig, config));
1919
1920
            if (localeFamilies[name]) {
1921
                localeFamilies[name].forEach(function (x) {
1922
                    defineLocale(x.name, x.config);
1923
                });
1924
            }
1925
1926
            // backwards compat for now: also set the locale
1927
            // make sure we set the locale AFTER all child locales have been
1928
            // created, so we won't end up with the child locale set.
1929
            getSetGlobalLocale(name);
1930
1931
1932
            return locales[name];
1933
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1934
            // useful for testing
1935
            delete locales[name];
1936
            return null;
1937
        }
1938
    }
1939
1940
    function updateLocale(name, config) {
1941
        if (config != null) {
1942
            var locale, tmpLocale, parentConfig = baseConfig;
1943
            // MERGE
1944
            tmpLocale = loadLocale(name);
1945
            if (tmpLocale != null) {
1946
                parentConfig = tmpLocale._config;
1947
            }
1948
            config = mergeConfigs(parentConfig, config);
1949
            locale = new Locale(config);
1950
            locale.parentLocale = locales[name];
1951
            locales[name] = locale;
1952
1953
            // backwards compat for now: also set the locale
1954
            getSetGlobalLocale(name);
1955
        } else {
1956
            // pass null for config to unupdate, useful for tests
1957
            if (locales[name] != null) {
1958
                if (locales[name].parentLocale != null) {
1959
                    locales[name] = locales[name].parentLocale;
1960
                } else if (locales[name] != null) {
1961
                    delete locales[name];
1962
                }
1963
            }
1964
        }
1965
        return locales[name];
1966
    }
1967
1968
    // returns locale data
1969
    function getLocale (key) {
1970
        var locale;
1971
1972
        if (key && key._locale && key._locale._abbr) {
1973
            key = key._locale._abbr;
1974
        }
1975
1976
        if (!key) {
1977
            return globalLocale;
1978
        }
1979
1980
        if (!isArray(key)) {
1981
            //short-circuit everything else
1982
            locale = loadLocale(key);
1983
            if (locale) {
1984
                return locale;
1985
            }
1986
            key = [key];
1987
        }
1988
1989
        return chooseLocale(key);
1990
    }
1991
1992
    function listLocales() {
1993
        return keys(locales);
1994
    }
1995
1996
    function checkOverflow (m) {
1997
        var overflow;
1998
        var a = m._a;
1999
2000
        if (a && getParsingFlags(m).overflow === -2) {
2001
            overflow =
2002
                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
2003
                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
2004
                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
2005
                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
2006
                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
2007
                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
2008
                -1;
2009
2010
            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
2011
                overflow = DATE;
2012
            }
2013
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
2014
                overflow = WEEK;
2015
            }
2016
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
2017
                overflow = WEEKDAY;
2018
            }
2019
2020
            getParsingFlags(m).overflow = overflow;
2021
        }
2022
2023
        return m;
2024
    }
2025
2026
    // Pick the first defined of two or three arguments.
2027
    function defaults(a, b, c) {
2028
        if (a != null) {
2029
            return a;
2030
        }
2031
        if (b != null) {
2032
            return b;
2033
        }
2034
        return c;
2035
    }
2036
2037
    function currentDateArray(config) {
2038
        // hooks is actually the exported moment object
2039
        var nowValue = new Date(hooks.now());
2040
        if (config._useUTC) {
2041
            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
2042
        }
2043
        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
2044
    }
2045
2046
    // convert an array to a date.
2047
    // the array should mirror the parameters below
2048
    // note: all values past the year are optional and will default to the lowest possible value.
2049
    // [year, month, day , hour, minute, second, millisecond]
2050
    function configFromArray (config) {
2051
        var i, date, input = [], currentDate, expectedWeekday, yearToUse;
2052
2053
        if (config._d) {
2054
            return;
2055
        }
2056
2057
        currentDate = currentDateArray(config);
2058
2059
        //compute day of the year from weeks and weekdays
2060
        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
2061
            dayOfYearFromWeekInfo(config);
2062
        }
2063
2064
        //if the day of the year is set, figure out what it is
2065
        if (config._dayOfYear != null) {
2066
            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
2067
2068
            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
2069
                getParsingFlags(config)._overflowDayOfYear = true;
2070
            }
2071
2072
            date = createUTCDate(yearToUse, 0, config._dayOfYear);
2073
            config._a[MONTH] = date.getUTCMonth();
2074
            config._a[DATE] = date.getUTCDate();
2075
        }
2076
2077
        // Default to current date.
2078
        // * if no year, month, day of month are given, default to today
2079
        // * if day of month is given, default month and year
2080
        // * if month is given, default only year
2081
        // * if year is given, don't default anything
2082
        for (i = 0; i < 3 && config._a[i] == null; ++i) {
2083
            config._a[i] = input[i] = currentDate[i];
2084
        }
2085
2086
        // Zero out whatever was not defaulted, including time
2087
        for (; i < 7; i++) {
2088
            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
2089
        }
2090
2091
        // Check for 24:00:00.000
2092
        if (config._a[HOUR] === 24 &&
2093
                config._a[MINUTE] === 0 &&
2094
                config._a[SECOND] === 0 &&
2095
                config._a[MILLISECOND] === 0) {
2096
            config._nextDay = true;
2097
            config._a[HOUR] = 0;
2098
        }
2099
2100
        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
2101
        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();
2102
2103
        // Apply timezone offset from input. The actual utcOffset can be changed
2104
        // with parseZone.
2105
        if (config._tzm != null) {
2106
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2107
        }
2108
2109
        if (config._nextDay) {
2110
            config._a[HOUR] = 24;
2111
        }
2112
2113
        // check for mismatching day of week
2114
        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
2115
            getParsingFlags(config).weekdayMismatch = true;
2116
        }
2117
    }
2118
2119
    function dayOfYearFromWeekInfo(config) {
2120
        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
2121
2122
        w = config._w;
2123
        if (w.GG != null || w.W != null || w.E != null) {
2124
            dow = 1;
2125
            doy = 4;
2126
2127
            // TODO: We need to take the current isoWeekYear, but that depends on
2128
            // how we interpret now (local, utc, fixed offset). So create
2129
            // a now version of current config (take local/utc/offset flags, and
2130
            // create now).
2131
            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
2132
            week = defaults(w.W, 1);
2133
            weekday = defaults(w.E, 1);
2134
            if (weekday < 1 || weekday > 7) {
2135
                weekdayOverflow = true;
2136
            }
2137
        } else {
2138
            dow = config._locale._week.dow;
2139
            doy = config._locale._week.doy;
2140
2141
            var curWeek = weekOfYear(createLocal(), dow, doy);
2142
2143
            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
2144
2145
            // Default to current week.
2146
            week = defaults(w.w, curWeek.week);
2147
2148
            if (w.d != null) {
2149
                // weekday -- low day numbers are considered next week
2150
                weekday = w.d;
2151
                if (weekday < 0 || weekday > 6) {
2152
                    weekdayOverflow = true;
2153
                }
2154
            } else if (w.e != null) {
2155
                // local weekday -- counting starts from beginning of week
2156
                weekday = w.e + dow;
2157
                if (w.e < 0 || w.e > 6) {
2158
                    weekdayOverflow = true;
2159
                }
2160
            } else {
2161
                // default to beginning of week
2162
                weekday = dow;
2163
            }
2164
        }
2165
        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
2166
            getParsingFlags(config)._overflowWeeks = true;
2167
        } else if (weekdayOverflow != null) {
2168
            getParsingFlags(config)._overflowWeekday = true;
2169
        } else {
2170
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
2171
            config._a[YEAR] = temp.year;
2172
            config._dayOfYear = temp.dayOfYear;
2173
        }
2174
    }
2175
2176
    // iso 8601 regex
2177
    // 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)
2178
    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
2179
    var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
2180
2181
    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
2182
2183
    var isoDates = [
2184
        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
2185
        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
2186
        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
2187
        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
2188
        ['YYYY-DDD', /\d{4}-\d{3}/],
2189
        ['YYYY-MM', /\d{4}-\d\d/, false],
2190
        ['YYYYYYMMDD', /[+-]\d{10}/],
2191
        ['YYYYMMDD', /\d{8}/],
2192
        // YYYYMM is NOT allowed by the standard
2193
        ['GGGG[W]WWE', /\d{4}W\d{3}/],
2194
        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
2195
        ['YYYYDDD', /\d{7}/]
2196
    ];
2197
2198
    // iso time formats and regexes
2199
    var isoTimes = [
2200
        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
2201
        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
2202
        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
2203
        ['HH:mm', /\d\d:\d\d/],
2204
        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
2205
        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
2206
        ['HHmmss', /\d\d\d\d\d\d/],
2207
        ['HHmm', /\d\d\d\d/],
2208
        ['HH', /\d\d/]
2209
    ];
2210
2211
    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
2212
2213
    // date from iso format
2214
    function configFromISO(config) {
2215
        var i, l,
2216
            string = config._i,
2217
            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
2218
            allowTime, dateFormat, timeFormat, tzFormat;
2219
2220
        if (match) {
2221
            getParsingFlags(config).iso = true;
2222
2223
            for (i = 0, l = isoDates.length; i < l; i++) {
2224
                if (isoDates[i][1].exec(match[1])) {
2225
                    dateFormat = isoDates[i][0];
2226
                    allowTime = isoDates[i][2] !== false;
2227
                    break;
2228
                }
2229
            }
2230
            if (dateFormat == null) {
2231
                config._isValid = false;
2232
                return;
2233
            }
2234
            if (match[3]) {
2235
                for (i = 0, l = isoTimes.length; i < l; i++) {
2236
                    if (isoTimes[i][1].exec(match[3])) {
2237
                        // match[2] should be 'T' or space
2238
                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
2239
                        break;
2240
                    }
2241
                }
2242
                if (timeFormat == null) {
2243
                    config._isValid = false;
2244
                    return;
2245
                }
2246
            }
2247
            if (!allowTime && timeFormat != null) {
2248
                config._isValid = false;
2249
                return;
2250
            }
2251
            if (match[4]) {
2252
                if (tzRegex.exec(match[4])) {
2253
                    tzFormat = 'Z';
2254
                } else {
2255
                    config._isValid = false;
2256
                    return;
2257
                }
2258
            }
2259
            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
2260
            configFromStringAndFormat(config);
2261
        } else {
2262
            config._isValid = false;
2263
        }
2264
    }
2265
2266
    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
2267
    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
2268
2269
    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
2270
        var result = [
2271
            untruncateYear(yearStr),
2272
            defaultLocaleMonthsShort.indexOf(monthStr),
2273
            parseInt(dayStr, 10),
2274
            parseInt(hourStr, 10),
2275
            parseInt(minuteStr, 10)
2276
        ];
2277
2278
        if (secondStr) {
2279
            result.push(parseInt(secondStr, 10));
2280
        }
2281
2282
        return result;
2283
    }
2284
2285
    function untruncateYear(yearStr) {
2286
        var year = parseInt(yearStr, 10);
2287
        if (year <= 49) {
2288
            return 2000 + year;
2289
        } else if (year <= 999) {
2290
            return 1900 + year;
2291
        }
2292
        return year;
2293
    }
2294
2295
    function preprocessRFC2822(s) {
2296
        // Remove comments and folding whitespace and replace multiple-spaces with a single space
2297
        return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
2298
    }
2299
2300
    function checkWeekday(weekdayStr, parsedInput, config) {
2301
        if (weekdayStr) {
2302
            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
2303
            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
2304
                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
2305
            if (weekdayProvided !== weekdayActual) {
2306
                getParsingFlags(config).weekdayMismatch = true;
2307
                config._isValid = false;
2308
                return false;
2309
            }
2310
        }
2311
        return true;
2312
    }
2313
2314
    var obsOffsets = {
2315
        UT: 0,
2316
        GMT: 0,
2317
        EDT: -4 * 60,
2318
        EST: -5 * 60,
2319
        CDT: -5 * 60,
2320
        CST: -6 * 60,
2321
        MDT: -6 * 60,
2322
        MST: -7 * 60,
2323
        PDT: -7 * 60,
2324
        PST: -8 * 60
2325
    };
2326
2327
    function calculateOffset(obsOffset, militaryOffset, numOffset) {
2328
        if (obsOffset) {
2329
            return obsOffsets[obsOffset];
2330
        } else if (militaryOffset) {
2331
            // the only allowed military tz is Z
2332
            return 0;
2333
        } else {
2334
            var hm = parseInt(numOffset, 10);
2335
            var m = hm % 100, h = (hm - m) / 100;
2336
            return h * 60 + m;
2337
        }
2338
    }
2339
2340
    // date and time from ref 2822 format
2341
    function configFromRFC2822(config) {
2342
        var match = rfc2822.exec(preprocessRFC2822(config._i));
2343
        if (match) {
2344
            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
2345
            if (!checkWeekday(match[1], parsedArray, config)) {
2346
                return;
2347
            }
2348
2349
            config._a = parsedArray;
2350
            config._tzm = calculateOffset(match[8], match[9], match[10]);
2351
2352
            config._d = createUTCDate.apply(null, config._a);
2353
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2354
2355
            getParsingFlags(config).rfc2822 = true;
2356
        } else {
2357
            config._isValid = false;
2358
        }
2359
    }
2360
2361
    // date from iso format or fallback
2362
    function configFromString(config) {
2363
        var matched = aspNetJsonRegex.exec(config._i);
2364
2365
        if (matched !== null) {
2366
            config._d = new Date(+matched[1]);
2367
            return;
2368
        }
2369
2370
        configFromISO(config);
2371
        if (config._isValid === false) {
2372
            delete config._isValid;
2373
        } else {
2374
            return;
2375
        }
2376
2377
        configFromRFC2822(config);
2378
        if (config._isValid === false) {
2379
            delete config._isValid;
2380
        } else {
2381
            return;
2382
        }
2383
2384
        // Final attempt, use Input Fallback
2385
        hooks.createFromInputFallback(config);
2386
    }
2387
2388
    hooks.createFromInputFallback = deprecate(
2389
        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
2390
        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
2391
        'discouraged and will be removed in an upcoming major release. Please refer to ' +
2392
        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
2393
        function (config) {
2394
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
2395
        }
2396
    );
2397
2398
    // constant that refers to the ISO standard
2399
    hooks.ISO_8601 = function () {};
2400
2401
    // constant that refers to the RFC 2822 form
2402
    hooks.RFC_2822 = function () {};
2403
2404
    // date from string and format string
2405
    function configFromStringAndFormat(config) {
2406
        // TODO: Move this to another part of the creation flow to prevent circular deps
2407
        if (config._f === hooks.ISO_8601) {
2408
            configFromISO(config);
2409
            return;
2410
        }
2411
        if (config._f === hooks.RFC_2822) {
2412
            configFromRFC2822(config);
2413
            return;
2414
        }
2415
        config._a = [];
2416
        getParsingFlags(config).empty = true;
2417
2418
        // This array is used to make a Date, either with `new Date` or `Date.UTC`
2419
        var string = '' + config._i,
2420
            i, parsedInput, tokens, token, skipped,
2421
            stringLength = string.length,
2422
            totalParsedInputLength = 0;
2423
2424
        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
2425
2426 View Code Duplication
        for (i = 0; i < tokens.length; i++) {
2427
            token = tokens[i];
2428
            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
2429
            // console.log('token', token, 'parsedInput', parsedInput,
2430
            //         'regex', getParseRegexForToken(token, config));
2431
            if (parsedInput) {
2432
                skipped = string.substr(0, string.indexOf(parsedInput));
2433
                if (skipped.length > 0) {
2434
                    getParsingFlags(config).unusedInput.push(skipped);
2435
                }
2436
                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
2437
                totalParsedInputLength += parsedInput.length;
2438
            }
2439
            // don't parse if it's not a known token
2440
            if (formatTokenFunctions[token]) {
2441
                if (parsedInput) {
2442
                    getParsingFlags(config).empty = false;
2443
                }
2444
                else {
2445
                    getParsingFlags(config).unusedTokens.push(token);
2446
                }
2447
                addTimeToArrayFromToken(token, parsedInput, config);
2448
            }
2449
            else if (config._strict && !parsedInput) {
2450
                getParsingFlags(config).unusedTokens.push(token);
2451
            }
2452
        }
2453
2454
        // add remaining unparsed input length to the string
2455
        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
2456
        if (string.length > 0) {
2457
            getParsingFlags(config).unusedInput.push(string);
2458
        }
2459
2460
        // clear _12h flag if hour is <= 12
2461
        if (config._a[HOUR] <= 12 &&
2462
            getParsingFlags(config).bigHour === true &&
2463
            config._a[HOUR] > 0) {
2464
            getParsingFlags(config).bigHour = undefined;
2465
        }
2466
2467
        getParsingFlags(config).parsedDateParts = config._a.slice(0);
2468
        getParsingFlags(config).meridiem = config._meridiem;
2469
        // handle meridiem
2470
        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
2471
2472
        configFromArray(config);
2473
        checkOverflow(config);
2474
    }
2475
2476
2477
    function meridiemFixWrap (locale, hour, meridiem) {
2478
        var isPm;
2479
2480
        if (meridiem == null) {
2481
            // nothing to do
2482
            return hour;
2483
        }
2484
        if (locale.meridiemHour != null) {
2485
            return locale.meridiemHour(hour, meridiem);
2486
        } else if (locale.isPM != null) {
2487
            // Fallback
2488
            isPm = locale.isPM(meridiem);
2489
            if (isPm && hour < 12) {
2490
                hour += 12;
2491
            }
2492
            if (!isPm && hour === 12) {
2493
                hour = 0;
2494
            }
2495
            return hour;
2496
        } else {
2497
            // this is not supposed to happen
2498
            return hour;
2499
        }
2500
    }
2501
2502
    // date from string and array of format strings
2503
    function configFromStringAndArray(config) {
2504
        var tempConfig,
2505
            bestMoment,
2506
2507
            scoreToBeat,
2508
            i,
2509
            currentScore;
2510
2511
        if (config._f.length === 0) {
2512
            getParsingFlags(config).invalidFormat = true;
2513
            config._d = new Date(NaN);
2514
            return;
2515
        }
2516
2517
        for (i = 0; i < config._f.length; i++) {
2518
            currentScore = 0;
2519
            tempConfig = copyConfig({}, config);
2520
            if (config._useUTC != null) {
2521
                tempConfig._useUTC = config._useUTC;
2522
            }
2523
            tempConfig._f = config._f[i];
2524
            configFromStringAndFormat(tempConfig);
2525
2526
            if (!isValid(tempConfig)) {
2527
                continue;
2528
            }
2529
2530
            // if there is any input that was not parsed add a penalty for that format
2531
            currentScore += getParsingFlags(tempConfig).charsLeftOver;
2532
2533
            //or tokens
2534
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
2535
2536
            getParsingFlags(tempConfig).score = currentScore;
2537
2538
            if (scoreToBeat == null || currentScore < scoreToBeat) {
2539
                scoreToBeat = currentScore;
2540
                bestMoment = tempConfig;
2541
            }
2542
        }
2543
2544
        extend(config, bestMoment || tempConfig);
2545
    }
2546
2547
    function configFromObject(config) {
2548
        if (config._d) {
2549
            return;
2550
        }
2551
2552
        var i = normalizeObjectUnits(config._i);
2553
        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
2554
            return obj && parseInt(obj, 10);
2555
        });
2556
2557
        configFromArray(config);
2558
    }
2559
2560
    function createFromConfig (config) {
2561
        var res = new Moment(checkOverflow(prepareConfig(config)));
2562
        if (res._nextDay) {
2563
            // Adding is smart enough around DST
2564
            res.add(1, 'd');
2565
            res._nextDay = undefined;
2566
        }
2567
2568
        return res;
2569
    }
2570
2571
    function prepareConfig (config) {
2572
        var input = config._i,
2573
            format = config._f;
2574
2575
        config._locale = config._locale || getLocale(config._l);
2576
2577
        if (input === null || (format === undefined && input === '')) {
2578
            return createInvalid({nullInput: true});
2579
        }
2580
2581
        if (typeof input === 'string') {
2582
            config._i = input = config._locale.preparse(input);
2583
        }
2584
2585
        if (isMoment(input)) {
2586
            return new Moment(checkOverflow(input));
2587
        } else if (isDate(input)) {
2588
            config._d = input;
2589
        } else if (isArray(format)) {
2590
            configFromStringAndArray(config);
2591
        } else if (format) {
2592
            configFromStringAndFormat(config);
2593
        }  else {
2594
            configFromInput(config);
2595
        }
2596
2597
        if (!isValid(config)) {
2598
            config._d = null;
2599
        }
2600
2601
        return config;
2602
    }
2603
2604
    function configFromInput(config) {
2605
        var input = config._i;
2606
        if (isUndefined(input)) {
2607
            config._d = new Date(hooks.now());
2608
        } else if (isDate(input)) {
2609
            config._d = new Date(input.valueOf());
2610
        } else if (typeof input === 'string') {
2611
            configFromString(config);
2612
        } else if (isArray(input)) {
2613
            config._a = map(input.slice(0), function (obj) {
2614
                return parseInt(obj, 10);
2615
            });
2616
            configFromArray(config);
2617
        } else if (isObject(input)) {
2618
            configFromObject(config);
2619
        } else if (isNumber(input)) {
2620
            // from milliseconds
2621
            config._d = new Date(input);
2622
        } else {
2623
            hooks.createFromInputFallback(config);
2624
        }
2625
    }
2626
2627
    function createLocalOrUTC (input, format, locale, strict, isUTC) {
2628
        var c = {};
2629
2630
        if (locale === true || locale === false) {
2631
            strict = locale;
2632
            locale = undefined;
2633
        }
2634
2635
        if ((isObject(input) && isObjectEmpty(input)) ||
2636
                (isArray(input) && input.length === 0)) {
2637
            input = undefined;
2638
        }
2639
        // object construction must be done this way.
2640
        // https://github.com/moment/moment/issues/1423
2641
        c._isAMomentObject = true;
2642
        c._useUTC = c._isUTC = isUTC;
2643
        c._l = locale;
2644
        c._i = input;
2645
        c._f = format;
2646
        c._strict = strict;
2647
2648
        return createFromConfig(c);
2649
    }
2650
2651
    function createLocal (input, format, locale, strict) {
2652
        return createLocalOrUTC(input, format, locale, strict, false);
2653
    }
2654
2655
    var prototypeMin = deprecate(
2656
        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
2657
        function () {
2658
            var other = createLocal.apply(null, arguments);
2659
            if (this.isValid() && other.isValid()) {
2660
                return other < this ? this : other;
2661
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
2662
                return createInvalid();
2663
            }
2664
        }
2665
    );
2666
2667
    var prototypeMax = deprecate(
2668
        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
2669
        function () {
2670
            var other = createLocal.apply(null, arguments);
2671
            if (this.isValid() && other.isValid()) {
2672
                return other > this ? this : other;
2673
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
2674
                return createInvalid();
2675
            }
2676
        }
2677
    );
2678
2679
    // Pick a moment m from moments so that m[fn](other) is true for all
2680
    // other. This relies on the function fn to be transitive.
2681
    //
2682
    // moments should either be an array of moment objects or an array, whose
2683
    // first element is an array of moment objects.
2684
    function pickBy(fn, moments) {
2685
        var res, i;
2686
        if (moments.length === 1 && isArray(moments[0])) {
2687
            moments = moments[0];
2688
        }
2689
        if (!moments.length) {
2690
            return createLocal();
2691
        }
2692
        res = moments[0];
2693
        for (i = 1; i < moments.length; ++i) {
2694
            if (!moments[i].isValid() || moments[i][fn](res)) {
2695
                res = moments[i];
2696
            }
2697
        }
2698
        return res;
2699
    }
2700
2701
    // TODO: Use [].sort instead?
2702
    function min () {
2703
        var args = [].slice.call(arguments, 0);
2704
2705
        return pickBy('isBefore', args);
2706
    }
2707
2708
    function max () {
2709
        var args = [].slice.call(arguments, 0);
2710
2711
        return pickBy('isAfter', args);
2712
    }
2713
2714
    var now = function () {
2715
        return Date.now ? Date.now() : +(new Date());
2716
    };
2717
2718
    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
2719
2720
    function isDurationValid(m) {
2721
        for (var key in m) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
2722
            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
2723
                return false;
2724
            }
2725
        }
2726
2727
        var unitHasDecimal = false;
2728
        for (var i = 0; i < ordering.length; ++i) {
2729
            if (m[ordering[i]]) {
2730
                if (unitHasDecimal) {
2731
                    return false; // only allow non-integers for smallest unit
2732
                }
2733
                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
2734
                    unitHasDecimal = true;
2735
                }
2736
            }
2737
        }
2738
2739
        return true;
2740
    }
2741
2742
    function isValid$1() {
2743
        return this._isValid;
2744
    }
2745
2746
    function createInvalid$1() {
2747
        return createDuration(NaN);
2748
    }
2749
2750
    function Duration (duration) {
2751
        var normalizedInput = normalizeObjectUnits(duration),
2752
            years = normalizedInput.year || 0,
2753
            quarters = normalizedInput.quarter || 0,
2754
            months = normalizedInput.month || 0,
2755
            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
2756
            days = normalizedInput.day || 0,
2757
            hours = normalizedInput.hour || 0,
2758
            minutes = normalizedInput.minute || 0,
2759
            seconds = normalizedInput.second || 0,
2760
            milliseconds = normalizedInput.millisecond || 0;
2761
2762
        this._isValid = isDurationValid(normalizedInput);
2763
2764
        // representation for dateAddRemove
2765
        this._milliseconds = +milliseconds +
2766
            seconds * 1e3 + // 1000
2767
            minutes * 6e4 + // 1000 * 60
2768
            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
2769
        // Because of dateAddRemove treats 24 hours as different from a
2770
        // day when working around DST, we need to store them separately
2771
        this._days = +days +
2772
            weeks * 7;
2773
        // It is impossible to translate months into days without knowing
2774
        // which months you are are talking about, so we have to store
2775
        // it separately.
2776
        this._months = +months +
2777
            quarters * 3 +
2778
            years * 12;
2779
2780
        this._data = {};
2781
2782
        this._locale = getLocale();
2783
2784
        this._bubble();
2785
    }
2786
2787
    function isDuration (obj) {
2788
        return obj instanceof Duration;
2789
    }
2790
2791
    function absRound (number) {
2792
        if (number < 0) {
2793
            return Math.round(-1 * number) * -1;
2794
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
2795
            return Math.round(number);
2796
        }
2797
    }
2798
2799
    // FORMATTING
2800
2801
    function offset (token, separator) {
2802
        addFormatToken(token, 0, 0, function () {
2803
            var offset = this.utcOffset();
2804
            var sign = '+';
2805
            if (offset < 0) {
2806
                offset = -offset;
2807
                sign = '-';
2808
            }
2809
            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
2810
        });
2811
    }
2812
2813
    offset('Z', ':');
2814
    offset('ZZ', '');
2815
2816
    // PARSING
2817
2818
    addRegexToken('Z',  matchShortOffset);
2819
    addRegexToken('ZZ', matchShortOffset);
2820
    addParseToken(['Z', 'ZZ'], function (input, array, config) {
2821
        config._useUTC = true;
2822
        config._tzm = offsetFromString(matchShortOffset, input);
2823
    });
2824
2825
    // HELPERS
2826
2827
    // timezone chunker
2828
    // '+10:00' > ['10',  '00']
2829
    // '-1530'  > ['-15', '30']
2830
    var chunkOffset = /([\+\-]|\d\d)/gi;
2831
2832
    function offsetFromString(matcher, string) {
2833
        var matches = (string || '').match(matcher);
2834
2835
        if (matches === null) {
2836
            return null;
2837
        }
2838
2839
        var chunk   = matches[matches.length - 1] || [];
2840
        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
2841
        var minutes = +(parts[1] * 60) + toInt(parts[2]);
2842
2843
        return minutes === 0 ?
2844
          0 :
2845
          parts[0] === '+' ? minutes : -minutes;
2846
    }
2847
2848
    // Return a moment from input, that is local/utc/zone equivalent to model.
2849
    function cloneWithOffset(input, model) {
2850
        var res, diff;
2851
        if (model._isUTC) {
2852
            res = model.clone();
2853
            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
2854
            // Use low-level api, because this fn is low-level api.
2855
            res._d.setTime(res._d.valueOf() + diff);
2856
            hooks.updateOffset(res, false);
2857
            return res;
2858
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
2859
            return createLocal(input).local();
2860
        }
2861
    }
2862
2863
    function getDateOffset (m) {
2864
        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
2865
        // https://github.com/moment/moment/pull/1871
2866
        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
2867
    }
2868
2869
    // HOOKS
2870
2871
    // This function will be called whenever a moment is mutated.
2872
    // It is intended to keep the offset in sync with the timezone.
2873
    hooks.updateOffset = function () {};
2874
2875
    // MOMENTS
2876
2877
    // keepLocalTime = true means only change the timezone, without
2878
    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
2879
    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
2880
    // +0200, so we adjust the time as needed, to be valid.
2881
    //
2882
    // Keeping the time actually adds/subtracts (one hour)
2883
    // from the actual represented time. That is why we call updateOffset
2884
    // a second time. In case it wants us to change the offset again
2885
    // _changeInProgress == true case, then we have to adjust, because
2886
    // there is no such time in the given timezone.
2887
    function getSetOffset (input, keepLocalTime, keepMinutes) {
2888
        var offset = this._offset || 0,
2889
            localAdjust;
2890
        if (!this.isValid()) {
2891
            return input != null ? this : NaN;
2892
        }
2893
        if (input != null) {
2894
            if (typeof input === 'string') {
2895
                input = offsetFromString(matchShortOffset, input);
2896
                if (input === null) {
2897
                    return this;
2898
                }
2899
            } else if (Math.abs(input) < 16 && !keepMinutes) {
2900
                input = input * 60;
2901
            }
2902
            if (!this._isUTC && keepLocalTime) {
2903
                localAdjust = getDateOffset(this);
2904
            }
2905
            this._offset = input;
2906
            this._isUTC = true;
2907
            if (localAdjust != null) {
2908
                this.add(localAdjust, 'm');
2909
            }
2910
            if (offset !== input) {
2911
                if (!keepLocalTime || this._changeInProgress) {
2912
                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);
2913
                } else if (!this._changeInProgress) {
2914
                    this._changeInProgress = true;
2915
                    hooks.updateOffset(this, true);
2916
                    this._changeInProgress = null;
2917
                }
2918
            }
2919
            return this;
2920
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
2921
            return this._isUTC ? offset : getDateOffset(this);
2922
        }
2923
    }
2924
2925
    function getSetZone (input, keepLocalTime) {
2926
        if (input != null) {
2927
            if (typeof input !== 'string') {
2928
                input = -input;
2929
            }
2930
2931
            this.utcOffset(input, keepLocalTime);
2932
2933
            return this;
2934
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
2935
            return -this.utcOffset();
2936
        }
2937
    }
2938
2939
    function setOffsetToUTC (keepLocalTime) {
2940
        return this.utcOffset(0, keepLocalTime);
2941
    }
2942
2943
    function setOffsetToLocal (keepLocalTime) {
2944
        if (this._isUTC) {
2945
            this.utcOffset(0, keepLocalTime);
2946
            this._isUTC = false;
2947
2948
            if (keepLocalTime) {
2949
                this.subtract(getDateOffset(this), 'm');
2950
            }
2951
        }
2952
        return this;
2953
    }
2954
2955
    function setOffsetToParsedOffset () {
2956
        if (this._tzm != null) {
2957
            this.utcOffset(this._tzm, false, true);
2958
        } else if (typeof this._i === 'string') {
2959
            var tZone = offsetFromString(matchOffset, this._i);
2960
            if (tZone != null) {
2961
                this.utcOffset(tZone);
2962
            }
2963
            else {
2964
                this.utcOffset(0, true);
2965
            }
2966
        }
2967
        return this;
2968
    }
2969
2970
    function hasAlignedHourOffset (input) {
2971
        if (!this.isValid()) {
2972
            return false;
2973
        }
2974
        input = input ? createLocal(input).utcOffset() : 0;
2975
2976
        return (this.utcOffset() - input) % 60 === 0;
2977
    }
2978
2979
    function isDaylightSavingTime () {
2980
        return (
2981
            this.utcOffset() > this.clone().month(0).utcOffset() ||
2982
            this.utcOffset() > this.clone().month(5).utcOffset()
2983
        );
2984
    }
2985
2986
    function isDaylightSavingTimeShifted () {
2987
        if (!isUndefined(this._isDSTShifted)) {
2988
            return this._isDSTShifted;
2989
        }
2990
2991
        var c = {};
2992
2993
        copyConfig(c, this);
2994
        c = prepareConfig(c);
2995
2996
        if (c._a) {
2997
            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
2998
            this._isDSTShifted = this.isValid() &&
2999
                compareArrays(c._a, other.toArray()) > 0;
3000
        } else {
3001
            this._isDSTShifted = false;
3002
        }
3003
3004
        return this._isDSTShifted;
3005
    }
3006
3007
    function isLocal () {
3008
        return this.isValid() ? !this._isUTC : false;
3009
    }
3010
3011
    function isUtcOffset () {
3012
        return this.isValid() ? this._isUTC : false;
3013
    }
3014
3015
    function isUtc () {
3016
        return this.isValid() ? this._isUTC && this._offset === 0 : false;
3017
    }
3018
3019
    // ASP.NET json date format regex
3020
    var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
3021
3022
    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
3023
    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
3024
    // and further modified to allow for strings containing both week and day
3025
    var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
3026
3027
    function createDuration (input, key) {
3028
        var duration = input,
3029
            // matching against regexp is expensive, do it on demand
3030
            match = null,
0 ignored issues
show
Unused Code introduced by
The assignment to match seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
3031
            sign,
3032
            ret,
3033
            diffRes;
3034
3035
        if (isDuration(input)) {
3036
            duration = {
3037
                ms : input._milliseconds,
3038
                d  : input._days,
3039
                M  : input._months
3040
            };
3041
        } else if (isNumber(input)) {
3042
            duration = {};
3043
            if (key) {
3044
                duration[key] = input;
3045
            } else {
3046
                duration.milliseconds = input;
3047
            }
3048
        } else if (!!(match = aspNetRegex.exec(input))) {
3049
            sign = (match[1] === '-') ? -1 : 1;
3050
            duration = {
3051
                y  : 0,
3052
                d  : toInt(match[DATE])                         * sign,
3053
                h  : toInt(match[HOUR])                         * sign,
3054
                m  : toInt(match[MINUTE])                       * sign,
3055
                s  : toInt(match[SECOND])                       * sign,
3056
                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
3057
            };
3058
        } else if (!!(match = isoRegex.exec(input))) {
3059
            sign = (match[1] === '-') ? -1 : 1;
3060
            duration = {
3061
                y : parseIso(match[2], sign),
3062
                M : parseIso(match[3], sign),
3063
                w : parseIso(match[4], sign),
3064
                d : parseIso(match[5], sign),
3065
                h : parseIso(match[6], sign),
3066
                m : parseIso(match[7], sign),
3067
                s : parseIso(match[8], sign)
3068
            };
3069
        } else if (duration == null) {// checks for null or undefined
3070
            duration = {};
3071
        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
3072
            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
3073
3074
            duration = {};
3075
            duration.ms = diffRes.milliseconds;
3076
            duration.M = diffRes.months;
3077
        }
3078
3079
        ret = new Duration(duration);
3080
3081
        if (isDuration(input) && hasOwnProp(input, '_locale')) {
3082
            ret._locale = input._locale;
3083
        }
3084
3085
        return ret;
3086
    }
3087
3088
    createDuration.fn = Duration.prototype;
3089
    createDuration.invalid = createInvalid$1;
3090
3091
    function parseIso (inp, sign) {
3092
        // We'd normally use ~~inp for this, but unfortunately it also
3093
        // converts floats to ints.
3094
        // inp may be undefined, so careful calling replace on it.
3095
        var res = inp && parseFloat(inp.replace(',', '.'));
3096
        // apply sign while we're at it
3097
        return (isNaN(res) ? 0 : res) * sign;
3098
    }
3099
3100
    function positiveMomentsDifference(base, other) {
3101
        var res = {};
3102
3103
        res.months = other.month() - base.month() +
3104
            (other.year() - base.year()) * 12;
3105
        if (base.clone().add(res.months, 'M').isAfter(other)) {
3106
            --res.months;
3107
        }
3108
3109
        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
3110
3111
        return res;
3112
    }
3113
3114
    function momentsDifference(base, other) {
3115
        var res;
3116
        if (!(base.isValid() && other.isValid())) {
3117
            return {milliseconds: 0, months: 0};
3118
        }
3119
3120
        other = cloneWithOffset(other, base);
3121
        if (base.isBefore(other)) {
3122
            res = positiveMomentsDifference(base, other);
3123
        } else {
3124
            res = positiveMomentsDifference(other, base);
3125
            res.milliseconds = -res.milliseconds;
3126
            res.months = -res.months;
3127
        }
3128
3129
        return res;
3130
    }
3131
3132
    // TODO: remove 'name' arg after deprecation is removed
3133
    function createAdder(direction, name) {
3134
        return function (val, period) {
3135
            var dur, tmp;
3136
            //invert the arguments, but complain about it
3137
            if (period !== null && !isNaN(+period)) {
3138
                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
3139
                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
3140
                tmp = val; val = period; period = tmp;
3141
            }
3142
3143
            val = typeof val === 'string' ? +val : val;
3144
            dur = createDuration(val, period);
3145
            addSubtract(this, dur, direction);
3146
            return this;
3147
        };
3148
    }
3149
3150
    function addSubtract (mom, duration, isAdding, updateOffset) {
3151
        var milliseconds = duration._milliseconds,
3152
            days = absRound(duration._days),
3153
            months = absRound(duration._months);
3154
3155
        if (!mom.isValid()) {
3156
            // No op
3157
            return;
3158
        }
3159
3160
        updateOffset = updateOffset == null ? true : updateOffset;
3161
3162
        if (months) {
3163
            setMonth(mom, get(mom, 'Month') + months * isAdding);
3164
        }
3165
        if (days) {
3166
            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
3167
        }
3168
        if (milliseconds) {
3169
            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
3170
        }
3171
        if (updateOffset) {
3172
            hooks.updateOffset(mom, days || months);
3173
        }
3174
    }
3175
3176
    var add      = createAdder(1, 'add');
3177
    var subtract = createAdder(-1, 'subtract');
3178
3179
    function getCalendarFormat(myMoment, now) {
3180
        var diff = myMoment.diff(now, 'days', true);
3181
        return diff < -6 ? 'sameElse' :
3182
                diff < -1 ? 'lastWeek' :
3183
                diff < 0 ? 'lastDay' :
3184
                diff < 1 ? 'sameDay' :
3185
                diff < 2 ? 'nextDay' :
3186
                diff < 7 ? 'nextWeek' : 'sameElse';
3187
    }
3188
3189
    function calendar$1 (time, formats) {
3190
        // We want to compare the start of today, vs this.
3191
        // Getting start-of-today depends on whether we're local/utc/offset or not.
3192
        var now = time || createLocal(),
3193
            sod = cloneWithOffset(now, this).startOf('day'),
3194
            format = hooks.calendarFormat(this, sod) || 'sameElse';
3195
3196
        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
3197
3198
        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
3199
    }
3200
3201
    function clone () {
3202
        return new Moment(this);
3203
    }
3204
3205
    function isAfter (input, units) {
3206
        var localInput = isMoment(input) ? input : createLocal(input);
3207
        if (!(this.isValid() && localInput.isValid())) {
3208
            return false;
3209
        }
3210
        units = normalizeUnits(units) || 'millisecond';
3211
        if (units === 'millisecond') {
3212
            return this.valueOf() > localInput.valueOf();
3213
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3214
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
3215
        }
3216
    }
3217
3218
    function isBefore (input, units) {
3219
        var localInput = isMoment(input) ? input : createLocal(input);
3220
        if (!(this.isValid() && localInput.isValid())) {
3221
            return false;
3222
        }
3223
        units = normalizeUnits(units) || 'millisecond';
3224
        if (units === 'millisecond') {
3225
            return this.valueOf() < localInput.valueOf();
3226
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3227
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
3228
        }
3229
    }
3230
3231
    function isBetween (from, to, units, inclusivity) {
3232
        var localFrom = isMoment(from) ? from : createLocal(from),
3233
            localTo = isMoment(to) ? to : createLocal(to);
3234
        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
3235
            return false;
3236
        }
3237
        inclusivity = inclusivity || '()';
3238
        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&
3239
            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
3240
    }
3241
3242
    function isSame (input, units) {
3243
        var localInput = isMoment(input) ? input : createLocal(input),
3244
            inputMs;
3245
        if (!(this.isValid() && localInput.isValid())) {
3246
            return false;
3247
        }
3248
        units = normalizeUnits(units) || 'millisecond';
3249
        if (units === 'millisecond') {
3250
            return this.valueOf() === localInput.valueOf();
3251
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3252
            inputMs = localInput.valueOf();
3253
            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
3254
        }
3255
    }
3256
3257
    function isSameOrAfter (input, units) {
3258
        return this.isSame(input, units) || this.isAfter(input, units);
3259
    }
3260
3261
    function isSameOrBefore (input, units) {
3262
        return this.isSame(input, units) || this.isBefore(input, units);
3263
    }
3264
3265
    function diff (input, units, asFloat) {
3266
        var that,
3267
            zoneDelta,
3268
            output;
3269
3270
        if (!this.isValid()) {
3271
            return NaN;
3272
        }
3273
3274
        that = cloneWithOffset(input, this);
3275
3276
        if (!that.isValid()) {
3277
            return NaN;
3278
        }
3279
3280
        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
3281
3282
        units = normalizeUnits(units);
3283
3284
        switch (units) {
3285
            case 'year': output = monthDiff(this, that) / 12; break;
3286
            case 'month': output = monthDiff(this, that); break;
3287
            case 'quarter': output = monthDiff(this, that) / 3; break;
3288
            case 'second': output = (this - that) / 1e3; break; // 1000
3289
            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
3290
            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
3291
            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
3292
            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
3293
            default: output = this - that;
3294
        }
3295
3296
        return asFloat ? output : absFloor(output);
3297
    }
3298
3299
    function monthDiff (a, b) {
3300
        // difference in months
3301
        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
3302
            // b is in (anchor - 1 month, anchor + 1 month)
3303
            anchor = a.clone().add(wholeMonthDiff, 'months'),
3304
            anchor2, adjust;
3305
3306
        if (b - anchor < 0) {
3307
            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
3308
            // linear across the month
3309
            adjust = (b - anchor) / (anchor - anchor2);
3310
        } else {
3311
            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
3312
            // linear across the month
3313
            adjust = (b - anchor) / (anchor2 - anchor);
3314
        }
3315
3316
        //check for negative zero, return zero if negative zero
3317
        return -(wholeMonthDiff + adjust) || 0;
3318
    }
3319
3320
    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
3321
    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
3322
3323
    function toString () {
3324
        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
3325
    }
3326
3327
    function toISOString(keepOffset) {
3328
        if (!this.isValid()) {
3329
            return null;
3330
        }
3331
        var utc = keepOffset !== true;
3332
        var m = utc ? this.clone().utc() : this;
3333
        if (m.year() < 0 || m.year() > 9999) {
3334
            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
3335
        }
3336
        if (isFunction(Date.prototype.toISOString)) {
3337
            // native implementation is ~50x faster, use it when we can
3338
            if (utc) {
3339
                return this.toDate().toISOString();
3340
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3341
                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
3342
            }
3343
        }
3344
        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
3345
    }
3346
3347
    /**
3348
     * Return a human readable representation of a moment that can
3349
     * also be evaluated to get a new moment which is the same
3350
     *
3351
     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
3352
     */
3353
    function inspect () {
3354
        if (!this.isValid()) {
3355
            return 'moment.invalid(/* ' + this._i + ' */)';
3356
        }
3357
        var func = 'moment';
3358
        var zone = '';
3359
        if (!this.isLocal()) {
3360
            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
3361
            zone = 'Z';
3362
        }
3363
        var prefix = '[' + func + '("]';
3364
        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
3365
        var datetime = '-MM-DD[T]HH:mm:ss.SSS';
3366
        var suffix = zone + '[")]';
3367
3368
        return this.format(prefix + year + datetime + suffix);
3369
    }
3370
3371
    function format (inputString) {
3372
        if (!inputString) {
3373
            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
3374
        }
3375
        var output = formatMoment(this, inputString);
3376
        return this.localeData().postformat(output);
3377
    }
3378
3379
    function from (time, withoutSuffix) {
3380
        if (this.isValid() &&
3381
                ((isMoment(time) && time.isValid()) ||
3382
                 createLocal(time).isValid())) {
3383
            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
3384
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3385
            return this.localeData().invalidDate();
3386
        }
3387
    }
3388
3389
    function fromNow (withoutSuffix) {
3390
        return this.from(createLocal(), withoutSuffix);
3391
    }
3392
3393
    function to (time, withoutSuffix) {
3394
        if (this.isValid() &&
3395
                ((isMoment(time) && time.isValid()) ||
3396
                 createLocal(time).isValid())) {
3397
            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
3398
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3399
            return this.localeData().invalidDate();
3400
        }
3401
    }
3402
3403
    function toNow (withoutSuffix) {
3404
        return this.to(createLocal(), withoutSuffix);
3405
    }
3406
3407
    // If passed a locale key, it will set the locale for this
3408
    // instance.  Otherwise, it will return the locale configuration
3409
    // variables for this instance.
3410
    function locale (key) {
3411
        var newLocaleData;
3412
3413
        if (key === undefined) {
3414
            return this._locale._abbr;
3415
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3416
            newLocaleData = getLocale(key);
3417
            if (newLocaleData != null) {
3418
                this._locale = newLocaleData;
3419
            }
3420
            return this;
3421
        }
3422
    }
3423
3424
    var lang = deprecate(
3425
        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
3426
        function (key) {
3427
            if (key === undefined) {
3428
                return this.localeData();
3429
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3430
                return this.locale(key);
3431
            }
3432
        }
3433
    );
3434
3435
    function localeData () {
3436
        return this._locale;
3437
    }
3438
3439
    var MS_PER_SECOND = 1000;
3440
    var MS_PER_MINUTE = 60 * MS_PER_SECOND;
3441
    var MS_PER_HOUR = 60 * MS_PER_MINUTE;
3442
    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
3443
3444
    // actual modulo - handles negative numbers (for dates before 1970):
3445
    function mod$1(dividend, divisor) {
3446
        return (dividend % divisor + divisor) % divisor;
3447
    }
3448
3449
    function localStartOfDate(y, m, d) {
3450
        // the date constructor remaps years 0-99 to 1900-1999
3451
        if (y < 100 && y >= 0) {
3452
            // preserve leap years using a full 400 year cycle, then reset
3453
            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
3454
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3455
            return new Date(y, m, d).valueOf();
3456
        }
3457
    }
3458
3459
    function utcStartOfDate(y, m, d) {
3460
        // Date.UTC remaps years 0-99 to 1900-1999
3461
        if (y < 100 && y >= 0) {
3462
            // preserve leap years using a full 400 year cycle, then reset
3463
            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
3464
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3465
            return Date.UTC(y, m, d);
3466
        }
3467
    }
3468
3469
    function startOf (units) {
3470
        var time;
3471
        units = normalizeUnits(units);
3472
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
3473
            return this;
3474
        }
3475
3476
        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
3477
3478
        switch (units) {
3479
            case 'year':
3480
                time = startOfDate(this.year(), 0, 1);
3481
                break;
3482
            case 'quarter':
3483
                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
3484
                break;
3485
            case 'month':
3486
                time = startOfDate(this.year(), this.month(), 1);
3487
                break;
3488
            case 'week':
3489
                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
3490
                break;
3491
            case 'isoWeek':
3492
                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
3493
                break;
3494
            case 'day':
3495
            case 'date':
3496
                time = startOfDate(this.year(), this.month(), this.date());
3497
                break;
3498
            case 'hour':
3499
                time = this._d.valueOf();
3500
                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
3501
                break;
3502
            case 'minute':
3503
                time = this._d.valueOf();
3504
                time -= mod$1(time, MS_PER_MINUTE);
3505
                break;
3506
            case 'second':
3507
                time = this._d.valueOf();
3508
                time -= mod$1(time, MS_PER_SECOND);
3509
                break;
3510
        }
3511
3512
        this._d.setTime(time);
0 ignored issues
show
Bug introduced by
The variable time seems to not be initialized for all possible execution paths. Are you sure setTime handles undefined variables?
Loading history...
3513
        hooks.updateOffset(this, true);
3514
        return this;
3515
    }
3516
3517
    function endOf (units) {
3518
        var time;
3519
        units = normalizeUnits(units);
3520
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
3521
            return this;
3522
        }
3523
3524
        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
3525
3526
        switch (units) {
3527
            case 'year':
3528
                time = startOfDate(this.year() + 1, 0, 1) - 1;
3529
                break;
3530
            case 'quarter':
3531
                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
3532
                break;
3533
            case 'month':
3534
                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
3535
                break;
3536
            case 'week':
3537
                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
3538
                break;
3539
            case 'isoWeek':
3540
                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
3541
                break;
3542
            case 'day':
3543
            case 'date':
3544
                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
3545
                break;
3546
            case 'hour':
3547
                time = this._d.valueOf();
3548
                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
3549
                break;
3550
            case 'minute':
3551
                time = this._d.valueOf();
3552
                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
3553
                break;
3554
            case 'second':
3555
                time = this._d.valueOf();
3556
                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
3557
                break;
3558
        }
3559
3560
        this._d.setTime(time);
0 ignored issues
show
Bug introduced by
The variable time seems to not be initialized for all possible execution paths. Are you sure setTime handles undefined variables?
Loading history...
3561
        hooks.updateOffset(this, true);
3562
        return this;
3563
    }
3564
3565
    function valueOf () {
3566
        return this._d.valueOf() - ((this._offset || 0) * 60000);
3567
    }
3568
3569
    function unix () {
3570
        return Math.floor(this.valueOf() / 1000);
3571
    }
3572
3573
    function toDate () {
3574
        return new Date(this.valueOf());
3575
    }
3576
3577
    function toArray () {
3578
        var m = this;
3579
        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
3580
    }
3581
3582
    function toObject () {
3583
        var m = this;
3584
        return {
3585
            years: m.year(),
3586
            months: m.month(),
3587
            date: m.date(),
3588
            hours: m.hours(),
3589
            minutes: m.minutes(),
3590
            seconds: m.seconds(),
3591
            milliseconds: m.milliseconds()
3592
        };
3593
    }
3594
3595
    function toJSON () {
3596
        // new Date(NaN).toJSON() === null
3597
        return this.isValid() ? this.toISOString() : null;
3598
    }
3599
3600
    function isValid$2 () {
3601
        return isValid(this);
3602
    }
3603
3604
    function parsingFlags () {
3605
        return extend({}, getParsingFlags(this));
3606
    }
3607
3608
    function invalidAt () {
3609
        return getParsingFlags(this).overflow;
3610
    }
3611
3612
    function creationData() {
3613
        return {
3614
            input: this._i,
3615
            format: this._f,
3616
            locale: this._locale,
3617
            isUTC: this._isUTC,
3618
            strict: this._strict
3619
        };
3620
    }
3621
3622
    // FORMATTING
3623
3624
    addFormatToken(0, ['gg', 2], 0, function () {
3625
        return this.weekYear() % 100;
3626
    });
3627
3628
    addFormatToken(0, ['GG', 2], 0, function () {
3629
        return this.isoWeekYear() % 100;
3630
    });
3631
3632
    function addWeekYearFormatToken (token, getter) {
3633
        addFormatToken(0, [token, token.length], 0, getter);
3634
    }
3635
3636
    addWeekYearFormatToken('gggg',     'weekYear');
3637
    addWeekYearFormatToken('ggggg',    'weekYear');
3638
    addWeekYearFormatToken('GGGG',  'isoWeekYear');
3639
    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
3640
3641
    // ALIASES
3642
3643
    addUnitAlias('weekYear', 'gg');
3644
    addUnitAlias('isoWeekYear', 'GG');
3645
3646
    // PRIORITY
3647
3648
    addUnitPriority('weekYear', 1);
3649
    addUnitPriority('isoWeekYear', 1);
3650
3651
3652
    // PARSING
3653
3654
    addRegexToken('G',      matchSigned);
3655
    addRegexToken('g',      matchSigned);
3656
    addRegexToken('GG',     match1to2, match2);
3657
    addRegexToken('gg',     match1to2, match2);
3658
    addRegexToken('GGGG',   match1to4, match4);
3659
    addRegexToken('gggg',   match1to4, match4);
3660
    addRegexToken('GGGGG',  match1to6, match6);
3661
    addRegexToken('ggggg',  match1to6, match6);
3662
3663
    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
3664
        week[token.substr(0, 2)] = toInt(input);
3665
    });
3666
3667
    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
3668
        week[token] = hooks.parseTwoDigitYear(input);
3669
    });
3670
3671
    // MOMENTS
3672
3673
    function getSetWeekYear (input) {
3674
        return getSetWeekYearHelper.call(this,
3675
                input,
3676
                this.week(),
3677
                this.weekday(),
3678
                this.localeData()._week.dow,
3679
                this.localeData()._week.doy);
3680
    }
3681
3682
    function getSetISOWeekYear (input) {
3683
        return getSetWeekYearHelper.call(this,
3684
                input, this.isoWeek(), this.isoWeekday(), 1, 4);
3685
    }
3686
3687
    function getISOWeeksInYear () {
3688
        return weeksInYear(this.year(), 1, 4);
3689
    }
3690
3691
    function getWeeksInYear () {
3692
        var weekInfo = this.localeData()._week;
3693
        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
3694
    }
3695
3696
    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
3697
        var weeksTarget;
3698
        if (input == null) {
3699
            return weekOfYear(this, dow, doy).year;
3700
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3701
            weeksTarget = weeksInYear(input, dow, doy);
3702
            if (week > weeksTarget) {
3703
                week = weeksTarget;
3704
            }
3705
            return setWeekAll.call(this, input, week, weekday, dow, doy);
3706
        }
3707
    }
3708
3709
    function setWeekAll(weekYear, week, weekday, dow, doy) {
3710
        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
3711
            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
3712
3713
        this.year(date.getUTCFullYear());
3714
        this.month(date.getUTCMonth());
3715
        this.date(date.getUTCDate());
3716
        return this;
3717
    }
3718
3719
    // FORMATTING
3720
3721
    addFormatToken('Q', 0, 'Qo', 'quarter');
3722
3723
    // ALIASES
3724
3725
    addUnitAlias('quarter', 'Q');
3726
3727
    // PRIORITY
3728
3729
    addUnitPriority('quarter', 7);
3730
3731
    // PARSING
3732
3733
    addRegexToken('Q', match1);
3734
    addParseToken('Q', function (input, array) {
3735
        array[MONTH] = (toInt(input) - 1) * 3;
3736
    });
3737
3738
    // MOMENTS
3739
3740
    function getSetQuarter (input) {
3741
        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
3742
    }
3743
3744
    // FORMATTING
3745
3746
    addFormatToken('D', ['DD', 2], 'Do', 'date');
3747
3748
    // ALIASES
3749
3750
    addUnitAlias('date', 'D');
3751
3752
    // PRIORITY
3753
    addUnitPriority('date', 9);
3754
3755
    // PARSING
3756
3757
    addRegexToken('D',  match1to2);
3758
    addRegexToken('DD', match1to2, match2);
3759
    addRegexToken('Do', function (isStrict, locale) {
3760
        // TODO: Remove "ordinalParse" fallback in next major release.
3761
        return isStrict ?
3762
          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
3763
          locale._dayOfMonthOrdinalParseLenient;
3764
    });
3765
3766
    addParseToken(['D', 'DD'], DATE);
3767
    addParseToken('Do', function (input, array) {
3768
        array[DATE] = toInt(input.match(match1to2)[0]);
3769
    });
3770
3771
    // MOMENTS
3772
3773
    var getSetDayOfMonth = makeGetSet('Date', true);
3774
3775
    // FORMATTING
3776
3777
    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
3778
3779
    // ALIASES
3780
3781
    addUnitAlias('dayOfYear', 'DDD');
3782
3783
    // PRIORITY
3784
    addUnitPriority('dayOfYear', 4);
3785
3786
    // PARSING
3787
3788
    addRegexToken('DDD',  match1to3);
3789
    addRegexToken('DDDD', match3);
3790
    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
3791
        config._dayOfYear = toInt(input);
3792
    });
3793
3794
    // HELPERS
3795
3796
    // MOMENTS
3797
3798
    function getSetDayOfYear (input) {
3799
        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
3800
        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
3801
    }
3802
3803
    // FORMATTING
3804
3805
    addFormatToken('m', ['mm', 2], 0, 'minute');
3806
3807
    // ALIASES
3808
3809
    addUnitAlias('minute', 'm');
3810
3811
    // PRIORITY
3812
3813
    addUnitPriority('minute', 14);
3814
3815
    // PARSING
3816
3817
    addRegexToken('m',  match1to2);
3818
    addRegexToken('mm', match1to2, match2);
3819
    addParseToken(['m', 'mm'], MINUTE);
3820
3821
    // MOMENTS
3822
3823
    var getSetMinute = makeGetSet('Minutes', false);
3824
3825
    // FORMATTING
3826
3827
    addFormatToken('s', ['ss', 2], 0, 'second');
3828
3829
    // ALIASES
3830
3831
    addUnitAlias('second', 's');
3832
3833
    // PRIORITY
3834
3835
    addUnitPriority('second', 15);
3836
3837
    // PARSING
3838
3839
    addRegexToken('s',  match1to2);
3840
    addRegexToken('ss', match1to2, match2);
3841
    addParseToken(['s', 'ss'], SECOND);
3842
3843
    // MOMENTS
3844
3845
    var getSetSecond = makeGetSet('Seconds', false);
3846
3847
    // FORMATTING
3848
3849
    addFormatToken('S', 0, 0, function () {
3850
        return ~~(this.millisecond() / 100);
3851
    });
3852
3853
    addFormatToken(0, ['SS', 2], 0, function () {
3854
        return ~~(this.millisecond() / 10);
3855
    });
3856
3857
    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
3858
    addFormatToken(0, ['SSSS', 4], 0, function () {
3859
        return this.millisecond() * 10;
3860
    });
3861
    addFormatToken(0, ['SSSSS', 5], 0, function () {
3862
        return this.millisecond() * 100;
3863
    });
3864
    addFormatToken(0, ['SSSSSS', 6], 0, function () {
3865
        return this.millisecond() * 1000;
3866
    });
3867
    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
3868
        return this.millisecond() * 10000;
3869
    });
3870
    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
3871
        return this.millisecond() * 100000;
3872
    });
3873
    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
3874
        return this.millisecond() * 1000000;
3875
    });
3876
3877
3878
    // ALIASES
3879
3880
    addUnitAlias('millisecond', 'ms');
3881
3882
    // PRIORITY
3883
3884
    addUnitPriority('millisecond', 16);
3885
3886
    // PARSING
3887
3888
    addRegexToken('S',    match1to3, match1);
3889
    addRegexToken('SS',   match1to3, match2);
3890
    addRegexToken('SSS',  match1to3, match3);
3891
3892
    var token;
3893
    for (token = 'SSSS'; token.length <= 9; token += 'S') {
3894
        addRegexToken(token, matchUnsigned);
3895
    }
3896
3897
    function parseMs(input, array) {
3898
        array[MILLISECOND] = toInt(('0.' + input) * 1000);
3899
    }
3900
3901
    for (token = 'S'; token.length <= 9; token += 'S') {
3902
        addParseToken(token, parseMs);
3903
    }
3904
    // MOMENTS
3905
3906
    var getSetMillisecond = makeGetSet('Milliseconds', false);
3907
3908
    // FORMATTING
3909
3910
    addFormatToken('z',  0, 0, 'zoneAbbr');
3911
    addFormatToken('zz', 0, 0, 'zoneName');
3912
3913
    // MOMENTS
3914
3915
    function getZoneAbbr () {
3916
        return this._isUTC ? 'UTC' : '';
3917
    }
3918
3919
    function getZoneName () {
3920
        return this._isUTC ? 'Coordinated Universal Time' : '';
3921
    }
3922
3923
    var proto = Moment.prototype;
3924
3925
    proto.add               = add;
3926
    proto.calendar          = calendar$1;
3927
    proto.clone             = clone;
3928
    proto.diff              = diff;
3929
    proto.endOf             = endOf;
3930
    proto.format            = format;
3931
    proto.from              = from;
3932
    proto.fromNow           = fromNow;
3933
    proto.to                = to;
3934
    proto.toNow             = toNow;
3935
    proto.get               = stringGet;
3936
    proto.invalidAt         = invalidAt;
3937
    proto.isAfter           = isAfter;
3938
    proto.isBefore          = isBefore;
3939
    proto.isBetween         = isBetween;
3940
    proto.isSame            = isSame;
3941
    proto.isSameOrAfter     = isSameOrAfter;
3942
    proto.isSameOrBefore    = isSameOrBefore;
3943
    proto.isValid           = isValid$2;
3944
    proto.lang              = lang;
3945
    proto.locale            = locale;
3946
    proto.localeData        = localeData;
3947
    proto.max               = prototypeMax;
3948
    proto.min               = prototypeMin;
3949
    proto.parsingFlags      = parsingFlags;
3950
    proto.set               = stringSet;
3951
    proto.startOf           = startOf;
3952
    proto.subtract          = subtract;
3953
    proto.toArray           = toArray;
3954
    proto.toObject          = toObject;
3955
    proto.toDate            = toDate;
3956
    proto.toISOString       = toISOString;
3957
    proto.inspect           = inspect;
3958
    proto.toJSON            = toJSON;
3959
    proto.toString          = toString;
3960
    proto.unix              = unix;
3961
    proto.valueOf           = valueOf;
3962
    proto.creationData      = creationData;
3963
    proto.year       = getSetYear;
3964
    proto.isLeapYear = getIsLeapYear;
3965
    proto.weekYear    = getSetWeekYear;
3966
    proto.isoWeekYear = getSetISOWeekYear;
3967
    proto.quarter = proto.quarters = getSetQuarter;
3968
    proto.month       = getSetMonth;
3969
    proto.daysInMonth = getDaysInMonth;
3970
    proto.week           = proto.weeks        = getSetWeek;
3971
    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
3972
    proto.weeksInYear    = getWeeksInYear;
3973
    proto.isoWeeksInYear = getISOWeeksInYear;
3974
    proto.date       = getSetDayOfMonth;
3975
    proto.day        = proto.days             = getSetDayOfWeek;
3976
    proto.weekday    = getSetLocaleDayOfWeek;
3977
    proto.isoWeekday = getSetISODayOfWeek;
3978
    proto.dayOfYear  = getSetDayOfYear;
3979
    proto.hour = proto.hours = getSetHour;
3980
    proto.minute = proto.minutes = getSetMinute;
3981
    proto.second = proto.seconds = getSetSecond;
3982
    proto.millisecond = proto.milliseconds = getSetMillisecond;
3983
    proto.utcOffset            = getSetOffset;
3984
    proto.utc                  = setOffsetToUTC;
3985
    proto.local                = setOffsetToLocal;
3986
    proto.parseZone            = setOffsetToParsedOffset;
3987
    proto.hasAlignedHourOffset = hasAlignedHourOffset;
3988
    proto.isDST                = isDaylightSavingTime;
3989
    proto.isLocal              = isLocal;
3990
    proto.isUtcOffset          = isUtcOffset;
3991
    proto.isUtc                = isUtc;
3992
    proto.isUTC                = isUtc;
3993
    proto.zoneAbbr = getZoneAbbr;
3994
    proto.zoneName = getZoneName;
3995
    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
3996
    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
3997
    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
3998
    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
3999
    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
4000
4001
    function createUnix (input) {
4002
        return createLocal(input * 1000);
4003
    }
4004
4005
    function createInZone () {
4006
        return createLocal.apply(null, arguments).parseZone();
4007
    }
4008
4009
    function preParsePostFormat (string) {
4010
        return string;
4011
    }
4012
4013
    var proto$1 = Locale.prototype;
4014
4015
    proto$1.calendar        = calendar;
4016
    proto$1.longDateFormat  = longDateFormat;
4017
    proto$1.invalidDate     = invalidDate;
4018
    proto$1.ordinal         = ordinal;
4019
    proto$1.preparse        = preParsePostFormat;
4020
    proto$1.postformat      = preParsePostFormat;
4021
    proto$1.relativeTime    = relativeTime;
4022
    proto$1.pastFuture      = pastFuture;
4023
    proto$1.set             = set;
4024
4025
    proto$1.months            =        localeMonths;
4026
    proto$1.monthsShort       =        localeMonthsShort;
4027
    proto$1.monthsParse       =        localeMonthsParse;
4028
    proto$1.monthsRegex       = monthsRegex;
4029
    proto$1.monthsShortRegex  = monthsShortRegex;
4030
    proto$1.week = localeWeek;
4031
    proto$1.firstDayOfYear = localeFirstDayOfYear;
4032
    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
4033
4034
    proto$1.weekdays       =        localeWeekdays;
4035
    proto$1.weekdaysMin    =        localeWeekdaysMin;
4036
    proto$1.weekdaysShort  =        localeWeekdaysShort;
4037
    proto$1.weekdaysParse  =        localeWeekdaysParse;
4038
4039
    proto$1.weekdaysRegex       =        weekdaysRegex;
4040
    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
4041
    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;
4042
4043
    proto$1.isPM = localeIsPM;
4044
    proto$1.meridiem = localeMeridiem;
4045
4046
    function get$1 (format, index, field, setter) {
4047
        var locale = getLocale();
4048
        var utc = createUTC().set(setter, index);
4049
        return locale[field](utc, format);
4050
    }
4051
4052
    function listMonthsImpl (format, index, field) {
4053
        if (isNumber(format)) {
4054
            index = format;
4055
            format = undefined;
4056
        }
4057
4058
        format = format || '';
4059
4060
        if (index != null) {
4061
            return get$1(format, index, field, 'month');
4062
        }
4063
4064
        var i;
4065
        var out = [];
4066
        for (i = 0; i < 12; i++) {
4067
            out[i] = get$1(format, i, field, 'month');
4068
        }
4069
        return out;
4070
    }
4071
4072
    // ()
4073
    // (5)
4074
    // (fmt, 5)
4075
    // (fmt)
4076
    // (true)
4077
    // (true, 5)
4078
    // (true, fmt, 5)
4079
    // (true, fmt)
4080
    function listWeekdaysImpl (localeSorted, format, index, field) {
4081
        if (typeof localeSorted === 'boolean') {
4082
            if (isNumber(format)) {
4083
                index = format;
4084
                format = undefined;
4085
            }
4086
4087
            format = format || '';
4088
        } else {
4089
            format = localeSorted;
4090
            index = format;
4091
            localeSorted = false;
4092
4093
            if (isNumber(format)) {
4094
                index = format;
4095
                format = undefined;
4096
            }
4097
4098
            format = format || '';
4099
        }
4100
4101
        var locale = getLocale(),
4102
            shift = localeSorted ? locale._week.dow : 0;
4103
4104
        if (index != null) {
4105
            return get$1(format, (index + shift) % 7, field, 'day');
4106
        }
4107
4108
        var i;
4109
        var out = [];
4110
        for (i = 0; i < 7; i++) {
4111
            out[i] = get$1(format, (i + shift) % 7, field, 'day');
4112
        }
4113
        return out;
4114
    }
4115
4116
    function listMonths (format, index) {
4117
        return listMonthsImpl(format, index, 'months');
4118
    }
4119
4120
    function listMonthsShort (format, index) {
4121
        return listMonthsImpl(format, index, 'monthsShort');
4122
    }
4123
4124
    function listWeekdays (localeSorted, format, index) {
4125
        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
4126
    }
4127
4128
    function listWeekdaysShort (localeSorted, format, index) {
4129
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
4130
    }
4131
4132
    function listWeekdaysMin (localeSorted, format, index) {
4133
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
4134
    }
4135
4136
    getSetGlobalLocale('en', {
4137
        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
4138
        ordinal : function (number) {
4139
            var b = number % 10,
4140
                output = (toInt(number % 100 / 10) === 1) ? 'th' :
4141
                (b === 1) ? 'st' :
4142
                (b === 2) ? 'nd' :
4143
                (b === 3) ? 'rd' : 'th';
4144
            return number + output;
4145
        }
4146
    });
4147
4148
    // Side effect imports
4149
4150
    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
4151
    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
4152
4153
    var mathAbs = Math.abs;
4154
4155
    function abs () {
4156
        var data           = this._data;
4157
4158
        this._milliseconds = mathAbs(this._milliseconds);
4159
        this._days         = mathAbs(this._days);
4160
        this._months       = mathAbs(this._months);
4161
4162
        data.milliseconds  = mathAbs(data.milliseconds);
4163
        data.seconds       = mathAbs(data.seconds);
4164
        data.minutes       = mathAbs(data.minutes);
4165
        data.hours         = mathAbs(data.hours);
4166
        data.months        = mathAbs(data.months);
4167
        data.years         = mathAbs(data.years);
4168
4169
        return this;
4170
    }
4171
4172
    function addSubtract$1 (duration, input, value, direction) {
4173
        var other = createDuration(input, value);
4174
4175
        duration._milliseconds += direction * other._milliseconds;
4176
        duration._days         += direction * other._days;
4177
        duration._months       += direction * other._months;
4178
4179
        return duration._bubble();
4180
    }
4181
4182
    // supports only 2.0-style add(1, 's') or add(duration)
4183
    function add$1 (input, value) {
4184
        return addSubtract$1(this, input, value, 1);
4185
    }
4186
4187
    // supports only 2.0-style subtract(1, 's') or subtract(duration)
4188
    function subtract$1 (input, value) {
4189
        return addSubtract$1(this, input, value, -1);
4190
    }
4191
4192
    function absCeil (number) {
4193
        if (number < 0) {
4194
            return Math.floor(number);
4195
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
4196
            return Math.ceil(number);
4197
        }
4198
    }
4199
4200
    function bubble () {
4201
        var milliseconds = this._milliseconds;
4202
        var days         = this._days;
4203
        var months       = this._months;
4204
        var data         = this._data;
4205
        var seconds, minutes, hours, years, monthsFromDays;
4206
4207
        // if we have a mix of positive and negative values, bubble down first
4208
        // check: https://github.com/moment/moment/issues/2166
4209
        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
4210
                (milliseconds <= 0 && days <= 0 && months <= 0))) {
4211
            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
4212
            days = 0;
4213
            months = 0;
4214
        }
4215
4216
        // The following code bubbles up values, see the tests for
4217
        // examples of what that means.
4218
        data.milliseconds = milliseconds % 1000;
4219
4220
        seconds           = absFloor(milliseconds / 1000);
4221
        data.seconds      = seconds % 60;
4222
4223
        minutes           = absFloor(seconds / 60);
4224
        data.minutes      = minutes % 60;
4225
4226
        hours             = absFloor(minutes / 60);
4227
        data.hours        = hours % 24;
4228
4229
        days += absFloor(hours / 24);
4230
4231
        // convert days to months
4232
        monthsFromDays = absFloor(daysToMonths(days));
4233
        months += monthsFromDays;
4234
        days -= absCeil(monthsToDays(monthsFromDays));
4235
4236
        // 12 months -> 1 year
4237
        years = absFloor(months / 12);
4238
        months %= 12;
4239
4240
        data.days   = days;
4241
        data.months = months;
4242
        data.years  = years;
4243
4244
        return this;
4245
    }
4246
4247
    function daysToMonths (days) {
4248
        // 400 years have 146097 days (taking into account leap year rules)
4249
        // 400 years have 12 months === 4800
4250
        return days * 4800 / 146097;
4251
    }
4252
4253
    function monthsToDays (months) {
4254
        // the reverse of daysToMonths
4255
        return months * 146097 / 4800;
4256
    }
4257
4258
    function as (units) {
4259
        if (!this.isValid()) {
4260
            return NaN;
4261
        }
4262
        var days;
4263
        var months;
4264
        var milliseconds = this._milliseconds;
4265
4266
        units = normalizeUnits(units);
4267
4268
        if (units === 'month' || units === 'quarter' || units === 'year') {
4269
            days = this._days + milliseconds / 864e5;
4270
            months = this._months + daysToMonths(days);
4271
            switch (units) {
4272
                case 'month':   return months;
4273
                case 'quarter': return months / 3;
4274
                case 'year':    return months / 12;
4275
            }
0 ignored issues
show
Comprehensibility introduced by
There is no default case in this switch, so nothing gets returned when all cases fail. You might want to consider adding a default or return undefined explicitly.
Loading history...
4276
        } else {
4277
            // handle milliseconds separately because of floating point math errors (issue #1867)
4278
            days = this._days + Math.round(monthsToDays(this._months));
4279
            switch (units) {
4280
                case 'week'   : return days / 7     + milliseconds / 6048e5;
4281
                case 'day'    : return days         + milliseconds / 864e5;
4282
                case 'hour'   : return days * 24    + milliseconds / 36e5;
4283
                case 'minute' : return days * 1440  + milliseconds / 6e4;
4284
                case 'second' : return days * 86400 + milliseconds / 1000;
4285
                // Math.floor prevents floating point math errors here
4286
                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
4287
                default: throw new Error('Unknown unit ' + units);
4288
            }
4289
        }
4290
    }
4291
4292
    // TODO: Use this.as('ms')?
4293
    function valueOf$1 () {
4294
        if (!this.isValid()) {
4295
            return NaN;
4296
        }
4297
        return (
4298
            this._milliseconds +
4299
            this._days * 864e5 +
4300
            (this._months % 12) * 2592e6 +
4301
            toInt(this._months / 12) * 31536e6
4302
        );
4303
    }
4304
4305
    function makeAs (alias) {
4306
        return function () {
4307
            return this.as(alias);
4308
        };
4309
    }
4310
4311
    var asMilliseconds = makeAs('ms');
4312
    var asSeconds      = makeAs('s');
4313
    var asMinutes      = makeAs('m');
4314
    var asHours        = makeAs('h');
4315
    var asDays         = makeAs('d');
4316
    var asWeeks        = makeAs('w');
4317
    var asMonths       = makeAs('M');
4318
    var asQuarters     = makeAs('Q');
4319
    var asYears        = makeAs('y');
4320
4321
    function clone$1 () {
4322
        return createDuration(this);
4323
    }
4324
4325
    function get$2 (units) {
4326
        units = normalizeUnits(units);
4327
        return this.isValid() ? this[units + 's']() : NaN;
4328
    }
4329
4330
    function makeGetter(name) {
4331
        return function () {
4332
            return this.isValid() ? this._data[name] : NaN;
4333
        };
4334
    }
4335
4336
    var milliseconds = makeGetter('milliseconds');
4337
    var seconds      = makeGetter('seconds');
4338
    var minutes      = makeGetter('minutes');
4339
    var hours        = makeGetter('hours');
4340
    var days         = makeGetter('days');
4341
    var months       = makeGetter('months');
4342
    var years        = makeGetter('years');
4343
4344
    function weeks () {
4345
        return absFloor(this.days() / 7);
4346
    }
4347
4348
    var round = Math.round;
4349
    var thresholds = {
4350
        ss: 44,         // a few seconds to seconds
4351
        s : 45,         // seconds to minute
4352
        m : 45,         // minutes to hour
4353
        h : 22,         // hours to day
4354
        d : 26,         // days to month
4355
        M : 11          // months to year
4356
    };
4357
4358
    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
4359
    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
4360
        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
4361
    }
4362
4363
    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
4364
        var duration = createDuration(posNegDuration).abs();
4365
        var seconds  = round(duration.as('s'));
4366
        var minutes  = round(duration.as('m'));
4367
        var hours    = round(duration.as('h'));
4368
        var days     = round(duration.as('d'));
4369
        var months   = round(duration.as('M'));
4370
        var years    = round(duration.as('y'));
4371
4372
        var a = seconds <= thresholds.ss && ['s', seconds]  ||
4373
                seconds < thresholds.s   && ['ss', seconds] ||
4374
                minutes <= 1             && ['m']           ||
4375
                minutes < thresholds.m   && ['mm', minutes] ||
4376
                hours   <= 1             && ['h']           ||
4377
                hours   < thresholds.h   && ['hh', hours]   ||
4378
                days    <= 1             && ['d']           ||
4379
                days    < thresholds.d   && ['dd', days]    ||
4380
                months  <= 1             && ['M']           ||
4381
                months  < thresholds.M   && ['MM', months]  ||
4382
                years   <= 1             && ['y']           || ['yy', years];
4383
4384
        a[2] = withoutSuffix;
4385
        a[3] = +posNegDuration > 0;
4386
        a[4] = locale;
4387
        return substituteTimeAgo.apply(null, a);
4388
    }
4389
4390
    // This function allows you to set the rounding function for relative time strings
4391
    function getSetRelativeTimeRounding (roundingFunction) {
4392
        if (roundingFunction === undefined) {
4393
            return round;
4394
        }
4395
        if (typeof(roundingFunction) === 'function') {
4396
            round = roundingFunction;
4397
            return true;
4398
        }
4399
        return false;
4400
    }
4401
4402
    // This function allows you to set a threshold for relative time strings
4403
    function getSetRelativeTimeThreshold (threshold, limit) {
4404
        if (thresholds[threshold] === undefined) {
4405
            return false;
4406
        }
4407
        if (limit === undefined) {
4408
            return thresholds[threshold];
4409
        }
4410
        thresholds[threshold] = limit;
4411
        if (threshold === 's') {
4412
            thresholds.ss = limit - 1;
4413
        }
4414
        return true;
4415
    }
4416
4417
    function humanize (withSuffix) {
4418
        if (!this.isValid()) {
4419
            return this.localeData().invalidDate();
4420
        }
4421
4422
        var locale = this.localeData();
4423
        var output = relativeTime$1(this, !withSuffix, locale);
4424
4425
        if (withSuffix) {
4426
            output = locale.pastFuture(+this, output);
4427
        }
4428
4429
        return locale.postformat(output);
4430
    }
4431
4432
    var abs$1 = Math.abs;
4433
4434
    function sign(x) {
4435
        return ((x > 0) - (x < 0)) || +x;
4436
    }
4437
4438
    function toISOString$1() {
4439
        // for ISO strings we do not use the normal bubbling rules:
4440
        //  * milliseconds bubble up until they become hours
4441
        //  * days do not bubble at all
4442
        //  * months bubble up until they become years
4443
        // This is because there is no context-free conversion between hours and days
4444
        // (think of clock changes)
4445
        // and also not between days and months (28-31 days per month)
4446
        if (!this.isValid()) {
4447
            return this.localeData().invalidDate();
4448
        }
4449
4450
        var seconds = abs$1(this._milliseconds) / 1000;
4451
        var days         = abs$1(this._days);
4452
        var months       = abs$1(this._months);
4453
        var minutes, hours, years;
4454
4455
        // 3600 seconds -> 60 minutes -> 1 hour
4456
        minutes           = absFloor(seconds / 60);
4457
        hours             = absFloor(minutes / 60);
4458
        seconds %= 60;
4459
        minutes %= 60;
4460
4461
        // 12 months -> 1 year
4462
        years  = absFloor(months / 12);
4463
        months %= 12;
4464
4465
4466
        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
4467
        var Y = years;
4468
        var M = months;
4469
        var D = days;
4470
        var h = hours;
4471
        var m = minutes;
4472
        var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
4473
        var total = this.asSeconds();
4474
4475
        if (!total) {
4476
            // this is the same as C#'s (Noda) and python (isodate)...
4477
            // but not other JS (goog.date)
4478
            return 'P0D';
4479
        }
4480
4481
        var totalSign = total < 0 ? '-' : '';
4482
        var ymSign = sign(this._months) !== sign(total) ? '-' : '';
4483
        var daysSign = sign(this._days) !== sign(total) ? '-' : '';
4484
        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
4485
4486
        return totalSign + 'P' +
4487
            (Y ? ymSign + Y + 'Y' : '') +
4488
            (M ? ymSign + M + 'M' : '') +
4489
            (D ? daysSign + D + 'D' : '') +
4490
            ((h || m || s) ? 'T' : '') +
4491
            (h ? hmsSign + h + 'H' : '') +
4492
            (m ? hmsSign + m + 'M' : '') +
4493
            (s ? hmsSign + s + 'S' : '');
4494
    }
4495
4496
    var proto$2 = Duration.prototype;
4497
4498
    proto$2.isValid        = isValid$1;
4499
    proto$2.abs            = abs;
4500
    proto$2.add            = add$1;
4501
    proto$2.subtract       = subtract$1;
4502
    proto$2.as             = as;
4503
    proto$2.asMilliseconds = asMilliseconds;
4504
    proto$2.asSeconds      = asSeconds;
4505
    proto$2.asMinutes      = asMinutes;
4506
    proto$2.asHours        = asHours;
4507
    proto$2.asDays         = asDays;
4508
    proto$2.asWeeks        = asWeeks;
4509
    proto$2.asMonths       = asMonths;
4510
    proto$2.asQuarters     = asQuarters;
4511
    proto$2.asYears        = asYears;
4512
    proto$2.valueOf        = valueOf$1;
4513
    proto$2._bubble        = bubble;
4514
    proto$2.clone          = clone$1;
4515
    proto$2.get            = get$2;
4516
    proto$2.milliseconds   = milliseconds;
4517
    proto$2.seconds        = seconds;
4518
    proto$2.minutes        = minutes;
4519
    proto$2.hours          = hours;
4520
    proto$2.days           = days;
4521
    proto$2.weeks          = weeks;
4522
    proto$2.months         = months;
4523
    proto$2.years          = years;
4524
    proto$2.humanize       = humanize;
4525
    proto$2.toISOString    = toISOString$1;
4526
    proto$2.toString       = toISOString$1;
4527
    proto$2.toJSON         = toISOString$1;
4528
    proto$2.locale         = locale;
4529
    proto$2.localeData     = localeData;
4530
4531
    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
4532
    proto$2.lang = lang;
4533
4534
    // Side effect imports
4535
4536
    // FORMATTING
4537
4538
    addFormatToken('X', 0, 0, 'unix');
4539
    addFormatToken('x', 0, 0, 'valueOf');
4540
4541
    // PARSING
4542
4543
    addRegexToken('x', matchSigned);
4544
    addRegexToken('X', matchTimestamp);
4545
    addParseToken('X', function (input, array, config) {
4546
        config._d = new Date(parseFloat(input, 10) * 1000);
4547
    });
4548
    addParseToken('x', function (input, array, config) {
4549
        config._d = new Date(toInt(input));
4550
    });
4551
4552
    // Side effect imports
4553
4554
4555
    hooks.version = '2.24.0';
4556
4557
    setHookCallback(createLocal);
4558
4559
    hooks.fn                    = proto;
4560
    hooks.min                   = min;
4561
    hooks.max                   = max;
4562
    hooks.now                   = now;
4563
    hooks.utc                   = createUTC;
4564
    hooks.unix                  = createUnix;
4565
    hooks.months                = listMonths;
4566
    hooks.isDate                = isDate;
4567
    hooks.locale                = getSetGlobalLocale;
4568
    hooks.invalid               = createInvalid;
4569
    hooks.duration              = createDuration;
4570
    hooks.isMoment              = isMoment;
4571
    hooks.weekdays              = listWeekdays;
4572
    hooks.parseZone             = createInZone;
4573
    hooks.localeData            = getLocale;
4574
    hooks.isDuration            = isDuration;
4575
    hooks.monthsShort           = listMonthsShort;
4576
    hooks.weekdaysMin           = listWeekdaysMin;
4577
    hooks.defineLocale          = defineLocale;
4578
    hooks.updateLocale          = updateLocale;
4579
    hooks.locales               = listLocales;
4580
    hooks.weekdaysShort         = listWeekdaysShort;
4581
    hooks.normalizeUnits        = normalizeUnits;
4582
    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
4583
    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
4584
    hooks.calendarFormat        = getCalendarFormat;
4585
    hooks.prototype             = proto;
4586
4587
    // currently HTML5 input type only supports 24-hour formats
4588
    hooks.HTML5_FMT = {
4589
        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
4590
        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
4591
        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
4592
        DATE: 'YYYY-MM-DD',                             // <input type="date" />
4593
        TIME: 'HH:mm',                                  // <input type="time" />
4594
        TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
4595
        TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
4596
        WEEK: 'GGGG-[W]WW',                             // <input type="week" />
4597
        MONTH: 'YYYY-MM'                                // <input type="month" />
4598
    };
4599
4600
    return hooks;
4601
4602
})));
4603