From e6925d18eae7bd4d3533a0a8288a82d5b9094831 Mon Sep 17 00:00:00 2001 From: Lingpeng Zheng Date: Fri, 7 Nov 2025 14:51:07 -0500 Subject: [PATCH] Replace Moment.js with Luxon for date handling, updating relevant parsing and formatting functions throughout the codebase. Adjust manifest and README to reflect the change. Remove Moment.js library. --- README.md | 2 +- content/modules/parsing.js | 332 +++++++++++++++++++++++-------------- content/modules/ui.js | 105 +++++++++++- lib/luxon.min.js | 2 +- lib/moment.min.js | 2 - manifest.json | 2 +- 6 files changed, 306 insertions(+), 139 deletions(-) delete mode 100644 lib/moment.min.js diff --git a/README.md b/README.md index 46db812..713472f 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ TDX-Enhanced/ │ ├── ui.js # UI components (toolbar, status, styles injection) │ └── observer.js # MutationObserver for dynamic content └── lib/ - ├── moment.min.js # Moment.js for date manipulation + ├── luxon.min.js # Luxon for date and time handling └── tinycolor.min.js # TinyColor for color operations ``` diff --git a/content/modules/parsing.js b/content/modules/parsing.js index d1603c2..d6cb9d1 100644 --- a/content/modules/parsing.js +++ b/content/modules/parsing.js @@ -37,6 +37,165 @@ * - Configures links to open in new tabs */ +const luxonGlobals = window.luxon || null +const { DateTime: LuxonDateTime } = luxonGlobals || {} + +const COMMON_DATE_FORMATS = [ + "ccc M/d/yy h:mm a", + "ccc MM/dd/yyyy h:mm a", + "M/d/yy h:mm a", + "MM/dd/yyyy h:mm a", + "yyyy-MM-dd HH:mm:ss", + "yyyy-LL-dd'T'HH:mm:ss" +] + +const LEGACY_CALENDAR_PARSE_FORMATS = [ + "M/d/yyyy h:mm a", + "M/d/yy h:mm a", + "MM/dd/yyyy h:mm a", + "MM/dd/yy h:mm a" +] + +const LEGACY_CALENDAR_OUTPUT_FORMAT = "M/d/yyyy h:mm a" +const DATETIME_LOCAL_FORMAT = "yyyy-LL-dd'T'HH:mm" + +function parseDateTimeFlexible(value, options = {}) { + if (!LuxonDateTime || typeof value !== "string") { + return null + } + + const trimmedValue = value.trim() + if (!trimmedValue) { + return null + } + + const { + formats = COMMON_DATE_FORMATS, + strictFirst = true, + allowLoose = true + } = options + + if (strictFirst) { + for (const format of formats) { + const strictParse = LuxonDateTime.fromFormat(trimmedValue, format, { + locale: "en", + strict: true + }) + if (strictParse.isValid) { + return strictParse + } + } + } + + for (const format of formats) { + const parsed = LuxonDateTime.fromFormat(trimmedValue, format, { + locale: "en", + strict: false + }) + if (parsed.isValid) { + return parsed + } + } + + const isoParsed = LuxonDateTime.fromISO(trimmedValue) + if (isoParsed.isValid) { + return isoParsed + } + + const rfcParsed = LuxonDateTime.fromRFC2822(trimmedValue) + if (rfcParsed.isValid) { + return rfcParsed + } + + const sqlParsed = LuxonDateTime.fromSQL(trimmedValue) + if (sqlParsed.isValid) { + return sqlParsed + } + + if (allowLoose) { + const jsDate = new Date(trimmedValue) + if (!Number.isNaN(jsDate.getTime())) { + return LuxonDateTime.fromJSDate(jsDate) + } + } + + return null +} + +function formatRelativeFromNow(dateTime) { + if (!LuxonDateTime || !dateTime || !dateTime.isValid) { + return null + } + + return dateTime.toRelative({ + base: LuxonDateTime.now(), + locale: "en" + }) +} + +function formatCalendarLabel(dateTime) { + if (!LuxonDateTime || !dateTime || !dateTime.isValid) { + return "" + } + + const now = LuxonDateTime.now() + const dayDifference = dateTime.startOf("day").diff(now.startOf("day"), "days").days + const timePart = dateTime.toFormat("h:mm a") + + if (dayDifference === 0) { + return `Today at ${timePart}` + } + + if (dayDifference === 1) { + return `Tomorrow at ${timePart}` + } + + if (dayDifference === -1) { + return `Yesterday at ${timePart}` + } + + if (Math.abs(dayDifference) < 7) { + return `${dateTime.toFormat("cccc")} at ${timePart}` + } + + return dateTime.toLocaleString(LuxonDateTime.DATETIME_MED) +} + +function applyMomentLikeSet(dateTime, setArgs = {}) { + if (!LuxonDateTime || !dateTime || !dateTime.isValid) { + return dateTime + } + + let result = dateTime + + if (Object.prototype.hasOwnProperty.call(setArgs, "d")) { + const target = setArgs.d + if (typeof target === "number" && Number.isFinite(target)) { + const currentMomentDay = result.weekday % 7 + const daysToShift = target - currentMomentDay + result = result.plus({ days: daysToShift }) + } + } + + if (Object.prototype.hasOwnProperty.call(setArgs, "h")) { + result = result.set({ hour: setArgs.h }) + } + + if (Object.prototype.hasOwnProperty.call(setArgs, "m")) { + result = result.set({ minute: setArgs.m }) + } + + return result +} + +window._tdxDateUtils = Object.assign(window._tdxDateUtils || {}, { + parseDateTime: parseDateTimeFlexible, + formatRelativeFromNow, + formatCalendarLabel, + DATETIME_LOCAL_FORMAT, + LEGACY_CALENDAR_OUTPUT_FORMAT +}) + /** * Updates heading elements with highlighting and embed functionality * @param {HTMLElement} mutation - The DOM element containing headings to update @@ -92,98 +251,82 @@ function parseTicket(mutation = null) { // Currently handles start and end dates for tasks let calendarInputs = document.querySelectorAll("#txtStartDate, #txtEndDate") if (calendarInputs && calendarInputs.length > 0) { - let originalFormat = "M/D/YYYY h:mm A"; - let newFormat = "YYYY-MM-DDTHH:mm"; - [...calendarInputs].forEach(calendarInput => { - // Parse existing date value - let dateMoment = window.moment(calendarInput.value, originalFormat) + let calendarDateTime = parseDateTimeFlexible(calendarInput.value, { + formats: LEGACY_CALENDAR_PARSE_FORMATS + }) - // Create new modern datetime-local input let newCalendarInput = document.createElement("input") newCalendarInput.id = `${calendarInput.id}-new` newCalendarInput.classList = calendarInput.classList newCalendarInput.type = "datetime-local" - // Create container for date modifier buttons let calendarButtonContainer = document.createElement("div") calendarButtonContainer.classList = ["calBox"] - // Create text element to display day of week and relative time let calendarText = document.createElement("span") - if (dateMoment && dateMoment.isValid()) { - calendarText.textContent = dateMoment.format('dddd') + if (calendarDateTime && calendarDateTime.isValid) { + calendarText.textContent = calendarDateTime.toFormat("cccc") } - /** - * Updates both the old TDX calendar input and new datetime-local input - * Also updates the calendar text display - */ function updateDate() { - if (!dateMoment || !dateMoment.isValid()) { + if (!calendarDateTime || !calendarDateTime.isValid) { return } - - // Update old TDX calendar input with original format - let parsedFormat = dateMoment.format(originalFormat) - calendarInput.value = parsedFormat - // Update new datetime-local calendar input with ISO format - let isoFormat = dateMoment.format(newFormat) - newCalendarInput.value = isoFormat - - // Update calendar text with relative time (e.g., "Today at 2:30 PM") + const legacyFormatValue = calendarDateTime.toFormat(LEGACY_CALENDAR_OUTPUT_FORMAT) + calendarInput.value = legacyFormatValue + + const isoFormatValue = calendarDateTime.toFormat(DATETIME_LOCAL_FORMAT) + newCalendarInput.value = isoFormatValue + if (calendarText) { - calendarText.textContent = dateMoment.calendar() + calendarText.textContent = formatCalendarLabel(calendarDateTime) } } - // Listen for changes to the new datetime-local input - // Convert back to original format when user changes the date newCalendarInput.addEventListener("input", event => { - let parsedValue = window.moment(event.target.value, newFormat) - if (parsedValue && parsedValue.isValid()) { - dateMoment = parsedValue + const parsedValue = parseDateTimeFlexible(event.target.value, { + formats: [DATETIME_LOCAL_FORMAT], + allowLoose: false + }) + + if (parsedValue && parsedValue.isValid) { + calendarDateTime = parsedValue updateDate() } }) - /** - * Modifies the date based on button configuration - * Handles business day logic (skips weekends, adjusts for after-hours) - * @param {Object} buttonConfig - Button configuration with 'add' or 'set' properties - */ function modifyDate(buttonConfig) { - if (!dateMoment || !dateMoment.isValid()) { + if (!calendarDateTime || !calendarDateTime.isValid) { return } - // Apply date modification (add time or set specific time) - if ('add' in buttonConfig) { - dateMoment.add(buttonConfig.add) - } else if ('set' in buttonConfig) { - dateMoment.set(buttonConfig.set) + let updatedDate = calendarDateTime + + if (Object.prototype.hasOwnProperty.call(buttonConfig, "add")) { + updatedDate = updatedDate.plus(buttonConfig.add) + } else if (Object.prototype.hasOwnProperty.call(buttonConfig, "set")) { + updatedDate = applyMomentLikeSet(updatedDate, buttonConfig.set) } - // Check if date falls on weekend or after business hours - let dayOfWeek = dateMoment.isoWeekday() // 1=Monday, 7=Sunday - let hour = dateMoment.hour() - let minute = dateMoment.minute() + const dayOfWeek = updatedDate.weekday + const hour = updatedDate.hour + const minute = updatedDate.minute - // If Friday after 5pm, move to next Monday at 8am if (dayOfWeek >= 5 && (hour > 17 || (hour === 17 && minute > 0))) { - dateMoment.set({ + updatedDate = applyMomentLikeSet(updatedDate, { h: 8, - d: dateMoment.date() + 7, + d: updatedDate.day + 7, m: 0 }) } else if (dayOfWeek > 5) { - // If Saturday or Sunday, move to next Monday - dateMoment.set({ - d: dateMoment.date() + 7 + updatedDate = applyMomentLikeSet(updatedDate, { + d: updatedDate.day + 7 }) } + calendarDateTime = updatedDate updateDate() } @@ -208,7 +351,6 @@ function parseTicket(mutation = null) { calendarButtonContainer.appendChild(buttonElement) } - // Initialize the date display updateDate() // Hide old calendar input (still needed for format conversion) @@ -465,8 +607,6 @@ function parseItem(item) { continue } - // Skip if already a relative time string (e.g., "3 hours ago", "in 2 days", "a few seconds ago") - // This prevents trying to parse already-converted relative times let textTrimmed = dateText.trim().toLowerCase() let isRelativeTime = textTrimmed.endsWith("ago") || textTrimmed.includes("from now") || @@ -475,68 +615,32 @@ function parseItem(item) { continue } - // Try parsing with common date formats first (strict mode) - let dateMoment = window.moment(dateText, [ - "ddd M/D/YY h:mm A", - "ddd MM/DD/YYYY h:mm A", - "M/D/YY h:mm A", - "MM/DD/YYYY h:mm A", - "YYYY-MM-DD HH:mm:ss", - "YYYY-MM-DDTHH:mm:ss" - ], true) - - // Only try loose parsing if strict parsing failed and it doesn't look like a relative time - if (!dateMoment.isValid()) { - // Check if it looks like a date format before trying loose parsing - // Skip if it's clearly not a date (e.g., relative time strings) - if (!relativeTimePattern.test(dateText.trim())) { - dateMoment = window.moment(dateText) - } - } - - // Convert to relative time format and update cell - if (dateMoment.isValid()) { - let relativeTimeText = dateMoment.fromNow() - if (relativeTimeText && relativeTimeText !== "Invalid date") { + let parsedDate = parseDateTimeFlexible(dateText) + if (parsedDate && parsedDate.isValid) { + let relativeTimeText = formatRelativeFromNow(parsedDate) + if (relativeTimeText) { dateCell.textContent = relativeTimeText } } } } - // Format detailed dates with calendar format (e.g., "Today at 2:30 PM", "Tomorrow at 9:00 AM") let detailedDateColumns = ['Date Due', 'Due', 'Created', 'Start'] for (const dateColumnName of detailedDateColumns) { if (dateColumnName in item) { let dateText = item[dateColumnName].txt let dateCell = item[dateColumnName].cell - // Try parsing with common date formats first (strict mode) - let dateMoment = window.moment(dateText, [ - "ddd M/D/YY h:mm A", - "ddd MM/DD/YYYY h:mm A", - "M/D/YY h:mm A", - "MM/DD/YYYY h:mm A", - "YYYY-MM-DD HH:mm:ss", - "YYYY-MM-DDTHH:mm:ss" - ], true) - - // If strict parsing fails, try without strict mode - if (!dateMoment.isValid()) { - dateMoment = window.moment(dateText) - } - - // Convert to calendar format and update cell - if (dateMoment.isValid()) { - let calendarFormatText = dateMoment.calendar() - if (calendarFormatText && calendarFormatText !== "Invalid date") { + let parsedDate = parseDateTimeFlexible(dateText) + if (parsedDate && parsedDate.isValid) { + let calendarFormatText = formatCalendarLabel(parsedDate) + if (calendarFormatText) { dateCell.textContent = calendarFormatText } } } } - // Highlight modified dates based on age (older = more red/intense) let modifiedDateColumns = ['Modified'] for (const dateColumnName of modifiedDateColumns) { if (dateColumnName in item) { @@ -545,10 +649,8 @@ function parseItem(item) { continue } - // Age threshold in hours (336 hours = 14 days) const ageThresholdHours = 336 - // Skip if already a relative time string - we can't calculate age from it let textTrimmed = modifiedDateData.txt.trim().toLowerCase() let isRelativeTime = textTrimmed.endsWith("ago") || textTrimmed.includes("from now") || @@ -557,40 +659,18 @@ function parseItem(item) { continue } - // Try parsing with common date formats first (strict mode) - let dateMoment = window.moment(modifiedDateData.txt, [ - "ddd M/D/YY h:mm A", - "ddd MM/DD/YYYY h:mm A", - "M/D/YY h:mm A", - "MM/DD/YYYY h:mm A", - "YYYY-MM-DD HH:mm:ss", - "YYYY-MM-DDTHH:mm:ss" - ], true) - - // Only try loose parsing if strict parsing failed and it doesn't look like a relative time - if (!dateMoment.isValid()) { - if (!isRelativeTime) { - dateMoment = window.moment(modifiedDateData.txt) - } - } - - // Only highlight if we have a valid date - if (!dateMoment.isValid()) { + let parsedDate = parseDateTimeFlexible(modifiedDateData.txt) + if (!parsedDate || !parsedDate.isValid || !LuxonDateTime) { continue } - - // Calculate age in hours - let duration = window.moment.duration(window.moment().diff(dateMoment)) - let ageInHours = duration.asHours() - // Calculate alpha value (0-1) based on age, capped at 1 + let ageInHours = LuxonDateTime.now().diff(parsedDate, 'hours').hours + let ageAlpha = ageInHours / ageThresholdHours ageAlpha = ageAlpha > 1 ? 1 : ageAlpha - // Apply highlighting based on age (higher alpha = older = more intense) let dateCell = modifiedDateData.cell handleHighlight("dateModified", ageAlpha, dateCell) - // Add class for text color contrast (light text for dark backgrounds, dark for light) dateCell.classList.add(ageAlpha > 0.5 ? "light" : "dark") } } diff --git a/content/modules/ui.js b/content/modules/ui.js index 14ed440..35842a2 100644 --- a/content/modules/ui.js +++ b/content/modules/ui.js @@ -200,15 +200,104 @@ async function injectToolbar() { statusIcon.className = "fa-solid fa-check" } - if (statusData.time) { - // Try to parse the time - it might be a date string or already a relative time - let statusTimeParsed = window.moment(statusData.time) - if (statusTimeParsed.isValid()) { - statusTime.textContent = statusTimeParsed.fromNow() + if (statusData.time !== undefined && statusData.time !== null) { + // added so much bs parsing code here because the status page is a mess + // this migration from moment.js to luxon is a pain + // ts pmo + const LuxonDateTime = (window.luxon && window.luxon.DateTime) || null + const dateUtils = window._tdxDateUtils || {} + const rawTimeValue = statusData.time + const normalizedString = (typeof rawTimeValue === "string") ? rawTimeValue.trim() : null + let statusTimeParsed = null + + if (typeof dateUtils.parseDateTime === "function") { + statusTimeParsed = dateUtils.parseDateTime(rawTimeValue, { + strictFirst: false + }) + } + if ((!statusTimeParsed || !statusTimeParsed.isValid) && LuxonDateTime) { + if (normalizedString) { + statusTimeParsed = LuxonDateTime.fromISO(normalizedString) + if (!statusTimeParsed.isValid) { + statusTimeParsed = LuxonDateTime.fromRFC2822(normalizedString) + } + if (!statusTimeParsed.isValid) { + statusTimeParsed = LuxonDateTime.fromSQL(normalizedString) + } + } + + if ((!statusTimeParsed || !statusTimeParsed.isValid) && typeof rawTimeValue === "number" && Number.isFinite(rawTimeValue)) { + statusTimeParsed = LuxonDateTime.fromMillis(rawTimeValue) + } + + if ((!statusTimeParsed || !statusTimeParsed.isValid) && rawTimeValue instanceof Date) { + statusTimeParsed = LuxonDateTime.fromJSDate(rawTimeValue) + } + + if ((!statusTimeParsed || !statusTimeParsed.isValid) && rawTimeValue && typeof rawTimeValue === "object" && !(rawTimeValue instanceof Date)) { + const candidateKeys = ["time", "Time", "date", "Date", "timestamp", "Timestamp"] + for (const key of candidateKeys) { + if (!Object.prototype.hasOwnProperty.call(rawTimeValue, key)) { + continue + } + + const candidateValue = rawTimeValue[key] + if (typeof candidateValue === "string" && candidateValue.trim()) { + const candidateString = candidateValue.trim() + statusTimeParsed = LuxonDateTime.fromISO(candidateString) + if (!statusTimeParsed.isValid) { + statusTimeParsed = LuxonDateTime.fromRFC2822(candidateString) + } + if (!statusTimeParsed.isValid) { + statusTimeParsed = LuxonDateTime.fromSQL(candidateString) + } + } else if (typeof candidateValue === "number" && Number.isFinite(candidateValue)) { + statusTimeParsed = LuxonDateTime.fromMillis(candidateValue) + } else if (candidateValue instanceof Date) { + statusTimeParsed = LuxonDateTime.fromJSDate(candidateValue) + } + + if (statusTimeParsed && statusTimeParsed.isValid) { + break + } + } + } + + if ((!statusTimeParsed || !statusTimeParsed.isValid) && normalizedString) { + const fallbackDate = new Date(normalizedString) + if (!Number.isNaN(fallbackDate.getTime())) { + statusTimeParsed = LuxonDateTime.fromJSDate(fallbackDate) + } + } + + if ((!statusTimeParsed || !statusTimeParsed.isValid)) { + const fallbackDate = new Date(rawTimeValue) + if (!Number.isNaN(fallbackDate.getTime())) { + statusTimeParsed = LuxonDateTime.fromJSDate(fallbackDate) + } + } + } + + if (statusTimeParsed && statusTimeParsed.isValid) { + let relativeText = null + if (typeof dateUtils.formatRelativeFromNow === "function") { + relativeText = dateUtils.formatRelativeFromNow(statusTimeParsed) + } else if (LuxonDateTime && typeof statusTimeParsed.toRelative === "function") { + relativeText = statusTimeParsed.toRelative({ + base: LuxonDateTime.now(), + locale: "en" + }) + } + + if (relativeText) { + statusTime.textContent = relativeText + } else if (LuxonDateTime) { + statusTime.textContent = statusTimeParsed.toLocaleString(LuxonDateTime.DATETIME_MED) + } else { + statusTime.textContent = normalizedString ?? "" + } } else { - // If it's not a valid date, it might already be a relative time string - // Just display it as-is - statusTime.textContent = statusData.time + statusTime.textContent = normalizedString ?? "" } } statusText.textContent = statusData.msg diff --git a/lib/luxon.min.js b/lib/luxon.min.js index 9a5a8c3..9b01303 100644 --- a/lib/luxon.min.js +++ b/lib/luxon.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var H;function f(){return H.apply(null,arguments)}function a(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function F(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function c(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function L(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(c(e,t))return;return 1}function o(e){return void 0===e}function u(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function V(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function G(e,t){for(var n=[],s=e.length,i=0;i>>0,s=0;sWe(e)?(r=e+1,t-We(e)):(r=e,t);return{year:r,dayOfYear:n}}function Be(e,t,n){var s,i,r=qe(e.year(),t,n),r=Math.floor((e.dayOfYear()-r-1)/7)+1;return r<1?s=r+N(i=e.year()-1,t,n):r>N(e.year(),t,n)?(s=r-N(e.year(),t,n),i=e.year()+1):(i=e.year(),s=r),{week:s,year:i}}function N(e,t,n){var s=qe(e,t,n),t=qe(e+1,t,n);return(We(e)-s+t)/7}s("w",["ww",2],"wo","week"),s("W",["WW",2],"Wo","isoWeek"),w("w",n,y),w("ww",n,t),w("W",n,y),w("WW",n,t),Oe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=M(e)});function Je(e,t){return e.slice(t,7).concat(e.slice(0,t))}s("d",0,"do","day"),s("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),s("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),s("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),s("e",0,0,"weekday"),s("E",0,0,"isoWeekday"),w("d",n),w("e",n),w("E",n),w("dd",function(e,t){return t.weekdaysMinRegex(e)}),w("ddd",function(e,t){return t.weekdaysShortRegex(e)}),w("dddd",function(e,t){return t.weekdaysRegex(e)}),Oe(["dd","ddd","dddd"],function(e,t,n,s){s=n._locale.weekdaysParse(e,s,n._strict);null!=s?t.d=s:m(n).invalidWeekday=e}),Oe(["d","e","E"],function(e,t,n,s){t[s]=M(e)});var Qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Xe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ke="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),et=i,tt=i,nt=i;function st(){function e(e,t){return t.length-e.length}for(var t,n,s,i=[],r=[],a=[],o=[],u=0;u<7;u++)s=l([2e3,1]).day(u),t=p(this.weekdaysMin(s,"")),n=p(this.weekdaysShort(s,"")),s=p(this.weekdays(s,"")),i.push(t),r.push(n),a.push(s),o.push(t),o.push(n),o.push(s);i.sort(e),r.sort(e),a.sort(e),o.sort(e),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function it(){return this.hours()%12||12}function rt(e,t){s(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function at(e,t){return t._meridiemParse}s("H",["HH",2],0,"hour"),s("h",["hh",2],0,it),s("k",["kk",2],0,function(){return this.hours()||24}),s("hmm",0,0,function(){return""+it.apply(this)+r(this.minutes(),2)}),s("hmmss",0,0,function(){return""+it.apply(this)+r(this.minutes(),2)+r(this.seconds(),2)}),s("Hmm",0,0,function(){return""+this.hours()+r(this.minutes(),2)}),s("Hmmss",0,0,function(){return""+this.hours()+r(this.minutes(),2)+r(this.seconds(),2)}),rt("a",!0),rt("A",!1),w("a",at),w("A",at),w("H",n,g),w("h",n,y),w("k",n,y),w("HH",n,t),w("hh",n,t),w("kk",n,t),w("hmm",me),w("hmmss",_e),w("Hmm",me),w("Hmmss",_e),v(["H","HH"],O),v(["k","kk"],function(e,t,n){e=M(e);t[O]=24===e?0:e}),v(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),v(["h","hh"],function(e,t,n){t[O]=M(e),m(n).bigHour=!0}),v("hmm",function(e,t,n){var s=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s)),m(n).bigHour=!0}),v("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s,2)),t[T]=M(e.substr(i)),m(n).bigHour=!0}),v("Hmm",function(e,t,n){var s=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s))}),v("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s,2)),t[T]=M(e.substr(i))});i=Re("Hours",!0);var ot,ut={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{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",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Fe,monthsShort:Le,week:{dow:0,doy:6},weekdays:Qe,weekdaysMin:Ke,weekdaysShort:Xe,meridiemParse:/[ap]\.?m?\.?/i},W={},lt={};function dt(e){return e&&e.toLowerCase().replace("_","-")}function ht(e){for(var t,n,s,i,r=0;r=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s=t-1)break;t--}r++}return ot}function ct(t){var e,n;if(void 0===W[t]&&"undefined"!=typeof module&&module&&module.exports&&((n=t)&&n.match("^[^/\\\\]*$")))try{e=ot._abbr,require("./locale/"+t),ft(e)}catch(e){W[t]=null}return W[t]}function ft(e,t){return e&&((t=o(t)?P(e):mt(e,t))?ot=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ot._abbr}function mt(e,t){if(null===t)return delete W[e],null;var n,s=ut;if(t.abbr=e,null!=W[e])Q("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=W[e]._config;else if(null!=t.parentLocale)if(null!=W[t.parentLocale])s=W[t.parentLocale]._config;else{if(null==(n=ct(t.parentLocale)))return lt[t.parentLocale]||(lt[t.parentLocale]=[]),lt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return W[e]=new K(X(s,t)),lt[e]&<[e].forEach(function(e){mt(e.name,e.config)}),ft(e),W[e]}function P(e){var t;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return ot;if(!a(e)){if(t=ct(e))return t;e=[e]}return ht(e)}function _t(e){var t=e._a;return t&&-2===m(e).overflow&&(t=t[Y]<0||11He(t[D],t[Y])?S:t[O]<0||24N(r,u,l)?m(s)._overflowWeeks=!0:null!=d?m(s)._overflowWeekday=!0:(h=$e(r,a,o,u,l),s._a[D]=h.year,s._dayOfYear=h.dayOfYear)),null!=e._dayOfYear&&(i=bt(e._a[D],n[D]),(e._dayOfYear>We(i)||0===e._dayOfYear)&&(m(e)._overflowDayOfYear=!0),d=ze(i,0,e._dayOfYear),e._a[Y]=d.getUTCMonth(),e._a[S]=d.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=n[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[O]&&0===e._a[b]&&0===e._a[T]&&0===e._a[Te]&&(e._nextDay=!0,e._a[O]=0),e._d=(e._useUTC?ze:Ze).apply(null,c),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[O]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(m(e).weekdayMismatch=!0)}}function xt(e){if(e._f===f.ISO_8601)Yt(e);else if(e._f===f.RFC_2822)Ot(e);else{e._a=[],m(e).empty=!0;for(var t,n,s,i,r,a=""+e._i,o=a.length,u=0,l=ae(e._f,e._locale).match(te)||[],d=l.length,h=0;he.valueOf():e.valueOf()"}),y.toJSON=function(){return this.isValid()?this.toISOString():null},y.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},y.unix=function(){return Math.floor(this.valueOf()/1e3)},y.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},y.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},y.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;nthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},y.isLocal=function(){return!!this.isValid()&&!this._isUTC},y.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},y.isUtc=At,y.isUTC=At,y.zoneAbbr=function(){return this._isUTC?"UTC":""},y.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},y.dates=e("dates accessor is deprecated. Use date instead.",ge),y.months=e("months accessor is deprecated. Use month instead",Ie),y.years=e("years accessor is deprecated. Use year instead",Pe),y.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,t),this):-this.utcOffset()}),y.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e,t={};return q(t,this),(t=Nt(t))._a?(e=(t._isUTC?l:R)(t._a),this._isDSTShifted=this.isValid()&&0e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[n++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var t=function(e){function t(){return e.apply(this,arguments)||this}return o(t,e),t}(q(Error)),P=function(t){function e(e){return t.call(this,"Invalid DateTime: "+e.toMessage())||this}return o(e,t),e}(t),Y=function(t){function e(e){return t.call(this,"Invalid Interval: "+e.toMessage())||this}return o(e,t),e}(t),H=function(t){function e(e){return t.call(this,"Invalid Duration: "+e.toMessage())||this}return o(e,t),e}(t),w=function(e){function t(){return e.apply(this,arguments)||this}return o(t,e),t}(t),J=function(t){function e(e){return t.call(this,"Invalid unit "+e)||this}return o(e,t),e}(t),u=function(e){function t(){return e.apply(this,arguments)||this}return o(t,e),t}(t),n=function(e){function t(){return e.call(this,"Zone is an abstract class")||this}return o(t,e),t}(t),t="numeric",r="short",a="long",G={year:t,month:t,day:t},$={year:t,month:r,day:t},B={year:t,month:r,day:t,weekday:r},Q={year:t,month:a,day:t},K={year:t,month:a,day:t,weekday:a},X={hour:t,minute:t},ee={hour:t,minute:t,second:t},te={hour:t,minute:t,second:t,timeZoneName:r},ne={hour:t,minute:t,second:t,timeZoneName:a},re={hour:t,minute:t,hourCycle:"h23"},ie={hour:t,minute:t,second:t,hourCycle:"h23"},oe={hour:t,minute:t,second:t,hourCycle:"h23",timeZoneName:r},ae={hour:t,minute:t,second:t,hourCycle:"h23",timeZoneName:a},se={year:t,month:t,day:t,hour:t,minute:t},ue={year:t,month:t,day:t,hour:t,minute:t,second:t},le={year:t,month:r,day:t,hour:t,minute:t},ce={year:t,month:r,day:t,hour:t,minute:t,second:t},fe={year:t,month:r,day:t,weekday:r,hour:t,minute:t},de={year:t,month:a,day:t,hour:t,minute:t,timeZoneName:r},he={year:t,month:a,day:t,hour:t,minute:t,second:t,timeZoneName:r},me={year:t,month:a,day:t,weekday:a,hour:t,minute:t,timeZoneName:a},ye={year:t,month:a,day:t,weekday:a,hour:t,minute:t,second:t,timeZoneName:a},s=function(){function e(){}var t=e.prototype;return t.offsetName=function(e,t){throw new n},t.formatOffset=function(e,t){throw new n},t.offset=function(e){throw new n},t.equals=function(e){throw new n},i(e,[{key:"type",get:function(){throw new n}},{key:"name",get:function(){throw new n}},{key:"ianaName",get:function(){return this.name}},{key:"isUniversal",get:function(){throw new n}},{key:"isValid",get:function(){throw new n}}]),e}(),ve=null,ge=function(e){function t(){return e.apply(this,arguments)||this}o(t,e);var n=t.prototype;return n.offsetName=function(e,t){return Ot(e,t.format,t.locale)},n.formatOffset=function(e,t){return Dt(this.offset(e),t)},n.offset=function(e){return-new Date(e).getTimezoneOffset()},n.equals=function(e){return"system"===e.type},i(t,[{key:"type",get:function(){return"system"}},{key:"name",get:function(){return(new Intl.DateTimeFormat).resolvedOptions().timeZone}},{key:"isUniversal",get:function(){return!1}},{key:"isValid",get:function(){return!0}}],[{key:"instance",get:function(){return ve=null===ve?new t:ve}}]),t}(s),pe=new Map;var ke={year:0,month:1,day:2,era:3,hour:4,minute:5,second:6};var we=new Map,c=function(n){function r(e){var t=n.call(this)||this;return t.zoneName=e,t.valid=r.isValidZone(e),t}o(r,n),r.create=function(e){var t=we.get(e);return void 0===t&&we.set(e,t=new r(e)),t},r.resetCache=function(){we.clear(),pe.clear()},r.isValidSpecifier=function(e){return this.isValidZone(e)},r.isValidZone=function(e){if(!e)return!1;try{return new Intl.DateTimeFormat("en-US",{timeZone:e}).format(),!0}catch(e){return!1}};var e=r.prototype;return e.offsetName=function(e,t){return Ot(e,t.format,t.locale,this.name)},e.formatOffset=function(e,t){return Dt(this.offset(e),t)},e.offset=function(e){var t,n,r,i,o,a,s,u;return!this.valid||(e=new Date(e),isNaN(e))?NaN:(i=this.name,void 0===(o=pe.get(i))&&(o=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:i,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",era:"short"}),pe.set(i,o)),a=(i=(i=o).formatToParts?function(e,t){for(var n=e.formatToParts(t),r=[],i=0;ibt(i,t,n)?(r=i+1,a=1):r=i,l({weekYear:r,weekNumber:a,weekday:o},It(e))}function it(e,t,n){void 0===n&&(n=1);var r,i=e.weekYear,o=e.weekNumber,a=e.weekday,n=nt(Xe(i,1,t=void 0===t?4:t),n),s=D(i),o=7*o+a-n-7+t,a=(o<1?o+=D(r=i-1):sO.twoDigitCutoffYear?1900+e:2e3+e}function Ot(e,t,n,r){void 0===r&&(r=null);var e=new Date(e),i={hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"},r=(r&&(i.timeZone=r),l({timeZoneName:t},i)),t=new Intl.DateTimeFormat(n,r).formatToParts(e).find(function(e){return"timezonename"===e.type.toLowerCase()});return t?t.value:null}function Tt(e,t){e=parseInt(e,10),Number.isNaN(e)&&(e=0),t=parseInt(t,10)||0;return 60*e+(e<0||Object.is(e,-0)?-t:t)}function Nt(e){var t=Number(e);if("boolean"!=typeof e&&""!==e&&Number.isFinite(t))return t;throw new u("Invalid unit value "+e)}function Mt(e,t){var n,r,i={};for(n in e)h(e,n)&&null!=(r=e[n])&&(i[t(n)]=Nt(r));return i}function Dt(e,t){var n=Math.trunc(Math.abs(e/60)),r=Math.trunc(Math.abs(e%60)),i=0<=e?"+":"-";switch(t){case"short":return i+m(n,2)+":"+m(r,2);case"narrow":return i+n+(0e},t.isBefore=function(e){return!!this.isValid&&this.e<=e},t.contains=function(e){return!!this.isValid&&this.s<=e&&this.e>e},t.set=function(e){var e=void 0===e?{}:e,t=e.start,e=e.end;return this.isValid?l.fromDateTimes(t||this.s,e||this.e):this},t.splitAt=function(){var t=this;if(!this.isValid)return[];for(var e=arguments.length,n=new Array(e),r=0;r+this.e?this.e:u;o.push(l.fromDateTimes(a,u)),a=u,s+=1}return o},t.splitBy=function(e){var t=x.fromDurationLike(e);if(!this.isValid||!t.isValid||0===t.as("milliseconds"))return[];for(var n=this.s,r=1,i=[];n+this.e?this.e:o;i.push(l.fromDateTimes(n,o)),n=o,r+=1}return i},t.divideEqually=function(e){return this.isValid?this.splitBy(this.length()/e).slice(0,e):[]},t.overlaps=function(e){return this.e>e.s&&this.s=e.e},t.equals=function(e){return!(!this.isValid||!e.isValid)&&this.s.equals(e.s)&&this.e.equals(e.e)},t.intersection=function(e){var t;return this.isValid?(t=(this.s>e.s?this:e).s,(e=(this.ee.e?this:e).e,l.fromDateTimes(t,e)):this},l.merge=function(e){var e=e.sort(function(e,t){return e.s-t.s}).reduce(function(e,t){var n=e[0],e=e[1];return e?e.overlaps(t)||e.abutsStart(t)?[n,e.union(t)]:[n.concat([e]),t]:[n,t]},[[],null]),t=e[0],e=e[1];return e&&t.push(e),t},l.xor=function(e){for(var t,n=null,r=0,i=[],e=e.map(function(e){return[{time:e.s,type:"s"},{time:e.e,type:"e"}]}),o=R((t=Array.prototype).concat.apply(t,e).sort(function(e,t){return e.time-t.time}));!(a=o()).done;)var a=a.value,n=1===(r+="s"===a.type?1:-1)?a.time:(n&&+n!=+a.time&&i.push(l.fromDateTimes(n,a.time)),null);return l.merge(i)},t.difference=function(){for(var t=this,e=arguments.length,n=new Array(e),r=0;rthis.valueOf())?this:e,r?e:this,t,n),r?e.negate():e):x.invalid("created by diffing an invalid DateTime")},t.diffNow=function(e,t){return void 0===e&&(e="milliseconds"),void 0===t&&(t={}),this.diff(k.now(),e,t)},t.until=function(e){return this.isValid?Zn.fromDateTimes(this,e):this},t.hasSame=function(e,t,n){var r;return!!this.isValid&&(r=e.valueOf(),(e=this.setZone(e.zone,{keepLocalTime:!0})).startOf(t,n)<=r)&&r<=e.endOf(t,n)},t.equals=function(e){return this.isValid&&e.isValid&&this.valueOf()===e.valueOf()&&this.zone.equals(e.zone)&&this.loc.equals(e.loc)},t.toRelative=function(e){var t,n,r,i;return this.isValid?(t=(e=void 0===e?{}:e).base||k.fromObject({},{zone:this.zone}),n=e.padding?thisthis.set({month:1,day:1}).offset||this.offset>this.set({month:5}).offset)}},{key:"isInLeapYear",get:function(){return gt(this.year)}},{key:"daysInMonth",get:function(){return pt(this.year,this.month)}},{key:"daysInYear",get:function(){return this.isValid?D(this.year):NaN}},{key:"weeksInWeekYear",get:function(){return this.isValid?bt(this.weekYear):NaN}},{key:"weeksInLocalWeekYear",get:function(){return this.isValid?bt(this.localWeekYear,this.loc.getMinDaysInFirstWeek(),this.loc.getStartOfWeek()):NaN}}],[{key:"DATE_SHORT",get:function(){return G}},{key:"DATE_MED",get:function(){return $}},{key:"DATE_MED_WITH_WEEKDAY",get:function(){return B}},{key:"DATE_FULL",get:function(){return Q}},{key:"DATE_HUGE",get:function(){return K}},{key:"TIME_SIMPLE",get:function(){return X}},{key:"TIME_WITH_SECONDS",get:function(){return ee}},{key:"TIME_WITH_SHORT_OFFSET",get:function(){return te}},{key:"TIME_WITH_LONG_OFFSET",get:function(){return ne}},{key:"TIME_24_SIMPLE",get:function(){return re}},{key:"TIME_24_WITH_SECONDS",get:function(){return ie}},{key:"TIME_24_WITH_SHORT_OFFSET",get:function(){return oe}},{key:"TIME_24_WITH_LONG_OFFSET",get:function(){return ae}},{key:"DATETIME_SHORT",get:function(){return se}},{key:"DATETIME_SHORT_WITH_SECONDS",get:function(){return ue}},{key:"DATETIME_MED",get:function(){return le}},{key:"DATETIME_MED_WITH_SECONDS",get:function(){return ce}},{key:"DATETIME_MED_WITH_WEEKDAY",get:function(){return fe}},{key:"DATETIME_FULL",get:function(){return de}},{key:"DATETIME_FULL_WITH_SECONDS",get:function(){return he}},{key:"DATETIME_HUGE",get:function(){return me}},{key:"DATETIME_HUGE_WITH_SECONDS",get:function(){return ye}}]),k}(Symbol.for("nodejs.util.inspect.custom"));function Or(e){if(W.isDateTime(e))return e;if(e&&e.valueOf&&v(e.valueOf()))return W.fromJSDate(e);if(e&&"object"==typeof e)return W.fromObject(e);throw new u("Unknown datetime argument: "+e+", of type "+typeof e)}return e.DateTime=W,e.Duration=x,e.FixedOffsetZone=f,e.IANAZone=c,e.Info=Wn,e.Interval=Zn,e.InvalidZone=ze,e.Settings=O,e.SystemZone=ge,e.VERSION="3.7.2",e.Zone=s,Object.defineProperty(e,"__esModule",{value:!0}),e}({}); \ No newline at end of file diff --git a/lib/moment.min.js b/lib/moment.min.js deleted file mode 100644 index 8b80f20..0000000 --- a/lib/moment.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var H;function _(){return H.apply(null,arguments)}function y(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function F(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function c(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function L(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(c(e,t))return;return 1}function g(e){return void 0===e}function w(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function V(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function G(e,t){for(var n=[],s=e.length,i=0;i>>0,s=0;sWe(e)?(r=e+1,t-We(e)):(r=e,t);return{year:r,dayOfYear:n}}function Be(e,t,n){var s,i,r=qe(e.year(),t,n),r=Math.floor((e.dayOfYear()-r-1)/7)+1;return r<1?s=r+N(i=e.year()-1,t,n):r>N(e.year(),t,n)?(s=r-N(e.year(),t,n),i=e.year()+1):(i=e.year(),s=r),{week:s,year:i}}function N(e,t,n){var s=qe(e,t,n),t=qe(e+1,t,n);return(We(e)-s+t)/7}s("w",["ww",2],"wo","week"),s("W",["WW",2],"Wo","isoWeek"),h("w",n,u),h("ww",n,t),h("W",n,u),h("WW",n,t),Oe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=M(e)});function Je(e,t){return e.slice(t,7).concat(e.slice(0,t))}s("d",0,"do","day"),s("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),s("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),s("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),s("e",0,0,"weekday"),s("E",0,0,"isoWeekday"),h("d",n),h("e",n),h("E",n),h("dd",function(e,t){return t.weekdaysMinRegex(e)}),h("ddd",function(e,t){return t.weekdaysShortRegex(e)}),h("dddd",function(e,t){return t.weekdaysRegex(e)}),Oe(["dd","ddd","dddd"],function(e,t,n,s){s=n._locale.weekdaysParse(e,s,n._strict);null!=s?t.d=s:p(n).invalidWeekday=e}),Oe(["d","e","E"],function(e,t,n,s){t[s]=M(e)});var Qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Xe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ke="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),et=i,tt=i,nt=i;function st(){function e(e,t){return t.length-e.length}for(var t,n,s,i=[],r=[],a=[],o=[],u=0;u<7;u++)s=l([2e3,1]).day(u),t=f(this.weekdaysMin(s,"")),n=f(this.weekdaysShort(s,"")),s=f(this.weekdays(s,"")),i.push(t),r.push(n),a.push(s),o.push(t),o.push(n),o.push(s);i.sort(e),r.sort(e),a.sort(e),o.sort(e),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function it(){return this.hours()%12||12}function rt(e,t){s(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function at(e,t){return t._meridiemParse}s("H",["HH",2],0,"hour"),s("h",["hh",2],0,it),s("k",["kk",2],0,function(){return this.hours()||24}),s("hmm",0,0,function(){return""+it.apply(this)+r(this.minutes(),2)}),s("hmmss",0,0,function(){return""+it.apply(this)+r(this.minutes(),2)+r(this.seconds(),2)}),s("Hmm",0,0,function(){return""+this.hours()+r(this.minutes(),2)}),s("Hmmss",0,0,function(){return""+this.hours()+r(this.minutes(),2)+r(this.seconds(),2)}),rt("a",!0),rt("A",!1),h("a",at),h("A",at),h("H",n,d),h("h",n,u),h("k",n,u),h("HH",n,t),h("hh",n,t),h("kk",n,t),h("hmm",me),h("hmmss",_e),h("Hmm",me),h("Hmmss",_e),v(["H","HH"],O),v(["k","kk"],function(e,t,n){e=M(e);t[O]=24===e?0:e}),v(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),v(["h","hh"],function(e,t,n){t[O]=M(e),p(n).bigHour=!0}),v("hmm",function(e,t,n){var s=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s)),p(n).bigHour=!0}),v("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s,2)),t[T]=M(e.substr(i)),p(n).bigHour=!0}),v("Hmm",function(e,t,n){var s=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s))}),v("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[O]=M(e.substr(0,s)),t[b]=M(e.substr(s,2)),t[T]=M(e.substr(i))});i=Re("Hours",!0);var ot,ut={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{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",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Fe,monthsShort:Le,week:{dow:0,doy:6},weekdays:Qe,weekdaysMin:Ke,weekdaysShort:Xe,meridiemParse:/[ap]\.?m?\.?/i},W={},lt={};function dt(e){return e&&e.toLowerCase().replace("_","-")}function ht(e){for(var t,n,s,i,r=0;r=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s=t-1)break;t--}r++}return ot}function ct(t){var e,n;if(void 0===W[t]&&"undefined"!=typeof module&&module&&module.exports&&(n=t)&&n.match("^[^/\\\\]*$"))try{e=ot._abbr,require("./locale/"+t),ft(e)}catch(e){W[t]=null}return W[t]}function ft(e,t){return e&&((t=g(t)?P(e):mt(e,t))?ot=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ot._abbr}function mt(e,t){if(null===t)return delete W[e],null;var n,s=ut;if(t.abbr=e,null!=W[e])Q("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=W[e]._config;else if(null!=t.parentLocale)if(null!=W[t.parentLocale])s=W[t.parentLocale]._config;else{if(null==(n=ct(t.parentLocale)))return lt[t.parentLocale]||(lt[t.parentLocale]=[]),lt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return W[e]=new K(X(s,t)),lt[e]&<[e].forEach(function(e){mt(e.name,e.config)}),ft(e),W[e]}function P(e){var t;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return ot;if(!y(e)){if(t=ct(e))return t;e=[e]}return ht(e)}function _t(e){var t=e._a;return t&&-2===p(e).overflow&&(t=t[Y]<0||11He(t[D],t[Y])?S:t[O]<0||24N(r,u,l)?p(s)._overflowWeeks=!0:null!=d?p(s)._overflowWeekday=!0:(h=$e(r,a,o,u,l),s._a[D]=h.year,s._dayOfYear=h.dayOfYear)),null!=e._dayOfYear&&(i=bt(e._a[D],n[D]),(e._dayOfYear>We(i)||0===e._dayOfYear)&&(p(e)._overflowDayOfYear=!0),d=ze(i,0,e._dayOfYear),e._a[Y]=d.getUTCMonth(),e._a[S]=d.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=n[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[O]&&0===e._a[b]&&0===e._a[T]&&0===e._a[Te]&&(e._nextDay=!0,e._a[O]=0),e._d=(e._useUTC?ze:Ze).apply(null,c),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[O]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(p(e).weekdayMismatch=!0)}}function xt(e){if(e._f===_.ISO_8601)Yt(e);else if(e._f===_.RFC_2822)Ot(e);else{e._a=[],p(e).empty=!0;for(var t,n,s,i,r,a=""+e._i,o=a.length,u=0,l=ae(e._f,e._locale).match(te)||[],d=l.length,h=0;he.valueOf():e.valueOf()"}),u.toJSON=function(){return this.isValid()?this.toISOString():null},u.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},u.unix=function(){return Math.floor(this.valueOf()/1e3)},u.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},u.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},u.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;nthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},u.isLocal=function(){return!!this.isValid()&&!this._isUTC},u.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},u.isUtc=At,u.isUTC=At,u.zoneAbbr=function(){return this._isUTC?"UTC":""},u.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},u.dates=e("dates accessor is deprecated. Use date instead.",ge),u.months=e("months accessor is deprecated. Use month instead",Ie),u.years=e("years accessor is deprecated. Use year instead",Pe),u.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,t),this):-this.utcOffset()}),u.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){var e,t;return g(this._isDSTShifted)&&(q(e={},this),(e=Nt(e))._a?(t=(e._isUTC?l:R)(e._a),this._isDSTShifted=this.isValid()&&0