diff --git a/web/libs/js/moment.js b/web/libs/js/moment.js index 2f7bffd8..13c5434f 100644 --- a/web/libs/js/moment.js +++ b/web/libs/js/moment.js @@ -1,18 +1,18 @@ //! moment.js -//! version : 2.14.1 +//! version : 2.24.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT -//! momentjs.com +//! moment.js ;(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.moment = factory() -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var hookCallback; - function utils_hooks__hooks () { + function hooks () { return hookCallback.apply(null, arguments); } @@ -27,16 +27,31 @@ } function isObject(input) { - return Object.prototype.toString.call(input) === '[object Object]'; + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; } function isObjectEmpty(obj) { - var k; - for (k in obj) { - // even if its not own property I'd still call it non-empty - return false; + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; } - return true; + } + + function isUndefined(input) { + return input === void 0; + } + + function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; } function isDate(input) { @@ -73,7 +88,7 @@ return a; } - function create_utc__createUTC (input, format, locale, strict) { + function createUTC (input, format, locale, strict) { return createLocalOrUTC(input, format, locale, strict, true).utc(); } @@ -91,7 +106,9 @@ userInvalidated : false, iso : false, parsedDateParts : [], - meridiem : null + meridiem : null, + rfc2822 : false, + weekdayMismatch : false }; } @@ -120,34 +137,42 @@ }; } - function valid__isValid(m) { + function isValid(m) { if (m._isValid == null) { var flags = getParsingFlags(m); var parsedParts = some.call(flags.parsedDateParts, function (i) { return i != null; }); - m._isValid = !isNaN(m._d.getTime()) && + var isNowValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && !flags.invalidMonth && !flags.invalidWeekday && + !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || (flags.meridiem && parsedParts)); if (m._strict) { - m._isValid = m._isValid && + isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined; } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } } return m._isValid; } - function valid__createInvalid (flags) { - var m = create_utc__createUTC(NaN); + function createInvalid (flags) { + var m = createUTC(NaN); if (flags != null) { extend(getParsingFlags(m), flags); } @@ -158,13 +183,9 @@ return m; } - function isUndefined(input) { - return input === void 0; - } - // Plugins that add properties should also add the key here (null value), // so we can properly clone ourselves. - var momentProperties = utils_hooks__hooks.momentProperties = []; + var momentProperties = hooks.momentProperties = []; function copyConfig(to, from) { var i, prop, val; @@ -201,7 +222,7 @@ } if (momentProperties.length > 0) { - for (i in momentProperties) { + for (i = 0; i < momentProperties.length; i++) { prop = momentProperties[i]; val = from[prop]; if (!isUndefined(val)) { @@ -219,11 +240,14 @@ function Moment(config) { copyConfig(this, config); this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } // Prevent infinite loop in case updateOffset creates new moment // objects. if (updateInProgress === false) { updateInProgress = true; - utils_hooks__hooks.updateOffset(this); + hooks.updateOffset(this); updateInProgress = false; } } @@ -268,7 +292,7 @@ } function warn(msg) { - if (utils_hooks__hooks.suppressDeprecationWarnings === false && + if (hooks.suppressDeprecationWarnings === false && (typeof console !== 'undefined') && console.warn) { console.warn('Deprecation warning: ' + msg); } @@ -278,11 +302,26 @@ var firstTime = true; return extend(function () { - if (utils_hooks__hooks.deprecationHandler != null) { - utils_hooks__hooks.deprecationHandler(null, msg); + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); } if (firstTime) { - warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack); + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); firstTime = false; } return fn.apply(this, arguments); @@ -292,8 +331,8 @@ var deprecations = {}; function deprecateSimple(name, msg) { - if (utils_hooks__hooks.deprecationHandler != null) { - utils_hooks__hooks.deprecationHandler(name, msg); + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); } if (!deprecations[name]) { warn(msg); @@ -301,14 +340,14 @@ } } - utils_hooks__hooks.suppressDeprecationWarnings = false; - utils_hooks__hooks.deprecationHandler = null; + hooks.suppressDeprecationWarnings = false; + hooks.deprecationHandler = null; function isFunction(input) { return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; } - function locale_set__set (config) { + function set (config) { var prop, i; for (i in config) { prop = config[i]; @@ -320,8 +359,11 @@ } this._config = config; // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _ordinalParseLenient. - this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source); + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); } function mergeConfigs(parentConfig, childConfig) { @@ -381,7 +423,7 @@ sameElse : 'L' }; - function locale_calendar__calendar (key, mom, now) { + function calendar (key, mom, now) { var output = this._calendar[key] || this._calendar['sameElse']; return isFunction(output) ? output.call(mom, now) : output; } @@ -417,29 +459,30 @@ } var defaultOrdinal = '%d'; - var defaultOrdinalParse = /\d{1,2}/; + var defaultDayOfMonthOrdinalParse = /\d{1,2}/; function ordinal (number) { return this._ordinal.replace('%d', number); } var defaultRelativeTime = { - future : '<%-lang.in%> %s', - past : '%s <%-lang.ago%>', - s : '<%-lang['a few seconds']%>', - m : '<%-lang['a minute']%>', - mm : '%d <%-lang.minutes%>', - h : '<%-lang['an hour']%>', - hh : '%d <%-lang.hours%>', - d : '<%-lang['a day']%>', - dd : '%d <%-lang.days%>', - M : '<%-lang['a month']%>', - MM : '%d <%-lang.months%>', - y : '<%-lang['a year']%>', - yy : '%d <%-lang.years%>' + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }; - function relative__relativeTime (number, withoutSuffix, string, isFuture) { + function relativeTime (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return (isFunction(output)) ? output(number, withoutSuffix, string, isFuture) : @@ -496,56 +539,6 @@ return units; } - function makeGetSet (unit, keepTime) { - return function (value) { - if (value != null) { - get_set__set(this, unit, value); - utils_hooks__hooks.updateOffset(this, keepTime); - return this; - } else { - return get_set__get(this, unit); - } - }; - } - - function get_set__get (mom, unit) { - return mom.isValid() ? - mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; - } - - function get_set__set (mom, unit, value) { - if (mom.isValid()) { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - - // MOMENTS - - function stringGet (units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); - } - return this; - } - - - function stringSet (units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units); - for (var i = 0; i < prioritized.length; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; - } - function zeroFill(number, targetLength, forceSign) { var absNumber = '' + Math.abs(number), zerosToFill = targetLength - absNumber.length, @@ -609,7 +602,7 @@ return function (mom) { var output = '', i; for (i = 0; i < length; i++) { - output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; } return output; }; @@ -666,8 +659,7 @@ // any word (or two) characters or numbers including two/three word month in arabic. // includes scottish gaelic two word and hyphenated months - var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i; - + 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; var regexes = {}; @@ -703,7 +695,7 @@ if (typeof token === 'string') { token = [token]; } - if (typeof callback === 'number') { + if (isNumber(callback)) { func = function (input, array) { array[callback] = toInt(input); }; @@ -736,6 +728,131 @@ var WEEK = 7; var WEEKDAY = 8; + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + + // ALIASES + + addUnitAlias('year', 'y'); + + // PRIORITIES + + addUnitPriority('year', 1); + + // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); + + // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + // HOOKS + + hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + // MOMENTS + + var getSetYear = makeGetSet('FullYear', true); + + function getIsLeapYear () { + return isLeapYear(this.year()); + } + + function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; + } + + function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } + + function set$1 (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + } + + // MOMENTS + + function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; + } + + + function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } + + function mod(n, x) { + return ((n % x) + x) % x; + } + var indexOf; if (Array.prototype.indexOf) { @@ -754,7 +871,12 @@ } function daysInMonth(year, month) { - return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); } // FORMATTING @@ -806,20 +928,28 @@ // LOCALES - var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/; + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; } var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; } - function units_month__handleStrictParse(monthName, format, strict) { + function handleStrictParse(monthName, format, strict) { var i, ii, mom, llc = monthName.toLocaleLowerCase(); if (!this._monthsParse) { // this is not used @@ -827,7 +957,7 @@ this._longMonthsParse = []; this._shortMonthsParse = []; for (i = 0; i < 12; ++i) { - mom = create_utc__createUTC([2000, i]); + mom = createUTC([2000, i]); this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); } @@ -864,7 +994,7 @@ var i, mom, regex; if (this._monthsParseExact) { - return units_month__handleStrictParse.call(this, monthName, format, strict); + return handleStrictParse.call(this, monthName, format, strict); } if (!this._monthsParse) { @@ -878,7 +1008,7 @@ // see sorting in computeMonthsParse for (i = 0; i < 12; i++) { // make the regex if we don't have it already - mom = create_utc__createUTC([2000, i]); + mom = createUTC([2000, i]); if (strict && !this._longMonthsParse[i]) { this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); @@ -914,7 +1044,7 @@ } else { value = mom.localeData().monthsParse(value); // TODO: Another silent failure? - if (typeof value !== 'number') { + if (!isNumber(value)) { return mom; } } @@ -928,10 +1058,10 @@ function getSetMonth (value) { if (value != null) { setMonth(this, value); - utils_hooks__hooks.updateOffset(this, true); + hooks.updateOffset(this, true); return this; } else { - return get_set__get(this, 'Month'); + return get(this, 'Month'); } } @@ -988,7 +1118,7 @@ i, mom; for (i = 0; i < 12; i++) { // make the regex if we don't have it already - mom = create_utc__createUTC([2000, i]); + mom = createUTC([2000, i]); shortPieces.push(this.monthsShort(mom, '')); longPieces.push(this.months(mom, '')); mixedPieces.push(this.months(mom, '')); @@ -1013,91 +1143,39 @@ this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); } - // FORMATTING - - addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? '' + y : '+' + y; - }); - - addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; - }); - - addFormatToken(0, ['YYYY', 4], 0, 'year'); - addFormatToken(0, ['YYYYY', 5], 0, 'year'); - addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); - - // ALIASES - - addUnitAlias('year', 'y'); - - // PRIORITIES - - addUnitPriority('year', 1); - - // PARSING - - addRegexToken('Y', matchSigned); - addRegexToken('YY', match1to2, match2); - addRegexToken('YYYY', match1to4, match4); - addRegexToken('YYYYY', match1to6, match6); - addRegexToken('YYYYYY', match1to6, match6); - - addParseToken(['YYYYY', 'YYYYYY'], YEAR); - addParseToken('YYYY', function (input, array) { - array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input); - }); - addParseToken('YY', function (input, array) { - array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input); - }); - addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); - }); - - // HELPERS - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - // HOOKS - - utils_hooks__hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - // MOMENTS - - var getSetYear = makeGetSet('FullYear', true); - - function getIsLeapYear () { - return isLeapYear(this.year()); - } - function createDate (y, m, d, h, M, s, ms) { - //can't just apply() to create a date: - //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply - var date = new Date(y, m, d, h, M, s, ms); - - //the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { - date.setFullYear(y); + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date; + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + date = new Date(y + 400, m, d, h, M, s, ms); + if (isFinite(date.getFullYear())) { + date.setFullYear(y); + } + } else { + date = new Date(y, m, d, h, M, s, ms); } + return date; } function createUTCDate (y) { - var date = new Date(Date.UTC.apply(null, arguments)); - - //the Date.UTC function remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { - date.setUTCFullYear(y); + var date; + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + var args = Array.prototype.slice.call(arguments); + // preserve leap years using a full 400 year cycle, then reset + args[0] = y + 400; + date = new Date(Date.UTC.apply(null, args)); + if (isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + } else { + date = new Date(Date.UTC.apply(null, arguments)); } + return date; } @@ -1111,7 +1189,7 @@ return -fwdlw + fwd - 1; } - //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday function dayOfYearFromWeeks(year, week, weekday, dow, doy) { var localWeekday = (7 + weekday - dow) % 7, weekOffset = firstWeekOffset(year, dow, doy), @@ -1199,7 +1277,7 @@ var defaultLocaleWeek = { dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. + doy : 6 // The week that contains Jan 6th is the first week of the year. }; function localeFirstDayOfWeek () { @@ -1308,24 +1386,31 @@ } // LOCALES + function shiftWeekdays (ws, n) { + return ws.slice(n, 7).concat(ws.slice(0, n)); + } var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); function localeWeekdays (m, format) { - return isArray(this._weekdays) ? this._weekdays[m.day()] : - this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; + var weekdays = isArray(this._weekdays) ? this._weekdays : + this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; + return (m === true) ? shiftWeekdays(weekdays, this._week.dow) + : (m) ? weekdays[m.day()] : weekdays; } var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); function localeWeekdaysShort (m) { - return this._weekdaysShort[m.day()]; + return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) + : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; } var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); function localeWeekdaysMin (m) { - return this._weekdaysMin[m.day()]; + return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) + : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; } - function day_of_week__handleStrictParse(weekdayName, format, strict) { + function handleStrictParse$1(weekdayName, format, strict) { var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); if (!this._weekdaysParse) { this._weekdaysParse = []; @@ -1333,7 +1418,7 @@ this._minWeekdaysParse = []; for (i = 0; i < 7; ++i) { - mom = create_utc__createUTC([2000, 1]).day(i); + mom = createUTC([2000, 1]).day(i); this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); @@ -1393,7 +1478,7 @@ var i, mom, regex; if (this._weekdaysParseExact) { - return day_of_week__handleStrictParse.call(this, weekdayName, format, strict); + return handleStrictParse$1.call(this, weekdayName, format, strict); } if (!this._weekdaysParse) { @@ -1406,11 +1491,11 @@ for (i = 0; i < 7; i++) { // make the regex if we don't have it already - mom = create_utc__createUTC([2000, 1]).day(i); + mom = createUTC([2000, 1]).day(i); if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); - this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); - this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); } if (!this._weekdaysParse[i]) { regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); @@ -1539,7 +1624,7 @@ i, mom, minp, shortp, longp; for (i = 0; i < 7; i++) { // make the regex if we don't have it already - mom = create_utc__createUTC([2000, 1]).day(i); + mom = createUTC([2000, 1]).day(i); minp = this.weekdaysMin(mom, ''); shortp = this.weekdaysShort(mom, ''); longp = this.weekdays(mom, ''); @@ -1629,8 +1714,10 @@ addRegexToken('A', matchMeridiem); addRegexToken('H', match1to2); addRegexToken('h', match1to2); + addRegexToken('k', match1to2); addRegexToken('HH', match1to2, match2); addRegexToken('hh', match1to2, match2); + addRegexToken('kk', match1to2, match2); addRegexToken('hmm', match3to4); addRegexToken('hmmss', match5to6); @@ -1638,6 +1725,10 @@ addRegexToken('Hmmss', match5to6); addParseToken(['H', 'HH'], HOUR); + addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; + }); addParseToken(['a', 'A'], function (input, array, config) { config._isPm = config._locale.isPM(input); config._meridiem = input; @@ -1694,7 +1785,7 @@ // MOMENTS // Setting the hour should keep the time, because the user explicitly - // specified which hour he wants. So trying to maintain the same hour (in + // specified which hour they want. So trying to maintain the same hour (in // a new timezone) makes sense. Adding/subtracting hours does not follow // this rule. var getSetHour = makeGetSet('Hours', true); @@ -1704,7 +1795,7 @@ longDateFormat: defaultLongDateFormat, invalidDate: defaultInvalidDate, ordinal: defaultOrdinal, - ordinalParse: defaultOrdinalParse, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, relativeTime: defaultRelativeTime, months: defaultLocaleMonths, @@ -1721,6 +1812,7 @@ // internal storage for locale config files var locales = {}; + var localeFamilies = {}; var globalLocale; function normalizeLocale(key) { @@ -1751,7 +1843,7 @@ } i++; } - return null; + return globalLocale; } function loadLocale(name) { @@ -1761,11 +1853,10 @@ module && module.exports) { try { oldLocale = globalLocale._abbr; - require('./locale/' + name); - // because defineLocale currently also sets the global locale, we - // want to undo that for lazy loaded locales - locale_locales__getSetGlobalLocale(oldLocale); - } catch (e) { } + var aliasedRequire = require; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} } return locales[name]; } @@ -1773,11 +1864,11 @@ // This function will load locale and then set the global locale. If // no arguments are passed in, it will simply return the current global // locale key. - function locale_locales__getSetGlobalLocale (key, values) { + function getSetGlobalLocale (key, values) { var data; if (key) { if (isUndefined(values)) { - data = locale_locales__getLocale(key); + data = getLocale(key); } else { data = defineLocale(key, values); @@ -1787,6 +1878,12 @@ // moment.duration._locale = moment._locale = data; globalLocale = data; } + else { + if ((typeof console !== 'undefined') && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn('Locale ' + key + ' not found. Did you forget to load it?'); + } + } } return globalLocale._abbr; @@ -1794,7 +1891,7 @@ function defineLocale (name, config) { if (config !== null) { - var parentConfig = baseConfig; + var locale, parentConfig = baseConfig; config.abbr = name; if (locales[name] != null) { deprecateSimple('defineLocaleOverride', @@ -1807,15 +1904,34 @@ if (locales[config.parentLocale] != null) { parentConfig = locales[config.parentLocale]._config; } else { - // treat as if there is no base config - deprecateSimple('parentLocaleUndefined', - 'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/'); + locale = loadLocale(config.parentLocale); + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } } } locales[name] = new Locale(mergeConfigs(parentConfig, config)); + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + // backwards compat for now: also set the locale - locale_locales__getSetGlobalLocale(name); + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + return locales[name]; } else { @@ -1827,10 +1943,11 @@ function updateLocale(name, config) { if (config != null) { - var locale, parentConfig = baseConfig; + var locale, tmpLocale, parentConfig = baseConfig; // MERGE - if (locales[name] != null) { - parentConfig = locales[name]._config; + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; } config = mergeConfigs(parentConfig, config); locale = new Locale(config); @@ -1838,7 +1955,7 @@ locales[name] = locale; // backwards compat for now: also set the locale - locale_locales__getSetGlobalLocale(name); + getSetGlobalLocale(name); } else { // pass null for config to unupdate, useful for tests if (locales[name] != null) { @@ -1853,7 +1970,7 @@ } // returns locale data - function locale_locales__getLocale (key) { + function getLocale (key) { var locale; if (key && key._locale && key._locale._abbr) { @@ -1876,7 +1993,7 @@ return chooseLocale(key); } - function locale_locales__listLocales() { + function listLocales() { return keys(locales); } @@ -1910,10 +2027,160 @@ return m; } + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; + } + + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } + + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function configFromArray (config) { + var i, date, input = [], currentDate, expectedWeekday, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); + + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from beginning of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to beginning of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + } + // iso 8601 regex // 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) - 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)?)?/; - 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)?)?/; + 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)?)?$/; + 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)?)?$/; var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; @@ -2000,6 +2267,101 @@ } } + // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 + 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}))$/; + + function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; + } + + function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; + } + + function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + + function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; + } + + var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 + }; + + function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } + } + + // date and time from ref 2822 format + function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } + } + // date from iso format or fallback function configFromString(config) { var matched = aspNetJsonRegex.exec(config._i); @@ -2012,170 +2374,48 @@ configFromISO(config); if (config._isValid === false) { delete config._isValid; - utils_hooks__hooks.createFromInputFallback(config); + } else { + return; } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); } - utils_hooks__hooks.createFromInputFallback = deprecate( - 'moment construction falls back to js Date. This is ' + - 'discouraged and will be removed in upcoming major ' + - 'release. Please refer to ' + + hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', function (config) { config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); } ); - // Pick the first defined of two or three arguments. - function defaults(a, b, c) { - if (a != null) { - return a; - } - if (b != null) { - return b; - } - return c; - } - - function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(utils_hooks__hooks.now()); - if (config._useUTC) { - return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; - } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function configFromArray (config) { - var i, date, input = [], currentDate, yearToUse; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse)) { - getParsingFlags(config)._overflowDayOfYear = true; - } - - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - - config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - } - - if (config._nextDay) { - config._a[HOUR] = 24; - } - } - - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year); - week = defaults(w.w, 1); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from begining of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to begining of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - } - // constant that refers to the ISO standard - utils_hooks__hooks.ISO_8601 = function () {}; + hooks.ISO_8601 = function () {}; + + // constant that refers to the RFC 2822 form + hooks.RFC_2822 = function () {}; // date from string and format string function configFromStringAndFormat(config) { // TODO: Move this to another part of the creation flow to prevent circular deps - if (config._f === utils_hooks__hooks.ISO_8601) { + if (config._f === hooks.ISO_8601) { configFromISO(config); return; } - + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } config._a = []; getParsingFlags(config).empty = true; @@ -2287,7 +2527,7 @@ tempConfig._f = config._f[i]; configFromStringAndFormat(tempConfig); - if (!valid__isValid(tempConfig)) { + if (!isValid(tempConfig)) { continue; } @@ -2336,10 +2576,10 @@ var input = config._i, format = config._f; - config._locale = config._locale || locale_locales__getLocale(config._l); + config._locale = config._locale || getLocale(config._l); if (input === null || (format === undefined && input === '')) { - return valid__createInvalid({nullInput: true}); + return createInvalid({nullInput: true}); } if (typeof input === 'string') { @@ -2348,17 +2588,17 @@ if (isMoment(input)) { return new Moment(checkOverflow(input)); - } else if (isArray(format)) { - configFromStringAndArray(config); } else if (isDate(input)) { config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); } else if (format) { configFromStringAndFormat(config); } else { configFromInput(config); } - if (!valid__isValid(config)) { + if (!isValid(config)) { config._d = null; } @@ -2367,8 +2607,8 @@ function configFromInput(config) { var input = config._i; - if (input === undefined) { - config._d = new Date(utils_hooks__hooks.now()); + if (isUndefined(input)) { + config._d = new Date(hooks.now()); } else if (isDate(input)) { config._d = new Date(input.valueOf()); } else if (typeof input === 'string') { @@ -2378,20 +2618,20 @@ return parseInt(obj, 10); }); configFromArray(config); - } else if (typeof(input) === 'object') { + } else if (isObject(input)) { configFromObject(config); - } else if (typeof(input) === 'number') { + } else if (isNumber(input)) { // from milliseconds config._d = new Date(input); } else { - utils_hooks__hooks.createFromInputFallback(config); + hooks.createFromInputFallback(config); } } function createLocalOrUTC (input, format, locale, strict, isUTC) { var c = {}; - if (typeof(locale) === 'boolean') { + if (locale === true || locale === false) { strict = locale; locale = undefined; } @@ -2412,18 +2652,18 @@ return createFromConfig(c); } - function local__createLocal (input, format, locale, strict) { + function createLocal (input, format, locale, strict) { return createLocalOrUTC(input, format, locale, strict, false); } var prototypeMin = deprecate( 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () { - var other = local__createLocal.apply(null, arguments); + var other = createLocal.apply(null, arguments); if (this.isValid() && other.isValid()) { return other < this ? this : other; } else { - return valid__createInvalid(); + return createInvalid(); } } ); @@ -2431,11 +2671,11 @@ var prototypeMax = deprecate( 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () { - var other = local__createLocal.apply(null, arguments); + var other = createLocal.apply(null, arguments); if (this.isValid() && other.isValid()) { return other > this ? this : other; } else { - return valid__createInvalid(); + return createInvalid(); } } ); @@ -2451,7 +2691,7 @@ moments = moments[0]; } if (!moments.length) { - return local__createLocal(); + return createLocal(); } res = moments[0]; for (i = 1; i < moments.length; ++i) { @@ -2479,18 +2719,52 @@ return Date.now ? Date.now() : +(new Date()); }; + var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + + function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; + } + + function isValid$1() { + return this._isValid; + } + + function createInvalid$1() { + return createDuration(NaN); + } + function Duration (duration) { var normalizedInput = normalizeObjectUnits(duration), years = normalizedInput.year || 0, quarters = normalizedInput.quarter || 0, months = normalizedInput.month || 0, - weeks = normalizedInput.week || 0, + weeks = normalizedInput.week || normalizedInput.isoWeek || 0, days = normalizedInput.day || 0, hours = normalizedInput.hour || 0, minutes = normalizedInput.minute || 0, seconds = normalizedInput.second || 0, milliseconds = normalizedInput.millisecond || 0; + this._isValid = isDurationValid(normalizedInput); + // representation for dateAddRemove this._milliseconds = +milliseconds + seconds * 1e3 + // 1000 @@ -2500,7 +2774,7 @@ // day when working around DST, we need to store them separately this._days = +days + weeks * 7; - // It is impossible translate months into days without knowing + // It is impossible to translate months into days without knowing // which months you are are talking about, so we have to store // it separately. this._months = +months + @@ -2509,7 +2783,7 @@ this._data = {}; - this._locale = locale_locales__getLocale(); + this._locale = getLocale(); this._bubble(); } @@ -2518,6 +2792,14 @@ return obj instanceof Duration; } + function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } + // FORMATTING function offset (token, separator) { @@ -2552,12 +2834,19 @@ var chunkOffset = /([\+\-]|\d\d)/gi; function offsetFromString(matcher, string) { - var matches = ((string || '').match(matcher) || []); + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + var chunk = matches[matches.length - 1] || []; var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; var minutes = +(parts[1] * 60) + toInt(parts[2]); - return parts[0] === '+' ? minutes : -minutes; + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; } // Return a moment from input, that is local/utc/zone equivalent to model. @@ -2565,13 +2854,13 @@ var res, diff; if (model._isUTC) { res = model.clone(); - diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api. res._d.setTime(res._d.valueOf() + diff); - utils_hooks__hooks.updateOffset(res, false); + hooks.updateOffset(res, false); return res; } else { - return local__createLocal(input).local(); + return createLocal(input).local(); } } @@ -2585,7 +2874,7 @@ // This function will be called whenever a moment is mutated. // It is intended to keep the offset in sync with the timezone. - utils_hooks__hooks.updateOffset = function () {}; + hooks.updateOffset = function () {}; // MOMENTS @@ -2599,7 +2888,7 @@ // a second time. In case it wants us to change the offset again // _changeInProgress == true case, then we have to adjust, because // there is no such time in the given timezone. - function getSetOffset (input, keepLocalTime) { + function getSetOffset (input, keepLocalTime, keepMinutes) { var offset = this._offset || 0, localAdjust; if (!this.isValid()) { @@ -2608,7 +2897,10 @@ if (input != null) { if (typeof input === 'string') { input = offsetFromString(matchShortOffset, input); - } else if (Math.abs(input) < 16) { + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { input = input * 60; } if (!this._isUTC && keepLocalTime) { @@ -2621,10 +2913,10 @@ } if (offset !== input) { if (!keepLocalTime || this._changeInProgress) { - add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false); + addSubtract(this, createDuration(input - offset, 'm'), 1, false); } else if (!this._changeInProgress) { this._changeInProgress = true; - utils_hooks__hooks.updateOffset(this, true); + hooks.updateOffset(this, true); this._changeInProgress = null; } } @@ -2665,10 +2957,16 @@ } function setOffsetToParsedOffset () { - if (this._tzm) { - this.utcOffset(this._tzm); + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); } else if (typeof this._i === 'string') { - this.utcOffset(offsetFromString(matchOffset, this._i)); + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } } return this; } @@ -2677,7 +2975,7 @@ if (!this.isValid()) { return false; } - input = input ? local__createLocal(input).utcOffset() : 0; + input = input ? createLocal(input).utcOffset() : 0; return (this.utcOffset() - input) % 60 === 0; } @@ -2700,7 +2998,7 @@ c = prepareConfig(c); if (c._a) { - var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a); + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0; } else { @@ -2723,14 +3021,14 @@ } // ASP.NET json date format regex - var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/; + var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere // and further modified to allow for strings containing both week and day - 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)?)?$/; + 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)?)?$/; - function create__createDuration (input, key) { + function createDuration (input, key) { var duration = input, // matching against regexp is expensive, do it on demand match = null, @@ -2744,7 +3042,7 @@ d : input._days, M : input._months }; - } else if (typeof input === 'number') { + } else if (isNumber(input)) { duration = {}; if (key) { duration[key] = input; @@ -2755,11 +3053,11 @@ sign = (match[1] === '-') ? -1 : 1; duration = { y : 0, - d : toInt(match[DATE]) * sign, - h : toInt(match[HOUR]) * sign, - m : toInt(match[MINUTE]) * sign, - s : toInt(match[SECOND]) * sign, - ms : toInt(match[MILLISECOND]) * sign + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match }; } else if (!!(match = isoRegex.exec(input))) { sign = (match[1] === '-') ? -1 : 1; @@ -2775,7 +3073,7 @@ } else if (duration == null) {// checks for null or undefined duration = {}; } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to)); + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); duration = {}; duration.ms = diffRes.milliseconds; @@ -2791,7 +3089,8 @@ return ret; } - create__createDuration.fn = Duration.prototype; + createDuration.fn = Duration.prototype; + createDuration.invalid = createInvalid$1; function parseIso (inp, sign) { // We'd normally use ~~inp for this, but unfortunately it also @@ -2803,7 +3102,7 @@ } function positiveMomentsDifference(base, other) { - var res = {milliseconds: 0, months: 0}; + var res = {}; res.months = other.month() - base.month() + (other.year() - base.year()) * 12; @@ -2834,14 +3133,6 @@ return res; } - function absRound (number) { - if (number < 0) { - return Math.round(-1 * number) * -1; - } else { - return Math.round(number); - } - } - // TODO: remove 'name' arg after deprecation is removed function createAdder(direction, name) { return function (val, period) { @@ -2854,13 +3145,13 @@ } val = typeof val === 'string' ? +val : val; - dur = create__createDuration(val, period); - add_subtract__addSubtract(this, dur, direction); + dur = createDuration(val, period); + addSubtract(this, dur, direction); return this; }; } - function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) { + function addSubtract (mom, duration, isAdding, updateOffset) { var milliseconds = duration._milliseconds, days = absRound(duration._days), months = absRound(duration._months); @@ -2872,22 +3163,22 @@ updateOffset = updateOffset == null ? true : updateOffset; + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } if (milliseconds) { mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); } - if (days) { - get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding); - } - if (months) { - setMonth(mom, get_set__get(mom, 'Month') + months * isAdding); - } if (updateOffset) { - utils_hooks__hooks.updateOffset(mom, days || months); + hooks.updateOffset(mom, days || months); } } - var add_subtract__add = createAdder(1, 'add'); - var add_subtract__subtract = createAdder(-1, 'subtract'); + var add = createAdder(1, 'add'); + var subtract = createAdder(-1, 'subtract'); function getCalendarFormat(myMoment, now) { var diff = myMoment.diff(now, 'days', true); @@ -2899,16 +3190,16 @@ diff < 7 ? 'nextWeek' : 'sameElse'; } - function moment_calendar__calendar (time, formats) { + function calendar$1 (time, formats) { // We want to compare the start of today, vs this. // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || local__createLocal(), + var now = time || createLocal(), sod = cloneWithOffset(now, this).startOf('day'), - format = utils_hooks__hooks.calendarFormat(this, sod) || 'sameElse'; + format = hooks.calendarFormat(this, sod) || 'sameElse'; var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); - return this.format(output || this.localeData().calendar(format, this, local__createLocal(now))); + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); } function clone () { @@ -2916,11 +3207,11 @@ } function isAfter (input, units) { - var localInput = isMoment(input) ? input : local__createLocal(input); + var localInput = isMoment(input) ? input : createLocal(input); if (!(this.isValid() && localInput.isValid())) { return false; } - units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + units = normalizeUnits(units) || 'millisecond'; if (units === 'millisecond') { return this.valueOf() > localInput.valueOf(); } else { @@ -2929,11 +3220,11 @@ } function isBefore (input, units) { - var localInput = isMoment(input) ? input : local__createLocal(input); + var localInput = isMoment(input) ? input : createLocal(input); if (!(this.isValid() && localInput.isValid())) { return false; } - units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + units = normalizeUnits(units) || 'millisecond'; if (units === 'millisecond') { return this.valueOf() < localInput.valueOf(); } else { @@ -2942,18 +3233,23 @@ } function isBetween (from, to, units, inclusivity) { + var localFrom = isMoment(from) ? from : createLocal(from), + localTo = isMoment(to) ? to : createLocal(to); + if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { + return false; + } inclusivity = inclusivity || '()'; - return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && - (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); + return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && + (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); } function isSame (input, units) { - var localInput = isMoment(input) ? input : local__createLocal(input), + var localInput = isMoment(input) ? input : createLocal(input), inputMs; if (!(this.isValid() && localInput.isValid())) { return false; } - units = normalizeUnits(units || 'millisecond'); + units = normalizeUnits(units) || 'millisecond'; if (units === 'millisecond') { return this.valueOf() === localInput.valueOf(); } else { @@ -2963,17 +3259,17 @@ } function isSameOrAfter (input, units) { - return this.isSame(input, units) || this.isAfter(input,units); + return this.isSame(input, units) || this.isAfter(input, units); } function isSameOrBefore (input, units) { - return this.isSame(input, units) || this.isBefore(input,units); + return this.isSame(input, units) || this.isBefore(input, units); } function diff (input, units, asFloat) { var that, zoneDelta, - delta, output; + output; if (!this.isValid()) { return NaN; @@ -2989,22 +3285,18 @@ units = normalizeUnits(units); - if (units === 'year' || units === 'month' || units === 'quarter') { - output = monthDiff(this, that); - if (units === 'quarter') { - output = output / 3; - } else if (units === 'year') { - output = output / 12; - } - } else { - delta = this - that; - output = units === 'second' ? delta / 1e3 : // 1000 - units === 'minute' ? delta / 6e4 : // 1000 * 60 - units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60 - units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst - units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst - delta; + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; } + return asFloat ? output : absFloor(output); } @@ -3029,30 +3321,60 @@ return -(wholeMonthDiff + adjust) || 0; } - utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; - utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; function toString () { return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); } - function moment_format__toISOString () { - var m = this.clone().utc(); - if (0 < m.year() && m.year() <= 9999) { - if (isFunction(Date.prototype.toISOString)) { - // native implementation is ~50x faster, use it when we can + function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { return this.toDate().toISOString(); } else { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); } - } else { - return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + + /** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ + function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); } function format (inputString) { if (!inputString) { - inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat; + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; } var output = formatMoment(this, inputString); return this.localeData().postformat(output); @@ -3061,29 +3383,29 @@ function from (time, withoutSuffix) { if (this.isValid() && ((isMoment(time) && time.isValid()) || - local__createLocal(time).isValid())) { - return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); } else { return this.localeData().invalidDate(); } } function fromNow (withoutSuffix) { - return this.from(local__createLocal(), withoutSuffix); + return this.from(createLocal(), withoutSuffix); } function to (time, withoutSuffix) { if (this.isValid() && ((isMoment(time) && time.isValid()) || - local__createLocal(time).isValid())) { - return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); } else { return this.localeData().invalidDate(); } } function toNow (withoutSuffix) { - return this.to(local__createLocal(), withoutSuffix); + return this.to(createLocal(), withoutSuffix); } // If passed a locale key, it will set the locale for this @@ -3095,7 +3417,7 @@ if (key === undefined) { return this._locale._abbr; } else { - newLocaleData = locale_locales__getLocale(key); + newLocaleData = getLocale(key); if (newLocaleData != null) { this._locale = newLocaleData; } @@ -3118,65 +3440,133 @@ return this._locale; } + var MS_PER_SECOND = 1000; + var MS_PER_MINUTE = 60 * MS_PER_SECOND; + var MS_PER_HOUR = 60 * MS_PER_MINUTE; + var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; + + // actual modulo - handles negative numbers (for dates before 1970): + function mod$1(dividend, divisor) { + return (dividend % divisor + divisor) % divisor; + } + + function localStartOfDate(y, m, d) { + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return new Date(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return new Date(y, m, d).valueOf(); + } + } + + function utcStartOfDate(y, m, d) { + // Date.UTC remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return Date.UTC(y, m, d); + } + } + function startOf (units) { + var time; units = normalizeUnits(units); - // the following switch intentionally omits break keywords - // to utilize falling through the cases. + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + + var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + switch (units) { case 'year': - this.month(0); - /* falls through */ + time = startOfDate(this.year(), 0, 1); + break; case 'quarter': + time = startOfDate(this.year(), this.month() - this.month() % 3, 1); + break; case 'month': - this.date(1); - /* falls through */ + time = startOfDate(this.year(), this.month(), 1); + break; case 'week': + time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); + break; case 'isoWeek': + time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); + break; case 'day': case 'date': - this.hours(0); - /* falls through */ + time = startOfDate(this.year(), this.month(), this.date()); + break; case 'hour': - this.minutes(0); - /* falls through */ + time = this._d.valueOf(); + time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); + break; case 'minute': - this.seconds(0); - /* falls through */ + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_MINUTE); + break; case 'second': - this.milliseconds(0); - } - - // weeks are a special case - if (units === 'week') { - this.weekday(0); - } - if (units === 'isoWeek') { - this.isoWeekday(1); - } - - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_SECOND); + break; } + this._d.setTime(time); + hooks.updateOffset(this, true); return this; } function endOf (units) { + var time; units = normalizeUnits(units); - if (units === undefined || units === 'millisecond') { + if (units === undefined || units === 'millisecond' || !this.isValid()) { return this; } - // 'date' is an alias for 'day', so it should be considered as such. - if (units === 'date') { - units = 'day'; + var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + + switch (units) { + case 'year': + time = startOfDate(this.year() + 1, 0, 1) - 1; + break; + case 'quarter': + time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; + break; + case 'month': + time = startOfDate(this.year(), this.month() + 1, 1) - 1; + break; + case 'week': + time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; + break; + case 'isoWeek': + time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; + break; + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; + break; + case 'hour': + time = this._d.valueOf(); + time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; + break; + case 'minute': + time = this._d.valueOf(); + time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; + break; + case 'second': + time = this._d.valueOf(); + time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; + break; } - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + this._d.setTime(time); + hooks.updateOffset(this, true); + return this; } - function to_type__valueOf () { + function valueOf () { return this._d.valueOf() - ((this._offset || 0) * 60000); } @@ -3211,8 +3601,8 @@ return this.isValid() ? this.toISOString() : null; } - function moment_valid__isValid () { - return valid__isValid(this); + function isValid$2 () { + return isValid(this); } function parsingFlags () { @@ -3279,7 +3669,7 @@ }); addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { - week[token] = utils_hooks__hooks.parseTwoDigitYear(input); + week[token] = hooks.parseTwoDigitYear(input); }); // MOMENTS @@ -3363,7 +3753,7 @@ addUnitAlias('date', 'D'); - // PRIOROITY + // PRIORITY addUnitPriority('date', 9); // PARSING @@ -3371,12 +3761,15 @@ addRegexToken('D', match1to2); addRegexToken('DD', match1to2, match2); addRegexToken('Do', function (isStrict, locale) { - return isStrict ? locale._ordinalParse : locale._ordinalParseLenient; + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; }); addParseToken(['D', 'DD'], DATE); addParseToken('Do', function (input, array) { - array[DATE] = toInt(input.match(match1to2)[0], 10); + array[DATE] = toInt(input.match(match1to2)[0]); }); // MOMENTS @@ -3531,169 +3924,137 @@ return this._isUTC ? 'Coordinated Universal Time' : ''; } - var momentPrototype__proto = Moment.prototype; + var proto = Moment.prototype; - momentPrototype__proto.add = add_subtract__add; - momentPrototype__proto.calendar = moment_calendar__calendar; - momentPrototype__proto.clone = clone; - momentPrototype__proto.diff = diff; - momentPrototype__proto.endOf = endOf; - momentPrototype__proto.format = format; - momentPrototype__proto.from = from; - momentPrototype__proto.fromNow = fromNow; - momentPrototype__proto.to = to; - momentPrototype__proto.toNow = toNow; - momentPrototype__proto.get = stringGet; - momentPrototype__proto.invalidAt = invalidAt; - momentPrototype__proto.isAfter = isAfter; - momentPrototype__proto.isBefore = isBefore; - momentPrototype__proto.isBetween = isBetween; - momentPrototype__proto.isSame = isSame; - momentPrototype__proto.isSameOrAfter = isSameOrAfter; - momentPrototype__proto.isSameOrBefore = isSameOrBefore; - momentPrototype__proto.isValid = moment_valid__isValid; - momentPrototype__proto.lang = lang; - momentPrototype__proto.locale = locale; - momentPrototype__proto.localeData = localeData; - momentPrototype__proto.max = prototypeMax; - momentPrototype__proto.min = prototypeMin; - momentPrototype__proto.parsingFlags = parsingFlags; - momentPrototype__proto.set = stringSet; - momentPrototype__proto.startOf = startOf; - momentPrototype__proto.subtract = add_subtract__subtract; - momentPrototype__proto.toArray = toArray; - momentPrototype__proto.toObject = toObject; - momentPrototype__proto.toDate = toDate; - momentPrototype__proto.toISOString = moment_format__toISOString; - momentPrototype__proto.toJSON = toJSON; - momentPrototype__proto.toString = toString; - momentPrototype__proto.unix = unix; - momentPrototype__proto.valueOf = to_type__valueOf; - momentPrototype__proto.creationData = creationData; + proto.add = add; + proto.calendar = calendar$1; + proto.clone = clone; + proto.diff = diff; + proto.endOf = endOf; + proto.format = format; + proto.from = from; + proto.fromNow = fromNow; + proto.to = to; + proto.toNow = toNow; + proto.get = stringGet; + proto.invalidAt = invalidAt; + proto.isAfter = isAfter; + proto.isBefore = isBefore; + proto.isBetween = isBetween; + proto.isSame = isSame; + proto.isSameOrAfter = isSameOrAfter; + proto.isSameOrBefore = isSameOrBefore; + proto.isValid = isValid$2; + proto.lang = lang; + proto.locale = locale; + proto.localeData = localeData; + proto.max = prototypeMax; + proto.min = prototypeMin; + proto.parsingFlags = parsingFlags; + proto.set = stringSet; + proto.startOf = startOf; + proto.subtract = subtract; + proto.toArray = toArray; + proto.toObject = toObject; + proto.toDate = toDate; + proto.toISOString = toISOString; + proto.inspect = inspect; + proto.toJSON = toJSON; + proto.toString = toString; + proto.unix = unix; + proto.valueOf = valueOf; + proto.creationData = creationData; + proto.year = getSetYear; + proto.isLeapYear = getIsLeapYear; + proto.weekYear = getSetWeekYear; + proto.isoWeekYear = getSetISOWeekYear; + proto.quarter = proto.quarters = getSetQuarter; + proto.month = getSetMonth; + proto.daysInMonth = getDaysInMonth; + proto.week = proto.weeks = getSetWeek; + proto.isoWeek = proto.isoWeeks = getSetISOWeek; + proto.weeksInYear = getWeeksInYear; + proto.isoWeeksInYear = getISOWeeksInYear; + proto.date = getSetDayOfMonth; + proto.day = proto.days = getSetDayOfWeek; + proto.weekday = getSetLocaleDayOfWeek; + proto.isoWeekday = getSetISODayOfWeek; + proto.dayOfYear = getSetDayOfYear; + proto.hour = proto.hours = getSetHour; + proto.minute = proto.minutes = getSetMinute; + proto.second = proto.seconds = getSetSecond; + proto.millisecond = proto.milliseconds = getSetMillisecond; + proto.utcOffset = getSetOffset; + proto.utc = setOffsetToUTC; + proto.local = setOffsetToLocal; + proto.parseZone = setOffsetToParsedOffset; + proto.hasAlignedHourOffset = hasAlignedHourOffset; + proto.isDST = isDaylightSavingTime; + proto.isLocal = isLocal; + proto.isUtcOffset = isUtcOffset; + proto.isUtc = isUtc; + proto.isUTC = isUtc; + proto.zoneAbbr = getZoneAbbr; + proto.zoneName = getZoneName; + proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); + proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); - // Year - momentPrototype__proto.year = getSetYear; - momentPrototype__proto.isLeapYear = getIsLeapYear; - - // Week Year - momentPrototype__proto.weekYear = getSetWeekYear; - momentPrototype__proto.isoWeekYear = getSetISOWeekYear; - - // Quarter - momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter; - - // Month - momentPrototype__proto.month = getSetMonth; - momentPrototype__proto.daysInMonth = getDaysInMonth; - - // Week - momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek; - momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek; - momentPrototype__proto.weeksInYear = getWeeksInYear; - momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear; - - // Day - momentPrototype__proto.date = getSetDayOfMonth; - momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek; - momentPrototype__proto.weekday = getSetLocaleDayOfWeek; - momentPrototype__proto.isoWeekday = getSetISODayOfWeek; - momentPrototype__proto.dayOfYear = getSetDayOfYear; - - // Hour - momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour; - - // Minute - momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute; - - // Second - momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond; - - // Millisecond - momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond; - - // Offset - momentPrototype__proto.utcOffset = getSetOffset; - momentPrototype__proto.utc = setOffsetToUTC; - momentPrototype__proto.local = setOffsetToLocal; - momentPrototype__proto.parseZone = setOffsetToParsedOffset; - momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset; - momentPrototype__proto.isDST = isDaylightSavingTime; - momentPrototype__proto.isLocal = isLocal; - momentPrototype__proto.isUtcOffset = isUtcOffset; - momentPrototype__proto.isUtc = isUtc; - momentPrototype__proto.isUTC = isUtc; - - // Timezone - momentPrototype__proto.zoneAbbr = getZoneAbbr; - momentPrototype__proto.zoneName = getZoneName; - - // Deprecations - momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); - momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); - momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); - momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); - momentPrototype__proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); - - var momentPrototype = momentPrototype__proto; - - function moment__createUnix (input) { - return local__createLocal(input * 1000); + function createUnix (input) { + return createLocal(input * 1000); } - function moment__createInZone () { - return local__createLocal.apply(null, arguments).parseZone(); + function createInZone () { + return createLocal.apply(null, arguments).parseZone(); } function preParsePostFormat (string) { return string; } - var prototype__proto = Locale.prototype; + var proto$1 = Locale.prototype; - prototype__proto.calendar = locale_calendar__calendar; - prototype__proto.longDateFormat = longDateFormat; - prototype__proto.invalidDate = invalidDate; - prototype__proto.ordinal = ordinal; - prototype__proto.preparse = preParsePostFormat; - prototype__proto.postformat = preParsePostFormat; - prototype__proto.relativeTime = relative__relativeTime; - prototype__proto.pastFuture = pastFuture; - prototype__proto.set = locale_set__set; + proto$1.calendar = calendar; + proto$1.longDateFormat = longDateFormat; + proto$1.invalidDate = invalidDate; + proto$1.ordinal = ordinal; + proto$1.preparse = preParsePostFormat; + proto$1.postformat = preParsePostFormat; + proto$1.relativeTime = relativeTime; + proto$1.pastFuture = pastFuture; + proto$1.set = set; - // Month - prototype__proto.months = localeMonths; - prototype__proto.monthsShort = localeMonthsShort; - prototype__proto.monthsParse = localeMonthsParse; - prototype__proto.monthsRegex = monthsRegex; - prototype__proto.monthsShortRegex = monthsShortRegex; + proto$1.months = localeMonths; + proto$1.monthsShort = localeMonthsShort; + proto$1.monthsParse = localeMonthsParse; + proto$1.monthsRegex = monthsRegex; + proto$1.monthsShortRegex = monthsShortRegex; + proto$1.week = localeWeek; + proto$1.firstDayOfYear = localeFirstDayOfYear; + proto$1.firstDayOfWeek = localeFirstDayOfWeek; - // Week - prototype__proto.week = localeWeek; - prototype__proto.firstDayOfYear = localeFirstDayOfYear; - prototype__proto.firstDayOfWeek = localeFirstDayOfWeek; + proto$1.weekdays = localeWeekdays; + proto$1.weekdaysMin = localeWeekdaysMin; + proto$1.weekdaysShort = localeWeekdaysShort; + proto$1.weekdaysParse = localeWeekdaysParse; - // Day of Week - prototype__proto.weekdays = localeWeekdays; - prototype__proto.weekdaysMin = localeWeekdaysMin; - prototype__proto.weekdaysShort = localeWeekdaysShort; - prototype__proto.weekdaysParse = localeWeekdaysParse; + proto$1.weekdaysRegex = weekdaysRegex; + proto$1.weekdaysShortRegex = weekdaysShortRegex; + proto$1.weekdaysMinRegex = weekdaysMinRegex; - prototype__proto.weekdaysRegex = weekdaysRegex; - prototype__proto.weekdaysShortRegex = weekdaysShortRegex; - prototype__proto.weekdaysMinRegex = weekdaysMinRegex; + proto$1.isPM = localeIsPM; + proto$1.meridiem = localeMeridiem; - // Hours - prototype__proto.isPM = localeIsPM; - prototype__proto.meridiem = localeMeridiem; - - function lists__get (format, index, field, setter) { - var locale = locale_locales__getLocale(); - var utc = create_utc__createUTC().set(setter, index); + function get$1 (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); return locale[field](utc, format); } function listMonthsImpl (format, index, field) { - if (typeof format === 'number') { + if (isNumber(format)) { index = format; format = undefined; } @@ -3701,13 +4062,13 @@ format = format || ''; if (index != null) { - return lists__get(format, index, field, 'month'); + return get$1(format, index, field, 'month'); } var i; var out = []; for (i = 0; i < 12; i++) { - out[i] = lists__get(format, i, field, 'month'); + out[i] = get$1(format, i, field, 'month'); } return out; } @@ -3722,7 +4083,7 @@ // (true, fmt) function listWeekdaysImpl (localeSorted, format, index, field) { if (typeof localeSorted === 'boolean') { - if (typeof format === 'number') { + if (isNumber(format)) { index = format; format = undefined; } @@ -3733,7 +4094,7 @@ index = format; localeSorted = false; - if (typeof format === 'number') { + if (isNumber(format)) { index = format; format = undefined; } @@ -3741,43 +4102,43 @@ format = format || ''; } - var locale = locale_locales__getLocale(), + var locale = getLocale(), shift = localeSorted ? locale._week.dow : 0; if (index != null) { - return lists__get(format, (index + shift) % 7, field, 'day'); + return get$1(format, (index + shift) % 7, field, 'day'); } var i; var out = []; for (i = 0; i < 7; i++) { - out[i] = lists__get(format, (i + shift) % 7, field, 'day'); + out[i] = get$1(format, (i + shift) % 7, field, 'day'); } return out; } - function lists__listMonths (format, index) { + function listMonths (format, index) { return listMonthsImpl(format, index, 'months'); } - function lists__listMonthsShort (format, index) { + function listMonthsShort (format, index) { return listMonthsImpl(format, index, 'monthsShort'); } - function lists__listWeekdays (localeSorted, format, index) { + function listWeekdays (localeSorted, format, index) { return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); } - function lists__listWeekdaysShort (localeSorted, format, index) { + function listWeekdaysShort (localeSorted, format, index) { return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); } - function lists__listWeekdaysMin (localeSorted, format, index) { + function listWeekdaysMin (localeSorted, format, index) { return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); } - locale_locales__getSetGlobalLocale('en', { - ordinalParse: /\d{1,2}(th|st|nd|rd)/, + getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -3789,12 +4150,13 @@ }); // Side effect imports - utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale); - utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale); + + hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); + hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); var mathAbs = Math.abs; - function duration_abs__abs () { + function abs () { var data = this._data; this._milliseconds = mathAbs(this._milliseconds); @@ -3811,8 +4173,8 @@ return this; } - function duration_add_subtract__addSubtract (duration, input, value, direction) { - var other = create__createDuration(input, value); + function addSubtract$1 (duration, input, value, direction) { + var other = createDuration(input, value); duration._milliseconds += direction * other._milliseconds; duration._days += direction * other._days; @@ -3822,13 +4184,13 @@ } // supports only 2.0-style add(1, 's') or add(duration) - function duration_add_subtract__add (input, value) { - return duration_add_subtract__addSubtract(this, input, value, 1); + function add$1 (input, value) { + return addSubtract$1(this, input, value, 1); } // supports only 2.0-style subtract(1, 's') or subtract(duration) - function duration_add_subtract__subtract (input, value) { - return duration_add_subtract__addSubtract(this, input, value, -1); + function subtract$1 (input, value) { + return addSubtract$1(this, input, value, -1); } function absCeil (number) { @@ -3898,16 +4260,23 @@ } function as (units) { + if (!this.isValid()) { + return NaN; + } var days; var months; var milliseconds = this._milliseconds; units = normalizeUnits(units); - if (units === 'month' || units === 'year') { - days = this._days + milliseconds / 864e5; + if (units === 'month' || units === 'quarter' || units === 'year') { + days = this._days + milliseconds / 864e5; months = this._months + daysToMonths(days); - return units === 'month' ? months : months / 12; + switch (units) { + case 'month': return months; + case 'quarter': return months / 3; + case 'year': return months / 12; + } } else { // handle milliseconds separately because of floating point math errors (issue #1867) days = this._days + Math.round(monthsToDays(this._months)); @@ -3925,7 +4294,10 @@ } // TODO: Use this.as('ms')? - function duration_as__valueOf () { + function valueOf$1 () { + if (!this.isValid()) { + return NaN; + } return ( this._milliseconds + this._days * 864e5 + @@ -3947,16 +4319,21 @@ var asDays = makeAs('d'); var asWeeks = makeAs('w'); var asMonths = makeAs('M'); + var asQuarters = makeAs('Q'); var asYears = makeAs('y'); - function duration_get__get (units) { + function clone$1 () { + return createDuration(this); + } + + function get$2 (units) { units = normalizeUnits(units); - return this[units + 's'](); + return this.isValid() ? this[units + 's']() : NaN; } function makeGetter(name) { return function () { - return this._data[name]; + return this.isValid() ? this._data[name] : NaN; }; } @@ -3974,11 +4351,12 @@ var round = Math.round; var thresholds = { - s: 45, // seconds to minute - m: 45, // minutes to hour - h: 22, // hours to day - d: 26, // days to month - M: 11 // months to year + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize @@ -3986,8 +4364,8 @@ return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } - function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) { - var duration = create__createDuration(posNegDuration).abs(); + function relativeTime$1 (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); var seconds = round(duration.as('s')); var minutes = round(duration.as('m')); var hours = round(duration.as('h')); @@ -3995,16 +4373,17 @@ var months = round(duration.as('M')); var years = round(duration.as('y')); - var a = seconds < thresholds.s && ['s', seconds] || - minutes <= 1 && ['m'] || - minutes < thresholds.m && ['mm', minutes] || - hours <= 1 && ['h'] || - hours < thresholds.h && ['hh', hours] || - days <= 1 && ['d'] || - days < thresholds.d && ['dd', days] || - months <= 1 && ['M'] || - months < thresholds.M && ['MM', months] || - years <= 1 && ['y'] || ['yy', years]; + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; a[2] = withoutSuffix; a[3] = +posNegDuration > 0; @@ -4013,7 +4392,7 @@ } // This function allows you to set the rounding function for relative time strings - function duration_humanize__getSetRelativeTimeRounding (roundingFunction) { + function getSetRelativeTimeRounding (roundingFunction) { if (roundingFunction === undefined) { return round; } @@ -4025,7 +4404,7 @@ } // This function allows you to set a threshold for relative time strings - function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) { + function getSetRelativeTimeThreshold (threshold, limit) { if (thresholds[threshold] === undefined) { return false; } @@ -4033,12 +4412,19 @@ return thresholds[threshold]; } thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } return true; } function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + var locale = this.localeData(); - var output = duration_humanize__relativeTime(this, !withSuffix, locale); + var output = relativeTime$1(this, !withSuffix, locale); if (withSuffix) { output = locale.pastFuture(+this, output); @@ -4047,9 +4433,13 @@ return locale.postformat(output); } - var iso_string__abs = Math.abs; + var abs$1 = Math.abs; - function iso_string__toISOString() { + function sign(x) { + return ((x > 0) - (x < 0)) || +x; + } + + function toISOString$1() { // for ISO strings we do not use the normal bubbling rules: // * milliseconds bubble up until they become hours // * days do not bubble at all @@ -4057,9 +4447,13 @@ // This is because there is no context-free conversion between hours and days // (think of clock changes) // and also not between days and months (28-31 days per month) - var seconds = iso_string__abs(this._milliseconds) / 1000; - var days = iso_string__abs(this._days); - var months = iso_string__abs(this._months); + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour @@ -4079,7 +4473,7 @@ var D = days; var h = hours; var m = minutes; - var s = seconds; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; var total = this.asSeconds(); if (!total) { @@ -4088,52 +4482,58 @@ return 'P0D'; } - return (total < 0 ? '-' : '') + - 'P' + - (Y ? Y + 'Y' : '') + - (M ? M + 'M' : '') + - (D ? D + 'D' : '') + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + ((h || m || s) ? 'T' : '') + - (h ? h + 'H' : '') + - (m ? m + 'M' : '') + - (s ? s + 'S' : ''); + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); } - var duration_prototype__proto = Duration.prototype; + var proto$2 = Duration.prototype; - duration_prototype__proto.abs = duration_abs__abs; - duration_prototype__proto.add = duration_add_subtract__add; - duration_prototype__proto.subtract = duration_add_subtract__subtract; - duration_prototype__proto.as = as; - duration_prototype__proto.asMilliseconds = asMilliseconds; - duration_prototype__proto.asSeconds = asSeconds; - duration_prototype__proto.asMinutes = asMinutes; - duration_prototype__proto.asHours = asHours; - duration_prototype__proto.asDays = asDays; - duration_prototype__proto.asWeeks = asWeeks; - duration_prototype__proto.asMonths = asMonths; - duration_prototype__proto.asYears = asYears; - duration_prototype__proto.valueOf = duration_as__valueOf; - duration_prototype__proto._bubble = bubble; - duration_prototype__proto.get = duration_get__get; - duration_prototype__proto.milliseconds = milliseconds; - duration_prototype__proto.seconds = seconds; - duration_prototype__proto.minutes = minutes; - duration_prototype__proto.hours = hours; - duration_prototype__proto.days = days; - duration_prototype__proto.weeks = weeks; - duration_prototype__proto.months = months; - duration_prototype__proto.years = years; - duration_prototype__proto.humanize = humanize; - duration_prototype__proto.toISOString = iso_string__toISOString; - duration_prototype__proto.toString = iso_string__toISOString; - duration_prototype__proto.toJSON = iso_string__toISOString; - duration_prototype__proto.locale = locale; - duration_prototype__proto.localeData = localeData; + proto$2.isValid = isValid$1; + proto$2.abs = abs; + proto$2.add = add$1; + proto$2.subtract = subtract$1; + proto$2.as = as; + proto$2.asMilliseconds = asMilliseconds; + proto$2.asSeconds = asSeconds; + proto$2.asMinutes = asMinutes; + proto$2.asHours = asHours; + proto$2.asDays = asDays; + proto$2.asWeeks = asWeeks; + proto$2.asMonths = asMonths; + proto$2.asQuarters = asQuarters; + proto$2.asYears = asYears; + proto$2.valueOf = valueOf$1; + proto$2._bubble = bubble; + proto$2.clone = clone$1; + proto$2.get = get$2; + proto$2.milliseconds = milliseconds; + proto$2.seconds = seconds; + proto$2.minutes = minutes; + proto$2.hours = hours; + proto$2.days = days; + proto$2.weeks = weeks; + proto$2.months = months; + proto$2.years = years; + proto$2.humanize = humanize; + proto$2.toISOString = toISOString$1; + proto$2.toString = toISOString$1; + proto$2.toJSON = toISOString$1; + proto$2.locale = locale; + proto$2.localeData = localeData; - // Deprecations - duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString); - duration_prototype__proto.lang = lang; + proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); + proto$2.lang = lang; // Side effect imports @@ -4156,40 +4556,51 @@ // Side effect imports - utils_hooks__hooks.version = '2.14.1'; + hooks.version = '2.24.0'; - setHookCallback(local__createLocal); + setHookCallback(createLocal); - utils_hooks__hooks.fn = momentPrototype; - utils_hooks__hooks.min = min; - utils_hooks__hooks.max = max; - utils_hooks__hooks.now = now; - utils_hooks__hooks.utc = create_utc__createUTC; - utils_hooks__hooks.unix = moment__createUnix; - utils_hooks__hooks.months = lists__listMonths; - utils_hooks__hooks.isDate = isDate; - utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale; - utils_hooks__hooks.invalid = valid__createInvalid; - utils_hooks__hooks.duration = create__createDuration; - utils_hooks__hooks.isMoment = isMoment; - utils_hooks__hooks.weekdays = lists__listWeekdays; - utils_hooks__hooks.parseZone = moment__createInZone; - utils_hooks__hooks.localeData = locale_locales__getLocale; - utils_hooks__hooks.isDuration = isDuration; - utils_hooks__hooks.monthsShort = lists__listMonthsShort; - utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin; - utils_hooks__hooks.defineLocale = defineLocale; - utils_hooks__hooks.updateLocale = updateLocale; - utils_hooks__hooks.locales = locale_locales__listLocales; - utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort; - utils_hooks__hooks.normalizeUnits = normalizeUnits; - utils_hooks__hooks.relativeTimeRounding = duration_humanize__getSetRelativeTimeRounding; - utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold; - utils_hooks__hooks.calendarFormat = getCalendarFormat; - utils_hooks__hooks.prototype = momentPrototype; + hooks.fn = proto; + hooks.min = min; + hooks.max = max; + hooks.now = now; + hooks.utc = createUTC; + hooks.unix = createUnix; + hooks.months = listMonths; + hooks.isDate = isDate; + hooks.locale = getSetGlobalLocale; + hooks.invalid = createInvalid; + hooks.duration = createDuration; + hooks.isMoment = isMoment; + hooks.weekdays = listWeekdays; + hooks.parseZone = createInZone; + hooks.localeData = getLocale; + hooks.isDuration = isDuration; + hooks.monthsShort = listMonthsShort; + hooks.weekdaysMin = listWeekdaysMin; + hooks.defineLocale = defineLocale; + hooks.updateLocale = updateLocale; + hooks.locales = listLocales; + hooks.weekdaysShort = listWeekdaysShort; + hooks.normalizeUnits = normalizeUnits; + hooks.relativeTimeRounding = getSetRelativeTimeRounding; + hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; + hooks.calendarFormat = getCalendarFormat; + hooks.prototype = proto; - var _moment = utils_hooks__hooks; + // currently HTML5 input type only supports 24-hour formats + hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'GGGG-[W]WW', // + MONTH: 'YYYY-MM' // + }; - return _moment; + return hooks; -})); +}))); \ No newline at end of file