momentJS 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 477552285d91991a86bb07853b768e2e638d5719
4
+ data.tar.gz: deef11f43cd31226e414f3bc842741a18cfa0bf5
5
+ SHA512:
6
+ metadata.gz: 14aad23b9754e42a209012c1430436fff67ae1f805c2b561317e9a67066ff5f7e9a98637b4ad5bb9f7750f351eab37753010727c804a28ec291dc218307bb5cc
7
+ data.tar.gz: ad729bfd32035d4758980732653ca301c20de6c41eb14cb539c391bfe8b88b5cdd7f6fb29aff5264a4308690e9ba49013e082b89eae85db96d6b27c49a66d21e
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .DS_Store
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in momentJS.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 stillnaughty
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # MomentJS
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'momentJS'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install momentJS
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ require "momentJS/version"
2
+ require "momentJS/engine"
@@ -0,0 +1,6 @@
1
+ module MomentJS
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module MomentJS
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'momentJS/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "momentJS"
8
+ spec.version = MomentJS::VERSION
9
+ spec.authors = ["stillnaughty"]
10
+ spec.email = ["ying@stillnaughty.com"]
11
+ spec.description = "Rails asset gems for momentJS"
12
+ spec.summary = "Rails asset gems for the customized momentJS based on v2.1.0"
13
+ spec.homepage = ""
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_development_dependency "bundler", "~> 1.3"
19
+ spec.add_development_dependency "rake"
20
+ end
@@ -0,0 +1,1664 @@
1
+ //= require moment.plugin
2
+
3
+ // moment.js
4
+ // version : 2.1.0
5
+ // author : Tim Wood
6
+ // license : MIT
7
+ // momentjs.com
8
+
9
+ (function (undefined) {
10
+
11
+ /************************************
12
+ Constants
13
+ ************************************/
14
+
15
+ var moment,
16
+ VERSION = "2.1.0",
17
+ round = Math.round, i,
18
+ // internal storage for language config files
19
+ languages = {},
20
+
21
+ // check for nodeJS
22
+ hasModule = (typeof module !== 'undefined' && module.exports),
23
+
24
+ // ASP.NET json date format regex
25
+ aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
26
+ aspNetTimeSpanJsonRegex = /(\-)?(\d*)?\.?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
27
+
28
+ // format tokens
29
+ formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
30
+ localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
31
+
32
+ // parsing token regexes
33
+ parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
34
+ parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
35
+ parseTokenThreeDigits = /\d{3}/, // 000 - 999
36
+ parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
37
+ parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
38
+ 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.
39
+ parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
40
+ parseTokenT = /T/i, // T (ISO seperator)
41
+ parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
42
+
43
+ // preliminary iso regex
44
+ // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
45
+ isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
46
+ isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
47
+
48
+ // iso time formats and regexes
49
+ isoTimes = [
50
+ ['HH:mm:ss.S', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
51
+ ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
52
+ ['HH:mm', /(T| )\d\d:\d\d/],
53
+ ['HH', /(T| )\d\d/]
54
+ ],
55
+
56
+ // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
57
+ parseTimezoneChunker = /([\+\-]|\d\d)/gi,
58
+
59
+ // getter and setter names
60
+ proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
61
+ unitMillisecondFactors = {
62
+ 'Milliseconds' : 1,
63
+ 'Seconds' : 1e3,
64
+ 'Minutes' : 6e4,
65
+ 'Hours' : 36e5,
66
+ 'Days' : 864e5,
67
+ 'Months' : 2592e6,
68
+ 'Years' : 31536e6
69
+ },
70
+
71
+ unitAliases = {
72
+ ms : 'millisecond',
73
+ s : 'second',
74
+ m : 'minute',
75
+ h : 'hour',
76
+ d : 'day',
77
+ w : 'week',
78
+ M : 'month',
79
+ y : 'year'
80
+ },
81
+
82
+ // format function strings
83
+ formatFunctions = {},
84
+
85
+ // tokens to ordinalize and pad
86
+ ordinalizeTokens = 'DDD w W M D d'.split(' '),
87
+ paddedTokens = 'M D H h m s w W'.split(' '),
88
+
89
+ formatTokenFunctions = {
90
+ M : function () {
91
+ return this.month() + 1;
92
+ },
93
+ MMM : function (format) {
94
+ return this.lang().monthsShort(this, format);
95
+ },
96
+ MMMM : function (format) {
97
+ return this.lang().months(this, format);
98
+ },
99
+ D : function () {
100
+ return this.date();
101
+ },
102
+ DDD : function () {
103
+ return this.dayOfYear();
104
+ },
105
+ d : function () {
106
+ return this.day();
107
+ },
108
+ dd : function (format) {
109
+ return this.lang().weekdaysMin(this, format);
110
+ },
111
+ ddd : function (format) {
112
+ return this.lang().weekdaysShort(this, format);
113
+ },
114
+ dddd : function (format) {
115
+ return this.lang().weekdays(this, format);
116
+ },
117
+ w : function () {
118
+ return this.week();
119
+ },
120
+ W : function () {
121
+ return this.isoWeek();
122
+ },
123
+ YY : function () {
124
+ return leftZeroFill(this.year() % 100, 2);
125
+ },
126
+ YYYY : function () {
127
+ return leftZeroFill(this.year(), 4);
128
+ },
129
+ YYYYY : function () {
130
+ return leftZeroFill(this.year(), 5);
131
+ },
132
+ gg : function () {
133
+ return leftZeroFill(this.weekYear() % 100, 2);
134
+ },
135
+ gggg : function () {
136
+ return this.weekYear();
137
+ },
138
+ ggggg : function () {
139
+ return leftZeroFill(this.weekYear(), 5);
140
+ },
141
+ GG : function () {
142
+ return leftZeroFill(this.isoWeekYear() % 100, 2);
143
+ },
144
+ GGGG : function () {
145
+ return this.isoWeekYear();
146
+ },
147
+ GGGGG : function () {
148
+ return leftZeroFill(this.isoWeekYear(), 5);
149
+ },
150
+ e : function () {
151
+ return this.weekday();
152
+ },
153
+ E : function () {
154
+ return this.isoWeekday();
155
+ },
156
+ a : function () {
157
+ return this.lang().meridiem(this.hours(), this.minutes(), true);
158
+ },
159
+ A : function () {
160
+ return this.lang().meridiem(this.hours(), this.minutes(), false);
161
+ },
162
+ H : function () {
163
+ return this.hours();
164
+ },
165
+ h : function () {
166
+ return this.hours() % 12 || 12;
167
+ },
168
+ m : function () {
169
+ return this.minutes();
170
+ },
171
+ s : function () {
172
+ return this.seconds();
173
+ },
174
+ S : function () {
175
+ return ~~(this.milliseconds() / 100);
176
+ },
177
+ SS : function () {
178
+ return leftZeroFill(~~(this.milliseconds() / 10), 2);
179
+ },
180
+ SSS : function () {
181
+ return leftZeroFill(this.milliseconds(), 3);
182
+ },
183
+ Z : function () {
184
+ var a = -this.zone(),
185
+ b = "+";
186
+ if (a < 0) {
187
+ a = -a;
188
+ b = "-";
189
+ }
190
+ return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
191
+ },
192
+ ZZ : function () {
193
+ var a = -this.zone(),
194
+ b = "+";
195
+ if (a < 0) {
196
+ a = -a;
197
+ b = "-";
198
+ }
199
+ return b + leftZeroFill(~~(10 * a / 6), 4);
200
+ },
201
+ z : function () {
202
+ return this.zoneAbbr();
203
+ },
204
+ zz : function () {
205
+ return this.zoneName();
206
+ },
207
+ X : function () {
208
+ return this.unix();
209
+ }
210
+ };
211
+
212
+ function padToken(func, count) {
213
+ return function (a) {
214
+ return leftZeroFill(func.call(this, a), count);
215
+ };
216
+ }
217
+ function ordinalizeToken(func, period) {
218
+ return function (a) {
219
+ return this.lang().ordinal(func.call(this, a), period);
220
+ };
221
+ }
222
+
223
+ while (ordinalizeTokens.length) {
224
+ i = ordinalizeTokens.pop();
225
+ formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
226
+ }
227
+ while (paddedTokens.length) {
228
+ i = paddedTokens.pop();
229
+ formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
230
+ }
231
+ formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
232
+
233
+
234
+ /************************************
235
+ Constructors
236
+ ************************************/
237
+
238
+ function Language() {
239
+
240
+ }
241
+
242
+ // Moment prototype object
243
+ function Moment(config) {
244
+ extend(this, config);
245
+ }
246
+
247
+ // Duration Constructor
248
+ function Duration(duration) {
249
+ var years = duration.years || duration.year || duration.y || 0,
250
+ months = duration.months || duration.month || duration.M || 0,
251
+ weeks = duration.weeks || duration.week || duration.w || 0,
252
+ days = duration.days || duration.day || duration.d || 0,
253
+ hours = duration.hours || duration.hour || duration.h || 0,
254
+ minutes = duration.minutes || duration.minute || duration.m || 0,
255
+ seconds = duration.seconds || duration.second || duration.s || 0,
256
+ milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
257
+
258
+ // store reference to input for deterministic cloning
259
+ this._input = duration;
260
+
261
+ // representation for dateAddRemove
262
+ this._milliseconds = milliseconds +
263
+ seconds * 1e3 + // 1000
264
+ minutes * 6e4 + // 1000 * 60
265
+ hours * 36e5; // 1000 * 60 * 60
266
+ // Because of dateAddRemove treats 24 hours as different from a
267
+ // day when working around DST, we need to store them separately
268
+ this._days = days +
269
+ weeks * 7;
270
+ // It is impossible translate months into days without knowing
271
+ // which months you are are talking about, so we have to store
272
+ // it separately.
273
+ this._months = months +
274
+ years * 12;
275
+
276
+ this._data = {};
277
+
278
+ this._bubble();
279
+ }
280
+
281
+
282
+ /************************************
283
+ Helpers
284
+ ************************************/
285
+
286
+
287
+ function extend(a, b) {
288
+ for (var i in b) {
289
+ if (b.hasOwnProperty(i)) {
290
+ a[i] = b[i];
291
+ }
292
+ }
293
+ return a;
294
+ }
295
+
296
+ function absRound(number) {
297
+ if (number < 0) {
298
+ return Math.ceil(number);
299
+ } else {
300
+ return Math.floor(number);
301
+ }
302
+ }
303
+
304
+ // left zero fill a number
305
+ // see http://jsperf.com/left-zero-filling for performance comparison
306
+ function leftZeroFill(number, targetLength) {
307
+ var output = number + '';
308
+ while (output.length < targetLength) {
309
+ output = '0' + output;
310
+ }
311
+ return output;
312
+ }
313
+
314
+ // helper function for _.addTime and _.subtractTime
315
+ function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
316
+ var milliseconds = duration._milliseconds,
317
+ days = duration._days,
318
+ months = duration._months,
319
+ minutes,
320
+ hours,
321
+ currentDate;
322
+
323
+ if (milliseconds) {
324
+ mom._d.setTime(+mom._d + milliseconds * isAdding);
325
+ }
326
+ // store the minutes and hours so we can restore them
327
+ if (days || months) {
328
+ minutes = mom.minute();
329
+ hours = mom.hour();
330
+ }
331
+ if (days) {
332
+ mom.date(mom.date() + days * isAdding);
333
+ }
334
+ if (months) {
335
+ mom.month(mom.month() + months * isAdding);
336
+ }
337
+ if (milliseconds && !ignoreUpdateOffset) {
338
+ moment.updateOffset(mom);
339
+ }
340
+ // restore the minutes and hours after possibly changing dst
341
+ if (days || months) {
342
+ mom.minute(minutes);
343
+ mom.hour(hours);
344
+ }
345
+ }
346
+
347
+ // check if is an array
348
+ function isArray(input) {
349
+ return Object.prototype.toString.call(input) === '[object Array]';
350
+ }
351
+
352
+ // compare two arrays, return the number of differences
353
+ function compareArrays(array1, array2) {
354
+ var len = Math.min(array1.length, array2.length),
355
+ lengthDiff = Math.abs(array1.length - array2.length),
356
+ diffs = 0,
357
+ i;
358
+ for (i = 0; i < len; i++) {
359
+ if (~~array1[i] !== ~~array2[i]) {
360
+ diffs++;
361
+ }
362
+ }
363
+ return diffs + lengthDiff;
364
+ }
365
+
366
+ function normalizeUnits(units) {
367
+ return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
368
+ }
369
+
370
+
371
+ /************************************
372
+ Languages
373
+ ************************************/
374
+
375
+
376
+ Language.prototype = {
377
+ set : function (config) {
378
+ var prop, i;
379
+ for (i in config) {
380
+ prop = config[i];
381
+ if (typeof prop === 'function') {
382
+ this[i] = prop;
383
+ } else {
384
+ this['_' + i] = prop;
385
+ }
386
+ }
387
+ },
388
+
389
+ _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
390
+ months : function (m) {
391
+ return this._months[m.month()];
392
+ },
393
+
394
+ _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
395
+ monthsShort : function (m) {
396
+ return this._monthsShort[m.month()];
397
+ },
398
+
399
+ monthsParse : function (monthName) {
400
+ var i, mom, regex;
401
+
402
+ if (!this._monthsParse) {
403
+ this._monthsParse = [];
404
+ }
405
+
406
+ for (i = 0; i < 12; i++) {
407
+ // make the regex if we don't have it already
408
+ if (!this._monthsParse[i]) {
409
+ mom = moment([2000, i]);
410
+ regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
411
+ this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
412
+ }
413
+ // test the regex
414
+ if (this._monthsParse[i].test(monthName)) {
415
+ return i;
416
+ }
417
+ }
418
+ },
419
+
420
+ _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
421
+ weekdays : function (m) {
422
+ return this._weekdays[m.day()];
423
+ },
424
+
425
+ _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
426
+ weekdaysShort : function (m) {
427
+ return this._weekdaysShort[m.day()];
428
+ },
429
+
430
+ _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
431
+ weekdaysMin : function (m) {
432
+ return this._weekdaysMin[m.day()];
433
+ },
434
+
435
+ weekdaysParse : function (weekdayName) {
436
+ var i, mom, regex;
437
+
438
+ if (!this._weekdaysParse) {
439
+ this._weekdaysParse = [];
440
+ }
441
+
442
+ for (i = 0; i < 7; i++) {
443
+ // make the regex if we don't have it already
444
+ if (!this._weekdaysParse[i]) {
445
+ mom = moment([2000, 1]).day(i);
446
+ regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
447
+ this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
448
+ }
449
+ // test the regex
450
+ if (this._weekdaysParse[i].test(weekdayName)) {
451
+ return i;
452
+ }
453
+ }
454
+ },
455
+
456
+ _longDateFormat : {
457
+ LT : "h:mm A",
458
+ L : "MM/DD/YYYY",
459
+ LL : "MMMM D YYYY",
460
+ LLL : "MMMM D YYYY LT",
461
+ LLLL : "dddd, MMMM D YYYY LT"
462
+ },
463
+ longDateFormat : function (key) {
464
+ var output = this._longDateFormat[key];
465
+ if (!output && this._longDateFormat[key.toUpperCase()]) {
466
+ output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
467
+ return val.slice(1);
468
+ });
469
+ this._longDateFormat[key] = output;
470
+ }
471
+ return output;
472
+ },
473
+
474
+ isPM : function (input) {
475
+ return ((input + '').toLowerCase()[0] === 'p');
476
+ },
477
+
478
+ _meridiemParse : /[ap]\.?m?\.?/i,
479
+ meridiem : function (hours, minutes, isLower) {
480
+ if (hours > 11) {
481
+ return isLower ? 'pm' : 'PM';
482
+ } else {
483
+ return isLower ? 'am' : 'AM';
484
+ }
485
+ },
486
+
487
+ _calendar : {
488
+ sameDay : '[Today at] LT',
489
+ nextDay : '[Tomorrow at] LT',
490
+ nextWeek : 'dddd [at] LT',
491
+ lastDay : '[Yesterday at] LT',
492
+ lastWeek : '[Last] dddd [at] LT',
493
+ sameElse : 'L'
494
+ },
495
+ calendar : function (key, mom) {
496
+ var output = this._calendar[key];
497
+ return typeof output === 'function' ? output.apply(mom) : output;
498
+ },
499
+
500
+ _relativeTime : {
501
+ future : "in %s",
502
+ past : "%s ago",
503
+ s : "a few seconds",
504
+ m : "a minute",
505
+ mm : "%d minutes",
506
+ h : "an hour",
507
+ hh : "%d hours",
508
+ d : "a day",
509
+ dd : "%d days",
510
+ M : "a month",
511
+ MM : "%d months",
512
+ y : "a year",
513
+ yy : "%d years"
514
+ },
515
+ relativeTime : function (number, withoutSuffix, string, isFuture) {
516
+ var output = this._relativeTime[string];
517
+ return (typeof output === 'function') ?
518
+ output(number, withoutSuffix, string, isFuture) :
519
+ output.replace(/%d/i, number);
520
+ },
521
+ pastFuture : function (diff, output) {
522
+ var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
523
+ return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
524
+ },
525
+
526
+ ordinal : function (number) {
527
+ return this._ordinal.replace("%d", number);
528
+ },
529
+ _ordinal : "%d",
530
+
531
+ preparse : function (string) {
532
+ return string;
533
+ },
534
+
535
+ postformat : function (string) {
536
+ return string;
537
+ },
538
+
539
+ week : function (mom) {
540
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
541
+ },
542
+ _week : {
543
+ dow : 0, // Sunday is the first day of the week.
544
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
545
+ }
546
+ };
547
+
548
+ // Loads a language definition into the `languages` cache. The function
549
+ // takes a key and optionally values. If not in the browser and no values
550
+ // are provided, it will load the language file module. As a convenience,
551
+ // this function also returns the language values.
552
+ function loadLang(key, values) {
553
+ values.abbr = key;
554
+ if (!languages[key]) {
555
+ languages[key] = new Language();
556
+ }
557
+ languages[key].set(values);
558
+ return languages[key];
559
+ }
560
+
561
+ // Determines which language definition to use and returns it.
562
+ //
563
+ // With no parameters, it will return the global language. If you
564
+ // pass in a language key, such as 'en', it will return the
565
+ // definition for 'en', so long as 'en' has already been loaded using
566
+ // moment.lang.
567
+ function getLangDefinition(key) {
568
+ if (!key) {
569
+ return moment.fn._lang;
570
+ }
571
+ if (!languages[key] && hasModule) {
572
+ try {
573
+ require('./lang/' + key);
574
+ } catch (e) {
575
+ // call with no params to set to default
576
+ return moment.fn._lang;
577
+ }
578
+ }
579
+ return languages[key];
580
+ }
581
+
582
+
583
+ /************************************
584
+ Formatting
585
+ ************************************/
586
+
587
+
588
+ function removeFormattingTokens(input) {
589
+ if (input.match(/\[.*\]/)) {
590
+ return input.replace(/^\[|\]$/g, "");
591
+ }
592
+ return input.replace(/\\/g, "");
593
+ }
594
+
595
+ function makeFormatFunction(format) {
596
+ var array = format.match(formattingTokens), i, length;
597
+
598
+ for (i = 0, length = array.length; i < length; i++) {
599
+ if (formatTokenFunctions[array[i]]) {
600
+ array[i] = formatTokenFunctions[array[i]];
601
+ } else {
602
+ array[i] = removeFormattingTokens(array[i]);
603
+ }
604
+ }
605
+
606
+ return function (mom) {
607
+ var output = "";
608
+ for (i = 0; i < length; i++) {
609
+ output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
610
+ }
611
+ return output;
612
+ };
613
+ }
614
+
615
+ // format date using native date object
616
+ function formatMoment(m, format) {
617
+ var i = 5;
618
+
619
+ function replaceLongDateFormatTokens(input) {
620
+ return m.lang().longDateFormat(input) || input;
621
+ }
622
+
623
+ while (i-- && localFormattingTokens.test(format)) {
624
+ format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
625
+ }
626
+
627
+ if (!formatFunctions[format]) {
628
+ formatFunctions[format] = makeFormatFunction(format);
629
+ }
630
+
631
+ return formatFunctions[format](m);
632
+ }
633
+
634
+
635
+ /************************************
636
+ Parsing
637
+ ************************************/
638
+
639
+
640
+ // get the regex to find the next token
641
+ function getParseRegexForToken(token, config) {
642
+ switch (token) {
643
+ case 'DDDD':
644
+ return parseTokenThreeDigits;
645
+ case 'YYYY':
646
+ return parseTokenFourDigits;
647
+ case 'YYYYY':
648
+ return parseTokenSixDigits;
649
+ case 'S':
650
+ case 'SS':
651
+ case 'SSS':
652
+ case 'DDD':
653
+ return parseTokenOneToThreeDigits;
654
+ case 'MMM':
655
+ case 'MMMM':
656
+ case 'dd':
657
+ case 'ddd':
658
+ case 'dddd':
659
+ return parseTokenWord;
660
+ case 'a':
661
+ case 'A':
662
+ return getLangDefinition(config._l)._meridiemParse;
663
+ case 'X':
664
+ return parseTokenTimestampMs;
665
+ case 'Z':
666
+ case 'ZZ':
667
+ return parseTokenTimezone;
668
+ case 'T':
669
+ return parseTokenT;
670
+ case 'MM':
671
+ case 'DD':
672
+ case 'YY':
673
+ case 'HH':
674
+ case 'hh':
675
+ case 'mm':
676
+ case 'ss':
677
+ case 'M':
678
+ case 'D':
679
+ case 'd':
680
+ case 'H':
681
+ case 'h':
682
+ case 'm':
683
+ case 's':
684
+ return parseTokenOneOrTwoDigits;
685
+ default :
686
+ return new RegExp(token.replace('\\', ''));
687
+ }
688
+ }
689
+
690
+ function timezoneMinutesFromString(string) {
691
+ var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
692
+ parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
693
+ minutes = +(parts[1] * 60) + ~~parts[2];
694
+
695
+ return parts[0] === '+' ? -minutes : minutes;
696
+ }
697
+
698
+ // function to convert string input to date
699
+ function addTimeToArrayFromToken(token, input, config) {
700
+ var a, datePartArray = config._a;
701
+
702
+ switch (token) {
703
+ // MONTH
704
+ case 'M' : // fall through to MM
705
+ case 'MM' :
706
+ datePartArray[1] = (input == null) ? 0 : ~~input - 1;
707
+ break;
708
+ case 'MMM' : // fall through to MMMM
709
+ case 'MMMM' :
710
+ a = getLangDefinition(config._l).monthsParse(input);
711
+ // if we didn't find a month name, mark the date as invalid.
712
+ if (a != null) {
713
+ datePartArray[1] = a;
714
+ } else {
715
+ config._isValid = false;
716
+ }
717
+ break;
718
+ // DAY OF MONTH
719
+ case 'D' : // fall through to DDDD
720
+ case 'DD' : // fall through to DDDD
721
+ case 'DDD' : // fall through to DDDD
722
+ case 'DDDD' :
723
+ if (input != null) {
724
+ datePartArray[2] = ~~input;
725
+ }
726
+ break;
727
+ // YEAR
728
+ case 'YY' :
729
+ datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
730
+ break;
731
+ case 'YYYY' :
732
+ case 'YYYYY' :
733
+ datePartArray[0] = ~~input;
734
+ break;
735
+ // AM / PM
736
+ case 'a' : // fall through to A
737
+ case 'A' :
738
+ config._isPm = getLangDefinition(config._l).isPM(input);
739
+ break;
740
+ // 24 HOUR
741
+ case 'H' : // fall through to hh
742
+ case 'HH' : // fall through to hh
743
+ case 'h' : // fall through to hh
744
+ case 'hh' :
745
+ datePartArray[3] = ~~input;
746
+ break;
747
+ // MINUTE
748
+ case 'm' : // fall through to mm
749
+ case 'mm' :
750
+ datePartArray[4] = ~~input;
751
+ break;
752
+ // SECOND
753
+ case 's' : // fall through to ss
754
+ case 'ss' :
755
+ datePartArray[5] = ~~input;
756
+ break;
757
+ // MILLISECOND
758
+ case 'S' :
759
+ case 'SS' :
760
+ case 'SSS' :
761
+ datePartArray[6] = ~~ (('0.' + input) * 1000);
762
+ break;
763
+ // UNIX TIMESTAMP WITH MS
764
+ case 'X':
765
+ config._d = new Date(parseFloat(input) * 1000);
766
+ break;
767
+ // TIMEZONE
768
+ case 'Z' : // fall through to ZZ
769
+ case 'ZZ' :
770
+ config._useUTC = true;
771
+ config._tzm = timezoneMinutesFromString(input);
772
+ break;
773
+ }
774
+
775
+ // if the input is null, the date is not valid
776
+ if (input == null) {
777
+ config._isValid = false;
778
+ }
779
+ }
780
+
781
+ // convert an array to a date.
782
+ // the array should mirror the parameters below
783
+ // note: all values past the year are optional and will default to the lowest possible value.
784
+ // [year, month, day , hour, minute, second, millisecond]
785
+ function dateFromArray(config) {
786
+ var i, date, input = [];
787
+
788
+ if (config._d) {
789
+ return;
790
+ }
791
+
792
+ for (i = 0; i < 7; i++) {
793
+ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
794
+ }
795
+
796
+ // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
797
+ input[3] += ~~((config._tzm || 0) / 60);
798
+ input[4] += ~~((config._tzm || 0) % 60);
799
+
800
+ date = new Date(0);
801
+
802
+ if (config._useUTC) {
803
+ date.setUTCFullYear(input[0], input[1], input[2]);
804
+ date.setUTCHours(input[3], input[4], input[5], input[6]);
805
+ } else {
806
+ date.setFullYear(input[0], input[1], input[2]);
807
+ date.setHours(input[3], input[4], input[5], input[6]);
808
+ }
809
+
810
+ config._d = date;
811
+ }
812
+
813
+ // date from string and format string
814
+ function makeDateFromStringAndFormat(config) {
815
+ // This array is used to make a Date, either with `new Date` or `Date.UTC`
816
+ var tokens = config._f.match(formattingTokens),
817
+ string = config._i,
818
+ i, parsedInput;
819
+
820
+ config._a = [];
821
+
822
+ for (i = 0; i < tokens.length; i++) {
823
+ parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
824
+ if (parsedInput) {
825
+ string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
826
+ }
827
+ // don't parse if its not a known token
828
+ if (formatTokenFunctions[tokens[i]]) {
829
+ addTimeToArrayFromToken(tokens[i], parsedInput, config);
830
+ }
831
+ }
832
+
833
+ // add remaining unparsed input to the string
834
+ if (string) {
835
+ config._il = string;
836
+ }
837
+
838
+ // handle am pm
839
+ if (config._isPm && config._a[3] < 12) {
840
+ config._a[3] += 12;
841
+ }
842
+ // if is 12 am, change hours to 0
843
+ if (config._isPm === false && config._a[3] === 12) {
844
+ config._a[3] = 0;
845
+ }
846
+ // return
847
+ dateFromArray(config);
848
+ }
849
+
850
+ // date from string and array of format strings
851
+ function makeDateFromStringAndArray(config) {
852
+ var tempConfig,
853
+ tempMoment,
854
+ bestMoment,
855
+
856
+ scoreToBeat = 99,
857
+ i,
858
+ currentScore;
859
+
860
+ for (i = 0; i < config._f.length; i++) {
861
+ tempConfig = extend({}, config);
862
+ tempConfig._f = config._f[i];
863
+ makeDateFromStringAndFormat(tempConfig);
864
+ tempMoment = new Moment(tempConfig);
865
+
866
+ currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
867
+
868
+ // if there is any input that was not parsed
869
+ // add a penalty for that format
870
+ if (tempMoment._il) {
871
+ currentScore += tempMoment._il.length;
872
+ }
873
+
874
+ if (currentScore < scoreToBeat) {
875
+ scoreToBeat = currentScore;
876
+ bestMoment = tempMoment;
877
+ }
878
+ }
879
+
880
+ extend(config, bestMoment);
881
+ }
882
+
883
+ // date from iso format
884
+ function makeDateFromString(config) {
885
+ var i,
886
+ string = config._i,
887
+ match = isoRegex.exec(string);
888
+
889
+ if (match) {
890
+ // match[2] should be "T" or undefined
891
+ config._f = 'YYYY-MM-DD' + (match[2] || " ");
892
+ for (i = 0; i < 4; i++) {
893
+ if (isoTimes[i][1].exec(string)) {
894
+ config._f += isoTimes[i][0];
895
+ break;
896
+ }
897
+ }
898
+ if (parseTokenTimezone.exec(string)) {
899
+ config._f += " Z";
900
+ }
901
+ makeDateFromStringAndFormat(config);
902
+ } else {
903
+ config._d = new Date(string);
904
+ }
905
+ }
906
+
907
+ function makeDateFromInput(config) {
908
+ var input = config._i,
909
+ matched = aspNetJsonRegex.exec(input);
910
+
911
+ if (input === undefined) {
912
+ config._d = new Date();
913
+ } else if (matched) {
914
+ config._d = new Date(+matched[1]);
915
+ } else if (typeof input === 'string') {
916
+ makeDateFromString(config);
917
+ } else if (isArray(input)) {
918
+ config._a = input.slice(0);
919
+ dateFromArray(config);
920
+ } else {
921
+ config._d = input instanceof Date ? new Date(+input) : new Date(input);
922
+ }
923
+ }
924
+
925
+
926
+ /************************************
927
+ Relative Time
928
+ ************************************/
929
+
930
+
931
+ // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
932
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
933
+ return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
934
+ }
935
+
936
+ function relativeTime(milliseconds, withoutSuffix, lang) {
937
+ var seconds = round(Math.abs(milliseconds) / 1000),
938
+ minutes = round(seconds / 60),
939
+ hours = round(minutes / 60),
940
+ days = round(hours / 24),
941
+ years = round(days / 365),
942
+ args = seconds < 45 && ['s', seconds] ||
943
+ minutes === 1 && ['m'] ||
944
+ minutes < 45 && ['mm', minutes] ||
945
+ hours === 1 && ['h'] ||
946
+ hours < 22 && ['hh', hours] ||
947
+ days === 1 && ['d'] ||
948
+ days <= 25 && ['dd', days] ||
949
+ days <= 45 && ['M'] ||
950
+ days < 345 && ['MM', round(days / 30)] ||
951
+ years === 1 && ['y'] || ['yy', years];
952
+ args[2] = withoutSuffix;
953
+ args[3] = milliseconds > 0;
954
+ args[4] = lang;
955
+ return substituteTimeAgo.apply({}, args);
956
+ }
957
+
958
+
959
+ /************************************
960
+ Week of Year
961
+ ************************************/
962
+
963
+
964
+ // firstDayOfWeek 0 = sun, 6 = sat
965
+ // the day of the week that starts the week
966
+ // (usually sunday or monday)
967
+ // firstDayOfWeekOfYear 0 = sun, 6 = sat
968
+ // the first week is the week that contains the first
969
+ // of this day of the week
970
+ // (eg. ISO weeks use thursday (4))
971
+ function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
972
+ var end = firstDayOfWeekOfYear - firstDayOfWeek,
973
+ daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
974
+ adjustedMoment;
975
+
976
+
977
+ if (daysToDayOfWeek > end) {
978
+ daysToDayOfWeek -= 7;
979
+ }
980
+
981
+ if (daysToDayOfWeek < end - 7) {
982
+ daysToDayOfWeek += 7;
983
+ }
984
+
985
+ adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
986
+ return {
987
+ week: Math.ceil(adjustedMoment.dayOfYear() / 7),
988
+ year: adjustedMoment.year()
989
+ };
990
+ }
991
+
992
+
993
+ /************************************
994
+ Top Level Functions
995
+ ************************************/
996
+
997
+ function makeMoment(config) {
998
+ var input = config._i,
999
+ format = config._f;
1000
+
1001
+ if (input === null || input === '') {
1002
+ return null;
1003
+ }
1004
+
1005
+ if (typeof input === 'string') {
1006
+ config._i = input = getLangDefinition().preparse(input);
1007
+ }
1008
+
1009
+ if (moment.isMoment(input)) {
1010
+ config = extend({}, input);
1011
+ config._d = new Date(+input._d);
1012
+ } else if (format) {
1013
+ if (isArray(format)) {
1014
+ makeDateFromStringAndArray(config);
1015
+ } else {
1016
+ makeDateFromStringAndFormat(config);
1017
+ }
1018
+ } else {
1019
+ makeDateFromInput(config);
1020
+ }
1021
+
1022
+ return new Moment(config);
1023
+ }
1024
+
1025
+ moment = function (input, format, lang) {
1026
+ return makeMoment({
1027
+ _i : input,
1028
+ _f : format,
1029
+ _l : lang,
1030
+ _isUTC : false
1031
+ });
1032
+ };
1033
+
1034
+ // creating with utc
1035
+ moment.utc = function (input, format, lang) {
1036
+ return makeMoment({
1037
+ _useUTC : true,
1038
+ _isUTC : true,
1039
+ _l : lang,
1040
+ _i : input,
1041
+ _f : format
1042
+ });
1043
+ };
1044
+
1045
+ // creating with unix timestamp (in seconds)
1046
+ moment.unix = function (input) {
1047
+ return moment(input * 1000);
1048
+ };
1049
+
1050
+ // duration
1051
+ moment.duration = function (input, key) {
1052
+ var isDuration = moment.isDuration(input),
1053
+ isNumber = (typeof input === 'number'),
1054
+ duration = (isDuration ? input._input : (isNumber ? {} : input)),
1055
+ matched = aspNetTimeSpanJsonRegex.exec(input),
1056
+ sign,
1057
+ ret;
1058
+
1059
+ if (isNumber) {
1060
+ if (key) {
1061
+ duration[key] = input;
1062
+ } else {
1063
+ duration.milliseconds = input;
1064
+ }
1065
+ } else if (matched) {
1066
+ sign = (matched[1] === "-") ? -1 : 1;
1067
+ duration = {
1068
+ y: 0,
1069
+ d: ~~matched[2] * sign,
1070
+ h: ~~matched[3] * sign,
1071
+ m: ~~matched[4] * sign,
1072
+ s: ~~matched[5] * sign,
1073
+ ms: ~~matched[6] * sign
1074
+ };
1075
+ }
1076
+
1077
+ ret = new Duration(duration);
1078
+
1079
+ if (isDuration && input.hasOwnProperty('_lang')) {
1080
+ ret._lang = input._lang;
1081
+ }
1082
+
1083
+ return ret;
1084
+ };
1085
+
1086
+ // version number
1087
+ moment.version = VERSION;
1088
+
1089
+ // default format
1090
+ moment.defaultFormat = isoFormat;
1091
+
1092
+ // This function will be called whenever a moment is mutated.
1093
+ // It is intended to keep the offset in sync with the timezone.
1094
+ moment.updateOffset = function () {};
1095
+
1096
+ // This function will load languages and then set the global language. If
1097
+ // no arguments are passed in, it will simply return the current global
1098
+ // language key.
1099
+ moment.lang = function (key, values) {
1100
+ if (!key) {
1101
+ return moment.fn._lang._abbr;
1102
+ }
1103
+ if (values) {
1104
+ loadLang(key, values);
1105
+ } else if (!languages[key]) {
1106
+ getLangDefinition(key);
1107
+ }
1108
+ moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1109
+ };
1110
+
1111
+ // returns language data
1112
+ moment.langData = function (key) {
1113
+ if (key && key._lang && key._lang._abbr) {
1114
+ key = key._lang._abbr;
1115
+ }
1116
+ return getLangDefinition(key);
1117
+ };
1118
+
1119
+ // compare moment object
1120
+ moment.isMoment = function (obj) {
1121
+ return obj instanceof Moment;
1122
+ };
1123
+
1124
+ // for typechecking Duration objects
1125
+ moment.isDuration = function (obj) {
1126
+ return obj instanceof Duration;
1127
+ };
1128
+
1129
+
1130
+ /************************************
1131
+ Moment Prototype
1132
+ ************************************/
1133
+
1134
+
1135
+ moment.fn = Moment.prototype = {
1136
+
1137
+ clone : function () {
1138
+ return moment(this);
1139
+ },
1140
+
1141
+ valueOf : function () {
1142
+ return +this._d + ((this._offset || 0) * 60000);
1143
+ },
1144
+
1145
+ unix : function () {
1146
+ return Math.floor(+this / 1000);
1147
+ },
1148
+
1149
+ toString : function () {
1150
+ return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
1151
+ },
1152
+
1153
+ toDate : function () {
1154
+ return this._offset ? new Date(+this) : this._d;
1155
+ },
1156
+
1157
+ toISOString : function () {
1158
+ return formatMoment(moment(this).utc(), 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1159
+ },
1160
+
1161
+ toArray : function () {
1162
+ var m = this;
1163
+ return [
1164
+ m.year(),
1165
+ m.month(),
1166
+ m.date(),
1167
+ m.hours(),
1168
+ m.minutes(),
1169
+ m.seconds(),
1170
+ m.milliseconds()
1171
+ ];
1172
+ },
1173
+
1174
+ isValid : function () {
1175
+ if (this._isValid == null) {
1176
+ if (this._a) {
1177
+ this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray());
1178
+ } else {
1179
+ this._isValid = !isNaN(this._d.getTime());
1180
+ }
1181
+ }
1182
+ return !!this._isValid;
1183
+ },
1184
+
1185
+ utc : function () {
1186
+ return this.zone(0);
1187
+ },
1188
+
1189
+ local : function () {
1190
+ this.zone(0);
1191
+ this._isUTC = false;
1192
+ return this;
1193
+ },
1194
+
1195
+ format : function (inputString) {
1196
+ var output = formatMoment(this, inputString || moment.defaultFormat);
1197
+ return this.lang().postformat(output);
1198
+ },
1199
+
1200
+ add : function (input, val) {
1201
+ var dur;
1202
+ // switch args to support add('s', 1) and add(1, 's')
1203
+ if (typeof input === 'string') {
1204
+ dur = moment.duration(+val, input);
1205
+ } else {
1206
+ dur = moment.duration(input, val);
1207
+ }
1208
+ addOrSubtractDurationFromMoment(this, dur, 1);
1209
+ return this;
1210
+ },
1211
+
1212
+ subtract : function (input, val) {
1213
+ var dur;
1214
+ // switch args to support subtract('s', 1) and subtract(1, 's')
1215
+ if (typeof input === 'string') {
1216
+ dur = moment.duration(+val, input);
1217
+ } else {
1218
+ dur = moment.duration(input, val);
1219
+ }
1220
+ addOrSubtractDurationFromMoment(this, dur, -1);
1221
+ return this;
1222
+ },
1223
+
1224
+ diff : function (input, units, asFloat) {
1225
+ var that = this._isUTC ? moment(input).zone(this._offset || 0) : moment(input).local(),
1226
+ zoneDiff = (this.zone() - that.zone()) * 6e4,
1227
+ diff, output;
1228
+
1229
+ units = normalizeUnits(units);
1230
+
1231
+ if (units === 'year' || units === 'month') {
1232
+ // average number of days in the months in the given dates
1233
+ diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
1234
+ // difference in months
1235
+ output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
1236
+ // adjust by taking difference in days, average number of days
1237
+ // and dst in the given months.
1238
+ output += ((this - moment(this).startOf('month')) -
1239
+ (that - moment(that).startOf('month'))) / diff;
1240
+ // same as above but with zones, to negate all dst
1241
+ output -= ((this.zone() - moment(this).startOf('month').zone()) -
1242
+ (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
1243
+ if (units === 'year') {
1244
+ output = output / 12;
1245
+ }
1246
+ } else {
1247
+ diff = (this - that);
1248
+ output = units === 'second' ? diff / 1e3 : // 1000
1249
+ units === 'minute' ? diff / 6e4 : // 1000 * 60
1250
+ units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
1251
+ units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
1252
+ units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
1253
+ diff;
1254
+ }
1255
+ return asFloat ? output : absRound(output);
1256
+ },
1257
+
1258
+ from : function (time, withoutSuffix) {
1259
+ return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
1260
+ },
1261
+
1262
+ fromNow : function (withoutSuffix) {
1263
+ return this.from(moment(), withoutSuffix);
1264
+ },
1265
+
1266
+ calendar : function () {
1267
+ var diff = this.diff(moment().startOf('day'), 'days', true),
1268
+ format = diff < -6 ? 'sameElse' :
1269
+ diff < -1 ? 'lastWeek' :
1270
+ diff < 0 ? 'lastDay' :
1271
+ diff < 1 ? 'sameDay' :
1272
+ diff < 2 ? 'nextDay' :
1273
+ diff < 7 ? 'nextWeek' : 'sameElse';
1274
+ return this.format(this.lang().calendar(format, this));
1275
+ },
1276
+
1277
+ isLeapYear : function () {
1278
+ var year = this.year();
1279
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1280
+ },
1281
+
1282
+ isDST : function () {
1283
+ return (this.zone() < this.clone().month(0).zone() ||
1284
+ this.zone() < this.clone().month(5).zone());
1285
+ },
1286
+
1287
+ day : function (input) {
1288
+ var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1289
+ if (input != null) {
1290
+ if (typeof input === 'string') {
1291
+ input = this.lang().weekdaysParse(input);
1292
+ if (typeof input !== 'number') {
1293
+ return this;
1294
+ }
1295
+ }
1296
+ return this.add({ d : input - day });
1297
+ } else {
1298
+ return day;
1299
+ }
1300
+ },
1301
+
1302
+ month : function (input) {
1303
+ var utc = this._isUTC ? 'UTC' : '',
1304
+ dayOfMonth,
1305
+ daysInMonth;
1306
+
1307
+ if (input != null) {
1308
+ if (typeof input === 'string') {
1309
+ input = this.lang().monthsParse(input);
1310
+ if (typeof input !== 'number') {
1311
+ return this;
1312
+ }
1313
+ }
1314
+
1315
+ dayOfMonth = this.date();
1316
+ this.date(1);
1317
+ this._d['set' + utc + 'Month'](input);
1318
+ this.date(Math.min(dayOfMonth, this.daysInMonth()));
1319
+
1320
+ moment.updateOffset(this);
1321
+ return this;
1322
+ } else {
1323
+ return this._d['get' + utc + 'Month']();
1324
+ }
1325
+ },
1326
+
1327
+ startOf: function (units) {
1328
+ units = normalizeUnits(units);
1329
+ // the following switch intentionally omits break keywords
1330
+ // to utilize falling through the cases.
1331
+ switch (units) {
1332
+ case 'year':
1333
+ this.month(0);
1334
+ /* falls through */
1335
+ case 'month':
1336
+ this.date(1);
1337
+ /* falls through */
1338
+ case 'week':
1339
+ case 'day':
1340
+ this.hours(0);
1341
+ /* falls through */
1342
+ case 'hour':
1343
+ this.minutes(0);
1344
+ /* falls through */
1345
+ case 'minute':
1346
+ this.seconds(0);
1347
+ /* falls through */
1348
+ case 'second':
1349
+ this.milliseconds(0);
1350
+ /* falls through */
1351
+ }
1352
+
1353
+ // weeks are a special case
1354
+ if (units === 'week') {
1355
+ this.weekday(0);
1356
+ }
1357
+
1358
+ return this;
1359
+ },
1360
+
1361
+ endOf: function (units) {
1362
+ return this.startOf(units).add(units, 1).subtract('ms', 1);
1363
+ },
1364
+
1365
+ isAfter: function (input, units) {
1366
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1367
+ return +this.clone().startOf(units) > +moment(input).startOf(units);
1368
+ },
1369
+
1370
+ isBefore: function (input, units) {
1371
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1372
+ return +this.clone().startOf(units) < +moment(input).startOf(units);
1373
+ },
1374
+
1375
+ isSame: function (input, units) {
1376
+ units = typeof units !== 'undefined' ? units : 'millisecond';
1377
+ return +this.clone().startOf(units) === +moment(input).startOf(units);
1378
+ },
1379
+
1380
+ min: function (other) {
1381
+ other = moment.apply(null, arguments);
1382
+ return other < this ? this : other;
1383
+ },
1384
+
1385
+ max: function (other) {
1386
+ other = moment.apply(null, arguments);
1387
+ return other > this ? this : other;
1388
+ },
1389
+
1390
+ zone : function (input) {
1391
+ var offset = this._offset || 0;
1392
+ if (input != null) {
1393
+ if (typeof input === "string") {
1394
+ input = timezoneMinutesFromString(input);
1395
+ }
1396
+ if (Math.abs(input) < 16) {
1397
+ input = input * 60;
1398
+ }
1399
+ this._offset = input;
1400
+ this._isUTC = true;
1401
+ if (offset !== input) {
1402
+ addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
1403
+ }
1404
+ } else {
1405
+ return this._isUTC ? offset : this._d.getTimezoneOffset();
1406
+ }
1407
+ return this;
1408
+ },
1409
+
1410
+ zoneAbbr : function () {
1411
+ return this._isUTC ? "UTC" : "";
1412
+ },
1413
+
1414
+ zoneName : function () {
1415
+ return this._isUTC ? "Coordinated Universal Time" : "";
1416
+ },
1417
+
1418
+ daysInMonth : function () {
1419
+ return moment.utc([this.year(), this.month() + 1, 0]).date();
1420
+ },
1421
+
1422
+ dayOfYear : function (input) {
1423
+ var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
1424
+ return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
1425
+ },
1426
+
1427
+ weekYear : function (input) {
1428
+ var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
1429
+ return input == null ? year : this.add("y", (input - year));
1430
+ },
1431
+
1432
+ isoWeekYear : function (input) {
1433
+ var year = weekOfYear(this, 1, 4).year;
1434
+ return input == null ? year : this.add("y", (input - year));
1435
+ },
1436
+
1437
+ week : function (input) {
1438
+ var week = this.lang().week(this);
1439
+ return input == null ? week : this.add("d", (input - week) * 7);
1440
+ },
1441
+
1442
+ isoWeek : function (input) {
1443
+ var week = weekOfYear(this, 1, 4).week;
1444
+ return input == null ? week : this.add("d", (input - week) * 7);
1445
+ },
1446
+
1447
+ weekday : function (input) {
1448
+ var weekday = (this._d.getDay() + 7 - this.lang()._week.dow) % 7;
1449
+ return input == null ? weekday : this.add("d", input - weekday);
1450
+ },
1451
+
1452
+ isoWeekday : function (input) {
1453
+ // behaves the same as moment#day except
1454
+ // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1455
+ // as a setter, sunday should belong to the previous week.
1456
+ return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
1457
+ },
1458
+
1459
+ // If passed a language key, it will set the language for this
1460
+ // instance. Otherwise, it will return the language configuration
1461
+ // variables for this instance.
1462
+ lang : function (key) {
1463
+ if (key === undefined) {
1464
+ return this._lang;
1465
+ } else {
1466
+ this._lang = getLangDefinition(key);
1467
+ return this;
1468
+ }
1469
+ }
1470
+ };
1471
+
1472
+ // helper for adding shortcuts
1473
+ function makeGetterAndSetter(name, key) {
1474
+ moment.fn[name] = moment.fn[name + 's'] = function (input) {
1475
+ var utc = this._isUTC ? 'UTC' : '';
1476
+ if (input != null) {
1477
+ this._d['set' + utc + key](input);
1478
+ moment.updateOffset(this);
1479
+ return this;
1480
+ } else {
1481
+ return this._d['get' + utc + key]();
1482
+ }
1483
+ };
1484
+ }
1485
+
1486
+ // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
1487
+ for (i = 0; i < proxyGettersAndSetters.length; i ++) {
1488
+ makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]);
1489
+ }
1490
+
1491
+ // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
1492
+ makeGetterAndSetter('year', 'FullYear');
1493
+
1494
+ // add plural methods
1495
+ moment.fn.days = moment.fn.day;
1496
+ moment.fn.months = moment.fn.month;
1497
+ moment.fn.weeks = moment.fn.week;
1498
+ moment.fn.isoWeeks = moment.fn.isoWeek;
1499
+
1500
+ // add aliased format methods
1501
+ moment.fn.toJSON = moment.fn.toISOString;
1502
+
1503
+ /************************************
1504
+ Duration Prototype
1505
+ ************************************/
1506
+
1507
+
1508
+ moment.duration.fn = Duration.prototype = {
1509
+ _bubble : function () {
1510
+ var milliseconds = this._milliseconds,
1511
+ days = this._days,
1512
+ months = this._months,
1513
+ data = this._data,
1514
+ seconds, minutes, hours, years;
1515
+
1516
+ // The following code bubbles up values, see the tests for
1517
+ // examples of what that means.
1518
+ data.milliseconds = milliseconds % 1000;
1519
+
1520
+ seconds = absRound(milliseconds / 1000);
1521
+ data.seconds = seconds % 60;
1522
+
1523
+ minutes = absRound(seconds / 60);
1524
+ data.minutes = minutes % 60;
1525
+
1526
+ hours = absRound(minutes / 60);
1527
+ data.hours = hours % 24;
1528
+
1529
+ days += absRound(hours / 24);
1530
+ data.days = days % 30;
1531
+
1532
+ months += absRound(days / 30);
1533
+ data.months = months % 12;
1534
+
1535
+ years = absRound(months / 12);
1536
+ data.years = years;
1537
+ },
1538
+
1539
+ weeks : function () {
1540
+ return absRound(this.days() / 7);
1541
+ },
1542
+
1543
+ valueOf : function () {
1544
+ return this._milliseconds +
1545
+ this._days * 864e5 +
1546
+ (this._months % 12) * 2592e6 +
1547
+ ~~(this._months / 12) * 31536e6;
1548
+ },
1549
+
1550
+ humanize : function (withSuffix) {
1551
+ var difference = +this,
1552
+ output = relativeTime(difference, !withSuffix, this.lang());
1553
+
1554
+ if (withSuffix) {
1555
+ output = this.lang().pastFuture(difference, output);
1556
+ }
1557
+
1558
+ return this.lang().postformat(output);
1559
+ },
1560
+
1561
+ add : function (input, val) {
1562
+ // supports only 2.0-style add(1, 's') or add(moment)
1563
+ var dur = moment.duration(input, val);
1564
+
1565
+ this._milliseconds += dur._milliseconds;
1566
+ this._days += dur._days;
1567
+ this._months += dur._months;
1568
+
1569
+ this._bubble();
1570
+
1571
+ return this;
1572
+ },
1573
+
1574
+ subtract : function (input, val) {
1575
+ var dur = moment.duration(input, val);
1576
+
1577
+ this._milliseconds -= dur._milliseconds;
1578
+ this._days -= dur._days;
1579
+ this._months -= dur._months;
1580
+
1581
+ this._bubble();
1582
+
1583
+ return this;
1584
+ },
1585
+
1586
+ get : function (units) {
1587
+ units = normalizeUnits(units);
1588
+ return this[units.toLowerCase() + 's']();
1589
+ },
1590
+
1591
+ as : function (units) {
1592
+ units = normalizeUnits(units);
1593
+ return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
1594
+ },
1595
+
1596
+ lang : moment.fn.lang
1597
+ };
1598
+
1599
+ function makeDurationGetter(name) {
1600
+ moment.duration.fn[name] = function () {
1601
+ return this._data[name];
1602
+ };
1603
+ }
1604
+
1605
+ function makeDurationAsGetter(name, factor) {
1606
+ moment.duration.fn['as' + name] = function () {
1607
+ return +this / factor;
1608
+ };
1609
+ }
1610
+
1611
+ for (i in unitMillisecondFactors) {
1612
+ if (unitMillisecondFactors.hasOwnProperty(i)) {
1613
+ makeDurationAsGetter(i, unitMillisecondFactors[i]);
1614
+ makeDurationGetter(i.toLowerCase());
1615
+ }
1616
+ }
1617
+
1618
+ makeDurationAsGetter('Weeks', 6048e5);
1619
+ moment.duration.fn.asMonths = function () {
1620
+ return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
1621
+ };
1622
+
1623
+
1624
+ /************************************
1625
+ Default Lang
1626
+ ************************************/
1627
+
1628
+
1629
+ // Set default language, other languages will inherit from English.
1630
+ moment.lang('en', {
1631
+ ordinal : function (number) {
1632
+ var b = number % 10,
1633
+ output = (~~ (number % 100 / 10) === 1) ? 'th' :
1634
+ (b === 1) ? 'st' :
1635
+ (b === 2) ? 'nd' :
1636
+ (b === 3) ? 'rd' : 'th';
1637
+ return number + output;
1638
+ }
1639
+ });
1640
+
1641
+
1642
+ /************************************
1643
+ Exposing Moment
1644
+ ************************************/
1645
+
1646
+
1647
+ // CommonJS module is defined
1648
+ if (hasModule) {
1649
+ module.exports = moment;
1650
+ }
1651
+ /*global ender:false */
1652
+ if (typeof ender === 'undefined') {
1653
+ // here, `this` means `window` in the browser, or `global` on the server
1654
+ // add `moment` as a global object via a string identifier,
1655
+ // for Closure Compiler "advanced" mode
1656
+ this['moment'] = moment;
1657
+ }
1658
+ /*global define:false */
1659
+ if (typeof define === "function" && define.amd) {
1660
+ define("moment", [], function () {
1661
+ return moment;
1662
+ });
1663
+ }
1664
+ }).call(this);