PageSourceSearch

https://www.cabmontcalm.com/gi2-modules/custom/membership/javascript/moment.js

js cabmontcalm.com collected 2026-10-08 09:20:00 UTC 99,201 bytes, 3,043 lines download raw bytes

1//! moment.js
2//! version : 2.9.0
3//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4//! license : MIT
5//! momentjs.com
6
7(function (undefined) {
8    /************************************
9        Constants
10    ************************************/
11
12    var moment,
13        VERSION = '2.9.0',
14        // the global-scope this is NOT the global object in Node.js
15        globalScope = (typeof global !== 'undefined' && (typeof window === 'undefined' || window === global.window)) ? global : this,
16        oldGlobalMoment,
17        round = Math.round,
18        hasOwnProperty = Object.prototype.hasOwnProperty,
19        i,
20
21        YEAR = 0,
22        MONTH = 1,
23        DATE = 2,
24        HOUR = 3,
25        MINUTE = 4,
26        SECOND = 5,
27        MILLISECOND = 6,
28
29        // internal storage for locale config files
30        locales = {},
31
32        // extra moment internal properties (plugins register props here)
33        momentProperties = [],
34
35        // check for nodeJS
36        hasModule = (typeof module !== 'undefined' && module && module.exports),
37
38        // ASP.NET json date format regex
39        aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
40        aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
41
42        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
43        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
44        isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
45
46        // format tokens
47        formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,
48        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
49
50        // parsing token regexes
51        parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
52        parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
53        parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
54        parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
55        parseTokenDigits = /\d+/, // nonzero number of digits
56        parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
57        parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
58        parseTokenT = /T/i, // T (ISO separator)
59        parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123
60        parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
61
62        //strict parsing regexes
63        parseTokenOneDigit = /\d/, // 0 - 9
64        parseTokenTwoDigits = /\d\d/, // 00 - 99
65        parseTokenThreeDigits = /\d{3}/, // 000 - 999
66        parseTokenFourDigits = /\d{4}/, // 0000 - 9999
67        parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
68        parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
69
70        // iso 8601 regex
71        // 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)
72        isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
73
74        isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
75
76        isoDates = [
77            ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
78            ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
79            ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
80            ['GGGG-[W]WW', /\d{4}-W\d{2}/],
81            ['YYYY-DDD', /\d{4}-\d{3}/]
82        ],
83
84        // iso time formats and regexes
85        isoTimes = [
86            ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
87            ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
88            ['HH:mm', /(T| )\d\d:\d\d/],
89            ['HH', /(T| )\d\d/]
90        ],
91
92        // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-', '15', '30']
93        parseTimezoneChunker = /([\+\-]|\d\d)/gi,
94
95        // getter and setter names
96        proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
97        unitMillisecondFactors = {
98            'Milliseconds' : 1,
99            'Seconds' : 1e3,
100            'Minutes' : 6e4,
101            'Hours' : 36e5,
102            'Days' : 864e5,
103            'Months' : 2592e6,
104            'Years' : 31536e6
105        },
106
107        unitAliases = {
108            ms : 'millisecond',
109            s : 'second',
110            m : 'minute',
111            h : 'hour',
112            d : 'day',
113            D : 'date',
114            w : 'week',
115            W : 'isoWeek',
116            M : 'month',
117            Q : 'quarter',
118            y : 'year',
119            DDD : 'dayOfYear',
120            e : 'weekday',
121            E : 'isoWeekday',
122            gg: 'weekYear',
123            GG: 'isoWeekYear'
124        },
125
126        camelFunctions = {
127            dayofyear : 'dayOfYear',
128            isoweekday : 'isoWeekday',
129            isoweek : 'isoWeek',
130            weekyear : 'weekYear',
131            isoweekyear : 'isoWeekYear'
132        },
133
134        // format function strings
135        formatFunctions = {},
136
137        // default relative time thresholds
138        relativeTimeThresholds = {
139            s: 45,  // seconds to minute
140            m: 45,  // minutes to hour
141            h: 22,  // hours to day
142            d: 26,  // days to month
143            M: 11   // months to year
144        },
145
146        // tokens to ordinalize and pad
147        ordinalizeTokens = 'DDD w W M D d'.split(' '),
148        paddedTokens = 'M D H h m s w W'.split(' '),
149
150        formatTokenFunctions = {
151            M    : function () {
152                return this.month() + 1;
153            },
154            MMM  : function (format) {
155                return this.localeData().monthsShort(this, format);
156            },
157            MMMM : function (format) {
158                return this.localeData().months(this, format);
159            },
160            D    : function () {
161                return this.date();
162            },
163            DDD  : function () {
164                return this.dayOfYear();
165            },
166            d    : function () {
167                return this.day();
168            },
169            dd   : function (format) {
170                return this.localeData().weekdaysMin(this, format);
171            },
172            ddd  : function (format) {
173                return this.localeData().weekdaysShort(this, format);
174            },
175            dddd : function (format) {
176                return this.localeData().weekdays(this, format);
177            },
178            w    : function () {
179                return this.week();
180            },
181            W    : function () {
182                return this.isoWeek();
183            },
184            YY   : function () {
185                return leftZeroFill(this.year() % 100, 2);
186            },
187            YYYY : function () {
188                return leftZeroFill(this.year(), 4);
189            },
190            YYYYY : function () {
191                return leftZeroFill(this.year(), 5);
192            },
193            YYYYYY : function () {
194                var y = this.year(), sign = y >= 0 ? '+' : '-';
195                return sign + leftZeroFill(Math.abs(y), 6);
196            },
197            gg   : function () {
198                return leftZeroFill(this.weekYear() % 100, 2);
199            },
200            gggg : function () {
201                return leftZeroFill(this.weekYear(), 4);
202            },
203            ggggg : function () {
204                return leftZeroFill(this.weekYear(), 5);
205            },
206            GG   : function () {
207                return leftZeroFill(this.isoWeekYear() % 100, 2);
208            },
209            GGGG : function () {
210                return leftZeroFill(this.isoWeekYear(), 4);
211            },
212            GGGGG : function () {
213                return leftZeroFill(this.isoWeekYear(), 5);
214            },
215            e : function () {
216                return this.weekday();
217            },
218            E : function () {
219                return this.isoWeekday();
220            },
221            a    : function () {
222                return this.localeData().meridiem(this.hours(), this.minutes(), true);
223            },
224            A    : function () {
225                return this.localeData().meridiem(this.hours(), this.minutes(), false);
226            },
227            H    : function () {
228                return this.hours();
229            },
230            h    : function () {
231                return this.hours() % 12 || 12;
232            },
233            m    : function () {
234                return this.minutes();
235            },
236            s    : function () {
237                return this.seconds();
238            },
239            S    : function () {
240                return toInt(this.milliseconds() / 100);
241            },
242            SS   : function () {
243                return leftZeroFill(toInt(this.milliseconds() / 10), 2);
244            },
245            SSS  : function () {
246                return leftZeroFill(this.milliseconds(), 3);
247            },
248            SSSS : function () {
249                return leftZeroFill(this.milliseconds(), 3);
250            },
251            Z    : function () {
252                var a = this.utcOffset(),
253                    b = '+';
254                if (a < 0) {
255                    a = -a;
256                    b = '-';
257                }
258                return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
259            },
260            ZZ   : function () {
261                var a = this.utcOffset(),
262                    b = '+';
263                if (a < 0) {
264                    a = -a;
265                    b = '-';
266                }
267                return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
268            },
269            z : function () {
270                return this.zoneAbbr();
271            },
272            zz : function () {
273                return this.zoneName();
274            },
275            x    : function () {
276                return this.valueOf();
277            },
278            X    : function () {
279                return this.unix();
280            },
281            Q : function () {
282                return this.quarter();
283            }
284        },
285
286        deprecations = {},
287
288        lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'],
289
290        updateInProgress = false;
291
292    // Pick the first defined of two or three arguments. dfl comes from
293    // default.
294    function dfl(a, b, c) {
295        switch (arguments.length) {
296            case 2: return a != null ? a : b;
297            case 3: return a != null ? a : b != null ? b : c;
298            default: throw new Error('Implement me');
299        }
300    }
301
302    function hasOwnProp(a, b) {
303        return hasOwnProperty.call(a, b);
304    }
305
306    function defaultParsingFlags() {
307        // We need to deep clone this object, and es5 standard is not very
308        // helpful.
309        return {
310            empty : false,
311            unusedTokens : [],
312            unusedInput : [],
313            overflow : -2,
314            charsLeftOver : 0,
315            nullInput : false,
316            invalidMonth : null,
317            invalidFormat : false,
318            userInvalidated : false,
319            iso: false
320        };
321    }
322
323    function printMsg(msg) {
324        if (moment.suppressDeprecationWarnings === false &&
325                typeof console !== 'undefined' && console.warn) {
326            console.warn('Deprecation warning: ' + msg);
327        }
328    }
329
330    function deprecate(msg, fn) {
331        var firstTime = true;
332        return extend(function () {
333            if (firstTime) {
334                printMsg(msg);
335                firstTime = false;
336            }
337            return fn.apply(this, arguments);
338        }, fn);
339    }
340
341    function deprecateSimple(name, msg) {
342        if (!deprecations[name]) {
343            printMsg(msg);
344            deprecations[name] = true;
345        }
346    }
347
348    function padToken(func, count) {
349        return function (a) {
350            return leftZeroFill(func.call(this, a), count);
351        };
352    }
353    function ordinalizeToken(func, period) {
354        return function (a) {
355            return this.localeData().ordinal(func.call(this, a), period);
356        };
357    }
358
359    function monthDiff(a, b) {
360        // difference in months
361        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
362            // b is in (anchor - 1 month, anchor + 1 month)
363            anchor = a.clone().add(wholeMonthDiff, 'months'),
364            anchor2, adjust;
365
366        if (b - anchor < 0) {
367            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
368            // linear across the month
369            adjust = (b - anchor) / (anchor - anchor2);
370        } else {
371            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
372            // linear across the month
373            adjust = (b - anchor) / (anchor2 - anchor);
374        }
375
376        return -(wholeMonthDiff + adjust);
377    }
378
379    while (ordinalizeTokens.length) {
380        i = ordinalizeTokens.pop();
381        formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
382    }
383    while (paddedTokens.length) {
384        i = paddedTokens.pop();
385        formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
386    }
387    formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
388
389
390    function meridiemFixWrap(locale, hour, meridiem) {
391        var isPm;
392
393        if (meridiem == null) {
394            // nothing to do
395            return hour;
396        }
397        if (locale.meridiemHour != null) {
398            return locale.meridiemHour(hour, meridiem);
399        } else if (locale.isPM != null) {
400            // Fallback
401            isPm = locale.isPM(meridiem);
402            if (isPm && hour < 12) {
403                hour += 12;
404            }
405            if (!isPm && hour === 12) {
406                hour = 0;
407            }
408            return hour;
409        } else {
410            // thie is not supposed to happen
411            return hour;
412        }
413    }
414
415    /************************************
416        Constructors
417    ************************************/
418
419    function Locale() {
420    }
421
422    // Moment prototype object
423    function Moment(config, skipOverflow) {
424        if (skipOverflow !== false) {
425            checkOverflow(config);
426        }
427        copyConfig(this, config);
428        this._d = new Date(+config._d);
429        // Prevent infinite loop in case updateOffset creates new moment
430        // objects.
431        if (updateInProgress === false) {
432            updateInProgress = true;
433            moment.updateOffset(this);
434            updateInProgress = false;
435        }
436    }
437
438    // Duration Constructor
439    function Duration(duration) {
440        var normalizedInput = normalizeObjectUnits(duration),
441            years = normalizedInput.year || 0,
442            quarters = normalizedInput.quarter || 0,
443            months = normalizedInput.month || 0,
444            weeks = normalizedInput.week || 0,
445            days = normalizedInput.day || 0,
446            hours = normalizedInput.hour || 0,
447            minutes = normalizedInput.minute || 0,
448            seconds = normalizedInput.second || 0,
449            milliseconds = normalizedInput.millisecond || 0;
450
451        // representation for dateAddRemove
452        this._milliseconds = +milliseconds +
453            seconds * 1e3 + // 1000
454            minutes * 6e4 + // 1000 * 60
455            hours * 36e5; // 1000 * 60 * 60
456        // Because of dateAddRemove treats 24 hours as different from a
457        // day when working around DST, we need to store them separately
458        this._days = +days +
459            weeks * 7;
460        // It is impossible translate months into days without knowing
461        // which months you are are talking about, so we have to store
462        // it separately.
463        this._months = +months +
464            quarters * 3 +
465            years * 12;
466
467        this._data = {};
468
469        this._locale = moment.localeData();
470
471        this._bubble();
472    }
473
474    /************************************
475        Helpers
476    ************************************/
477
478
479    function extend(a, b) {
480        for (var i in b) {
481            if (hasOwnProp(b, i)) {
482                a[i] = b[i];
483            }
484        }
485
486        if (hasOwnProp(b, 'toString')) {
487            a.toString = b.toString;
488        }
489
490        if (hasOwnProp(b, 'valueOf')) {
491            a.valueOf = b.valueOf;
492        }
493
494        return a;
495    }
496
497    function copyConfig(to, from) {
498        var i, prop, val;
499
500        if (typeof from._isAMomentObject !== 'undefined') {
501            to._isAMomentObject = from._isAMomentObject;
502        }
503        if (typeof from._i !== 'undefined') {
504            to._i = from._i;
505        }
506        if (typeof from._f !== 'undefined') {
507            to._f = from._f;
508        }
509        if (typeof from._l !== 'undefined') {
510            to._l = from._l;
511        }
512        if (typeof from._strict !== 'undefined') {
513            to._strict = from._strict;
514        }
515        if (typeof from._tzm !== 'undefined') {
516            to._tzm = from._tzm;
517        }
518        if (typeof from._isUTC !== 'undefined') {
519            to._isUTC = from._isUTC;
520        }
521        if (typeof from._offset !== 'undefined') {
522            to._offset = from._offset;
523        }
524        if (typeof from._pf !== 'undefined') {
525            to._pf = from._pf;
526        }
527        if (typeof from._locale !== 'undefined') {
528            to._locale = from._locale;
529        }
530
531        if (momentProperties.length > 0) {
532            for (i in momentProperties) {
533                prop = momentProperties[i];
534                val = from[prop];
535                if (typeof val !== 'undefined') {
536                    to[prop] = val;
537                }
538            }
539        }
540
541        return to;
542    }
543
544    function absRound(number) {
545        if (number < 0) {
546            return Math.ceil(number);
547        } else {
548            return Math.floor(number);
549        }
550    }
551
552    // left zero fill a number
553    // see http://jsperf.com/left-zero-filling for performance comparison
554    function leftZeroFill(number, targetLength, forceSign) {
555        var output = '' + Math.abs(number),
556            sign = number >= 0;
557
558        while (output.length < targetLength) {
559            output = '0' + output;
560        }
561        return (sign ? (forceSign ? '+' : '') : '-') + output;
562    }
563
564    function positiveMomentsDifference(base, other) {
565        var res = {milliseconds: 0, months: 0};
566
567        res.months = other.month() - base.month() +
568            (other.year() - base.year()) * 12;
569        if (base.clone().add(res.months, 'M').isAfter(other)) {
570            --res.months;
571        }
572
573        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
574
575        return res;
576    }
577
578    function momentsDifference(base, other) {
579        var res;
580        other = makeAs(other, base);
581        if (base.isBefore(other)) {
582            res = positiveMomentsDifference(base, other);
583        } else {
584            res = positiveMomentsDifference(other, base);
585            res.milliseconds = -res.milliseconds;
586            res.months = -res.months;
587        }
588
589        return res;
590    }
591
592    // TODO: remove 'name' arg after deprecation is removed
593    function createAdder(direction, name) {
594        return function (val, period) {
595            var dur, tmp;
596            //invert the arguments, but complain about it
597            if (period !== null && !isNaN(+period)) {
598                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
599                tmp = val; val = period; period = tmp;
600            }
601
602            val = typeof val === 'string' ? +val : val;
603            dur = moment.duration(val, period);
604            addOrSubtractDurationFromMoment(this, dur, direction);
605            return this;
606        };
607    }
608
609    function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
610        var milliseconds = duration._milliseconds,
611            days = duration._days,
612            months = duration._months;
613        updateOffset = updateOffset == null ? true : updateOffset;
614
615        if (milliseconds) {
616            mom._d.setTime(+mom._d + milliseconds * isAdding);
617        }
618        if (days) {
619            rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
620        }
621        if (months) {
622            rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
623        }
624        if (updateOffset) {
625            moment.updateOffset(mom, days || months);
626        }
627    }
628
629    // check if is an array
630    function isArray(input) {
631        return Object.prototype.toString.call(input) === '[object Array]';
632    }
633
634    function isDate(input) {
635        return Object.prototype.toString.call(input) === '[object Date]' ||
636            input instanceof Date;
637    }
638
639    // compare two arrays, return the number of differences
640    function compareArrays(array1, array2, dontConvert) {
641        var len = Math.min(array1.length, array2.length),
642            lengthDiff = Math.abs(array1.length - array2.length),
643            diffs = 0,
644            i;
645        for (i = 0; i < len; i++) {
646            if ((dontConvert && array1[i] !== array2[i]) ||
647                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
648                diffs++;
649            }
650        }
651        return diffs + lengthDiff;
652    }
653
654    function normalizeUnits(units) {
655        if (units) {
656            var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
657            units = unitAliases[units] || camelFunctions[lowered] || lowered;
658        }
659        return units;
660    }
661
662    function normalizeObjectUnits(inputObject) {
663        var normalizedInput = {},
664            normalizedProp,
665            prop;
666
667        for (prop in inputObject) {
668            if (hasOwnProp(inputObject, prop)) {
669                normalizedProp = normalizeUnits(prop);
670                if (normalizedProp) {
671                    normalizedInput[normalizedProp] = inputObject[prop];
672                }
673            }
674        }
675
676        return normalizedInput;
677    }
678
679    function makeList(field) {
680        var count, setter;
681
682        if (field.indexOf('week') === 0) {
683            count = 7;
684            setter = 'day';
685        }
686        else if (field.indexOf('month') === 0) {
687            count = 12;
688            setter = 'month';
689        }
690        else {
691            return;
692        }
693
694        moment[field] = function (format, index) {
695            var i, getter,
696                method = moment._locale[field],
697                results = [];
698
699            if (typeof format === 'number') {
700                index = format;
701                format = undefined;
702            }
703
704            getter = function (i) {
705                var m = moment().utc().set(setter, i);
706                return method.call(moment._locale, m, format || '');
707            };
708
709            if (index != null) {
710                return getter(index);
711            }
712            else {
713                for (i = 0; i < count; i++) {
714                    results.push(getter(i));
715                }
716                return results;
717            }
718        };
719    }
720
721    function toInt(argumentForCoercion) {
722        var coercedNumber = +argumentForCoercion,
723            value = 0;
724
725        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
726            if (coercedNumber >= 0) {
727                value = Math.floor(coercedNumber);
728            } else {
729                value = Math.ceil(coercedNumber);
730            }
731        }
732
733        return value;
734    }
735
736    function daysInMonth(year, month) {
737        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
738    }
739
740    function weeksInYear(year, dow, doy) {
741        return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
742    }
743
744    function daysInYear(year) {
745        return isLeapYear(year) ? 366 : 365;
746    }
747
748    function isLeapYear(year) {
749        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
750    }
751
752    function checkOverflow(m) {
753        var overflow;
754        if (m._a && m._pf.overflow === -2) {
755            overflow =
756                m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
757                m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
758                m._a[HOUR] < 0 || m._a[HOUR] > 24 ||
759                    (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 ||
760                                           m._a[SECOND] !== 0 ||
761                                           m._a[MILLISECOND] !== 0)) ? HOUR :
762                m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
763                m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
764                m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
765                -1;
766
767            if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
768                overflow = DATE;
769            }
770
771            m._pf.overflow = overflow;
772        }
773    }
774
775    function isValid(m) {
776        if (m._isValid == null) {
777            m._isValid = !isNaN(m._d.getTime()) &&
778                m._pf.overflow < 0 &&
779                !m._pf.empty &&
780                !m._pf.invalidMonth &&
781                !m._pf.nullInput &&
782                !m._pf.invalidFormat &&
783                !m._pf.userInvalidated;
784
785            if (m._strict) {
786                m._isValid = m._isValid &&
787                    m._pf.charsLeftOver === 0 &&
788                    m._pf.unusedTokens.length === 0 &&
789                    m._pf.bigHour === undefined;
790            }
791        }
792        return m._isValid;
793    }
794
795    function normalizeLocale(key) {
796        return key ? key.toLowerCase().replace('_', '-') : key;
797    }
798
799    // pick the locale from the array
800    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list tr
800ying each
801    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
802    function chooseLocale(names) {
803        var i = 0, j, next, locale, split;
804
805        while (i < names.length) {
806            split = normalizeLocale(names[i]).split('-');
807            j = split.length;
808            next = normalizeLocale(names[i + 1]);
809            next = next ? next.split('-') : null;
810            while (j > 0) {
811                locale = loadLocale(split.slice(0, j).join('-'));
812                if (locale) {
813                    return locale;
814                }
815                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
816                    //the next array item is better than a shallower substring of this one
817                    break;
818                }
819                j--;
820            }
821            i++;
822        }
823        return null;
824    }
825
826    function loadLocale(name) {
827        var oldLocale = null;
828        if (!locales[name] && hasModule) {
829            try {
830                oldLocale = moment.locale();
831                require('./locale/' + name);
832                // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
833                moment.locale(oldLocale);
834            } catch (e) { }
835        }
836        return locales[name];
837    }
838
839    // Return a moment from input, that is local/utc/utcOffset equivalent to
840    // model.
841    function makeAs(input, model) {
842        var res, diff;
843        if (model._isUTC) {
844            res = model.clone();
845            diff = (moment.isMoment(input) || isDate(input) ?
846                    +input : +moment(input)) - (+res);
847            // Use low-level api, because this fn is low-level api.
848            res._d.setTime(+res._d + diff);
849            moment.updateOffset(res, false);
850            return res;
851        } else {
852            return moment(input).local();
853        }
854    }
855
856    /************************************
857        Locale
858    ************************************/
859
860
861    extend(Locale.prototype, {
862
863        set : function (config) {
864            var prop, i;
865            for (i in config) {
866                prop = config[i];
867                if (typeof prop === 'function') {
868                    this[i] = prop;
869                } else {
870                    this['_' + i] = prop;
871                }
872            }
873            // Lenient ordinal parsing accepts just a number in addition to
874            // number + (possibly) stuff coming from _ordinalParseLenient.
875            this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source);
876        },
877
878        _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
879        months : function (m) {
880            return this._months[m.month()];
881        },
882
883        _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
884        monthsShort : function (m) {
885            return this._monthsShort[m.month()];
886        },
887
888        monthsParse : function (monthName, format, strict) {
889            var i, mom, regex;
890
891            if (!this._monthsParse) {
892                this._monthsParse = [];
893                this._longMonthsParse = [];
894                this._shortMonthsParse = [];
895            }
896
897            for (i = 0; i < 12; i++) {
898                // make the regex if we don't have it already
899                mom = moment.utc([2000, i]);
900                if (strict && !this._longMonthsParse[i]) {
901                    this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
902                    this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
903                }
904                if (!strict && !this._monthsParse[i]) {
905                    regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
906                    this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
907                }
908                // test the regex
909                if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
910                    return i;
911                } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
912                    return i;
913                } else if (!strict && this._monthsParse[i].test(monthName)) {
914                    return i;
915                }
916            }
917        },
918
919        _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
920        weekdays : function (m) {
921            return this._weekdays[m.day()];
922        },
923
924        _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
925        weekdaysShort : function (m) {
926            return this._weekdaysShort[m.day()];
927        },
928
929        _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
930        weekdaysMin : function (m) {
931            return this._weekdaysMin[m.day()];
932        },
933
934        weekdaysParse : function (weekdayName) {
935            var i, mom, regex;
936
937            if (!this._weekdaysParse) {
938                this._weekdaysParse = [];
939            }
940
941            for (i = 0; i < 7; i++) {
942                // make the regex if we don't have it already
943                if (!this._weekdaysParse[i]) {
944                    mom = moment([2000, 1]).day(i);
945                    regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
946                    this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
947                }
948                // test the regex
949                if (this._weekdaysParse[i].test(weekdayName)) {
950                    return i;
951                }
952            }
953        },
954
955        _longDateFormat : {
956            LTS : 'h:mm:ss A',
957            LT : 'h:mm A',
958            L : 'MM/DD/YYYY',
959            LL : 'MMMM D, YYYY',
960            LLL : 'MMMM D, YYYY LT',
961            LLLL : 'dddd, MMMM D, YYYY LT'
962        },
963        longDateFormat : function (key) {
964            var output = this._longDateFormat[key];
965            if (!output && this._longDateFormat[key.toUpperCase()]) {
966                output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
967                    return val.slice(1);
968                });
969                this._longDateFormat[key] = output;
970            }
971            return output;
972        },
973
974        isPM : function (input) {
975            // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing str
975ings like arrays
976            // Using charAt should be more compatible.
977            return ((input + '').toLowerCase().charAt(0) === 'p');
978        },
979
980        _meridiemParse : /[ap]\.?m?\.?/i,
981        meridiem : function (hours, minutes, isLower) {
982            if (hours > 11) {
983                return isLower ? 'pm' : 'PM';
984            } else {
985                return isLower ? 'am' : 'AM';
986            }
987        },
988
989
990        _calendar : {
991            sameDay : '[Today at] LT',
992            nextDay : '[Tomorrow at] LT',
993            nextWeek : 'dddd [at] LT',
994            lastDay : '[Yesterday at] LT',
995            lastWeek : '[Last] dddd [at] LT',
996            sameElse : 'L'
997        },
998        calendar : function (key, mom, now) {
999            var output = this._calendar[key];
1000            return typeof output === 'function' ? output.apply(mom, [now]) : output;
1001        },
1002
1003        _relativeTime : {
1004            future : 'in %s',
1005            past : '%s ago',
1006            s : 'a few seconds',
1007            m : 'a minute',
1008            mm : '%d minutes',
1009            h : 'an hour',
1010            hh : '%d hours',
1011            d : 'a day',
1012            dd : '%d days',
1013            M : 'a month',
1014            MM : '%d months',
1015            y : 'a year',
1016            yy : '%d years'
1017        },
1018
1019        relativeTime : function (number, withoutSuffix, string, isFuture) {
1020            var output = this._relativeTime[string];
1021            return (typeof output === 'function') ?
1022                output(number, withoutSuffix, string, isFuture) :
1023                output.replace(/%d/i, number);
1024        },
1025
1026        pastFuture : function (diff, output) {
1027            var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
1028            return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
1029        },
1030
1031        ordinal : function (number) {
1032            return this._ordinal.replace('%d', number);
1033        },
1034        _ordinal : '%d',
1035        _ordinalParse : /\d{1,2}/,
1036
1037        preparse : function (string) {
1038            return string;
1039        },
1040
1041        postformat : function (string) {
1042            return string;
1043        },
1044
1045        week : function (mom) {
1046            return weekOfYear(mom, this._week.dow, this._week.doy).week;
1047        },
1048
1049        _week : {
1050            dow : 0, // Sunday is the first day of the week.
1051            doy : 6  // The week that contains Jan 1st is the first week of the year.
1052        },
1053
1054        firstDayOfWeek : function () {
1055            return this._week.dow;
1056        },
1057
1058        firstDayOfYear : function () {
1059            return this._week.doy;
1060        },
1061
1062        _invalidDate: 'Invalid date',
1063        invalidDate: function () {
1064            return this._invalidDate;
1065        }
1066    });
1067
1068    /************************************
1069        Formatting
1070    ************************************/
1071
1072
1073    function removeFormattingTokens(input) {
1074        if (input.match(/\[[\s\S]/)) {
1075            return input.replace(/^\[|\]$/g, '');
1076        }
1077        return input.replace(/\\/g, '');
1078    }
1079
1080    function makeFormatFunction(format) {
1081        var array = format.match(formattingTokens), i, length;
1082
1083        for (i = 0, length = array.length; i < length; i++) {
1084            if (formatTokenFunctions[array[i]]) {
1085                array[i] = formatTokenFunctions[array[i]];
1086            } else {
1087                array[i] = removeFormattingTokens(array[i]);
1088            }
1089        }
1090
1091        return function (mom) {
1092            var output = '';
1093            for (i = 0; i < length; i++) {
1094                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
1095            }
1096            return output;
1097        };
1098    }
1099
1100    // format date using native date object
1101    function formatMoment(m, format) {
1102        if (!m.isValid()) {
1103            return m.localeData().invalidDate();
1104        }
1105
1106        format = expandFormat(format, m.localeData());
1107
1108        if (!formatFunctions[format]) {
1109            formatFunctions[format] = makeFormatFunction(format);
1110        }
1111
1112        return formatFunctions[format](m);
1113    }
1114
1115    function expandFormat(format, locale) {
1116        var i = 5;
1117
1118        function replaceLongDateFormatTokens(input) {
1119            return locale.longDateFormat(input) || input;
1120        }
1121
1122        localFormattingTokens.lastIndex = 0;
1123        while (i >= 0 && localFormattingTokens.test(format)) {
1124            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
1125            localFormattingTokens.lastIndex = 0;
1126            i -= 1;
1127        }
1128
1129        return format;
1130    }
1131
1132
1133    /************************************
1134        Parsing
1135    ************************************/
1136
1137
1138    // get the regex to find the next token
1139    function getParseRegexForToken(token, config) {
1140        var a, strict = config._strict;
1141        switch (token) {
1142        case 'Q':
1143            return parseTokenOneDigit;
1144        case 'DDDD':
1145            return parseTokenThreeDigits;
1146        case 'YYYY':
1147        case 'GGGG':
1148        case 'gggg':
1149            return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
1150        case 'Y':
1151        case 'G':
1152        case 'g':
1153            return parseTokenSignedNumber;
1154        case 'YYYYYY':
1155        case 'YYYYY':
1156        case 'GGGGG':
1157        case 'ggggg':
1158            return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
1159        case 'S':
1160            if (strict) {
1161                return parseTokenOneDigit;
1162            }
1163            /* falls through */
1164        case 'SS':
1165            if (strict) {
1166                return parseTokenTwoDigits;
1167            }
1168            /* falls through */
1169        case 'SSS':
1170            if (strict) {
1171                return parseTokenThreeDigits;
1172            }
1173            /* falls through */
1174        case 'DDD':
1175            return parseTokenOneToThreeDigits;
1176        case 'MMM':
1177        case 'MMMM':
1178        case 'dd':
1179        case 'ddd':
1180        case 'dddd':
1181            return parseTokenWord;
1182        case 'a':
1183        case 'A':
1184            return config._locale._meridiemParse;
1185        case 'x':
1186            return parseTokenOffsetMs;
1187        case 'X':
1188            return parseTokenTimestampMs;
1189        case 'Z':
1190        case 'ZZ':
1191            return parseTokenTimezone;
1192        case 'T':
1193            return parseTokenT;
1194        case 'SSSS':
1195            return parseTokenDigits;
1196        case 'MM':
1197        case 'DD':
1198        case 'YY':
1199        case 'GG':
1200        case 'gg':
1201        case 'HH':
1202        case 'hh':
1203        case 'mm':
1204        case 'ss':
1205        case 'ww':
1206        case 'WW':
1207            return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
1208        case 'M':
1209        case 'D':
1210        case 'd':
1211        case 'H':
1212        case 'h':
1213        case 'm':
1214        case 's':
1215        case 'w':
1216        case 'W':
1217        case 'e':
1218        case 'E':
1219            return parseTokenOneOrTwoDigits;
1220        case 'Do':
1221            return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient;
1222        default :
1223            a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
1224            return a;
1225        }
1226    }
1227
1228    function utcOffsetFromString(string) {
1229        string = string || '';
1230        var possibleTzMatches = (string.match(parseTokenTimezone) || []),
1231            tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
1232            parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
1233            minutes = +(parts[1] * 60) + toInt(parts[2]);
1234
1235        return parts[0] === '+' ? minutes : -minutes;
1236    }
1237
1238    // function to convert string input to date
1239    function addTimeToArrayFromToken(token, input, config) {
1240        var a, datePartArray = config._a;
1241
1242        switch (token) {
1243        // QUARTER
1244        case 'Q':
1245            if (input != null) {
1246                datePartArray[MONTH] = (toInt(input) - 1) * 3;
1247            }
1248            break;
1249        // MONTH
1250        case 'M' : // fall through to MM
1251        case 'MM' :
1252            if (input != null) {
1253                datePartArray[MONTH] = toInt(input) - 1;
1254            }
1255            break;
1256        case 'MMM' : // fall through to MMMM
1257        case 'MMMM' :
1258            a = config._locale.monthsParse(input, token, config._strict);
1259            // if we didn't find a month name, mark the date as invalid.
1260            if (a != null) {
1261                datePartArray[MONTH] = a;
1262            } else {
1263                config._pf.invalidMonth = input;
1264            }
1265            break;
1266        // DAY OF MONTH
1267        case 'D' : // fall through to DD
1268        case 'DD' :
1269            if (input != null) {
1270                datePartArray[DATE] = toInt(input);
1271            }
1272            break;
1273        case 'Do' :
1274            if (input != null) {
1275                datePartArray[DATE] = toInt(parseInt(
1276                            input.match(/\d{1,2}/)[0], 10));
1277            }
1278            break;
1279        // DAY OF YEAR
1280        case 'DDD' : // fall through to DDDD
1281        case 'DDDD' :
1282            if (input != null) {
1283                config._dayOfYear = toInt(input);
1284            }
1285
1286            break;
1287        // YEAR
1288        case 'YY' :
1289            datePartArray[YEAR] = moment.parseTwoDigitYear(input);
1290            break;
1291        case 'YYYY' :
1292        case 'YYYYY' :
1293        case 'YYYYYY' :
1294            datePartArray[YEAR] = toInt(input);
1295            break;
1296        // AM / PM
1297        case 'a' : // fall through to A
1298        case 'A' :
1299            config._meridiem = input;
1300            // config._isPm = config._locale.isPM(input);
1301            break;
1302        // HOUR
1303        case 'h' : // fall through to hh
1304        case 'hh' :
1305            config._pf.bigHour = true;
1306            /* falls through */
1307        case 'H' : // fall through to HH
1308        case 'HH' :
1309            datePartArray[HOUR] = toInt(input);
1310            break;
1311        // MINUTE
1312        case 'm' : // fall through to mm
1313        case 'mm' :
1314            datePartArray[MINUTE] = toInt(input);
1315            break;
1316        // SECOND
1317        case 's' : // fall through to ss
1318        case 'ss' :
1319            datePartArray[SECOND] = toInt(input);
1320            break;
1321        // MILLISECOND
1322        case 'S' :
1323        case 'SS' :
1324        case 'SSS' :
1325        case 'SSSS' :
1326            datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
1327            break;
1328        // UNIX OFFSET (MILLISECONDS)
1329        case 'x':
1330            config._d = new Date(toInt(input));
1331            break;
1332        // UNIX TIMESTAMP WITH MS
1333        case 'X':
1334            config._d = new Date(parseFloat(input) * 1000);
1335            break;
1336        // TIMEZONE
1337        case 'Z' : // fall through to ZZ
1338        case 'ZZ' :
1339            config._useUTC = true;
1340            config._tzm = utcOffsetFromString(input);
1341            break;
1342        // WEEKDAY - human
1343        case 'dd':
1344        case 'ddd':
1345        case 'dddd':
1346            a = config._locale.weekdaysParse(input);
1347            // if we didn't get a weekday name, mark the date as invalid
1348            if (a != null) {
1349                config._w = config._w || {};
1350                config._w['d'] = a;
1351            } else {
1352                config._pf.invalidWeekday = input;
1353            }
1354            break;
1355        // WEEK, WEEK DAY - numeric
1356        case 'w':
1357        case 'ww':
1358        case 'W':
1359        case 'WW':
1360        case 'd':
1361        case 'e':
1362        case 'E':
1363            token = token.substr(0, 1);
1364            /* falls through */
1365        case 'gggg':
1366        case 'GGGG':
1367        case 'GGGGG':
1368            token = token.substr(0, 2);
1369            if (input) {
1370                config._w = config._w || {};
1371                config._w[token] = toInt(input);
1372            }
1373            break;
1374        case 'gg':
1375        case 'GG':
1376            config._w = config._w || {};
1377            config._w[token] = moment.parseTwoDigitYear(input);
1378        }
1379    }
1380
1381    function dayOfYearFromWeekInfo(config) {
1382        var w, weekYear, week, weekday, dow, doy, temp;
1383
1384        w = config._w;
1385        if (w.GG != null || w.W != null || w.E != null) {
1386            dow = 1;
1387            doy = 4;
1388
1389            // TODO: We need to take the current isoWeekYear, but that depends on
1390            // how we interpret now (local, utc, fixed offset). So create
1391            // a now version of current config (take local/utc/offset flags, and
1392            // create now).
1393            weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
1394            week = dfl(w.W, 1);
1395            weekday = dfl(w.E, 1);
1396        } else {
1397            dow = config._locale._week.dow;
1398            doy = config._locale._week.doy;
1399
vendor: 4,460 bytes, lines 1400-1535
1400            weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
1401            week = dfl(w.w, 1);
1402
1403            if (w.d != null) {
1404                // weekday -- low day numbers are considered next week
1405                weekday = w.d;
1406                if (weekday < dow) {
1407                    ++week;
1408                }
1409            } else if (w.e != null) {
1410                // local weekday -- counting starts from begining of week
1411                weekday = w.e + dow;
1412            } else {
1413                // default to begining of week
1414                weekday = dow;
1415            }
1416        }
1417        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
1418
1419        config._a[YEAR] = temp.year;
1420        config._dayOfYear = temp.dayOfYear;
1421    }
1422
1423    // convert an array to a date.
1424    // the array should mirror the parameters below
1425    // note: all values past the year are optional and will default to the lowest possible value.
1426    // [year, month, day , hour, minute, second, millisecond]
1427    function dateFromConfig(config) {
1428        var i, date, input = [], currentDate, yearToUse;
1429
1430        if (config._d) {
1431            return;
1432        }
1433
1434        currentDate = currentDateArray(config);
1435
1436        //compute day of the year from weeks and weekdays
1437        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
1438            dayOfYearFromWeekInfo(config);
1439        }
1440
1441        //if the day of the year is set, figure out what it is
1442        if (config._dayOfYear) {
1443            yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
1444
1445            if (config._dayOfYear > daysInYear(yearToUse)) {
1446                config._pf._overflowDayOfYear = true;
1447            }
1448
1449            date = makeUTCDate(yearToUse, 0, config._dayOfYear);
1450            config._a[MONTH] = date.getUTCMonth();
1451            config._a[DATE] = date.getUTCDate();
1452        }
1453
1454        // Default to current date.
1455        // * if no year, month, day of month are given, default to today
1456        // * if day of month is given, default month and year
1457        // * if month is given, default only year
1458        // * if year is given, don't default anything
1459        for (i = 0; i < 3 && config._a[i] == null; ++i) {
1460            config._a[i] = input[i] = currentDate[i];
1461        }
1462
1463        // Zero out whatever was not defaulted, including time
1464        for (; i < 7; i++) {
1465            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
1466        }
1467
1468        // Check for 24:00:00.000
1469        if (config._a[HOUR] === 24 &&
1470                config._a[MINUTE] === 0 &&
1471                config._a[SECOND] === 0 &&
1472                config._a[MILLISECOND] === 0) {
1473            config._nextDay = true;
1474            config._a[HOUR] = 0;
1475        }
1476
1477        config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
1478        // Apply timezone offset from input. The actual utcOffset can be changed
1479        // with parseZone.
1480        if (config._tzm != null) {
1481            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
1482        }
1483
1484        if (config._nextDay) {
1485            config._a[HOUR] = 24;
1486        }
1487    }
1488
1489    function dateFromObject(config) {
1490        var normalizedInput;
1491
1492        if (config._d) {
1493            return;
1494        }
1495
1496        normalizedInput = normalizeObjectUnits(config._i);
1497        config._a = [
1498            normalizedInput.year,
1499            normalizedInput.month,
1500            normalizedInput.day || normalizedInput.date,
1501            normalizedInput.hour,
1502            normalizedInput.minute,
1503            normalizedInput.second,
1504            normalizedInput.millisecond
1505        ];
1506
1507        dateFromConfig(config);
1508    }
1509
1510    function currentDateArray(config) {
1511        var now = new Date();
1512        if (config._useUTC) {
1513            return [
1514                now.getUTCFullYear(),
1515                now.getUTCMonth(),
1516                now.getUTCDate()
1517            ];
1518        } else {
1519            return [now.getFullYear(), now.getMonth(), now.getDate()];
1520        }
1521    }
1522
1523    // date from string and format string
1524    function makeDateFromStringAndFormat(config) {
1525        if (config._f === moment.ISO_8601) {
1526            parseISO(config);
1527            return;
1528        }
1529
1530        config._a = [];
1531        config._pf.empty = true;
1532
1533        // This array is used to make a Date, either with `new Date` or `Date.UTC`
1534        var string = '' + config._i,
1535            i, parsedInput, tokens, token, skipped,
1536            stringLength = string.length,
1537            totalParsedInputLength = 0;
1538
1539        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
1540
1541        for (i = 0; i < tokens.length; i++) {
1542            token = tokens[i];
1543            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
1544            if (parsedInput) {
1545                skipped = string.substr(0, string.indexOf(parsedInput));
1546                if (skipped.length > 0) {
1547                    config._pf.unusedInput.push(skipped);
1548                }
1549                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
1550                totalParsedInputLength += parsedInput.length;
1551            }
1552            // don't parse if it's not a known token
1553            if (formatTokenFunctions[token]) {
1554                if (parsedInput) {
1555                    config._pf.empty = false;
1556                }
1557                else {
1558                    config._pf.unusedTokens.push(token);
1559                }
1560                addTimeToArrayFromToken(token, parsedInput, config);
1561            }
1562            else if (config._strict && !parsedInput) {
1563                config._pf.unusedTokens.push(token);
1564            }
1565        }
1566
1567        // add remaining unparsed input length to the string
1568        config._pf.charsLeftOver = stringLength - totalParsedInputLength;
1569        if (string.length > 0) {
1570            config._pf.unusedInput.push(string);
1571        }
1572
1573        // clear _12h flag if hour is <= 12
1574        if (config._pf.bigHour === true && config._a[HOUR] <= 12) {
1575            config._pf.bigHour = undefined;
1576        }
1577        // handle meridiem
1578        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR],
1579                config._meridiem);
1580        dateFromConfig(config);
1581        checkOverflow(config);
1582    }
1583
1584    function unescapeFormat(s) {
1585        return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
1586            return p1 || p2 || p3 || p4;
1587        });
1588    }
1589
1590    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
1591    function regexpEscape(s) {
1592        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
1593    }
1594
1595    // date from string and array of format strings
1596    function makeDateFromStringAndArray(config) {
1597        var tempConfig,
1598            bestMoment,
1599
1600            scoreToBeat,
1601            i,
1602            currentScore;
1603
1604        if (config._f.length === 0) {
1605            config._pf.invalidFormat = true;
1606            config._d = new Date(NaN);
1607            return;
1608        }
1609
1610        for (i = 0; i < config._f.length; i++) {
1611            currentScore = 0;
1612            tempConfig = copyConfig({}, config);
1613            if (config._useUTC != null) {
1614                tempConfig._useUTC = config._useUTC;
1615            }
1616            tempConfig._pf = defaultParsingFlags();
1617            tempConfig._f = config._f[i];
1618            makeDateFromStringAndFormat(tempConfig);
1619
1620            if (!isValid(tempConfig)) {
1621                continue;
1622            }
1623
1624            // if there is any input that was not parsed add a penalty for that format
1625            currentScore += tempConfig._pf.charsLeftOver;
1626
1627            //or tokens
1628            currentScore += tempConfig._pf.unusedTokens.length * 10;
1629
1630            tempConfig._pf.score = currentScore;
1631
1632            if (scoreToBeat == null || currentScore < scoreToBeat) {
1633                scoreToBeat = currentScore;
1634                bestMoment = tempConfig;
1635            }
1636        }
1637
1638        extend(config, bestMoment || tempConfig);
1639    }
1640
1641    // date from iso format
1642    function parseISO(config) {
1643        var i, l,
1644            string = config._i,
1645            match = isoRegex.exec(string);
1646
1647        if (match) {
1648            config._pf.iso = true;
1649            for (i = 0, l = isoDates.length; i < l; i++) {
1650                if (isoDates[i][1].exec(string)) {
1651                    // match[5] should be 'T' or undefined
1652                    config._f = isoDates[i][0] + (match[6] || ' ');
1653                    break;
1654                }
1655            }
1656            for (i = 0, l = isoTimes.length; i < l; i++) {
1657                if (isoTimes[i][1].exec(string)) {
1658                    config._f += isoTimes[i][0];
1659                    break;
1660                }
1661            }
1662            if (string.match(parseTokenTimezone)) {
1663                config._f += 'Z';
1664            }
1665            makeDateFromStringAndFormat(config);
1666        } else {
1667            config._isValid = false;
1668        }
1669    }
1670
1671    // date from iso format or fallback
1672    function makeDateFromString(config) {
1673        parseISO(config);
1674        if (config._isValid === false) {
1675            delete config._isValid;
1676            moment.createFromInputFallback(config);
1677        }
1678    }
1679
1680    function map(arr, fn) {
1681        var res = [], i;
1682        for (i = 0; i < arr.length; ++i) {
1683            res.push(fn(arr[i], i));
1684        }
1685        return res;
1686    }
1687
1688    function makeDateFromInput(config) {
1689        var input = config._i, matched;
1690        if (input === undefined) {
1691            config._d = new Date();
1692        } else if (isDate(input)) {
1693            config._d = new Date(+input);
1694        } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
1695            config._d = new Date(+matched[1]);
1696        } else if (typeof input === 'string') {
1697            makeDateFromString(config);
1698        } else if (isArray(input)) {
1699            config._a = map(input.slice(0), function (obj) {
1700                return parseInt(obj, 10);
1701            });
1702            dateFromConfig(config);
1703        } else if (typeof(input) === 'object') {
1704            dateFromObject(config);
1705        } else if (typeof(input) === 'number') {
1706            // from milliseconds
1707            config._d = new Date(input);
1708        } else {
1709            moment.createFromInputFallback(config);
1710        }
1711    }
1712
1713    function makeDate(y, m, d, h, M, s, ms) {
1714        //can't just apply() to create a date:
1715        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
1716        var date = new Date(y, m, d, h, M, s, ms);
1717
1718        //the date constructor doesn't accept years < 1970
1719        if (y < 1970) {
1720            date.setFullYear(y);
1721        }
1722        return date;
1723    }
1724
1725    function makeUTCDate(y) {
1726        var date = new Date(Date.UTC.apply(null, arguments));
1727        if (y < 1970) {
1728            date.setUTCFullYear(y);
1729        }
1730        return date;
1731    }
1732
1733    function parseWeekday(input, locale) {
1734        if (typeof input === 'string') {
1735            if (!isNaN(input)) {
1736                input = parseInt(input, 10);
1737            }
1738            else {
1739                input = locale.weekdaysParse(input);
1740                if (typeof input !== 'number') {
1741                    return null;
1742                }
1743            }
1744        }
1745        return input;
1746    }
1747
1748    /************************************
1749        Relative Time
1750    ************************************/
1751
1752
1753    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
1754    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
1755        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1756    }
1757
1758    function relativeTime(posNegDuration, withoutSuffix, locale) {
1759        var duration = moment.duration(posNegDuration).abs(),
1760            seconds = round(duration.as('s')),
1761            minutes = round(duration.as('m')),
1762            hours = round(duration.as('h')),
1763            days = round(duration.as('d')),
1764            months = round(duration.as('M')),
1765            years = round(duration.as('y')),
1766
1767            args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1768                minutes === 1 && ['m'] ||
1769                minutes < relativeTimeThresholds.m && ['mm', minutes] ||
1770                hours === 1 && ['h'] ||
1771                hours < relativeTimeThresholds.h && ['hh', hours] ||
1772                days === 1 && ['d'] ||
1773                days < relativeTimeThresholds.d && ['dd', days] ||
1774                months === 1 && ['M'] ||
1775                months < relativeTimeThresholds.M && ['MM', months] ||
1776                years === 1 && ['y'] || ['yy', years];
1777
1778        args[2] = withoutSuffix;
1779        args[3] = +posNegDuration > 0;
1780        args[4] = locale;
1781        return substituteTimeAgo.apply({}, args);
1782    }
1783
1784
1785    /************************************
1786        Week of Year
1787    ************************************/
1788
1789
1790    // firstDayOfWeek       0 = sun, 6 = sat
1791    //                      the day of the week that starts the week
1792    //                      (usually sunday or monday)
1793    // firstDayOfWeekOfYear 0 = sun, 6 = sat
1794    //                      the first week is the week that contains the first
1795    //                      of this day of the week
1796    //                      (eg. ISO weeks use thursday (4))
1797    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
1798        var end = firstDayOfWeekOfYear - firstDayOfWeek,
1799            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
1800            adjustedMoment;
1801
1802
1803        if (daysToDayOfWeek > end) {
1804            daysToDayOfWeek -= 7;
1805        }
1806
1807        if (daysToDayOfWeek < end - 7) {
1808            daysToDayOfWeek += 7;
1809        }
1810
1811        adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
1812        return {
1813            week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1814            year: adjustedMoment.year()
1815        };
1816    }
1817
1818    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1819    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
1820        var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
1821
1822        d = d === 0 ? 7 : d;
1823        weekday = weekday != null ? weekday : firstDayOfWeek;
1824        daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
1825        dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
1826
1827        return {
1828            year: dayOfYear > 0 ? year : year - 1,
1829            dayOfYear: dayOfYear > 0 ?  dayOfYear : daysInYear(year - 1) + dayOfYear
1830        };
1831    }
1832
1833    /************************************
1834        Top Level Functions
1835    ************************************/
1836
1837    function makeMoment(config) {
1838        var input = config._i,
1839            format = config._f,
1840            res;
1841
1842        config._locale = config._locale || moment.localeData(config._l);
1843
1844        if (input === null || (format === undefined && input === '')) {
1845            return moment.invalid({nullInput: true});
1846        }
1847
1848        if (typeof input === 'string') {
1849            config._i = input = config._locale.preparse(input);
1850        }
1851
1852        if (moment.isMoment(input)) {
1853            return new Moment(input, true);
1854        } else if (format) {
1855            if (isArray(format)) {
1856                makeDateFromStringAndArray(config);
1857            } else {
1858                makeDateFromStringAndFormat(config);
1859            }
1860        } else {
1861            makeDateFromInput(config);
1862        }
1863
1864        res = new Moment(config);
1865        if (res._nextDay) {
1866            // Adding is smart enough around DST
1867            res.add(1, 'd');
1868            res._nextDay = undefined;
1869        }
1870
1871        return res;
1872    }
1873
1874    moment = function (input, format, locale, strict) {
1875        var c;
1876
1877        if (typeof(locale) === 'boolean') {
1878            strict = locale;
1879            locale = undefined;
1880        }
1881        // object construction must be done this way.
1882        // https://github.com/moment/moment/issues/1423
1883        c = {};
1884        c._isAMomentObject = true;
1885        c._i = input;
1886        c._f = format;
1887        c._l = locale;
1888        c._strict = strict;
1889        c._isUTC = false;
1890        c._pf = defaultParsingFlags();
1891
1892        return makeMoment(c);
1893    };
1894
1895    moment.suppressDeprecationWarnings = false;
1896
1897    moment.createFromInputFallback = deprecate(
1898        'moment construction falls back to js Date. This is ' +
1899        'discouraged and will be removed in upcoming major ' +
1900        'release. Please refer to ' +
1901        'https://github.com/moment/moment/issues/1407 for more info.',
1902        function (config) {
1903            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
1904        }
1905    );
1906
1907    // Pick a moment m from moments so that m[fn](other) is true for all
1908    // other. This relies on the function fn to be transitive.
1909    //
1910    // moments should either be an array of moment objects or an array, whose
1911    // first element is an array of moment objects.
1912    function pickBy(fn, moments) {
1913        var res, i;
1914        if (moments.length === 1 && isArray(moments[0])) {
1915            moments = moments[0];
1916        }
1917        if (!moments.length) {
1918            return moment();
1919        }
1920        res = moments[0];
1921        for (i = 1; i < moments.length; ++i) {
1922            if (moments[i][fn](res)) {
1923                res = moments[i];
1924            }
1925        }
1926        return res;
1927    }
1928
1929    moment.min = function () {
1930        var args = [].slice.call(arguments, 0);
1931
1932        return pickBy('isBefore', args);
1933    };
1934
1935    moment.max = function () {
1936        var args = [].slice.call(arguments, 0);
1937
1938        return pickBy('isAfter', args);
1939    };
1940
1941    // creating with utc
1942    moment.utc = function (input, format, locale, strict) {
1943        var c;
1944
1945        if (typeof(locale) === 'boolean') {
1946            strict = locale;
1947            locale = undefined;
1948        }
1949        // object construction must be done this way.
1950        // https://github.com/moment/moment/issues/1423
1951        c = {};
1952        c._isAMomentObject = true;
1953        c._useUTC = true;
1954        c._isUTC = true;
1955        c._l = locale;
1956        c._i = input;
1957        c._f = format;
1958        c._strict = strict;
1959        c._pf = defaultParsingFlags();
1960
1961        return makeMoment(c).utc();
1962    };
1963
1964    // creating with unix timestamp (in seconds)
1965    moment.unix = function (input) {
1966        return moment(input * 1000);
1967    };
1968
1969    // duration
1970    moment.duration = function (input, key) {
1971        var duration = input,
1972            // matching against regexp is expensive, do it on demand
1973            match = null,
1974            sign,
1975            ret,
1976            parseIso,
1977            diffRes;
1978
1979        if (moment.isDuration(input)) {
1980            duration = {
1981                ms: input._milliseconds,
1982                d: input._days,
1983                M: input._months
1984            };
1985        } else if (typeof input === 'number') {
1986            duration = {};
1987            if (key) {
1988                duration[key] = input;
1989            } else {
1990                duration.milliseconds = input;
1991            }
1992        } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
1993            sign = (match[1] === '-') ? -1 : 1;
1994            duration = {
1995                y: 0,
1996                d: toInt(match[DATE]) * sign,
1997                h: toInt(match[HOUR]) * sign,
1998                m: toInt(match[MINUTE]) * sign,
1999                s: toInt(match[SECOND]) * sign,
2000                ms: toInt(match[MILLISECOND]) * sign
2001            };
2002        } else if (!!(match = isoDurationRegex.exec(input))) {
2003            sign = (match[1] === '-') ? -1 : 1;
2004            parseIso = function (inp) {
2005                // We'd normally use ~~inp for this, but unfortunately it also
2006                // converts floats to ints.
2007                // inp may be undefined, so careful calling replace on it.
2008                var res = inp && parseFloat(inp.replace(',', '.'));
2009                // apply sign while we're at it
2010                return (isNaN(res) ? 0 : res) * sign;
2011            };
2012            duration = {
2013                y: parseIso(match[2]),
2014                M: parseIso(match[3]),
2015                d: parseIso(match[4]),
2016                h: parseIso(match[5]),
2017                m: parseIso(match[6]),
2018                s: parseIso(match[7]),
2019                w: parseIso(match[8])
2020            };
2021        } else if (duration == null) {// checks for null or undefined
2022            duration = {};
2023        } else if (typeof duration === 'object' &&
2024                ('from' in duration || 'to' in duration)) {
2025            diffRes = momentsDifference(moment(duration.from), moment(duration.to));
2026
2027            duration = {};
2028            duration.ms = diffRes.milliseconds;
2029            duration.M = diffRes.months;
2030        }
2031
2032        ret = new Duration(duration);
2033
2034        if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
2035            ret._locale = input._locale;
2036        }
2037
2038        return ret;
2039    };
2040
2041    // version number
2042    moment.version = VERSION;
2043
2044    // default format
2045    moment.defaultFormat = isoFormat;
2046
2047    // constant that refers to the ISO standard
2048    moment.ISO_8601 = function () {};
2049
2050    // Plugins that add properties should also add the key here (null value),
2051    // so we can properly clone ourselves.
2052    moment.momentProperties = momentProperties;
2053
2054    // This function will be called whenever a moment is mutated.
2055    // It is intended to keep the offset in sync with the timezone.
2056    moment.updateOffset = function () {};
2057
2058    // This function allows you to set a threshold for relative time strings
2059    moment.relativeTimeThreshold = function (threshold, limit) {
2060        if (relativeTimeThresholds[threshold] === undefined) {
2061            return false;
2062        }
2063        if (limit === undefined) {
2064            return relativeTimeThresholds[threshold];
2065        }
2066        relativeTimeThresholds[threshold] = limit;
2067        return true;
2068    };
2069
2070    moment.lang = deprecate(
2071        'moment.lang is deprecated. Use moment.locale instead.',
2072        function (key, value) {
2073            return moment.locale(key, value);
2074        }
2075    );
2076
2077    // This function will load locale and then set the global locale.  If
2078    // no arguments are passed in, it will simply return the current global
2079    // locale key.
2080    moment.locale = function (key, values) {
2081        var data;
2082        if (key) {
2083            if (typeof(values) !== 'undefined') {
2084                data = moment.defineLocale(key, values);
2085            }
2086            else {
2087                data = moment.localeData(key);
2088            }
2089
2090            if (data) {
2091                moment.duration._locale = moment._locale = data;
2092            }
2093        }
2094
2095        return moment._locale._abbr;
2096    };
2097
2098    moment.defineLocale = function (name, values) {
2099        if (values !== null) {
2100            values.abbr = name;
2101            if (!locales[name]) {
2102                locales[name] = new Locale();
2103            }
2104            locales[name].set(values);
2105
2106            // backwards compat for now: also set the locale
2107            moment.locale(name);
2108
2109            return locales[name];
2110        } else {
2111            // useful for testing
2112            delete locales[name];
2113            return null;
2114        }
2115    };
2116
2117    moment.langData = deprecate(
2118        'moment.langData is deprecated. Use moment.localeData instead.',
2119        function (key) {
2120            return moment.localeData(key);
2121        }
2122    );
2123
2124    // returns locale data
2125    moment.localeData = function (key) {
2126        var locale;
2127
2128        if (key && key._locale && key._locale._abbr) {
2129            key = key._locale._abbr;
2130        }
2131
2132        if (!key) {
2133            return moment._locale;
2134        }
2135
2136        if (!isArray(key)) {
2137            //short-circuit everything else
2138            locale = loadLocale(key);
2139            if (locale) {
2140                return locale;
2141            }
2142            key = [key];
2143        }
2144
2145        return chooseLocale(key);
2146    };
2147
2148    // compare moment object
2149    moment.isMoment = function (obj) {
2150        return obj instanceof Moment ||
2151            (obj != null && hasOwnProp(obj, '_isAMomentObject'));
2152    };
2153
2154    // for typechecking Duration objects
2155    moment.isDuration = function (obj) {
2156        return obj instanceof Duration;
2157    };
2158
2159    for (i = lists.length - 1; i >= 0; --i) {
2160        makeList(lists[i]);
2161    }
2162
2163    moment.normalizeUnits = function (units) {
2164        return normalizeUnits(units);
2165    };
2166
2167    moment.invalid = function (flags) {
2168        var m = moment.utc(NaN);
2169        if (flags != null) {
2170            extend(m._pf, flags);
2171        }
2172        else {
2173            m._pf.userInvalidated = true;
2174        }
2175
2176        return m;
2177    };
2178
2179    moment.parseZone = function () {
2180        return moment.apply(null, arguments).parseZone();
2181    };
2182
2183    moment.parseTwoDigitYear = function (input) {
2184        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
2185    };
2186
2187    moment.isDate = isDate;
2188
2189    /************************************
2190        Moment Prototype
2191    ************************************/
2192
2193
2194    extend(moment.fn = Moment.prototype, {
2195
2196        clone : function () {
2197            return moment(this);
2198        },
2199
2200        valueOf : function () {
2201            return +this._d - ((this._offset || 0) * 60000);
2202        },
2203
2204        unix : function () {
2205            return Math.floor(+this / 1000);
2206        },
2207
2208        toString : function () {
2209            return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
2210        },
2211
2212        toDate : function () {
2213            return this._offset ? new Date(+this) : this._d;
2214        },
2215
2216        toISOString : function () {
2217            var m = moment(this).utc();
2218            if (0 < m.year() && m.year() <= 9999) {
2219                if ('function' === typeof Date.prototype.toISOString) {
2220                    // native implementation is ~50x faster, use it when we can
2221                    return this.toDate().toISOString();
2222                } else {
2223                    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
2224                }
2225            } else {
2226                return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
2227            }
2228        },
2229
2230        toArray : function () {
2231            var m = this;
2232            return [
2233                m.year(),
2234                m.month(),
2235                m.date(),
2236                m.hours(),
2237                m.minutes(),
2238                m.seconds(),
2239                m.milliseconds()
2240            ];
2241        },
2242
2243        isValid : function () {
2244            return isValid(this);
2245        },
2246
2247        isDSTShifted : function () {
2248            if (this._a) {
2249                return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
2250            }
2251
2252            return false;
2253        },
2254
2255        parsingFlags : function () {
2256            return extend({}, this._pf);
2257        },
2258
2259        invalidAt: function () {
2260            return this._pf.overflow;
2261        },
2262
2263        utc : function (keepLocalTime) {
2264            return this.utcOffset(0, keepLocalTime);
2265        },
2266
2267        local : function (keepLocalTime) {
2268            if (this._isUTC) {
2269                this.utcOffset(0, keepLocalTime);
2270                this._isUTC = false;
2271
2272                if (keepLocalTime) {
2273                    this.subtract(this._dateUtcOffset(), 'm');
2274                }
2275            }
2276            return this;
2277        },
2278
2279        format : function (inputString) {
2280            var output = formatMoment(this, inputString || moment.defaultFormat);
2281            return this.localeData().postformat(output);
2282        },
2283
2284        add : createAdder(1, 'add'),
2285
2286        subtract : createAdder(-1, 'subtract'),
2287
2288        diff : function (input, units, asFloat) {
2289            var that = makeAs(input, this),
2290                zoneDiff = (that.utcOffset() - this.utcOffset()) * 6e4,
2291                anchor, diff, output, daysAdjust;
2292
2293            units = normalizeUnits(units);
2294
2295            if (units === 'year' || units === 'month' || units === 'quarter') {
2296                output = monthDiff(this, that);
2297                if (units === 'quarter') {
2298                    output = output / 3;
2299                } else if (units === 'year') {
2300                    output = output / 12;
2301                }
2302            } else {
2303                diff = this - that;
2304                output = units === 'second' ? diff / 1e3 : // 1000
2305                    units === 'minute' ? diff / 6e4 : // 1000 * 60
2306                    units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
2307                    units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
2308                    units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
2309                    diff;
2310            }
2311            return asFloat ? output : absRound(output);
2312        },
2313
2314        from : function (time, withoutSuffix) {
2315            return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
2316        },
2317
2318        fromNow : function (withoutSuffix) {
2319            return this.from(moment(), withoutSuffix);
2320        },
2321
2322        calendar : function (time) {
2323            // We want to compare the start of today, vs this.
2324            // Getting start-of-today depends on whether we're locat/utc/offset
2325            // or not.
2326            var now = time || moment(),
2327                sod = makeAs(now, this).startOf('day'),
2328                diff = this.diff(sod, 'days', true),
2329                format = diff < -6 ? 'sameElse' :
2330                    diff < -1 ? 'lastWeek' :
2331                    diff < 0 ? 'lastDay' :
2332                    diff < 1 ? 'sameDay' :
2333                    diff < 2 ? 'nextDay' :
2334                    diff < 7 ? 'nextWeek' : 'sameElse';
2335            return this.format(this.localeData().calendar(format, this, moment(now)));
2336        },
2337
2338        isLeapYear : function () {
2339            return isLeapYear(this.year());
2340        },
2341
2342        isDST : function () {
2343            return (this.utcOffset() > this.clone().month(0).utcOffset() ||
2344                this.utcOffset() > this.clone().month(5).utcOffset());
2345        },
2346
2347        day : function (input) {
2348            var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
2349            if (input != null) {
2350                input = parseWeekday(input, this.localeData());
2351                return this.add(input - day, 'd');
2352            } else {
2353                return day;
2354            }
2355        },
2356
2357        month : makeAccessor('Month', true),
2358
2359        startOf : function (units) {
2360            units = normalizeUnits(units);
2361            // the following switch intentionally omits break keywords
2362            // to utilize falling through the cases.
2363            switch (units) {
2364            case 'year':
2365                this.month(0);
2366                /* falls through */
2367            case 'quarter':
2368            case 'month':
2369                this.date(1);
2370                /* falls through */
2371            case 'week':
2372            case 'isoWeek':
2373            case 'day':
2374                this.hours(0);
2375                /* falls through */
2376            case 'hour':
2377                this.minutes(0);
2378                /* falls through */
2379            case 'minute':
2380                this.seconds(0);
2381                /* falls through */
2382            case 'second':
2383                this.milliseconds(0);
2384                /* falls through */
2385            }
2386
2387            // weeks are a special case
2388            if (units === 'week') {
2389                this.weekday(0);
2390            } else if (units === 'isoWeek') {
2391                this.isoWeekday(1);
2392            }
2393
2394            // quarters are also special
2395            if (units === 'quarter') {
2396                this.month(Math.floor(this.month() / 3) * 3);
2397            }
2398
2399            return this;
2400        },
2401
2402        endOf: function (units) {
2403            units = normalizeUnits(units);
2404            if (units === undefined || units === 'millisecond') {
2405                return this;
2406            }
2407            return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
2408        },
2409
2410        isAfter: function (input, units) {
2411            var inputMs;
2412            units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
2413            if (units === 'millisecond') {
2414                input = moment.isMoment(input) ? input : moment(input);
2415                return +this > +input;
2416            } else {
2417                inputMs = moment.isMoment(input) ? +input : +moment(input);
2418                return inputMs < +this.clone().startOf(units);
2419            }
2420        },
2421
2422        isBefore: function (input, units) {
2423            var inputMs;
2424            units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
2425            if (units === 'millisecond') {
2426                input = moment.isMoment(input) ? input : moment(input);
2427                return +this < +input;
2428            } else {
2429                inputMs = moment.isMoment(input) ? +input : +moment(input);
2430                return +this.clone().endOf(units) < inputMs;
2431            }
2432        },
2433
2434        isBetween: function (from, to, units) {
2435            return this.isAfter(from, units) && this.isBefore(to, units);
2436        },
2437
2438        isSame: function (input, units) {
2439            var inputMs;
2440            units = normalizeUnits(units || 'millisecond');
2441            if (units === 'millisecond') {
2442                input = moment.isMoment(input) ? input : moment(input);
2443                return +this === +input;
2444            } else {
2445                inputMs = +moment(input);
2446                return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
2447            }
2448        },
2449
2450        min: deprecate(
2451                 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
2452                 function (other) {
2453                     other = moment.apply(null, arguments);
2454                     return other < this ? this : other;
2455                 }
2456         ),
2457
2458        max: deprecate(
2459                'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
2460                function (other) {
2461                    other = moment.apply(null, arguments);
2462                    return other > this ? this : other;
2463                }
2464        ),
2465
2466        zone : deprecate(
2467                'moment().zone is deprecated, use moment().utcOffset instead. ' +
2468                'https://github.com/moment/moment/issues/1779',
2469                function (input, keepLocalTime) {
2470                    if (input != null) {
2471                        if (typeof input !== 'string') {
2472                            input = -input;
2473                        }
2474
2475                        this.utcOffset(input, keepLocalTime);
2476
2477                        return this;
2478                    } else {
2479                        return -this.utcOffset();
2480                    }
2481                }
2482        ),
2483
2484        // keepLocalTime = true means only change the timezone, without
2485        // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
2486        // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
2487        // +0200, so we adjust the time as needed, to be valid.
2488        //
2489        // Keeping the time actually adds/subtracts (one hour)
2490        // from the actual represented time. That is why we call updateOffset
2491        // a second time. In case it wants us to change the offset again
2492        // _changeInProgress == true case, then we have to adjust, because
2493        // there is no such time in the given timezone.
2494        utcOffset : function (input, keepLocalTime) {
2495            var offset = this._offset || 0,
2496                localAdjust;
2497            if (input != null) {
2498                if (typeof input === 'string') {
2499                    input = utcOffsetFromString(input);
2500                }
2501                if (Math.abs(input) < 16) {
2502                    input = input * 60;
2503                }
2504                if (!this._isUTC && keepLocalTime) {
2505                    localAdjust = this._dateUtcOffset();
2506                }
2507                this._offset = input;
2508                this._isUTC = true;
2509                if (localAdjust != null) {
2510                    this.add(localAdjust, 'm');
2511                }
2512                if (offset !== input) {
2513                    if (!keepLocalTime || this._changeInProgress) {
2514                        addOrSubtractDurationFromMoment(this,
2515                                moment.duration(input - offset, 'm'), 1, false);
2516                    } else if (!this._changeInProgress) {
2517                        this._changeInProgress = true;
2518                        moment.updateOffset(this, true);
2519                        this._changeInProgress = null;
2520                    }
2521                }
2522
2523                return this;
2524            } else {
2525                return this._isUTC ? offset : this._dateUtcOffset();
2526            }
2527        },
2528
2529        isLocal : function () {
2530            return !this._isUTC;
2531        },
2532
2533        isUtcOffset : function () {
2534            return this._isUTC;
2535        },
2536
2537        isUtc : function () {
2538            return this._isUTC && this._offset === 0;
2539        },
2540
2541        zoneAbbr : function () {
2542            return this._isUTC ? 'UTC' : '';
2543        },
2544
2545        zoneName : function () {
2546            return this._isUTC ? 'Coordinated Universal Time' : '';
2547        },
2548
2549        parseZone : function () {
2550            if (this._tzm) {
2551                this.utcOffset(this._tzm);
2552            } else if (typeof this._i === 'string') {
2553                this.utcOffset(utcOffsetFromString(this._i));
2554            }
2555            return this;
2556        },
2557
2558        hasAlignedHourOffset : function (input) {
2559            if (!input) {
2560                input = 0;
2561            }
2562            else {
2563                input = moment(input).utcOffset();
2564            }
2565
2566            return (this.utcOffset() - input) % 60 === 0;
2567        },
2568
2569        daysInMonth : function () {
2570            return daysInMonth(this.year(), this.month());
2571        },
2572
2573        dayOfYear : function (input) {
2574            var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
2575            return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
2576        },
2577
2578        quarter : function (input) {
2579            return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
2580        },
2581
2582        weekYear : function (input) {
2583            var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
2584            return input == null ? year : this.add((input - year), 'y');
2585        },
2586
2587        isoWeekYear : function (input) {
2588            var year = weekOfYear(this, 1, 4).year;
2589            return input == null ? year : this.add((input - year), 'y');
2590        },
2591
2592        week : function (input) {
2593            var week = this.localeData().week(this);
2594            return input == null ? week : this.add((input - week) * 7, 'd');
2595        },
2596
2597        isoWeek : function (input) {
2598            var week = weekOfYear(this, 1, 4).week;
2599            return input == null ? week : this.add((input - week) * 7, 'd');
2600        },
2601
2602        weekday : function (input) {
2603            var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
2604            return input == null ? weekday : this.add(input - weekday, 'd');
2605        },
2606
2607        isoWeekday : function (input) {
2608            // behaves the same as moment#day except
2609            // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
2610            // as a setter, sunday should belong to the previous week.
2611            return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
2612        },
2613
2614        isoWeeksInYear : function () {
2615            return weeksInYear(this.year(), 1, 4);
2616        },
2617
2618        weeksInYear : function () {
2619            var weekInfo = this.localeData()._week;
2620            return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
2621        },
2622
2623        get : function (units) {
2624            units = normalizeUnits(units);
2625            return this[units]();
2626        },
2627
2628        set : function (units, value) {
2629            var unit;
2630            if (typeof units === 'object') {
2631                for (unit in units) {
2632                    this.set(unit, units[unit]);
2633                }
2634            }
2635            else {
2636                units = normalizeUnits(units);
2637                if (typeof this[units] === 'function') {
2638                    this[units](value);
2639                }
2640            }
2641            return this;
2642        },
2643
2644        // If passed a locale key, it will set the locale for this
2645        // instance.  Otherwise, it will return the locale configuration
2646        // variables for this instance.
2647        locale : function (key) {
2648            var newLocaleData;
2649
2650            if (key === undefined) {
2651                return this._locale._abbr;
2652            } else {
2653                newLocaleData = moment.localeData(key);
2654                if (newLocaleData != null) {
2655                    this._locale = newLocaleData;
2656                }
2657                return this;
2658            }
2659        },
2660
2661        lang : deprecate(
2662            'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
2663            function (key) {
2664                if (key === undefined) {
2665                    return this.localeData();
2666                } else {
2667                    return this.locale(key);
2668                }
2669            }
2670        ),
2671
2672        localeData : function () {
2673            return this._locale;
2674        },
2675
2676        _dateUtcOffset : function () {
2677            // On Firefox.24 Date#getTimezoneOffset returns a floating point.
2678            // https://github.com/moment/moment/pull/1871
2679            return -Math.round(this._d.getTimezoneOffset() / 15) * 15;
2680        }
2681
2682    });
2683
2684    function rawMonthSetter(mom, value) {
2685        var dayOfMonth;
2686
2687        // TODO: Move this out of here!
2688        if (typeof value === 'string') {
2689            value = mom.localeData().monthsParse(value);
2690            // TODO: Another silent failure?
2691            if (typeof value !== 'number') {
2692                return mom;
2693            }
2694        }
2695
2696        dayOfMonth = Math.min(mom.date(),
2697                daysInMonth(mom.year(), value));
2698        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
2699        return mom;
2700    }
2701
2702    function rawGetter(mom, unit) {
2703        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
2704    }
2705
2706    function rawSetter(mom, unit, value) {
2707        if (unit === 'Month') {
2708            return rawMonthSetter(mom, value);
2709        } else {
2710            return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
2711        }
2712    }
2713
2714    function makeAccessor(unit, keepTime) {
2715        return function (value) {
2716            if (value != null) {
2717                rawSetter(this, unit, value);
2718                moment.updateOffset(this, keepTime);
2719                return this;
2720            } else {
2721                return rawGetter(this, unit);
2722            }
2723        };
2724    }
2725
2726    moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
2727    moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
2728    moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
2729    // Setting the hour should keep the time, because the user explicitly
2730    // specified which hour he wants. So trying to maintain the same hour (in
2731    // a new timezone) makes sense. Adding/subtracting hours does not follow
2732    // this rule.
2733    moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
2734    // moment.fn.month is defined separately
2735    moment.fn.date = makeAccessor('Date', true);
2736    moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
2737    moment.fn.year = makeAccessor('FullYear', true);
2738    moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
2739
2740    // add plural methods
2741    moment.fn.days = moment.fn.day;
2742    moment.fn.months = moment.fn.month;
2743    moment.fn.weeks = moment.fn.week;
2744    moment.fn.isoWeeks = moment.fn.isoWeek;
2745    moment.fn.quarters = moment.fn.quarter;
2746
2747    // add aliased format methods
2748    moment.fn.toJSON = moment.fn.toISOString;
2749
2750    // alias isUtc for dev-friendliness
2751    moment.fn.isUTC = moment.fn.isUtc;
2752
2753    /************************************
2754        Duration Prototype
2755    ************************************/
2756
2757
2758    function daysToYears (days) {
2759        // 400 years have 146097 days (taking into account leap year rules)
2760        return days * 400 / 146097;
2761    }
2762
2763    function yearsToDays (years) {
2764        // years * 365 + absRound(years / 4) -
2765        //     absRound(years / 100) + absRound(years / 400);
2766        return years * 146097 / 400;
2767    }
2768
2769    extend(moment.duration.fn = Duration.prototype, {
2770
2771        _bubble : function () {
2772            var milliseconds = this._milliseconds,
2773                days = this._days,
2774                months = this._months,
2775                data = this._data,
2776                seconds, minutes, hours, years = 0;
2777
2778            // The following code bubbles up values, see the tests for
2779            // examples of what that means.
2780            data.milliseconds = milliseconds % 1000;
2781
2782            seconds = absRound(milliseconds / 1000);
2783            data.seconds = seconds % 60;
2784
2785            minutes = absRound(seconds / 60);
2786            data.minutes = minutes % 60;
2787
2788            hours = absRound(minutes / 60);
2789            data.hours = hours % 24;
2790
2791            days += absRound(hours / 24);
2792
2793            // Accurately convert days to years, assume start from year 0.
2794            years = absRound(daysToYears(days));
2795            days -= absRound(yearsToDays(years));
2796
2797            // 30 days to a month
2798            // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
2799            months += absRound(days / 30);
2800            days %= 30;
2801
2802            // 12 months -> 1 year
2803            years += absRound(months / 12);
2804            months %= 12;
2805
2806            data.days = days;
2807            data.months = months;
2808            data.years = years;
2809        },
2810
2811        abs : function () {
2812            this._milliseconds = Math.abs(this._milliseconds);
2813            this._days = Math.abs(this._days);
2814            this._months = Math.abs(this._months);
2815
2816            this._data.milliseconds = Math.abs(this._data.milliseconds);
2817            this._data.seconds = Math.abs(this._data.seconds);
2818            this._data.minutes = Math.abs(this._data.minutes);
2819            this._data.hours = Math.abs(this._data.hours);
2820            this._data.months = Math.abs(this._data.months);
2821            this._data.years = Math.abs(this._data.years);
2822
2823            return this;
2824        },
2825
2826        weeks : function () {
2827            return absRound(this.days() / 7);
2828        },
2829
2830        valueOf : function () {
2831            return this._milliseconds +
2832              this._days * 864e5 +
2833              (this._months % 12) * 2592e6 +
2834              toInt(this._months / 12) * 31536e6;
2835        },
2836
2837        humanize : function (withSuffix) {
2838            var output = relativeTime(this, !withSuffix, this.localeData());
2839
2840            if (withSuffix) {
2841                output = this.localeData().pastFuture(+this, output);
2842            }
2843
2844            return this.localeData().postformat(output);
2845        },
2846
2847        add : function (input, val) {
2848            // supports only 2.0-style add(1, 's') or add(moment)
2849            var dur = moment.duration(input, val);
2850
2851            this._milliseconds += dur._milliseconds;
2852            this._days += dur._days;
2853            this._months += dur._months;
2854
2855            this._bubble();
2856
2857            return this;
2858        },
2859
2860        subtract : function (input, val) {
2861            var dur = moment.duration(input, val);
2862
2863            this._milliseconds -= dur._milliseconds;
2864            this._days -= dur._days;
2865            this._months -= dur._months;
2866
2867            this._bubble();
2868
2869            return this;
2870        },
2871
2872        get : function (units) {
2873            units = normalizeUnits(units);
2874            return this[units.toLowerCase() + 's']();
2875        },
2876
2877        as : function (units) {
2878            var days, months;
2879            units = normalizeUnits(units);
2880
2881            if (units === 'month' || units === 'year') {
2882                days = this._days + this._milliseconds / 864e5;
2883                months = this._months + daysToYears(days) * 12;
2884                return units === 'month' ? months : months / 12;
2885            } else {
2886                // handle milliseconds separately because of floating point math errors (issue #1867)
2887                days = this._days + Math.round(yearsToDays(this._months / 12));
2888                switch (units) {
2889                    case 'week': return days / 7 + this._milliseconds / 6048e5;
2890                    case 'day': return days + this._milliseconds / 864e5;
2891                    case 'hour': return days * 24 + this._milliseconds / 36e5;
2892                    case 'minute': return days * 24 * 60 + this._milliseconds / 6e4;
2893                    case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000;
2894                    // Math.floor prevents floating point math errors here
2895                    case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;
2896                    default: throw new Error('Unknown unit ' + units);
2897                }
2898            }
2899        },
2900
2901        lang : moment.fn.lang,
2902        locale : moment.fn.locale,
2903
2904        toIsoString : deprecate(
2905            'toIsoString() is deprecated. Please use toISOString() instead ' +
2906            '(notice the capitals)',
2907            function () {
2908                return this.toISOString();
2909            }
2910        ),
2911
2912        toISOString : function () {
2913            // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2914            var years = Math.abs(this.years()),
2915                months = Math.abs(this.months()),
2916                days = Math.abs(this.days()),
2917                hours = Math.abs(this.hours()),
2918                minutes = Math.abs(this.minutes()),
2919                seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
2920
2921            if (!this.asSeconds()) {
2922                // this is the same as C#'s (Noda) and python (isodate)...
2923                // but not other JS (goog.date)
2924                return 'P0D';
2925            }
2926
2927            return (this.asSeconds() < 0 ? '-' : '') +
2928                'P' +
2929                (years ? years + 'Y' : '') +
2930                (months ? months + 'M' : '') +
2931                (days ? days + 'D' : '') +
2932                ((hours || minutes || seconds) ? 'T' : '') +
2933                (hours ? hours + 'H' : '') +
2934                (minutes ? minutes + 'M' : '') +
2935                (seconds ? seconds + 'S' : '');
2936        },
2937
2938        localeData : function () {
2939            return this._locale;
2940        },
2941
2942        toJSON : function () {
2943            return this.toISOString();
2944        }
2945    });
2946
2947    moment.duration.fn.toString = moment.duration.fn.toISOString;
2948
2949    function makeDurationGetter(name) {
2950        moment.duration.fn[name] = function () {
2951            return this._data[name];
2952        };
2953    }
2954
2955    for (i in unitMillisecondFactors) {
2956        if (hasOwnProp(unitMillisecondFactors, i)) {
2957            makeDurationGetter(i.toLowerCase());
2958        }
2959    }
2960
2961    moment.duration.fn.asMilliseconds = function () {
2962        return this.as('ms');
2963    };
2964    moment.duration.fn.asSeconds = function () {
2965        return this.as('s');
2966    };
2967    moment.duration.fn.asMinutes = function () {
2968        return this.as('m');
2969    };
2970    moment.duration.fn.asHours = function () {
2971        return this.as('h');
2972    };
2973    moment.duration.fn.asDays = function () {
2974        return this.as('d');
2975    };
2976    moment.duration.fn.asWeeks = function () {
2977        return this.as('weeks');
2978    };
2979    moment.duration.fn.asMonths = function () {
2980        return this.as('M');
2981    };
2982    moment.duration.fn.asYears = function () {
2983        return this.as('y');
2984    };
2985
2986    /************************************
2987        Default Locale
2988    ************************************/
2989
2990
2991    // Set default locale, other locale will inherit from English.
2992    moment.locale('en', {
2993        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
2994        ordinal : function (number) {
2995            var b = number % 10,
2996                output = (toInt(number % 100 / 10) === 1) ? 'th' :
2997                (b === 1) ? 'st' :
2998                (b === 2) ? 'nd' :
2999                (b === 3) ? 'rd' : 'th';
3000            return number + output;
3001        }
3002    });
3003
3004    /* EMBED_LOCALES */
3005
3006    /************************************
3007        Exposing Moment
3008    ************************************/
3009
3010    function makeGlobal(shouldDeprecate) {
3011        /*global ender:false */
3012        if (typeof ender !== 'undefined') {
3013            return;
3014        }
3015        oldGlobalMoment = globalScope.moment;
3016        if (shouldDeprecate) {
3017            globalScope.moment = deprecate(
3018                    'Accessing Moment through the global scope is ' +
3019                    'deprecated, and will be removed in an upcoming ' +
3020                    'release.',
3021                    moment);
3022        } else {
3023            globalScope.moment = moment;
3024        }
3025    }
3026
3027    // CommonJS module is defined
3028    if (hasModule) {
3029        module.exports = moment;
3030    } else if (typeof define === 'function' && define.amd) {
3031        define(function (require, exports, module) {
3032            if (module.config && module.config() && module.config().noGlobal === true) {
3033                // release the global variable
3034                globalScope.moment = oldGlobalMoment;
3035            }
3036
3037            return moment;
3038        });
3039        makeGlobal(true);
3040    } else {
3041        makeGlobal();
3042    }
3043}
3043).call(this);

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