upmin-admin 0.0.39 → 0.1.0

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