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