diff --git a/dist/habitrpg-shared.js b/dist/habitrpg-shared.js index 164b2b7223..e4e1e33f0d 100644 --- a/dist/habitrpg-shared.js +++ b/dist/habitrpg-shared.js @@ -6853,23 +6853,20 @@ process.chdir = function (dir) { }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],4:[function(require,module,exports){ -(function (global){ //! moment.js -//! version : 2.8.1 +//! version : 2.4.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com (function (undefined) { + /************************************ Constants ************************************/ var moment, - VERSION = '2.8.1', - // the global-scope this is NOT the global object in Node.js - globalScope = typeof global !== 'undefined' ? global : this, - oldGlobalMoment, + VERSION = "2.4.0", round = Math.round, i, @@ -6881,11 +6878,8 @@ process.chdir = function (dir) { SECOND = 5, MILLISECOND = 6, - // internal storage for locale config files - locales = {}, - - // extra moment internal properties (plugins register props here) - momentProperties = [], + // internal storage for language config files + languages = {}, // check for nodeJS hasModule = (typeof module !== 'undefined' && module.exports), @@ -6899,46 +6893,37 @@ process.chdir = function (dir) { isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, // parsing token regexes parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 - parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 - parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 + parseTokenThreeDigits = /\d{3}/, // 000 - 999 + parseTokenFourDigits = /\d{1,4}/, // 0 - 9999 + parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 parseTokenDigits = /\d+/, // nonzero number of digits parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. - parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z - parseTokenT = /T/i, // T (ISO separator) + parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z + parseTokenT = /T/i, // T (ISO seperator) parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 - parseTokenOrdinal = /\d{1,2}/, - //strict parsing regexes - parseTokenOneDigit = /\d/, // 0 - 9 - parseTokenTwoDigits = /\d\d/, // 00 - 99 - parseTokenThreeDigits = /\d{3}/, // 000 - 999 - parseTokenFourDigits = /\d{4}/, // 0000 - 9999 - parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 - parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf - - // 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) - isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + // preliminary iso 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) + isoRegex = /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d:?\d\d|Z)?)?$/, isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], - ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], - ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], - ['GGGG-[W]WW', /\d{4}-W\d{2}/], - ['YYYY-DDD', /\d{4}-\d{3}/] + 'YYYY-MM-DD', + 'GGGG-[W]WW', + 'GGGG-[W]WW-E', + 'YYYY-DDD' ], // iso time formats and regexes isoTimes = [ - ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], ['HH:mm', /(T| )\d\d:\d\d/], ['HH', /(T| )\d\d/] @@ -6969,7 +6954,6 @@ process.chdir = function (dir) { w : 'week', W : 'isoWeek', M : 'month', - Q : 'quarter', y : 'year', DDD : 'dayOfYear', e : 'weekday', @@ -6989,15 +6973,6 @@ process.chdir = function (dir) { // format function strings formatFunctions = {}, - // default relative time thresholds - relativeTimeThresholds = { - 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 - }, - // tokens to ordinalize and pad ordinalizeTokens = 'DDD w W M D d'.split(' '), paddedTokens = 'M D H h m s w W'.split(' '), @@ -7007,10 +6982,10 @@ process.chdir = function (dir) { return this.month() + 1; }, MMM : function (format) { - return this.localeData().monthsShort(this, format); + return this.lang().monthsShort(this, format); }, MMMM : function (format) { - return this.localeData().months(this, format); + return this.lang().months(this, format); }, D : function () { return this.date(); @@ -7022,13 +6997,13 @@ process.chdir = function (dir) { return this.day(); }, dd : function (format) { - return this.localeData().weekdaysMin(this, format); + return this.lang().weekdaysMin(this, format); }, ddd : function (format) { - return this.localeData().weekdaysShort(this, format); + return this.lang().weekdaysShort(this, format); }, dddd : function (format) { - return this.localeData().weekdays(this, format); + return this.lang().weekdays(this, format); }, w : function () { return this.week(); @@ -7045,15 +7020,11 @@ process.chdir = function (dir) { YYYYY : function () { return leftZeroFill(this.year(), 5); }, - YYYYYY : function () { - var y = this.year(), sign = y >= 0 ? '+' : '-'; - return sign + leftZeroFill(Math.abs(y), 6); - }, gg : function () { return leftZeroFill(this.weekYear() % 100, 2); }, gggg : function () { - return leftZeroFill(this.weekYear(), 4); + return this.weekYear(); }, ggggg : function () { return leftZeroFill(this.weekYear(), 5); @@ -7062,7 +7033,7 @@ process.chdir = function (dir) { return leftZeroFill(this.isoWeekYear() % 100, 2); }, GGGG : function () { - return leftZeroFill(this.isoWeekYear(), 4); + return this.isoWeekYear(); }, GGGGG : function () { return leftZeroFill(this.isoWeekYear(), 5); @@ -7074,10 +7045,10 @@ process.chdir = function (dir) { return this.isoWeekday(); }, a : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), true); + return this.lang().meridiem(this.hours(), this.minutes(), true); }, A : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), false); + return this.lang().meridiem(this.hours(), this.minutes(), false); }, H : function () { return this.hours(); @@ -7105,21 +7076,21 @@ process.chdir = function (dir) { }, Z : function () { var a = -this.zone(), - b = '+'; + b = "+"; if (a < 0) { a = -a; - b = '-'; + b = "-"; } - return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); + return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2); }, ZZ : function () { var a = -this.zone(), - b = '+'; + b = "+"; if (a < 0) { a = -a; - b = '-'; + b = "-"; } - return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); + return b + leftZeroFill(toInt(10 * a / 6), 4); }, z : function () { return this.zoneAbbr(); @@ -7129,68 +7100,11 @@ process.chdir = function (dir) { }, X : function () { return this.unix(); - }, - Q : function () { - return this.quarter(); } }, - deprecations = {}, - lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; - // Pick the first defined of two or three arguments. dfl comes from - // default. - function dfl(a, b, c) { - switch (arguments.length) { - case 2: return a != null ? a : b; - case 3: return a != null ? a : b != null ? b : c; - default: throw new Error('Implement me'); - } - } - - function defaultParsingFlags() { - // We need to deep clone this object, and es5 standard is not very - // helpful. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso: false - }; - } - - function printMsg(msg) { - if (moment.suppressDeprecationWarnings === false && - typeof console !== 'undefined' && console.warn) { - console.warn("Deprecation warning: " + msg); - } - } - - function deprecate(msg, fn) { - var firstTime = true; - return extend(function () { - if (firstTime) { - printMsg(msg); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - function deprecateSimple(name, msg) { - if (!deprecations[name]) { - printMsg(msg); - deprecations[name] = true; - } - } - function padToken(func, count) { return function (a) { return leftZeroFill(func.call(this, a), count); @@ -7198,7 +7112,7 @@ process.chdir = function (dir) { } function ordinalizeToken(func, period) { return function (a) { - return this.localeData().ordinal(func.call(this, a), period); + return this.lang().ordinal(func.call(this, a), period); }; } @@ -7217,23 +7131,20 @@ process.chdir = function (dir) { Constructors ************************************/ - function Locale() { + function Language() { + } // Moment prototype object - function Moment(config, skipOverflow) { - if (skipOverflow !== false) { - checkOverflow(config); - } - copyConfig(this, config); - this._d = new Date(+config._d); + function Moment(config) { + checkOverflow(config); + extend(this, config); } // Duration Constructor function Duration(duration) { var normalizedInput = normalizeObjectUnits(duration), years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, months = normalizedInput.month || 0, weeks = normalizedInput.week || 0, days = normalizedInput.day || 0, @@ -7242,6 +7153,9 @@ process.chdir = function (dir) { seconds = normalizedInput.second || 0, milliseconds = normalizedInput.millisecond || 0; + // store reference to input for deterministic cloning + this._input = duration; + // representation for dateAddRemove this._milliseconds = +milliseconds + seconds * 1e3 + // 1000 @@ -7255,13 +7169,10 @@ process.chdir = function (dir) { // which months you are are talking about, so we have to store // it separately. this._months = +months + - quarters * 3 + years * 12; this._data = {}; - this._locale = moment.localeData(); - this._bubble(); } @@ -7277,64 +7188,17 @@ process.chdir = function (dir) { } } - if (b.hasOwnProperty('toString')) { + if (b.hasOwnProperty("toString")) { a.toString = b.toString; } - if (b.hasOwnProperty('valueOf')) { + if (b.hasOwnProperty("valueOf")) { a.valueOf = b.valueOf; } return a; } - function copyConfig(to, from) { - var i, prop, val; - - if (typeof from._isAMomentObject !== 'undefined') { - to._isAMomentObject = from._isAMomentObject; - } - if (typeof from._i !== 'undefined') { - to._i = from._i; - } - if (typeof from._f !== 'undefined') { - to._f = from._f; - } - if (typeof from._l !== 'undefined') { - to._l = from._l; - } - if (typeof from._strict !== 'undefined') { - to._strict = from._strict; - } - if (typeof from._tzm !== 'undefined') { - to._tzm = from._tzm; - } - if (typeof from._isUTC !== 'undefined') { - to._isUTC = from._isUTC; - } - if (typeof from._offset !== 'undefined') { - to._offset = from._offset; - } - if (typeof from._pf !== 'undefined') { - to._pf = from._pf; - } - if (typeof from._locale !== 'undefined') { - to._locale = from._locale; - } - - if (momentProperties.length > 0) { - for (i in momentProperties) { - prop = momentProperties[i]; - val = from[prop]; - if (typeof val !== 'undefined') { - to[prop] = val; - } - } - } - - return to; - } - function absRound(number) { if (number < 0) { return Math.ceil(number); @@ -7345,78 +7209,43 @@ process.chdir = function (dir) { // left zero fill a number // see http://jsperf.com/left-zero-filling for performance comparison - function leftZeroFill(number, targetLength, forceSign) { - var output = '' + Math.abs(number), - sign = number >= 0; - + function leftZeroFill(number, targetLength) { + var output = number + ''; while (output.length < targetLength) { output = '0' + output; } - return (sign ? (forceSign ? '+' : '') : '-') + output; + return output; } - function positiveMomentsDifference(base, other) { - var res = {milliseconds: 0, months: 0}; - - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } - - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - - return res; - } - - function momentsDifference(base, other) { - var res; - other = makeAs(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } - - return res; - } - - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period)."); - tmp = val; val = period; period = tmp; - } - - val = typeof val === 'string' ? +val : val; - dur = moment.duration(val, period); - addOrSubtractDurationFromMoment(this, dur, direction); - return this; - }; - } - - function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { + // helper function for _.addTime and _.subtractTime + function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) { var milliseconds = duration._milliseconds, days = duration._days, - months = duration._months; - updateOffset = updateOffset == null ? true : updateOffset; + months = duration._months, + minutes, + hours; if (milliseconds) { mom._d.setTime(+mom._d + milliseconds * isAdding); } + // store the minutes and hours so we can restore them + if (days || months) { + minutes = mom.minute(); + hours = mom.hour(); + } if (days) { - rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); + mom.date(mom.date() + days * isAdding); } if (months) { - rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); + mom.month(mom.month() + months * isAdding); } - if (updateOffset) { - moment.updateOffset(mom, days || months); + if (milliseconds && !ignoreUpdateOffset) { + moment.updateOffset(mom); + } + // restore the minutes and hours after possibly changing dst + if (days || months) { + mom.minute(minutes); + mom.hour(hours); } } @@ -7426,8 +7255,8 @@ process.chdir = function (dir) { } function isDate(input) { - return Object.prototype.toString.call(input) === '[object Date]' || - input instanceof Date; + return Object.prototype.toString.call(input) === '[object Date]' || + input instanceof Date; } // compare two arrays, return the number of differences @@ -7456,7 +7285,8 @@ process.chdir = function (dir) { function normalizeObjectUnits(inputObject) { var normalizedInput = {}, normalizedProp, - prop; + prop, + index; for (prop in inputObject) { if (inputObject.hasOwnProperty(prop)) { @@ -7487,7 +7317,7 @@ process.chdir = function (dir) { moment[field] = function (format, index) { var i, getter, - method = moment._locale[field], + method = moment.fn._lang[field], results = []; if (typeof format === 'number') { @@ -7497,7 +7327,7 @@ process.chdir = function (dir) { getter = function (i) { var m = moment().utc().set(setter, i); - return method.call(moment._locale, m, format || ''); + return method.call(moment.fn._lang, m, format || ''); }; if (index != null) { @@ -7531,10 +7361,6 @@ process.chdir = function (dir) { return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); } - function weeksInYear(year, dow, doy) { - return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; - } - function daysInYear(year) { return isLeapYear(year) ? 366 : 365; } @@ -7563,6 +7389,21 @@ process.chdir = function (dir) { } } + function initializeParsingFlags(config) { + config._pf = { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso: false + }; + } + function isValid(m) { if (m._isValid == null) { m._isValid = !isNaN(m._d.getTime()) && @@ -7582,62 +7423,16 @@ process.chdir = function (dir) { return m._isValid; } - function normalizeLocale(key) { + function normalizeLanguage(key) { return key ? key.toLowerCase().replace('_', '-') : key; } - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, j, next, locale, split; - - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return null; - } - - function loadLocale(name) { - var oldLocale = null; - if (!locales[name] && hasModule) { - try { - oldLocale = moment.locale(); - require('./locale/' + name); - // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales - moment.locale(oldLocale); - } catch (e) { } - } - return locales[name]; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function makeAs(input, model) { - return model._isUTC ? moment(input).zone(model._offset || 0) : - moment(input).local(); - } - /************************************ - Locale + Languages ************************************/ - extend(Locale.prototype, { + extend(Language.prototype, { set : function (config) { var prop, i; @@ -7651,12 +7446,12 @@ process.chdir = function (dir) { } }, - _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), months : function (m) { return this._months[m.month()]; }, - _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), monthsShort : function (m) { return this._monthsShort[m.month()]; }, @@ -7682,17 +7477,17 @@ process.chdir = function (dir) { } }, - _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), weekdays : function (m) { return this._weekdays[m.day()]; }, - _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), weekdaysShort : function (m) { return this._weekdaysShort[m.day()]; }, - _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), weekdaysMin : function (m) { return this._weekdaysMin[m.day()]; }, @@ -7719,11 +7514,11 @@ process.chdir = function (dir) { }, _longDateFormat : { - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY LT', - LLLL : 'dddd, MMMM D, YYYY LT' + LT : "h:mm A", + L : "MM/DD/YYYY", + LL : "MMMM D YYYY", + LLL : "MMMM D YYYY LT", + LLLL : "dddd, MMMM D YYYY LT" }, longDateFormat : function (key) { var output = this._longDateFormat[key]; @@ -7765,37 +7560,35 @@ process.chdir = function (dir) { }, _relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few 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' + future : "in %s", + past : "%s ago", + s : "a few 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" }, - relativeTime : function (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return (typeof output === 'function') ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); }, - pastFuture : function (diff, output) { var format = this._relativeTime[diff > 0 ? 'future' : 'past']; return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); }, ordinal : function (number) { - return this._ordinal.replace('%d', number); + return this._ordinal.replace("%d", number); }, - _ordinal : '%d', + _ordinal : "%d", preparse : function (string) { return string; @@ -7820,6 +7613,78 @@ process.chdir = function (dir) { } }); + // Loads a language definition into the `languages` cache. The function + // takes a key and optionally values. If not in the browser and no values + // are provided, it will load the language file module. As a convenience, + // this function also returns the language values. + function loadLang(key, values) { + values.abbr = key; + if (!languages[key]) { + languages[key] = new Language(); + } + languages[key].set(values); + return languages[key]; + } + + // Remove a language from the `languages` cache. Mostly useful in tests. + function unloadLang(key) { + delete languages[key]; + } + + // Determines which language definition to use and returns it. + // + // With no parameters, it will return the global language. If you + // pass in a language key, such as 'en', it will return the + // definition for 'en', so long as 'en' has already been loaded using + // moment.lang. + function getLangDefinition(key) { + var i = 0, j, lang, next, split, + get = function (k) { + if (!languages[k] && hasModule) { + try { + require('./lang/' + k); + } catch (e) { } + } + return languages[k]; + }; + + if (!key) { + return moment.fn._lang; + } + + if (!isArray(key)) { + //short-circuit everything else + lang = get(key); + if (lang) { + return lang; + } + key = [key]; + } + + //pick the language from the array + //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + while (i < key.length) { + split = normalizeLanguage(key[i]).split('-'); + j = split.length; + next = normalizeLanguage(key[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + lang = get(split.slice(0, j).join('-')); + if (lang) { + return lang; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return moment.fn._lang; + } + /************************************ Formatting ************************************/ @@ -7827,9 +7692,9 @@ process.chdir = function (dir) { function removeFormattingTokens(input) { if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); + return input.replace(/^\[|\]$/g, ""); } - return input.replace(/\\/g, ''); + return input.replace(/\\/g, ""); } function makeFormatFunction(format) { @@ -7844,7 +7709,7 @@ process.chdir = function (dir) { } return function (mom) { - var output = ''; + var output = ""; for (i = 0; i < length; i++) { output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; } @@ -7854,11 +7719,12 @@ process.chdir = function (dir) { // format date using native date object function formatMoment(m, format) { + if (!m.isValid()) { - return m.localeData().invalidDate(); + return m.lang().invalidDate(); } - format = expandFormat(format, m.localeData()); + format = expandFormat(format, m.lang()); if (!formatFunctions[format]) { formatFunctions[format] = makeFormatFunction(format); @@ -7867,11 +7733,11 @@ process.chdir = function (dir) { return formatFunctions[format](m); } - function expandFormat(format, locale) { + function expandFormat(format, lang) { var i = 5; function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; + return lang.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; @@ -7892,40 +7758,21 @@ process.chdir = function (dir) { // get the regex to find the next token function getParseRegexForToken(token, config) { - var a, strict = config._strict; + var a; switch (token) { - case 'Q': - return parseTokenOneDigit; case 'DDDD': return parseTokenThreeDigits; case 'YYYY': case 'GGGG': case 'gggg': - return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; - case 'Y': - case 'G': - case 'g': - return parseTokenSignedNumber; - case 'YYYYYY': + return parseTokenFourDigits; case 'YYYYY': case 'GGGGG': case 'ggggg': - return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; + return parseTokenSixDigits; case 'S': - if (strict) { - return parseTokenOneDigit; - } - /* falls through */ case 'SS': - if (strict) { - return parseTokenTwoDigits; - } - /* falls through */ case 'SSS': - if (strict) { - return parseTokenThreeDigits; - } - /* falls through */ case 'DDD': return parseTokenOneToThreeDigits; case 'MMM': @@ -7936,7 +7783,7 @@ process.chdir = function (dir) { return parseTokenWord; case 'a': case 'A': - return config._locale._meridiemParse; + return getLangDefinition(config._l)._meridiemParse; case 'X': return parseTokenTimestampMs; case 'Z': @@ -7955,9 +7802,6 @@ process.chdir = function (dir) { case 'hh': case 'mm': case 'ss': - case 'ww': - case 'WW': - return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; case 'M': case 'D': case 'd': @@ -7966,23 +7810,21 @@ process.chdir = function (dir) { case 'm': case 's': case 'w': + case 'ww': case 'W': + case 'WW': case 'e': case 'E': return parseTokenOneOrTwoDigits; - case 'Do': - return parseTokenOrdinal; default : - a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); + a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i")); return a; } } function timezoneMinutesFromString(string) { - string = string || ''; - var possibleTzMatches = (string.match(parseTokenTimezone) || []), - tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], - parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], + var tzchunk = (parseTokenTimezone.exec(string) || [])[0], + parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0], minutes = +(parts[1] * 60) + toInt(parts[2]); return parts[0] === '+' ? -minutes : minutes; @@ -7993,12 +7835,6 @@ process.chdir = function (dir) { var a, datePartArray = config._a; switch (token) { - // QUARTER - case 'Q': - if (input != null) { - datePartArray[MONTH] = (toInt(input) - 1) * 3; - } - break; // MONTH case 'M' : // fall through to MM case 'MM' : @@ -8008,7 +7844,7 @@ process.chdir = function (dir) { break; case 'MMM' : // fall through to MMMM case 'MMMM' : - a = config._locale.monthsParse(input); + a = getLangDefinition(config._l).monthsParse(input); // if we didn't find a month name, mark the date as invalid. if (a != null) { datePartArray[MONTH] = a; @@ -8023,11 +7859,6 @@ process.chdir = function (dir) { datePartArray[DATE] = toInt(input); } break; - case 'Do' : - if (input != null) { - datePartArray[DATE] = toInt(parseInt(input, 10)); - } - break; // DAY OF YEAR case 'DDD' : // fall through to DDDD case 'DDDD' : @@ -8038,17 +7869,16 @@ process.chdir = function (dir) { break; // YEAR case 'YY' : - datePartArray[YEAR] = moment.parseTwoDigitYear(input); + datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000); break; case 'YYYY' : case 'YYYYY' : - case 'YYYYYY' : datePartArray[YEAR] = toInt(input); break; // AM / PM case 'a' : // fall through to A case 'A' : - config._isPm = config._locale.isPM(input); + config._isPm = getLangDefinition(config._l).isPM(input); break; // 24 HOUR case 'H' : // fall through to hh @@ -8084,93 +7914,39 @@ process.chdir = function (dir) { config._useUTC = true; config._tzm = timezoneMinutesFromString(input); break; - // WEEKDAY - human - case 'dd': - case 'ddd': - case 'dddd': - a = config._locale.weekdaysParse(input); - // if we didn't get a weekday name, mark the date as invalid - if (a != null) { - config._w = config._w || {}; - config._w['d'] = a; - } else { - config._pf.invalidWeekday = input; - } - break; - // WEEK, WEEK DAY - numeric case 'w': case 'ww': case 'W': case 'WW': case 'd': + case 'dd': + case 'ddd': + case 'dddd': case 'e': case 'E': token = token.substr(0, 1); /* falls through */ + case 'gg': case 'gggg': + case 'GG': case 'GGGG': case 'GGGGG': token = token.substr(0, 2); if (input) { config._w = config._w || {}; - config._w[token] = toInt(input); + config._w[token] = input; } break; - case 'gg': - case 'GG': - config._w = config._w || {}; - config._w[token] = moment.parseTwoDigitYear(input); } } - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp; - - 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 = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); - week = dfl(w.W, 1); - weekday = dfl(w.E, 1); - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); - week = dfl(w.w, 1); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < dow) { - ++week; - } - } else if (w.e != null) { - // local weekday -- counting starts from begining of week - weekday = w.e + dow; - } else { - // default to begining of week - weekday = dow; - } - } - temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - // 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 dateFromConfig(config) { - var i, date, input = [], currentDate, yearToUse; + var i, date, input = [], currentDate, + yearToUse, fixYear, w, temp, lang, weekday, week; if (config._d) { return; @@ -8180,12 +7956,38 @@ process.chdir = function (dir) { //compute day of the year from weeks and weekdays if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); + fixYear = function (val) { + return val ? + (val.length < 3 ? (parseInt(val, 10) > 68 ? '19' + val : '20' + val) : val) : + (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); + }; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); + } + else { + lang = getLangDefinition(config._l); + weekday = w.d != null ? parseWeekday(w.d, lang) : + (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); + + week = parseInt(w.w, 10) || 1; + + //if we're parsing 'd', then the low day numbers may be next week + if (w.d != null && weekday < lang._week.dow) { + week++; + } + + temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); + } + + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; } //if the day of the year is set, figure out what it is if (config._dayOfYear) { - yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); + yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; if (config._dayOfYear > daysInYear(yearToUse)) { config._pf._overflowDayOfYear = true; @@ -8210,12 +8012,11 @@ process.chdir = function (dir) { config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } + // add the offsets to the time to be parsed so that we can have a clean array for checking isValid + input[HOUR] += toInt((config._tzm || 0) / 60); + input[MINUTE] += toInt((config._tzm || 0) % 60); + config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); - // Apply timezone offset from input. The actual zone can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); - } } function dateFromObject(config) { @@ -8254,25 +8055,22 @@ process.chdir = function (dir) { // date from string and format string function makeDateFromStringAndFormat(config) { - if (config._f === moment.ISO_8601) { - parseISO(config); - return; - } config._a = []; config._pf.empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, + var lang = getLangDefinition(config._l), + string = '' + config._i, i, parsedInput, tokens, token, skipped, stringLength = string.length, totalParsedInputLength = 0; - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + tokens = expandFormat(config._f, lang).match(formattingTokens) || []; for (i = 0; i < tokens.length; i++) { token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + parsedInput = (getParseRegexForToken(token, config).exec(string) || [])[0]; if (parsedInput) { skipped = string.substr(0, string.indexOf(parsedInput)); if (skipped.length > 0) { @@ -8343,8 +8141,8 @@ process.chdir = function (dir) { for (i = 0; i < config._f.length; i++) { currentScore = 0; - tempConfig = copyConfig({}, config); - tempConfig._pf = defaultParsingFlags(); + tempConfig = extend({}, config); + initializeParsingFlags(tempConfig); tempConfig._f = config._f[i]; makeDateFromStringAndFormat(tempConfig); @@ -8370,64 +8168,55 @@ process.chdir = function (dir) { } // date from iso format - function parseISO(config) { - var i, l, + function makeDateFromString(config) { + var i, string = config._i, match = isoRegex.exec(string); if (match) { config._pf.iso = true; - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(string)) { + for (i = 4; i > 0; i--) { + if (match[i]) { // match[5] should be "T" or undefined - config._f = isoDates[i][0] + (match[6] || ' '); + config._f = isoDates[i - 1] + (match[6] || " "); break; } } - for (i = 0, l = isoTimes.length; i < l; i++) { + for (i = 0; i < 4; i++) { if (isoTimes[i][1].exec(string)) { config._f += isoTimes[i][0]; break; } } - if (string.match(parseTokenTimezone)) { - config._f += 'Z'; + if (parseTokenTimezone.exec(string)) { + config._f += "Z"; } makeDateFromStringAndFormat(config); - } else { - config._isValid = false; } - } - - // date from iso format or fallback - function makeDateFromString(config) { - parseISO(config); - if (config._isValid === false) { - delete config._isValid; - moment.createFromInputFallback(config); + else { + config._d = new Date(string); } } function makeDateFromInput(config) { - var input = config._i, matched; + var input = config._i, + matched = aspNetJsonRegex.exec(input); + if (input === undefined) { config._d = new Date(); - } else if (isDate(input)) { - config._d = new Date(+input); - } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { + } else if (matched) { config._d = new Date(+matched[1]); } else if (typeof input === 'string') { makeDateFromString(config); } else if (isArray(input)) { config._a = input.slice(0); dateFromConfig(config); + } else if (isDate(input)) { + config._d = new Date(+input); } else if (typeof(input) === 'object') { dateFromObject(config); - } else if (typeof(input) === 'number') { - // from milliseconds - config._d = new Date(input); } else { - moment.createFromInputFallback(config); + config._d = new Date(input); } } @@ -8451,13 +8240,13 @@ process.chdir = function (dir) { return date; } - function parseWeekday(input, locale) { + function parseWeekday(input, language) { if (typeof input === 'string') { if (!isNaN(input)) { input = parseInt(input, 10); } else { - input = locale.weekdaysParse(input); + input = language.weekdaysParse(input); if (typeof input !== 'number') { return null; } @@ -8472,33 +8261,29 @@ process.chdir = function (dir) { // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { + return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } - function relativeTime(posNegDuration, withoutSuffix, locale) { - var duration = moment.duration(posNegDuration).abs(), - seconds = round(duration.as('s')), - minutes = round(duration.as('m')), - hours = round(duration.as('h')), - days = round(duration.as('d')), - months = round(duration.as('M')), - years = round(duration.as('y')), - - args = seconds < relativeTimeThresholds.s && ['s', seconds] || + function relativeTime(milliseconds, withoutSuffix, lang) { + var seconds = round(Math.abs(milliseconds) / 1000), + minutes = round(seconds / 60), + hours = round(minutes / 60), + days = round(hours / 24), + years = round(days / 365), + args = seconds < 45 && ['s', seconds] || minutes === 1 && ['m'] || - minutes < relativeTimeThresholds.m && ['mm', minutes] || + minutes < 45 && ['mm', minutes] || hours === 1 && ['h'] || - hours < relativeTimeThresholds.h && ['hh', hours] || + hours < 22 && ['hh', hours] || days === 1 && ['d'] || - days < relativeTimeThresholds.d && ['dd', days] || - months === 1 && ['M'] || - months < relativeTimeThresholds.M && ['MM', months] || + days <= 25 && ['dd', days] || + days <= 45 && ['M'] || + days < 345 && ['MM', round(days / 30)] || years === 1 && ['y'] || ['yy', years]; - args[2] = withoutSuffix; - args[3] = +posNegDuration > 0; - args[4] = locale; + args[3] = milliseconds > 0; + args[4] = lang; return substituteTimeAgo.apply({}, args); } @@ -8529,7 +8314,7 @@ process.chdir = function (dir) { daysToDayOfWeek += 7; } - adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); + adjustedMoment = moment(mom).add('d', daysToDayOfWeek); return { week: Math.ceil(adjustedMoment.dayOfYear() / 7), year: adjustedMoment.year() @@ -8538,11 +8323,11 @@ process.chdir = function (dir) { //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { - var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; + var d = new Date(Date.UTC(year, 0)).getUTCDay(), + daysToAdd, dayOfYear; - d = d === 0 ? 7 : d; weekday = weekday != null ? weekday : firstDayOfWeek; - daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); + daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0); dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; return { @@ -8559,18 +8344,22 @@ process.chdir = function (dir) { var input = config._i, format = config._f; - config._locale = config._locale || moment.localeData(config._l); + if (typeof config._pf === 'undefined') { + initializeParsingFlags(config); + } - if (input === null || (format === undefined && input === '')) { + if (input === null) { return moment.invalid({nullInput: true}); } if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); + config._i = input = getLangDefinition().preparse(input); } if (moment.isMoment(input)) { - return new Moment(input, true); + config = extend({}, input); + + config._d = new Date(+input._d); } else if (format) { if (isArray(format)) { makeDateFromStringAndArray(config); @@ -8584,94 +8373,38 @@ process.chdir = function (dir) { return new Moment(config); } - moment = function (input, format, locale, strict) { - var c; - - if (typeof(locale) === "boolean") { - strict = locale; - locale = undefined; + moment = function (input, format, lang, strict) { + if (typeof(lang) === "boolean") { + strict = lang; + lang = undefined; } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._i = input; - c._f = format; - c._l = locale; - c._strict = strict; - c._isUTC = false; - c._pf = defaultParsingFlags(); - - return makeMoment(c); - }; - - moment.suppressDeprecationWarnings = false; - - moment.createFromInputFallback = deprecate( - 'moment construction falls back to js Date. This is ' + - 'discouraged and will be removed in upcoming major ' + - 'release. Please refer to ' + - 'https://github.com/moment/moment/issues/1407 for more info.', - function (config) { - config._d = new Date(config._i); - } - ); - - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return moment(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } - - moment.min = function () { - var args = [].slice.call(arguments, 0); - - return pickBy('isBefore', args); - }; - - moment.max = function () { - var args = [].slice.call(arguments, 0); - - return pickBy('isAfter', args); + return makeMoment({ + _i : input, + _f : format, + _l : lang, + _strict : strict, + _isUTC : false + }); }; // creating with utc - moment.utc = function (input, format, locale, strict) { - var c; + moment.utc = function (input, format, lang, strict) { + var m; - if (typeof(locale) === "boolean") { - strict = locale; - locale = undefined; + if (typeof(lang) === "boolean") { + strict = lang; + lang = undefined; } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._useUTC = true; - c._isUTC = true; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - c._pf = defaultParsingFlags(); + m = makeMoment({ + _useUTC : true, + _isUTC : true, + _l : lang, + _i : input, + _f : format, + _strict : strict + }).utc(); - return makeMoment(c).utc(); + return m; }; // creating with unix timestamp (in seconds) @@ -8681,29 +8414,25 @@ process.chdir = function (dir) { // duration moment.duration = function (input, key) { - var duration = input, + var isDuration = moment.isDuration(input), + isNumber = (typeof input === 'number'), + duration = (isDuration ? input._input : (isNumber ? {} : input)), // matching against regexp is expensive, do it on demand match = null, sign, ret, parseIso, - diffRes; + timeEmpty, + dateTimeEmpty; - if (moment.isDuration(input)) { - duration = { - ms: input._milliseconds, - d: input._days, - M: input._months - }; - } else if (typeof input === 'number') { - duration = {}; + if (isNumber) { if (key) { duration[key] = input; } else { duration.milliseconds = input; } } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; + sign = (match[1] === "-") ? -1 : 1; duration = { y: 0, d: toInt(match[DATE]) * sign, @@ -8713,7 +8442,7 @@ process.chdir = function (dir) { ms: toInt(match[MILLISECOND]) * sign }; } else if (!!(match = isoDurationRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; + sign = (match[1] === "-") ? -1 : 1; parseIso = function (inp) { // We'd normally use ~~inp for this, but unfortunately it also // converts floats to ints. @@ -8731,19 +8460,12 @@ process.chdir = function (dir) { s: parseIso(match[7]), w: parseIso(match[8]) }; - } else if (typeof duration === 'object' && - ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(moment(duration.from), moment(duration.to)); - - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; } ret = new Duration(duration); - if (moment.isDuration(input) && input.hasOwnProperty('_locale')) { - ret._locale = input._locale; + if (isDuration && input.hasOwnProperty('_lang')) { + ret._lang = input._lang; } return ret; @@ -8755,111 +8477,41 @@ process.chdir = function (dir) { // default format moment.defaultFormat = isoFormat; - // constant that refers to the ISO standard - moment.ISO_8601 = function () {}; - - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - moment.momentProperties = momentProperties; - // This function will be called whenever a moment is mutated. // It is intended to keep the offset in sync with the timezone. moment.updateOffset = function () {}; - // This function allows you to set a threshold for relative time strings - moment.relativeTimeThreshold = function (threshold, limit) { - if (relativeTimeThresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return relativeTimeThresholds[threshold]; - } - relativeTimeThresholds[threshold] = limit; - return true; - }; - - moment.lang = deprecate( - "moment.lang is deprecated. Use moment.locale instead.", - function (key, value) { - return moment.locale(key, value); - } - ); - - // This function will load locale and then set the global locale. If + // This function will load languages and then set the global language. If // no arguments are passed in, it will simply return the current global - // locale key. - moment.locale = function (key, values) { - var data; - if (key) { - if (typeof(values) !== "undefined") { - data = moment.defineLocale(key, values); - } - else { - data = moment.localeData(key); - } - - if (data) { - moment.duration._locale = moment._locale = data; - } - } - - return moment._locale._abbr; - }; - - moment.defineLocale = function (name, values) { - if (values !== null) { - values.abbr = name; - if (!locales[name]) { - locales[name] = new Locale(); - } - locales[name].set(values); - - // backwards compat for now: also set the locale - moment.locale(name); - - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - }; - - moment.langData = deprecate( - "moment.langData is deprecated. Use moment.localeData instead.", - function (key) { - return moment.localeData(key); - } - ); - - // returns locale data - moment.localeData = function (key) { - var locale; - - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } - + // language key. + moment.lang = function (key, values) { + var r; if (!key) { - return moment._locale; + return moment.fn._lang._abbr; } - - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; + if (values) { + loadLang(normalizeLanguage(key), values); + } else if (values === null) { + unloadLang(key); + key = 'en'; + } else if (!languages[key]) { + getLangDefinition(key); } + r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); + return r._abbr; + }; - return chooseLocale(key); + // returns language data + moment.langData = function (key) { + if (key && key._lang && key._lang._abbr) { + key = key._lang._abbr; + } + return getLangDefinition(key); }; // compare moment object moment.isMoment = function (obj) { - return obj instanceof Moment || - (obj != null && obj.hasOwnProperty('_isAMomentObject')); + return obj instanceof Moment; }; // for typechecking Duration objects @@ -8887,12 +8539,8 @@ process.chdir = function (dir) { return m; }; - moment.parseZone = function () { - return moment.apply(null, arguments).parseZone(); - }; - - moment.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + moment.parseZone = function (input) { + return moment(input).parseZone(); }; /************************************ @@ -8915,7 +8563,7 @@ process.chdir = function (dir) { }, toString : function () { - return this.clone().locale('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); + return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); }, toDate : function () { @@ -8923,12 +8571,7 @@ process.chdir = function (dir) { }, toISOString : function () { - var m = moment(this).utc(); - if (0 < m.year() && m.year() <= 9999) { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } else { - return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } + return formatMoment(moment(this).utc(), 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); }, toArray : function () { @@ -8949,6 +8592,7 @@ process.chdir = function (dir) { }, isDSTShifted : function () { + if (this._a) { return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; } @@ -8964,33 +8608,47 @@ process.chdir = function (dir) { return this._pf.overflow; }, - utc : function (keepLocalTime) { - return this.zone(0, keepLocalTime); + utc : function () { + return this.zone(0); }, - local : function (keepLocalTime) { - if (this._isUTC) { - this.zone(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.add(this._d.getTimezoneOffset(), 'm'); - } - } + local : function () { + this.zone(0); + this._isUTC = false; return this; }, format : function (inputString) { var output = formatMoment(this, inputString || moment.defaultFormat); - return this.localeData().postformat(output); + return this.lang().postformat(output); }, - add : createAdder(1, 'add'), + add : function (input, val) { + var dur; + // switch args to support add('s', 1) and add(1, 's') + if (typeof input === 'string') { + dur = moment.duration(+val, input); + } else { + dur = moment.duration(input, val); + } + addOrSubtractDurationFromMoment(this, dur, 1); + return this; + }, - subtract : createAdder(-1, 'subtract'), + subtract : function (input, val) { + var dur; + // switch args to support subtract('s', 1) and subtract(1, 's') + if (typeof input === 'string') { + dur = moment.duration(+val, input); + } else { + dur = moment.duration(input, val); + } + addOrSubtractDurationFromMoment(this, dur, -1); + return this; + }, diff : function (input, units, asFloat) { - var that = makeAs(input, this), + var that = this._isUTC ? moment(input).zone(this._offset || 0) : moment(input).local(), zoneDiff = (this.zone() - that.zone()) * 6e4, diff, output; @@ -9024,26 +8682,22 @@ process.chdir = function (dir) { }, from : function (time, withoutSuffix) { - return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); }, fromNow : function (withoutSuffix) { return this.from(moment(), withoutSuffix); }, - calendar : function (time) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're zone'd or not. - var now = time || moment(), - sod = makeAs(now, this).startOf('day'), - diff = this.diff(sod, 'days', true), + calendar : function () { + var diff = this.diff(moment().zone(this.zone()).startOf('day'), 'days', true), format = diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.localeData().calendar(format, this)); + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + return this.format(this.lang().calendar(format, this)); }, isLeapYear : function () { @@ -9058,16 +8712,38 @@ process.chdir = function (dir) { day : function (input) { var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); + input = parseWeekday(input, this.lang()); + return this.add({ d : input - day }); } else { return day; } }, - month : makeAccessor('Month', true), + month : function (input) { + var utc = this._isUTC ? 'UTC' : '', + dayOfMonth; - startOf : function (units) { + if (input != null) { + if (typeof input === 'string') { + input = this.lang().monthsParse(input); + if (typeof input !== 'number') { + return this; + } + } + + dayOfMonth = this.date(); + this.date(1); + this._d['set' + utc + 'Month'](input); + this.date(Math.min(dayOfMonth, this.daysInMonth())); + + moment.updateOffset(this); + return this; + } else { + return this._d['get' + utc + 'Month'](); + } + }, + + startOf: function (units) { units = normalizeUnits(units); // the following switch intentionally omits break keywords // to utilize falling through the cases. @@ -9075,7 +8751,6 @@ process.chdir = function (dir) { case 'year': this.month(0); /* falls through */ - case 'quarter': case 'month': this.date(1); /* falls through */ @@ -9102,17 +8777,12 @@ process.chdir = function (dir) { this.isoWeekday(1); } - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); - } - return this; }, endOf: function (units) { units = normalizeUnits(units); - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); }, isAfter: function (input, units) { @@ -9126,63 +8796,33 @@ process.chdir = function (dir) { }, isSame: function (input, units) { - units = units || 'ms'; - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); + units = typeof units !== 'undefined' ? units : 'millisecond'; + return +this.clone().startOf(units) === +moment(input).startOf(units); }, - min: deprecate( - 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', - function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - } - ), + min: function (other) { + other = moment.apply(null, arguments); + return other < this ? this : other; + }, - max: deprecate( - 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', - function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; - } - ), + max: function (other) { + other = moment.apply(null, arguments); + return other > this ? this : other; + }, - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // 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. - zone : function (input, keepLocalTime) { - var offset = this._offset || 0, - localAdjust; + zone : function (input) { + var offset = this._offset || 0; if (input != null) { - if (typeof input === 'string') { + if (typeof input === "string") { input = timezoneMinutesFromString(input); } if (Math.abs(input) < 16) { input = input * 60; } - if (!this._isUTC && keepLocalTime) { - localAdjust = this._d.getTimezoneOffset(); - } this._offset = input; this._isUTC = true; - if (localAdjust != null) { - this.subtract(localAdjust, 'm'); - } if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addOrSubtractDurationFromMoment(this, - moment.duration(offset - input, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - moment.updateOffset(this, true); - this._changeInProgress = null; - } + addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true); } } else { return this._isUTC ? offset : this._d.getTimezoneOffset(); @@ -9191,17 +8831,15 @@ process.chdir = function (dir) { }, zoneAbbr : function () { - return this._isUTC ? 'UTC' : ''; + return this._isUTC ? "UTC" : ""; }, zoneName : function () { - return this._isUTC ? 'Coordinated Universal Time' : ''; + return this._isUTC ? "Coordinated Universal Time" : ""; }, parseZone : function () { - if (this._tzm) { - this.zone(this._tzm); - } else if (typeof this._i === 'string') { + if (typeof this._i === 'string') { this.zone(this._i); } return this; @@ -9224,36 +8862,32 @@ process.chdir = function (dir) { dayOfYear : function (input) { var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - }, - - quarter : function (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); }, weekYear : function (input) { - var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; - return input == null ? year : this.add((input - year), 'y'); + var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; + return input == null ? year : this.add("y", (input - year)); }, isoWeekYear : function (input) { var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add((input - year), 'y'); + return input == null ? year : this.add("y", (input - year)); }, week : function (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); + var week = this.lang().week(this); + return input == null ? week : this.add("d", (input - week) * 7); }, isoWeek : function (input) { var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); + return input == null ? week : this.add("d", (input - week) * 7); }, weekday : function (input) { - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); + var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; + return input == null ? weekday : this.add("d", input - weekday); }, isoWeekday : function (input) { @@ -9263,15 +8897,6 @@ process.chdir = function (dir) { return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); }, - isoWeeksInYear : function () { - return weeksInYear(this.year(), 1, 4); - }, - - weeksInYear : function () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - }, - get : function (units) { units = normalizeUnits(units); return this[units](); @@ -9285,97 +8910,46 @@ process.chdir = function (dir) { return this; }, - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration + // If passed a language key, it will set the language for this + // instance. Otherwise, it will return the language configuration // variables for this instance. - locale : function (key) { + lang : function (key) { if (key === undefined) { - return this._locale._abbr; + return this._lang; } else { - this._locale = moment.localeData(key); + this._lang = getLangDefinition(key); return this; } - }, - - lang : deprecate( - "moment().lang() is deprecated. Use moment().localeData() instead.", - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - this._locale = moment.localeData(key); - return this; - } - } - ), - - localeData : function () { - return this._locale; } }); - function rawMonthSetter(mom, value) { - var dayOfMonth; - - // TODO: Move this out of here! - if (typeof value === 'string') { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (typeof value !== 'number') { - return mom; - } - } - - dayOfMonth = Math.min(mom.date(), - daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function rawGetter(mom, unit) { - return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); - } - - function rawSetter(mom, unit, value) { - if (unit === 'Month') { - return rawMonthSetter(mom, value); - } else { - return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - - function makeAccessor(unit, keepTime) { - return function (value) { - if (value != null) { - rawSetter(this, unit, value); - moment.updateOffset(this, keepTime); + // helper for adding shortcuts + function makeGetterAndSetter(name, key) { + moment.fn[name] = moment.fn[name + 's'] = function (input) { + var utc = this._isUTC ? 'UTC' : ''; + if (input != null) { + this._d['set' + utc + key](input); + moment.updateOffset(this); return this; } else { - return rawGetter(this, unit); + return this._d['get' + utc + key](); } }; } - moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); - moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); - moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); - // Setting the hour should keep the time, because the user explicitly - // specified which hour he wants. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); - // moment.fn.month is defined separately - moment.fn.date = makeAccessor('Date', true); - moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); - moment.fn.year = makeAccessor('FullYear', true); - moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); + // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) + for (i = 0; i < proxyGettersAndSetters.length; i ++) { + makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]); + } + + // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') + makeGetterAndSetter('year', 'FullYear'); // add plural methods moment.fn.days = moment.fn.day; moment.fn.months = moment.fn.month; moment.fn.weeks = moment.fn.week; moment.fn.isoWeeks = moment.fn.isoWeek; - moment.fn.quarters = moment.fn.quarter; // add aliased format methods moment.fn.toJSON = moment.fn.toISOString; @@ -9385,17 +8959,6 @@ process.chdir = function (dir) { ************************************/ - function daysToYears (days) { - // 400 years have 146097 days (taking into account leap year rules) - return days * 400 / 146097; - } - - function yearsToDays (years) { - // years * 365 + absRound(years / 4) - - // absRound(years / 100) + absRound(years / 400); - return years * 146097 / 400; - } - extend(moment.duration.fn = Duration.prototype, { _bubble : function () { @@ -9403,7 +8966,7 @@ process.chdir = function (dir) { days = this._days, months = this._months, data = this._data, - seconds, minutes, hours, years = 0; + seconds, minutes, hours, years; // The following code bubbles up values, see the tests for // examples of what that means. @@ -9419,40 +8982,15 @@ process.chdir = function (dir) { data.hours = hours % 24; days += absRound(hours / 24); + data.days = days % 30; - // Accurately convert days to years, assume start from year 0. - years = absRound(daysToYears(days)); - days -= absRound(yearsToDays(years)); - - // 30 days to a month - // TODO (iskren): Use anchor date (like 1st Jan) to compute this. months += absRound(days / 30); - days %= 30; + data.months = months % 12; - // 12 months -> 1 year - years += absRound(months / 12); - months %= 12; - - data.days = days; - data.months = months; + years = absRound(months / 12); data.years = years; }, - abs : function () { - this._milliseconds = Math.abs(this._milliseconds); - this._days = Math.abs(this._days); - this._months = Math.abs(this._months); - - this._data.milliseconds = Math.abs(this._data.milliseconds); - this._data.seconds = Math.abs(this._data.seconds); - this._data.minutes = Math.abs(this._data.minutes); - this._data.hours = Math.abs(this._data.hours); - this._data.months = Math.abs(this._data.months); - this._data.years = Math.abs(this._data.years); - - return this; - }, - weeks : function () { return absRound(this.days() / 7); }, @@ -9465,13 +9003,14 @@ process.chdir = function (dir) { }, humanize : function (withSuffix) { - var output = relativeTime(this, !withSuffix, this.localeData()); + var difference = +this, + output = relativeTime(difference, !withSuffix, this.lang()); if (withSuffix) { - output = this.localeData().pastFuture(+this, output); + output = this.lang().pastFuture(difference, output); } - return this.localeData().postformat(output); + return this.lang().postformat(output); }, add : function (input, val) { @@ -9505,39 +9044,13 @@ process.chdir = function (dir) { }, as : function (units) { - var days, months; units = normalizeUnits(units); - - days = this._days + this._milliseconds / 864e5; - if (units === 'month' || units === 'year') { - months = this._months + daysToYears(days) * 12; - return units === 'month' ? months : months / 12; - } else { - days += yearsToDays(this._months / 12); - switch (units) { - case 'week': return days / 7; - case 'day': return days; - case 'hour': return days * 24; - case 'minute': return days * 24 * 60; - case 'second': return days * 24 * 60 * 60; - case 'millisecond': return days * 24 * 60 * 60 * 1000; - default: throw new Error('Unknown unit ' + units); - } - } + return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); }, lang : moment.fn.lang, - locale : moment.fn.locale, - toIsoString : deprecate( - "toIsoString() is deprecated. Please use toISOString() instead " + - "(notice the capitals)", - function () { - return this.toISOString(); - } - ), - - toISOString : function () { + toIsoString : function () { // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js var years = Math.abs(this.years()), months = Math.abs(this.months()), @@ -9561,10 +9074,6 @@ process.chdir = function (dir) { (hours ? hours + 'H' : '') + (minutes ? minutes + 'M' : '') + (seconds ? seconds + 'S' : ''); - }, - - localeData : function () { - return this._locale; } }); @@ -9574,44 +9083,32 @@ process.chdir = function (dir) { }; } + function makeDurationAsGetter(name, factor) { + moment.duration.fn['as' + name] = function () { + return +this / factor; + }; + } + for (i in unitMillisecondFactors) { if (unitMillisecondFactors.hasOwnProperty(i)) { + makeDurationAsGetter(i, unitMillisecondFactors[i]); makeDurationGetter(i.toLowerCase()); } } - moment.duration.fn.asMilliseconds = function () { - return this.as('ms'); - }; - moment.duration.fn.asSeconds = function () { - return this.as('s'); - }; - moment.duration.fn.asMinutes = function () { - return this.as('m'); - }; - moment.duration.fn.asHours = function () { - return this.as('h'); - }; - moment.duration.fn.asDays = function () { - return this.as('d'); - }; - moment.duration.fn.asWeeks = function () { - return this.as('weeks'); - }; + makeDurationAsGetter('Weeks', 6048e5); moment.duration.fn.asMonths = function () { - return this.as('M'); - }; - moment.duration.fn.asYears = function () { - return this.as('y'); + return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; }; + /************************************ - Default Locale + Default Lang ************************************/ - // Set default locale, other locale will inherit from English. - moment.locale('en', { + // Set default language, other languages will inherit from English. + moment.lang('en', { ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -9622,48 +9119,55 @@ process.chdir = function (dir) { } }); - /* EMBED_LOCALES */ + /* EMBED_LANGUAGES */ /************************************ Exposing Moment ************************************/ - function makeGlobal(shouldDeprecate) { + function makeGlobal(deprecate) { + var warned = false, local_moment = moment; /*global ender:false */ if (typeof ender !== 'undefined') { return; } - oldGlobalMoment = globalScope.moment; - if (shouldDeprecate) { - globalScope.moment = deprecate( - 'Accessing Moment through the global scope is ' + - 'deprecated, and will be removed in an upcoming ' + - 'release.', - moment); + // here, `this` means `window` in the browser, or `global` on the server + // add `moment` as a global object via a string identifier, + // for Closure Compiler "advanced" mode + if (deprecate) { + this.moment = function () { + if (!warned && console && console.warn) { + warned = true; + console.warn( + "Accessing Moment through the global scope is " + + "deprecated, and will be removed in an upcoming " + + "release."); + } + return local_moment.apply(null, arguments); + }; } else { - globalScope.moment = moment; + this['moment'] = moment; } } // CommonJS module is defined if (hasModule) { module.exports = moment; - } else if (typeof define === 'function' && define.amd) { - define('moment', function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal === true) { - // release the global variable - globalScope.moment = oldGlobalMoment; + makeGlobal(true); + } else if (typeof define === "function" && define.amd) { + define("moment", function (require, exports, module) { + if (module.config().noGlobal !== true) { + // If user provided noGlobal, he is aware of global + makeGlobal(module.config().noGlobal === undefined); } return moment; }); - makeGlobal(true); } else { makeGlobal(); } }).call(this); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],5:[function(require,module,exports){ var api, classes, diminishingReturns, events, gear, gearTypes, i18n, moment, mystery, repeat, t, _; @@ -13368,14 +12872,19 @@ api.taskClasses = function(task, filters, dayStart, lastCron, showCompleted, mai return 'hidden'; } if (main) { - for (filter in filters) { - enabled = filters[filter]; - if (enabled && !((_ref = task.tags) != null ? _ref[filter] : void 0)) { - return 'hidden'; + if (!task._editing) { + for (filter in filters) { + enabled = filters[filter]; + if (enabled && !((_ref = task.tags) != null ? _ref[filter] : void 0)) { + return 'hidden'; + } } } } classes = type; + if (task._editing) { + classes += " beingEdited"; + } if (type === 'todo' || type === 'daily') { if (completed || (type === 'daily' && !api.shouldDo(+(new Date), task.repeat, { dayStart: dayStart @@ -14926,4 +14435,4 @@ api.wrap = function(user, main) { }).call(this,require("/vagrant/node_modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js")) -},{"./content.coffee":5,"./i18n.coffee":6,"/vagrant/node_modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":2,"lodash":3,"moment":4}]},{},[1]) +},{"./content.coffee":5,"./i18n.coffee":6,"/vagrant/node_modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":2,"lodash":3,"moment":4}]},{},[1]) \ No newline at end of file diff --git a/script/index.coffee b/script/index.coffee index 4f56d19d2e..dd8a8203b7 100644 --- a/script/index.coffee +++ b/script/index.coffee @@ -245,13 +245,19 @@ api.taskClasses = (task, filters=[], dayStart=0, lastCron=+new Date, showComplet # Filters if main # only show when on your own list - for filter, enabled of filters - if enabled and not task.tags?[filter] - # All the other classes don't matter - return 'hidden' + if !task._editing # always show task being edited (even when tag removed) + for filter, enabled of filters + if enabled and not task.tags?[filter] + # All the other classes don't matter + return 'hidden' classes = type + if task._editing + classes += " beingEdited" # Assists filtering by third-party themes. + # Example: theme normally hides daily when not scheduled for today, + # BUT keeps showing daily when being edited to unschedule it for today + # show as completed if completed (naturally) or not required for today if type in ['todo', 'daily'] if completed or (type is 'daily' and !api.shouldDo(+new Date, task.repeat, {dayStart}))