PageSourceSearch

https://public.skyworthxr.com/officialWebsite/production/inland/assets/js/moment.js

js skyworthxr.com collected 2026-10-07 06:55:22 UTC 145,607 bytes, 4,603 lines download raw bytes

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

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.