flashgrid-ext 2.2.5 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc8a1562a0f9ca9b276bd7bef00f80e9d5a2531e
4
- data.tar.gz: 13c4541874fa7f0485f119607e712edce102d9ce
3
+ metadata.gz: 48ae2c233d0dacccc45dabd1b60d01c3c7464a74
4
+ data.tar.gz: d325508a8a57ed51924a41f2f91c311dcfb360a1
5
5
  SHA512:
6
- metadata.gz: ca8c0ef30b07bd35f87468b97cc56076962232c8c43cdc7e511d307fec60e09f46a78934f77d4694164d7bcdd3b44af6a5b3f6fd4479d061a70cc784d81c8b38
7
- data.tar.gz: eef1e631a8cfbc71fd9b7fe18b0cdeacc3ce767fd016a100682ac55b1c39ff653cb1bc3ba68dcbfd1a345e1bcc674a7d0ac81576d9ee4a6866b934c67a94de80
6
+ metadata.gz: 4de3c3dc7c88cf21b19306f979e78aca31878d86f882498aeb795270ccbe37f0051fbd79bb7351e92dca56d6b0851ac99fc530c66ec85fc027301612b43ae16f
7
+ data.tar.gz: 80ca03e9046cfef7359be5970355a0d864fc7e62cd00c13882a6155782617fd35a95c4fe12e169d632613a0385d7d4a3187acb8aed21fe9d0acd7f51596cdb19
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Flashgrid Ext.
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/flashgrid-ext.svg)](http://badge.fury.io/rb/flashgrid-ext)
4
+
3
5
  [Flashgrid Ext.](http://flashgrid-ext.drexed.com) is an extention of useful and cool javascripts for Flashgrid framework
4
6
 
5
7
  To get started, check out [http://flashgrid-ext.drexed.com](http://flashgrid-ext.drexed.com)!
@@ -1,5 +1,5 @@
1
1
  module Flashgrid
2
2
  module Ext
3
- VERSION = "2.2.5"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
  end
@@ -1,15 +1,15 @@
1
1
  (function (undefined) {
2
-
3
2
  /************************************
4
3
  Constants
5
4
  ************************************/
6
5
 
7
6
  var moment,
8
- VERSION = "2.7.0",
7
+ VERSION = '2.8.2',
9
8
  // the global-scope this is NOT the global object in Node.js
10
9
  globalScope = typeof global !== 'undefined' ? global : this,
11
10
  oldGlobalMoment,
12
11
  round = Math.round,
12
+ hasOwnProperty = Object.prototype.hasOwnProperty,
13
13
  i,
14
14
 
15
15
  YEAR = 0,
@@ -20,22 +20,11 @@
20
20
  SECOND = 5,
21
21
  MILLISECOND = 6,
22
22
 
23
- // internal storage for language config files
24
- languages = {},
23
+ // internal storage for locale config files
24
+ locales = {},
25
25
 
26
- // moment internal properties
27
- momentProperties = {
28
- _isAMomentObject: null,
29
- _i : null,
30
- _f : null,
31
- _l : null,
32
- _strict : null,
33
- _tzm : null,
34
- _isUTC : null,
35
- _offset : null, // optional. Combine with _isUTC
36
- _pf : null,
37
- _lang : null // optional
38
- },
26
+ // extra moment internal properties (plugins register props here)
27
+ momentProperties = [],
39
28
 
40
29
  // check for nodeJS
41
30
  hasModule = (typeof module !== 'undefined' && module.exports),
@@ -94,7 +83,7 @@
94
83
  ['HH', /(T| )\d\d/]
95
84
  ],
96
85
 
97
- // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
86
+ // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-15', '30']
98
87
  parseTimezoneChunker = /([\+\-]|\d\d)/gi,
99
88
 
100
89
  // getter and setter names
@@ -141,12 +130,11 @@
141
130
 
142
131
  // default relative time thresholds
143
132
  relativeTimeThresholds = {
144
- s: 45, //seconds to minutes
145
- m: 45, //minutes to hours
146
- h: 22, //hours to days
147
- dd: 25, //days to month (month == 1)
148
- dm: 45, //days to months (months > 1)
149
- dy: 345 //days to year
133
+ s: 45, // seconds to minute
134
+ m: 45, // minutes to hour
135
+ h: 22, // hours to day
136
+ d: 26, // days to month
137
+ M: 11 // months to year
150
138
  },
151
139
 
152
140
  // tokens to ordinalize and pad
@@ -158,10 +146,10 @@
158
146
  return this.month() + 1;
159
147
  },
160
148
  MMM : function (format) {
161
- return this.lang().monthsShort(this, format);
149
+ return this.localeData().monthsShort(this, format);
162
150
  },
163
151
  MMMM : function (format) {
164
- return this.lang().months(this, format);
152
+ return this.localeData().months(this, format);
165
153
  },
166
154
  D : function () {
167
155
  return this.date();
@@ -173,13 +161,13 @@
173
161
  return this.day();
174
162
  },
175
163
  dd : function (format) {
176
- return this.lang().weekdaysMin(this, format);
164
+ return this.localeData().weekdaysMin(this, format);
177
165
  },
178
166
  ddd : function (format) {
179
- return this.lang().weekdaysShort(this, format);
167
+ return this.localeData().weekdaysShort(this, format);
180
168
  },
181
169
  dddd : function (format) {
182
- return this.lang().weekdays(this, format);
170
+ return this.localeData().weekdays(this, format);
183
171
  },
184
172
  w : function () {
185
173
  return this.week();
@@ -225,10 +213,10 @@
225
213
  return this.isoWeekday();
226
214
  },
227
215
  a : function () {
228
- return this.lang().meridiem(this.hours(), this.minutes(), true);
216
+ return this.localeData().meridiem(this.hours(), this.minutes(), true);
229
217
  },
230
218
  A : function () {
231
- return this.lang().meridiem(this.hours(), this.minutes(), false);
219
+ return this.localeData().meridiem(this.hours(), this.minutes(), false);
232
220
  },
233
221
  H : function () {
234
222
  return this.hours();
@@ -256,19 +244,19 @@
256
244
  },
257
245
  Z : function () {
258
246
  var a = -this.zone(),
259
- b = "+";
247
+ b = '+';
260
248
  if (a < 0) {
261
249
  a = -a;
262
- b = "-";
250
+ b = '-';
263
251
  }
264
- return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
252
+ return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
265
253
  },
266
254
  ZZ : function () {
267
255
  var a = -this.zone(),
268
- b = "+";
256
+ b = '+';
269
257
  if (a < 0) {
270
258
  a = -a;
271
- b = "-";
259
+ b = '-';
272
260
  }
273
261
  return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
274
262
  },
@@ -286,6 +274,8 @@
286
274
  }
287
275
  },
288
276
 
277
+ deprecations = {},
278
+
289
279
  lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
290
280
 
291
281
  // Pick the first defined of two or three arguments. dfl comes from
@@ -294,10 +284,14 @@
294
284
  switch (arguments.length) {
295
285
  case 2: return a != null ? a : b;
296
286
  case 3: return a != null ? a : b != null ? b : c;
297
- default: throw new Error("Implement me");
287
+ default: throw new Error('Implement me');
298
288
  }
299
289
  }
300
290
 
291
+ function hasOwnProp(a, b) {
292
+ return hasOwnProperty.call(a, b);
293
+ }
294
+
301
295
  function defaultParsingFlags() {
302
296
  // We need to deep clone this object, and es5 standard is not very
303
297
  // helpful.
@@ -315,23 +309,31 @@
315
309
  };
316
310
  }
317
311
 
312
+ function printMsg(msg) {
313
+ if (moment.suppressDeprecationWarnings === false &&
314
+ typeof console !== 'undefined' && console.warn) {
315
+ console.warn('Deprecation warning: ' + msg);
316
+ }
317
+ }
318
+
318
319
  function deprecate(msg, fn) {
319
320
  var firstTime = true;
320
- function printMsg() {
321
- if (moment.suppressDeprecationWarnings === false &&
322
- typeof console !== 'undefined' && console.warn) {
323
- console.warn("Deprecation warning: " + msg);
324
- }
325
- }
326
321
  return extend(function () {
327
322
  if (firstTime) {
328
- printMsg();
323
+ printMsg(msg);
329
324
  firstTime = false;
330
325
  }
331
326
  return fn.apply(this, arguments);
332
327
  }, fn);
333
328
  }
334
329
 
330
+ function deprecateSimple(name, msg) {
331
+ if (!deprecations[name]) {
332
+ printMsg(msg);
333
+ deprecations[name] = true;
334
+ }
335
+ }
336
+
335
337
  function padToken(func, count) {
336
338
  return function (a) {
337
339
  return leftZeroFill(func.call(this, a), count);
@@ -339,7 +341,7 @@
339
341
  }
340
342
  function ordinalizeToken(func, period) {
341
343
  return function (a) {
342
- return this.lang().ordinal(func.call(this, a), period);
344
+ return this.localeData().ordinal(func.call(this, a), period);
343
345
  };
344
346
  }
345
347
 
@@ -358,14 +360,16 @@
358
360
  Constructors
359
361
  ************************************/
360
362
 
361
- function Language() {
362
-
363
+ function Locale() {
363
364
  }
364
365
 
365
366
  // Moment prototype object
366
- function Moment(config) {
367
- checkOverflow(config);
368
- extend(this, config);
367
+ function Moment(config, skipOverflow) {
368
+ if (skipOverflow !== false) {
369
+ checkOverflow(config);
370
+ }
371
+ copyConfig(this, config);
372
+ this._d = new Date(+config._d);
369
373
  }
370
374
 
371
375
  // Duration Constructor
@@ -399,6 +403,8 @@
399
403
 
400
404
  this._data = {};
401
405
 
406
+ this._locale = moment.localeData();
407
+
402
408
  this._bubble();
403
409
  }
404
410
 
@@ -409,31 +415,67 @@
409
415
 
410
416
  function extend(a, b) {
411
417
  for (var i in b) {
412
- if (b.hasOwnProperty(i)) {
418
+ if (hasOwnProp(b, i)) {
413
419
  a[i] = b[i];
414
420
  }
415
421
  }
416
422
 
417
- if (b.hasOwnProperty("toString")) {
423
+ if (hasOwnProp(b, 'toString')) {
418
424
  a.toString = b.toString;
419
425
  }
420
426
 
421
- if (b.hasOwnProperty("valueOf")) {
427
+ if (hasOwnProp(b, 'valueOf')) {
422
428
  a.valueOf = b.valueOf;
423
429
  }
424
430
 
425
431
  return a;
426
432
  }
427
433
 
428
- function cloneMoment(m) {
429
- var result = {}, i;
430
- for (i in m) {
431
- if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
432
- result[i] = m[i];
434
+ function copyConfig(to, from) {
435
+ var i, prop, val;
436
+
437
+ if (typeof from._isAMomentObject !== 'undefined') {
438
+ to._isAMomentObject = from._isAMomentObject;
439
+ }
440
+ if (typeof from._i !== 'undefined') {
441
+ to._i = from._i;
442
+ }
443
+ if (typeof from._f !== 'undefined') {
444
+ to._f = from._f;
445
+ }
446
+ if (typeof from._l !== 'undefined') {
447
+ to._l = from._l;
448
+ }
449
+ if (typeof from._strict !== 'undefined') {
450
+ to._strict = from._strict;
451
+ }
452
+ if (typeof from._tzm !== 'undefined') {
453
+ to._tzm = from._tzm;
454
+ }
455
+ if (typeof from._isUTC !== 'undefined') {
456
+ to._isUTC = from._isUTC;
457
+ }
458
+ if (typeof from._offset !== 'undefined') {
459
+ to._offset = from._offset;
460
+ }
461
+ if (typeof from._pf !== 'undefined') {
462
+ to._pf = from._pf;
463
+ }
464
+ if (typeof from._locale !== 'undefined') {
465
+ to._locale = from._locale;
466
+ }
467
+
468
+ if (momentProperties.length > 0) {
469
+ for (i in momentProperties) {
470
+ prop = momentProperties[i];
471
+ val = from[prop];
472
+ if (typeof val !== 'undefined') {
473
+ to[prop] = val;
474
+ }
433
475
  }
434
476
  }
435
477
 
436
- return result;
478
+ return to;
437
479
  }
438
480
 
439
481
  function absRound(number) {
@@ -456,7 +498,51 @@
456
498
  return (sign ? (forceSign ? '+' : '') : '-') + output;
457
499
  }
458
500
 
459
- // helper function for _.addTime and _.subtractTime
501
+ function positiveMomentsDifference(base, other) {
502
+ var res = {milliseconds: 0, months: 0};
503
+
504
+ res.months = other.month() - base.month() +
505
+ (other.year() - base.year()) * 12;
506
+ if (base.clone().add(res.months, 'M').isAfter(other)) {
507
+ --res.months;
508
+ }
509
+
510
+ res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
511
+
512
+ return res;
513
+ }
514
+
515
+ function momentsDifference(base, other) {
516
+ var res;
517
+ other = makeAs(other, base);
518
+ if (base.isBefore(other)) {
519
+ res = positiveMomentsDifference(base, other);
520
+ } else {
521
+ res = positiveMomentsDifference(other, base);
522
+ res.milliseconds = -res.milliseconds;
523
+ res.months = -res.months;
524
+ }
525
+
526
+ return res;
527
+ }
528
+
529
+ // TODO: remove 'name' arg after deprecation is removed
530
+ function createAdder(direction, name) {
531
+ return function (val, period) {
532
+ var dur, tmp;
533
+ //invert the arguments, but complain about it
534
+ if (period !== null && !isNaN(+period)) {
535
+ deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
536
+ tmp = val; val = period; period = tmp;
537
+ }
538
+
539
+ val = typeof val === 'string' ? +val : val;
540
+ dur = moment.duration(val, period);
541
+ addOrSubtractDurationFromMoment(this, dur, direction);
542
+ return this;
543
+ };
544
+ }
545
+
460
546
  function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
461
547
  var milliseconds = duration._milliseconds,
462
548
  days = duration._days,
@@ -483,8 +569,8 @@
483
569
  }
484
570
 
485
571
  function isDate(input) {
486
- return Object.prototype.toString.call(input) === '[object Date]' ||
487
- input instanceof Date;
572
+ return Object.prototype.toString.call(input) === '[object Date]' ||
573
+ input instanceof Date;
488
574
  }
489
575
 
490
576
  // compare two arrays, return the number of differences
@@ -516,7 +602,7 @@
516
602
  prop;
517
603
 
518
604
  for (prop in inputObject) {
519
- if (inputObject.hasOwnProperty(prop)) {
605
+ if (hasOwnProp(inputObject, prop)) {
520
606
  normalizedProp = normalizeUnits(prop);
521
607
  if (normalizedProp) {
522
608
  normalizedInput[normalizedProp] = inputObject[prop];
@@ -544,7 +630,7 @@
544
630
 
545
631
  moment[field] = function (format, index) {
546
632
  var i, getter,
547
- method = moment.fn._lang[field],
633
+ method = moment._locale[field],
548
634
  results = [];
549
635
 
550
636
  if (typeof format === 'number') {
@@ -554,7 +640,7 @@
554
640
 
555
641
  getter = function (i) {
556
642
  var m = moment().utc().set(setter, i);
557
- return method.call(moment.fn._lang, m, format || '');
643
+ return method.call(moment._locale, m, format || '');
558
644
  };
559
645
 
560
646
  if (index != null) {
@@ -639,10 +725,50 @@
639
725
  return m._isValid;
640
726
  }
641
727
 
642
- function normalizeLanguage(key) {
728
+ function normalizeLocale(key) {
643
729
  return key ? key.toLowerCase().replace('_', '-') : key;
644
730
  }
645
731
 
732
+ // pick the locale from the array
733
+ // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
734
+ // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
735
+ function chooseLocale(names) {
736
+ var i = 0, j, next, locale, split;
737
+
738
+ while (i < names.length) {
739
+ split = normalizeLocale(names[i]).split('-');
740
+ j = split.length;
741
+ next = normalizeLocale(names[i + 1]);
742
+ next = next ? next.split('-') : null;
743
+ while (j > 0) {
744
+ locale = loadLocale(split.slice(0, j).join('-'));
745
+ if (locale) {
746
+ return locale;
747
+ }
748
+ if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
749
+ //the next array item is better than a shallower substring of this one
750
+ break;
751
+ }
752
+ j--;
753
+ }
754
+ i++;
755
+ }
756
+ return null;
757
+ }
758
+
759
+ function loadLocale(name) {
760
+ var oldLocale = null;
761
+ if (!locales[name] && hasModule) {
762
+ try {
763
+ oldLocale = moment.locale();
764
+ require('./locale/' + name);
765
+ // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
766
+ moment.locale(oldLocale);
767
+ } catch (e) { }
768
+ }
769
+ return locales[name];
770
+ }
771
+
646
772
  // Return a moment from input, that is local/utc/zone equivalent to model.
647
773
  function makeAs(input, model) {
648
774
  return model._isUTC ? moment(input).zone(model._offset || 0) :
@@ -650,11 +776,11 @@
650
776
  }
651
777
 
652
778
  /************************************
653
- Languages
779
+ Locale
654
780
  ************************************/
655
781
 
656
782
 
657
- extend(Language.prototype, {
783
+ extend(Locale.prototype, {
658
784
 
659
785
  set : function (config) {
660
786
  var prop, i;
@@ -668,12 +794,12 @@
668
794
  }
669
795
  },
670
796
 
671
- _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
797
+ _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
672
798
  months : function (m) {
673
799
  return this._months[m.month()];
674
800
  },
675
801
 
676
- _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
802
+ _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
677
803
  monthsShort : function (m) {
678
804
  return this._monthsShort[m.month()];
679
805
  },
@@ -699,17 +825,17 @@
699
825
  }
700
826
  },
701
827
 
702
- _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
828
+ _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
703
829
  weekdays : function (m) {
704
830
  return this._weekdays[m.day()];
705
831
  },
706
832
 
707
- _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
833
+ _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
708
834
  weekdaysShort : function (m) {
709
835
  return this._weekdaysShort[m.day()];
710
836
  },
711
837
 
712
- _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
838
+ _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
713
839
  weekdaysMin : function (m) {
714
840
  return this._weekdaysMin[m.day()];
715
841
  },
@@ -736,11 +862,11 @@
736
862
  },
737
863
 
738
864
  _longDateFormat : {
739
- LT : "h:mm A",
740
- L : "MM/DD/YYYY",
741
- LL : "MMMM D YYYY",
742
- LLL : "MMMM D YYYY LT",
743
- LLLL : "dddd, MMMM D YYYY LT"
865
+ LT : 'h:mm A',
866
+ L : 'MM/DD/YYYY',
867
+ LL : 'MMMM D, YYYY',
868
+ LLL : 'MMMM D, YYYY LT',
869
+ LLLL : 'dddd, MMMM D, YYYY LT'
744
870
  },
745
871
  longDateFormat : function (key) {
746
872
  var output = this._longDateFormat[key];
@@ -782,35 +908,37 @@
782
908
  },
783
909
 
784
910
  _relativeTime : {
785
- future : "in %s",
786
- past : "%s ago",
787
- s : "a few seconds",
788
- m : "a minute",
789
- mm : "%d minutes",
790
- h : "an hour",
791
- hh : "%d hours",
792
- d : "a day",
793
- dd : "%d days",
794
- M : "a month",
795
- MM : "%d months",
796
- y : "a year",
797
- yy : "%d years"
911
+ future : 'in %s',
912
+ past : '%s ago',
913
+ s : 'a few seconds',
914
+ m : 'a minute',
915
+ mm : '%d minutes',
916
+ h : 'an hour',
917
+ hh : '%d hours',
918
+ d : 'a day',
919
+ dd : '%d days',
920
+ M : 'a month',
921
+ MM : '%d months',
922
+ y : 'a year',
923
+ yy : '%d years'
798
924
  },
925
+
799
926
  relativeTime : function (number, withoutSuffix, string, isFuture) {
800
927
  var output = this._relativeTime[string];
801
928
  return (typeof output === 'function') ?
802
929
  output(number, withoutSuffix, string, isFuture) :
803
930
  output.replace(/%d/i, number);
804
931
  },
932
+
805
933
  pastFuture : function (diff, output) {
806
934
  var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
807
935
  return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
808
936
  },
809
937
 
810
938
  ordinal : function (number) {
811
- return this._ordinal.replace("%d", number);
939
+ return this._ordinal.replace('%d', number);
812
940
  },
813
- _ordinal : "%d",
941
+ _ordinal : '%d',
814
942
 
815
943
  preparse : function (string) {
816
944
  return string;
@@ -835,78 +963,6 @@
835
963
  }
836
964
  });
837
965
 
838
- // Loads a language definition into the `languages` cache. The function
839
- // takes a key and optionally values. If not in the browser and no values
840
- // are provided, it will load the language file module. As a convenience,
841
- // this function also returns the language values.
842
- function loadLang(key, values) {
843
- values.abbr = key;
844
- if (!languages[key]) {
845
- languages[key] = new Language();
846
- }
847
- languages[key].set(values);
848
- return languages[key];
849
- }
850
-
851
- // Remove a language from the `languages` cache. Mostly useful in tests.
852
- function unloadLang(key) {
853
- delete languages[key];
854
- }
855
-
856
- // Determines which language definition to use and returns it.
857
- //
858
- // With no parameters, it will return the global language. If you
859
- // pass in a language key, such as 'en', it will return the
860
- // definition for 'en', so long as 'en' has already been loaded using
861
- // moment.lang.
862
- function getLangDefinition(key) {
863
- var i = 0, j, lang, next, split,
864
- get = function (k) {
865
- if (!languages[k] && hasModule) {
866
- try {
867
- require('./lang/' + k);
868
- } catch (e) { }
869
- }
870
- return languages[k];
871
- };
872
-
873
- if (!key) {
874
- return moment.fn._lang;
875
- }
876
-
877
- if (!isArray(key)) {
878
- //short-circuit everything else
879
- lang = get(key);
880
- if (lang) {
881
- return lang;
882
- }
883
- key = [key];
884
- }
885
-
886
- //pick the language from the array
887
- //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
888
- //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
889
- while (i < key.length) {
890
- split = normalizeLanguage(key[i]).split('-');
891
- j = split.length;
892
- next = normalizeLanguage(key[i + 1]);
893
- next = next ? next.split('-') : null;
894
- while (j > 0) {
895
- lang = get(split.slice(0, j).join('-'));
896
- if (lang) {
897
- return lang;
898
- }
899
- if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
900
- //the next array item is better than a shallower substring of this one
901
- break;
902
- }
903
- j--;
904
- }
905
- i++;
906
- }
907
- return moment.fn._lang;
908
- }
909
-
910
966
  /************************************
911
967
  Formatting
912
968
  ************************************/
@@ -914,9 +970,9 @@
914
970
 
915
971
  function removeFormattingTokens(input) {
916
972
  if (input.match(/\[[\s\S]/)) {
917
- return input.replace(/^\[|\]$/g, "");
973
+ return input.replace(/^\[|\]$/g, '');
918
974
  }
919
- return input.replace(/\\/g, "");
975
+ return input.replace(/\\/g, '');
920
976
  }
921
977
 
922
978
  function makeFormatFunction(format) {
@@ -931,7 +987,7 @@
931
987
  }
932
988
 
933
989
  return function (mom) {
934
- var output = "";
990
+ var output = '';
935
991
  for (i = 0; i < length; i++) {
936
992
  output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
937
993
  }
@@ -941,12 +997,11 @@
941
997
 
942
998
  // format date using native date object
943
999
  function formatMoment(m, format) {
944
-
945
1000
  if (!m.isValid()) {
946
- return m.lang().invalidDate();
1001
+ return m.localeData().invalidDate();
947
1002
  }
948
1003
 
949
- format = expandFormat(format, m.lang());
1004
+ format = expandFormat(format, m.localeData());
950
1005
 
951
1006
  if (!formatFunctions[format]) {
952
1007
  formatFunctions[format] = makeFormatFunction(format);
@@ -955,11 +1010,11 @@
955
1010
  return formatFunctions[format](m);
956
1011
  }
957
1012
 
958
- function expandFormat(format, lang) {
1013
+ function expandFormat(format, locale) {
959
1014
  var i = 5;
960
1015
 
961
1016
  function replaceLongDateFormatTokens(input) {
962
- return lang.longDateFormat(input) || input;
1017
+ return locale.longDateFormat(input) || input;
963
1018
  }
964
1019
 
965
1020
  localFormattingTokens.lastIndex = 0;
@@ -1000,13 +1055,19 @@
1000
1055
  case 'ggggg':
1001
1056
  return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
1002
1057
  case 'S':
1003
- if (strict) { return parseTokenOneDigit; }
1058
+ if (strict) {
1059
+ return parseTokenOneDigit;
1060
+ }
1004
1061
  /* falls through */
1005
1062
  case 'SS':
1006
- if (strict) { return parseTokenTwoDigits; }
1063
+ if (strict) {
1064
+ return parseTokenTwoDigits;
1065
+ }
1007
1066
  /* falls through */
1008
1067
  case 'SSS':
1009
- if (strict) { return parseTokenThreeDigits; }
1068
+ if (strict) {
1069
+ return parseTokenThreeDigits;
1070
+ }
1010
1071
  /* falls through */
1011
1072
  case 'DDD':
1012
1073
  return parseTokenOneToThreeDigits;
@@ -1018,7 +1079,7 @@
1018
1079
  return parseTokenWord;
1019
1080
  case 'a':
1020
1081
  case 'A':
1021
- return getLangDefinition(config._l)._meridiemParse;
1082
+ return config._locale._meridiemParse;
1022
1083
  case 'X':
1023
1084
  return parseTokenTimestampMs;
1024
1085
  case 'Z':
@@ -1055,13 +1116,13 @@
1055
1116
  case 'Do':
1056
1117
  return parseTokenOrdinal;
1057
1118
  default :
1058
- a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
1119
+ a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
1059
1120
  return a;
1060
1121
  }
1061
1122
  }
1062
1123
 
1063
1124
  function timezoneMinutesFromString(string) {
1064
- string = string || "";
1125
+ string = string || '';
1065
1126
  var possibleTzMatches = (string.match(parseTokenTimezone) || []),
1066
1127
  tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
1067
1128
  parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
@@ -1090,7 +1151,7 @@
1090
1151
  break;
1091
1152
  case 'MMM' : // fall through to MMMM
1092
1153
  case 'MMMM' :
1093
- a = getLangDefinition(config._l).monthsParse(input);
1154
+ a = config._locale.monthsParse(input);
1094
1155
  // if we didn't find a month name, mark the date as invalid.
1095
1156
  if (a != null) {
1096
1157
  datePartArray[MONTH] = a;
@@ -1130,7 +1191,7 @@
1130
1191
  // AM / PM
1131
1192
  case 'a' : // fall through to A
1132
1193
  case 'A' :
1133
- config._isPm = getLangDefinition(config._l).isPM(input);
1194
+ config._isPm = config._locale.isPM(input);
1134
1195
  break;
1135
1196
  // 24 HOUR
1136
1197
  case 'H' : // fall through to hh
@@ -1170,7 +1231,7 @@
1170
1231
  case 'dd':
1171
1232
  case 'ddd':
1172
1233
  case 'dddd':
1173
- a = getLangDefinition(config._l).weekdaysParse(input);
1234
+ a = config._locale.weekdaysParse(input);
1174
1235
  // if we didn't get a weekday name, mark the date as invalid
1175
1236
  if (a != null) {
1176
1237
  config._w = config._w || {};
@@ -1206,7 +1267,7 @@
1206
1267
  }
1207
1268
 
1208
1269
  function dayOfYearFromWeekInfo(config) {
1209
- var w, weekYear, week, weekday, dow, doy, temp, lang;
1270
+ var w, weekYear, week, weekday, dow, doy, temp;
1210
1271
 
1211
1272
  w = config._w;
1212
1273
  if (w.GG != null || w.W != null || w.E != null) {
@@ -1221,9 +1282,8 @@
1221
1282
  week = dfl(w.W, 1);
1222
1283
  weekday = dfl(w.E, 1);
1223
1284
  } else {
1224
- lang = getLangDefinition(config._l);
1225
- dow = lang._week.dow;
1226
- doy = lang._week.doy;
1285
+ dow = config._locale._week.dow;
1286
+ doy = config._locale._week.doy;
1227
1287
 
1228
1288
  weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
1229
1289
  week = dfl(w.w, 1);
@@ -1337,7 +1397,6 @@
1337
1397
 
1338
1398
  // date from string and format string
1339
1399
  function makeDateFromStringAndFormat(config) {
1340
-
1341
1400
  if (config._f === moment.ISO_8601) {
1342
1401
  parseISO(config);
1343
1402
  return;
@@ -1347,13 +1406,12 @@
1347
1406
  config._pf.empty = true;
1348
1407
 
1349
1408
  // This array is used to make a Date, either with `new Date` or `Date.UTC`
1350
- var lang = getLangDefinition(config._l),
1351
- string = '' + config._i,
1409
+ var string = '' + config._i,
1352
1410
  i, parsedInput, tokens, token, skipped,
1353
1411
  stringLength = string.length,
1354
1412
  totalParsedInputLength = 0;
1355
1413
 
1356
- tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
1414
+ tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
1357
1415
 
1358
1416
  for (i = 0; i < tokens.length; i++) {
1359
1417
  token = tokens[i];
@@ -1428,7 +1486,7 @@
1428
1486
 
1429
1487
  for (i = 0; i < config._f.length; i++) {
1430
1488
  currentScore = 0;
1431
- tempConfig = extend({}, config);
1489
+ tempConfig = copyConfig({}, config);
1432
1490
  tempConfig._pf = defaultParsingFlags();
1433
1491
  tempConfig._f = config._f[i];
1434
1492
  makeDateFromStringAndFormat(tempConfig);
@@ -1464,8 +1522,8 @@
1464
1522
  config._pf.iso = true;
1465
1523
  for (i = 0, l = isoDates.length; i < l; i++) {
1466
1524
  if (isoDates[i][1].exec(string)) {
1467
- // match[5] should be "T" or undefined
1468
- config._f = isoDates[i][0] + (match[6] || " ");
1525
+ // match[5] should be 'T' or undefined
1526
+ config._f = isoDates[i][0] + (match[6] || ' ');
1469
1527
  break;
1470
1528
  }
1471
1529
  }
@@ -1476,7 +1534,7 @@
1476
1534
  }
1477
1535
  }
1478
1536
  if (string.match(parseTokenTimezone)) {
1479
- config._f += "Z";
1537
+ config._f += 'Z';
1480
1538
  }
1481
1539
  makeDateFromStringAndFormat(config);
1482
1540
  } else {
@@ -1494,20 +1552,18 @@
1494
1552
  }
1495
1553
 
1496
1554
  function makeDateFromInput(config) {
1497
- var input = config._i,
1498
- matched = aspNetJsonRegex.exec(input);
1499
-
1555
+ var input = config._i, matched;
1500
1556
  if (input === undefined) {
1501
1557
  config._d = new Date();
1502
- } else if (matched) {
1558
+ } else if (isDate(input)) {
1559
+ config._d = new Date(+input);
1560
+ } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
1503
1561
  config._d = new Date(+matched[1]);
1504
1562
  } else if (typeof input === 'string') {
1505
1563
  makeDateFromString(config);
1506
1564
  } else if (isArray(input)) {
1507
1565
  config._a = input.slice(0);
1508
1566
  dateFromConfig(config);
1509
- } else if (isDate(input)) {
1510
- config._d = new Date(+input);
1511
1567
  } else if (typeof(input) === 'object') {
1512
1568
  dateFromObject(config);
1513
1569
  } else if (typeof(input) === 'number') {
@@ -1538,13 +1594,13 @@
1538
1594
  return date;
1539
1595
  }
1540
1596
 
1541
- function parseWeekday(input, language) {
1597
+ function parseWeekday(input, locale) {
1542
1598
  if (typeof input === 'string') {
1543
1599
  if (!isNaN(input)) {
1544
1600
  input = parseInt(input, 10);
1545
1601
  }
1546
1602
  else {
1547
- input = language.weekdaysParse(input);
1603
+ input = locale.weekdaysParse(input);
1548
1604
  if (typeof input !== 'number') {
1549
1605
  return null;
1550
1606
  }
@@ -1559,29 +1615,33 @@
1559
1615
 
1560
1616
 
1561
1617
  // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
1562
- function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
1563
- return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1618
+ function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
1619
+ return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
1564
1620
  }
1565
1621
 
1566
- function relativeTime(milliseconds, withoutSuffix, lang) {
1567
- var seconds = round(Math.abs(milliseconds) / 1000),
1568
- minutes = round(seconds / 60),
1569
- hours = round(minutes / 60),
1570
- days = round(hours / 24),
1571
- years = round(days / 365),
1572
- args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1622
+ function relativeTime(posNegDuration, withoutSuffix, locale) {
1623
+ var duration = moment.duration(posNegDuration).abs(),
1624
+ seconds = round(duration.as('s')),
1625
+ minutes = round(duration.as('m')),
1626
+ hours = round(duration.as('h')),
1627
+ days = round(duration.as('d')),
1628
+ months = round(duration.as('M')),
1629
+ years = round(duration.as('y')),
1630
+
1631
+ args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
1573
1632
  minutes === 1 && ['m'] ||
1574
1633
  minutes < relativeTimeThresholds.m && ['mm', minutes] ||
1575
1634
  hours === 1 && ['h'] ||
1576
1635
  hours < relativeTimeThresholds.h && ['hh', hours] ||
1577
1636
  days === 1 && ['d'] ||
1578
- days <= relativeTimeThresholds.dd && ['dd', days] ||
1579
- days <= relativeTimeThresholds.dm && ['M'] ||
1580
- days < relativeTimeThresholds.dy && ['MM', round(days / 30)] ||
1637
+ days < relativeTimeThresholds.d && ['dd', days] ||
1638
+ months === 1 && ['M'] ||
1639
+ months < relativeTimeThresholds.M && ['MM', months] ||
1581
1640
  years === 1 && ['y'] || ['yy', years];
1641
+
1582
1642
  args[2] = withoutSuffix;
1583
- args[3] = milliseconds > 0;
1584
- args[4] = lang;
1643
+ args[3] = +posNegDuration > 0;
1644
+ args[4] = locale;
1585
1645
  return substituteTimeAgo.apply({}, args);
1586
1646
  }
1587
1647
 
@@ -1612,7 +1672,7 @@
1612
1672
  daysToDayOfWeek += 7;
1613
1673
  }
1614
1674
 
1615
- adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
1675
+ adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
1616
1676
  return {
1617
1677
  week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1618
1678
  year: adjustedMoment.year()
@@ -1642,18 +1702,18 @@
1642
1702
  var input = config._i,
1643
1703
  format = config._f;
1644
1704
 
1705
+ config._locale = config._locale || moment.localeData(config._l);
1706
+
1645
1707
  if (input === null || (format === undefined && input === '')) {
1646
1708
  return moment.invalid({nullInput: true});
1647
1709
  }
1648
1710
 
1649
1711
  if (typeof input === 'string') {
1650
- config._i = input = getLangDefinition().preparse(input);
1712
+ config._i = input = config._locale.preparse(input);
1651
1713
  }
1652
1714
 
1653
1715
  if (moment.isMoment(input)) {
1654
- config = cloneMoment(input);
1655
-
1656
- config._d = new Date(+input._d);
1716
+ return new Moment(input, true);
1657
1717
  } else if (format) {
1658
1718
  if (isArray(format)) {
1659
1719
  makeDateFromStringAndArray(config);
@@ -1667,12 +1727,12 @@
1667
1727
  return new Moment(config);
1668
1728
  }
1669
1729
 
1670
- moment = function (input, format, lang, strict) {
1730
+ moment = function (input, format, locale, strict) {
1671
1731
  var c;
1672
1732
 
1673
- if (typeof(lang) === "boolean") {
1674
- strict = lang;
1675
- lang = undefined;
1733
+ if (typeof(locale) === 'boolean') {
1734
+ strict = locale;
1735
+ locale = undefined;
1676
1736
  }
1677
1737
  // object construction must be done this way.
1678
1738
  // https://github.com/moment/moment/issues/1423
@@ -1680,7 +1740,7 @@
1680
1740
  c._isAMomentObject = true;
1681
1741
  c._i = input;
1682
1742
  c._f = format;
1683
- c._l = lang;
1743
+ c._l = locale;
1684
1744
  c._strict = strict;
1685
1745
  c._isUTC = false;
1686
1746
  c._pf = defaultParsingFlags();
@@ -1691,13 +1751,14 @@
1691
1751
  moment.suppressDeprecationWarnings = false;
1692
1752
 
1693
1753
  moment.createFromInputFallback = deprecate(
1694
- "moment construction falls back to js Date. This is " +
1695
- "discouraged and will be removed in upcoming major " +
1696
- "release. Please refer to " +
1697
- "https://github.com/moment/moment/issues/1407 for more info.",
1698
- function (config) {
1699
- config._d = new Date(config._i);
1700
- });
1754
+ 'moment construction falls back to js Date. This is ' +
1755
+ 'discouraged and will be removed in upcoming major ' +
1756
+ 'release. Please refer to ' +
1757
+ 'https://github.com/moment/moment/issues/1407 for more info.',
1758
+ function (config) {
1759
+ config._d = new Date(config._i);
1760
+ }
1761
+ );
1701
1762
 
1702
1763
  // Pick a moment m from moments so that m[fn](other) is true for all
1703
1764
  // other. This relies on the function fn to be transitive.
@@ -1734,12 +1795,12 @@
1734
1795
  };
1735
1796
 
1736
1797
  // creating with utc
1737
- moment.utc = function (input, format, lang, strict) {
1798
+ moment.utc = function (input, format, locale, strict) {
1738
1799
  var c;
1739
1800
 
1740
- if (typeof(lang) === "boolean") {
1741
- strict = lang;
1742
- lang = undefined;
1801
+ if (typeof(locale) === 'boolean') {
1802
+ strict = locale;
1803
+ locale = undefined;
1743
1804
  }
1744
1805
  // object construction must be done this way.
1745
1806
  // https://github.com/moment/moment/issues/1423
@@ -1747,7 +1808,7 @@
1747
1808
  c._isAMomentObject = true;
1748
1809
  c._useUTC = true;
1749
1810
  c._isUTC = true;
1750
- c._l = lang;
1811
+ c._l = locale;
1751
1812
  c._i = input;
1752
1813
  c._f = format;
1753
1814
  c._strict = strict;
@@ -1768,7 +1829,8 @@
1768
1829
  match = null,
1769
1830
  sign,
1770
1831
  ret,
1771
- parseIso;
1832
+ parseIso,
1833
+ diffRes;
1772
1834
 
1773
1835
  if (moment.isDuration(input)) {
1774
1836
  duration = {
@@ -1784,7 +1846,7 @@
1784
1846
  duration.milliseconds = input;
1785
1847
  }
1786
1848
  } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
1787
- sign = (match[1] === "-") ? -1 : 1;
1849
+ sign = (match[1] === '-') ? -1 : 1;
1788
1850
  duration = {
1789
1851
  y: 0,
1790
1852
  d: toInt(match[DATE]) * sign,
@@ -1794,7 +1856,7 @@
1794
1856
  ms: toInt(match[MILLISECOND]) * sign
1795
1857
  };
1796
1858
  } else if (!!(match = isoDurationRegex.exec(input))) {
1797
- sign = (match[1] === "-") ? -1 : 1;
1859
+ sign = (match[1] === '-') ? -1 : 1;
1798
1860
  parseIso = function (inp) {
1799
1861
  // We'd normally use ~~inp for this, but unfortunately it also
1800
1862
  // converts floats to ints.
@@ -1812,12 +1874,19 @@
1812
1874
  s: parseIso(match[7]),
1813
1875
  w: parseIso(match[8])
1814
1876
  };
1877
+ } else if (typeof duration === 'object' &&
1878
+ ('from' in duration || 'to' in duration)) {
1879
+ diffRes = momentsDifference(moment(duration.from), moment(duration.to));
1880
+
1881
+ duration = {};
1882
+ duration.ms = diffRes.milliseconds;
1883
+ duration.M = diffRes.months;
1815
1884
  }
1816
1885
 
1817
1886
  ret = new Duration(duration);
1818
1887
 
1819
- if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
1820
- ret._lang = input._lang;
1888
+ if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
1889
+ ret._locale = input._locale;
1821
1890
  }
1822
1891
 
1823
1892
  return ret;
@@ -1841,46 +1910,99 @@
1841
1910
  moment.updateOffset = function () {};
1842
1911
 
1843
1912
  // This function allows you to set a threshold for relative time strings
1844
- moment.relativeTimeThreshold = function(threshold, limit) {
1845
- if (relativeTimeThresholds[threshold] === undefined) {
1846
- return false;
1847
- }
1848
- relativeTimeThresholds[threshold] = limit;
1849
- return true;
1913
+ moment.relativeTimeThreshold = function (threshold, limit) {
1914
+ if (relativeTimeThresholds[threshold] === undefined) {
1915
+ return false;
1916
+ }
1917
+ if (limit === undefined) {
1918
+ return relativeTimeThresholds[threshold];
1919
+ }
1920
+ relativeTimeThresholds[threshold] = limit;
1921
+ return true;
1850
1922
  };
1851
1923
 
1852
- // This function will load languages and then set the global language. If
1924
+ moment.lang = deprecate(
1925
+ 'moment.lang is deprecated. Use moment.locale instead.',
1926
+ function (key, value) {
1927
+ return moment.locale(key, value);
1928
+ }
1929
+ );
1930
+
1931
+ // This function will load locale and then set the global locale. If
1853
1932
  // no arguments are passed in, it will simply return the current global
1854
- // language key.
1855
- moment.lang = function (key, values) {
1856
- var r;
1857
- if (!key) {
1858
- return moment.fn._lang._abbr;
1859
- }
1860
- if (values) {
1861
- loadLang(normalizeLanguage(key), values);
1862
- } else if (values === null) {
1863
- unloadLang(key);
1864
- key = 'en';
1865
- } else if (!languages[key]) {
1866
- getLangDefinition(key);
1867
- }
1868
- r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
1869
- return r._abbr;
1933
+ // locale key.
1934
+ moment.locale = function (key, values) {
1935
+ var data;
1936
+ if (key) {
1937
+ if (typeof(values) !== 'undefined') {
1938
+ data = moment.defineLocale(key, values);
1939
+ }
1940
+ else {
1941
+ data = moment.localeData(key);
1942
+ }
1943
+
1944
+ if (data) {
1945
+ moment.duration._locale = moment._locale = data;
1946
+ }
1947
+ }
1948
+
1949
+ return moment._locale._abbr;
1870
1950
  };
1871
1951
 
1872
- // returns language data
1873
- moment.langData = function (key) {
1874
- if (key && key._lang && key._lang._abbr) {
1875
- key = key._lang._abbr;
1952
+ moment.defineLocale = function (name, values) {
1953
+ if (values !== null) {
1954
+ values.abbr = name;
1955
+ if (!locales[name]) {
1956
+ locales[name] = new Locale();
1957
+ }
1958
+ locales[name].set(values);
1959
+
1960
+ // backwards compat for now: also set the locale
1961
+ moment.locale(name);
1962
+
1963
+ return locales[name];
1964
+ } else {
1965
+ // useful for testing
1966
+ delete locales[name];
1967
+ return null;
1968
+ }
1969
+ };
1970
+
1971
+ moment.langData = deprecate(
1972
+ 'moment.langData is deprecated. Use moment.localeData instead.',
1973
+ function (key) {
1974
+ return moment.localeData(key);
1975
+ }
1976
+ );
1977
+
1978
+ // returns locale data
1979
+ moment.localeData = function (key) {
1980
+ var locale;
1981
+
1982
+ if (key && key._locale && key._locale._abbr) {
1983
+ key = key._locale._abbr;
1984
+ }
1985
+
1986
+ if (!key) {
1987
+ return moment._locale;
1876
1988
  }
1877
- return getLangDefinition(key);
1989
+
1990
+ if (!isArray(key)) {
1991
+ //short-circuit everything else
1992
+ locale = loadLocale(key);
1993
+ if (locale) {
1994
+ return locale;
1995
+ }
1996
+ key = [key];
1997
+ }
1998
+
1999
+ return chooseLocale(key);
1878
2000
  };
1879
2001
 
1880
2002
  // compare moment object
1881
2003
  moment.isMoment = function (obj) {
1882
2004
  return obj instanceof Moment ||
1883
- (obj != null && obj.hasOwnProperty('_isAMomentObject'));
2005
+ (obj != null && hasOwnProp(obj, '_isAMomentObject'));
1884
2006
  };
1885
2007
 
1886
2008
  // for typechecking Duration objects
@@ -1936,7 +2058,7 @@
1936
2058
  },
1937
2059
 
1938
2060
  toString : function () {
1939
- return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
2061
+ return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
1940
2062
  },
1941
2063
 
1942
2064
  toDate : function () {
@@ -1970,7 +2092,6 @@
1970
2092
  },
1971
2093
 
1972
2094
  isDSTShifted : function () {
1973
-
1974
2095
  if (this._a) {
1975
2096
  return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
1976
2097
  }
@@ -1986,48 +2107,30 @@
1986
2107
  return this._pf.overflow;
1987
2108
  },
1988
2109
 
1989
- utc : function () {
1990
- return this.zone(0);
2110
+ utc : function (keepLocalTime) {
2111
+ return this.zone(0, keepLocalTime);
1991
2112
  },
1992
2113
 
1993
- local : function () {
1994
- this.zone(0);
1995
- this._isUTC = false;
2114
+ local : function (keepLocalTime) {
2115
+ if (this._isUTC) {
2116
+ this.zone(0, keepLocalTime);
2117
+ this._isUTC = false;
2118
+
2119
+ if (keepLocalTime) {
2120
+ this.add(this._d.getTimezoneOffset(), 'm');
2121
+ }
2122
+ }
1996
2123
  return this;
1997
2124
  },
1998
2125
 
1999
2126
  format : function (inputString) {
2000
2127
  var output = formatMoment(this, inputString || moment.defaultFormat);
2001
- return this.lang().postformat(output);
2128
+ return this.localeData().postformat(output);
2002
2129
  },
2003
2130
 
2004
- add : function (input, val) {
2005
- var dur;
2006
- // switch args to support add('s', 1) and add(1, 's')
2007
- if (typeof input === 'string' && typeof val === 'string') {
2008
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
2009
- } else if (typeof input === 'string') {
2010
- dur = moment.duration(+val, input);
2011
- } else {
2012
- dur = moment.duration(input, val);
2013
- }
2014
- addOrSubtractDurationFromMoment(this, dur, 1);
2015
- return this;
2016
- },
2131
+ add : createAdder(1, 'add'),
2017
2132
 
2018
- subtract : function (input, val) {
2019
- var dur;
2020
- // switch args to support subtract('s', 1) and subtract(1, 's')
2021
- if (typeof input === 'string' && typeof val === 'string') {
2022
- dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
2023
- } else if (typeof input === 'string') {
2024
- dur = moment.duration(+val, input);
2025
- } else {
2026
- dur = moment.duration(input, val);
2027
- }
2028
- addOrSubtractDurationFromMoment(this, dur, -1);
2029
- return this;
2030
- },
2133
+ subtract : createAdder(-1, 'subtract'),
2031
2134
 
2032
2135
  diff : function (input, units, asFloat) {
2033
2136
  var that = makeAs(input, this),
@@ -2064,7 +2167,7 @@
2064
2167
  },
2065
2168
 
2066
2169
  from : function (time, withoutSuffix) {
2067
- return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
2170
+ return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
2068
2171
  },
2069
2172
 
2070
2173
  fromNow : function (withoutSuffix) {
@@ -2083,7 +2186,7 @@
2083
2186
  diff < 1 ? 'sameDay' :
2084
2187
  diff < 2 ? 'nextDay' :
2085
2188
  diff < 7 ? 'nextWeek' : 'sameElse';
2086
- return this.format(this.lang().calendar(format, this));
2189
+ return this.format(this.localeData().calendar(format, this));
2087
2190
  },
2088
2191
 
2089
2192
  isLeapYear : function () {
@@ -2098,8 +2201,8 @@
2098
2201
  day : function (input) {
2099
2202
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
2100
2203
  if (input != null) {
2101
- input = parseWeekday(input, this.lang());
2102
- return this.add({ d : input - day });
2204
+ input = parseWeekday(input, this.localeData());
2205
+ return this.add(input - day, 'd');
2103
2206
  } else {
2104
2207
  return day;
2105
2208
  }
@@ -2107,7 +2210,7 @@
2107
2210
 
2108
2211
  month : makeAccessor('Month', true),
2109
2212
 
2110
- startOf: function (units) {
2213
+ startOf : function (units) {
2111
2214
  units = normalizeUnits(units);
2112
2215
  // the following switch intentionally omits break keywords
2113
2216
  // to utilize falling through the cases.
@@ -2152,7 +2255,7 @@
2152
2255
 
2153
2256
  endOf: function (units) {
2154
2257
  units = normalizeUnits(units);
2155
- return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
2258
+ return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
2156
2259
  },
2157
2260
 
2158
2261
  isAfter: function (input, units) {
@@ -2171,7 +2274,7 @@
2171
2274
  },
2172
2275
 
2173
2276
  min: deprecate(
2174
- "moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",
2277
+ 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
2175
2278
  function (other) {
2176
2279
  other = moment.apply(null, arguments);
2177
2280
  return other < this ? this : other;
@@ -2179,36 +2282,43 @@
2179
2282
  ),
2180
2283
 
2181
2284
  max: deprecate(
2182
- "moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",
2285
+ 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
2183
2286
  function (other) {
2184
2287
  other = moment.apply(null, arguments);
2185
2288
  return other > this ? this : other;
2186
2289
  }
2187
2290
  ),
2188
2291
 
2189
- // keepTime = true means only change the timezone, without affecting
2190
- // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
2191
- // It is possible that 5:31:26 doesn't exist int zone +0200, so we
2192
- // adjust the time as needed, to be valid.
2292
+ // keepLocalTime = true means only change the timezone, without
2293
+ // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
2294
+ // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
2295
+ // +0200, so we adjust the time as needed, to be valid.
2193
2296
  //
2194
2297
  // Keeping the time actually adds/subtracts (one hour)
2195
2298
  // from the actual represented time. That is why we call updateOffset
2196
2299
  // a second time. In case it wants us to change the offset again
2197
2300
  // _changeInProgress == true case, then we have to adjust, because
2198
2301
  // there is no such time in the given timezone.
2199
- zone : function (input, keepTime) {
2200
- var offset = this._offset || 0;
2302
+ zone : function (input, keepLocalTime) {
2303
+ var offset = this._offset || 0,
2304
+ localAdjust;
2201
2305
  if (input != null) {
2202
- if (typeof input === "string") {
2306
+ if (typeof input === 'string') {
2203
2307
  input = timezoneMinutesFromString(input);
2204
2308
  }
2205
2309
  if (Math.abs(input) < 16) {
2206
2310
  input = input * 60;
2207
2311
  }
2312
+ if (!this._isUTC && keepLocalTime) {
2313
+ localAdjust = this._d.getTimezoneOffset();
2314
+ }
2208
2315
  this._offset = input;
2209
2316
  this._isUTC = true;
2317
+ if (localAdjust != null) {
2318
+ this.subtract(localAdjust, 'm');
2319
+ }
2210
2320
  if (offset !== input) {
2211
- if (!keepTime || this._changeInProgress) {
2321
+ if (!keepLocalTime || this._changeInProgress) {
2212
2322
  addOrSubtractDurationFromMoment(this,
2213
2323
  moment.duration(offset - input, 'm'), 1, false);
2214
2324
  } else if (!this._changeInProgress) {
@@ -2224,11 +2334,11 @@
2224
2334
  },
2225
2335
 
2226
2336
  zoneAbbr : function () {
2227
- return this._isUTC ? "UTC" : "";
2337
+ return this._isUTC ? 'UTC' : '';
2228
2338
  },
2229
2339
 
2230
2340
  zoneName : function () {
2231
- return this._isUTC ? "Coordinated Universal Time" : "";
2341
+ return this._isUTC ? 'Coordinated Universal Time' : '';
2232
2342
  },
2233
2343
 
2234
2344
  parseZone : function () {
@@ -2257,7 +2367,7 @@
2257
2367
 
2258
2368
  dayOfYear : function (input) {
2259
2369
  var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
2260
- return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
2370
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
2261
2371
  },
2262
2372
 
2263
2373
  quarter : function (input) {
@@ -2265,28 +2375,28 @@
2265
2375
  },
2266
2376
 
2267
2377
  weekYear : function (input) {
2268
- var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
2269
- return input == null ? year : this.add("y", (input - year));
2378
+ var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
2379
+ return input == null ? year : this.add((input - year), 'y');
2270
2380
  },
2271
2381
 
2272
2382
  isoWeekYear : function (input) {
2273
2383
  var year = weekOfYear(this, 1, 4).year;
2274
- return input == null ? year : this.add("y", (input - year));
2384
+ return input == null ? year : this.add((input - year), 'y');
2275
2385
  },
2276
2386
 
2277
2387
  week : function (input) {
2278
- var week = this.lang().week(this);
2279
- return input == null ? week : this.add("d", (input - week) * 7);
2388
+ var week = this.localeData().week(this);
2389
+ return input == null ? week : this.add((input - week) * 7, 'd');
2280
2390
  },
2281
2391
 
2282
2392
  isoWeek : function (input) {
2283
2393
  var week = weekOfYear(this, 1, 4).week;
2284
- return input == null ? week : this.add("d", (input - week) * 7);
2394
+ return input == null ? week : this.add((input - week) * 7, 'd');
2285
2395
  },
2286
2396
 
2287
2397
  weekday : function (input) {
2288
- var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
2289
- return input == null ? weekday : this.add("d", input - weekday);
2398
+ var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
2399
+ return input == null ? weekday : this.add(input - weekday, 'd');
2290
2400
  },
2291
2401
 
2292
2402
  isoWeekday : function (input) {
@@ -2301,7 +2411,7 @@
2301
2411
  },
2302
2412
 
2303
2413
  weeksInYear : function () {
2304
- var weekInfo = this._lang._week;
2414
+ var weekInfo = this.localeData()._week;
2305
2415
  return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
2306
2416
  },
2307
2417
 
@@ -2318,16 +2428,32 @@
2318
2428
  return this;
2319
2429
  },
2320
2430
 
2321
- // If passed a language key, it will set the language for this
2322
- // instance. Otherwise, it will return the language configuration
2431
+ // If passed a locale key, it will set the locale for this
2432
+ // instance. Otherwise, it will return the locale configuration
2323
2433
  // variables for this instance.
2324
- lang : function (key) {
2434
+ locale : function (key) {
2325
2435
  if (key === undefined) {
2326
- return this._lang;
2436
+ return this._locale._abbr;
2327
2437
  } else {
2328
- this._lang = getLangDefinition(key);
2438
+ this._locale = moment.localeData(key);
2329
2439
  return this;
2330
2440
  }
2441
+ },
2442
+
2443
+ lang : deprecate(
2444
+ 'moment().lang() is deprecated. Use moment().localeData() instead.',
2445
+ function (key) {
2446
+ if (key === undefined) {
2447
+ return this.localeData();
2448
+ } else {
2449
+ this._locale = moment.localeData(key);
2450
+ return this;
2451
+ }
2452
+ }
2453
+ ),
2454
+
2455
+ localeData : function () {
2456
+ return this._locale;
2331
2457
  }
2332
2458
  });
2333
2459
 
@@ -2336,7 +2462,7 @@
2336
2462
 
2337
2463
  // TODO: Move this out of here!
2338
2464
  if (typeof value === 'string') {
2339
- value = mom.lang().monthsParse(value);
2465
+ value = mom.localeData().monthsParse(value);
2340
2466
  // TODO: Another silent failure?
2341
2467
  if (typeof value !== 'number') {
2342
2468
  return mom;
@@ -2383,9 +2509,9 @@
2383
2509
  moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
2384
2510
  // moment.fn.month is defined separately
2385
2511
  moment.fn.date = makeAccessor('Date', true);
2386
- moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true));
2512
+ moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
2387
2513
  moment.fn.year = makeAccessor('FullYear', true);
2388
- moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true));
2514
+ moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
2389
2515
 
2390
2516
  // add plural methods
2391
2517
  moment.fn.days = moment.fn.day;
@@ -2402,6 +2528,17 @@
2402
2528
  ************************************/
2403
2529
 
2404
2530
 
2531
+ function daysToYears (days) {
2532
+ // 400 years have 146097 days (taking into account leap year rules)
2533
+ return days * 400 / 146097;
2534
+ }
2535
+
2536
+ function yearsToDays (years) {
2537
+ // years * 365 + absRound(years / 4) -
2538
+ // absRound(years / 100) + absRound(years / 400);
2539
+ return years * 146097 / 400;
2540
+ }
2541
+
2405
2542
  extend(moment.duration.fn = Duration.prototype, {
2406
2543
 
2407
2544
  _bubble : function () {
@@ -2409,7 +2546,7 @@
2409
2546
  days = this._days,
2410
2547
  months = this._months,
2411
2548
  data = this._data,
2412
- seconds, minutes, hours, years;
2549
+ seconds, minutes, hours, years = 0;
2413
2550
 
2414
2551
  // The following code bubbles up values, see the tests for
2415
2552
  // examples of what that means.
@@ -2425,15 +2562,40 @@
2425
2562
  data.hours = hours % 24;
2426
2563
 
2427
2564
  days += absRound(hours / 24);
2428
- data.days = days % 30;
2429
2565
 
2566
+ // Accurately convert days to years, assume start from year 0.
2567
+ years = absRound(daysToYears(days));
2568
+ days -= absRound(yearsToDays(years));
2569
+
2570
+ // 30 days to a month
2571
+ // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
2430
2572
  months += absRound(days / 30);
2431
- data.months = months % 12;
2573
+ days %= 30;
2574
+
2575
+ // 12 months -> 1 year
2576
+ years += absRound(months / 12);
2577
+ months %= 12;
2432
2578
 
2433
- years = absRound(months / 12);
2579
+ data.days = days;
2580
+ data.months = months;
2434
2581
  data.years = years;
2435
2582
  },
2436
2583
 
2584
+ abs : function () {
2585
+ this._milliseconds = Math.abs(this._milliseconds);
2586
+ this._days = Math.abs(this._days);
2587
+ this._months = Math.abs(this._months);
2588
+
2589
+ this._data.milliseconds = Math.abs(this._data.milliseconds);
2590
+ this._data.seconds = Math.abs(this._data.seconds);
2591
+ this._data.minutes = Math.abs(this._data.minutes);
2592
+ this._data.hours = Math.abs(this._data.hours);
2593
+ this._data.months = Math.abs(this._data.months);
2594
+ this._data.years = Math.abs(this._data.years);
2595
+
2596
+ return this;
2597
+ },
2598
+
2437
2599
  weeks : function () {
2438
2600
  return absRound(this.days() / 7);
2439
2601
  },
@@ -2446,14 +2608,13 @@
2446
2608
  },
2447
2609
 
2448
2610
  humanize : function (withSuffix) {
2449
- var difference = +this,
2450
- output = relativeTime(difference, !withSuffix, this.lang());
2611
+ var output = relativeTime(this, !withSuffix, this.localeData());
2451
2612
 
2452
2613
  if (withSuffix) {
2453
- output = this.lang().pastFuture(difference, output);
2614
+ output = this.localeData().pastFuture(+this, output);
2454
2615
  }
2455
2616
 
2456
- return this.lang().postformat(output);
2617
+ return this.localeData().postformat(output);
2457
2618
  },
2458
2619
 
2459
2620
  add : function (input, val) {
@@ -2487,13 +2648,39 @@
2487
2648
  },
2488
2649
 
2489
2650
  as : function (units) {
2651
+ var days, months;
2490
2652
  units = normalizeUnits(units);
2491
- return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
2653
+
2654
+ days = this._days + this._milliseconds / 864e5;
2655
+ if (units === 'month' || units === 'year') {
2656
+ months = this._months + daysToYears(days) * 12;
2657
+ return units === 'month' ? months : months / 12;
2658
+ } else {
2659
+ days += yearsToDays(this._months / 12);
2660
+ switch (units) {
2661
+ case 'week': return days / 7;
2662
+ case 'day': return days;
2663
+ case 'hour': return days * 24;
2664
+ case 'minute': return days * 24 * 60;
2665
+ case 'second': return days * 24 * 60 * 60;
2666
+ case 'millisecond': return days * 24 * 60 * 60 * 1000;
2667
+ default: throw new Error('Unknown unit ' + units);
2668
+ }
2669
+ }
2492
2670
  },
2493
2671
 
2494
2672
  lang : moment.fn.lang,
2673
+ locale : moment.fn.locale,
2674
+
2675
+ toIsoString : deprecate(
2676
+ 'toIsoString() is deprecated. Please use toISOString() instead ' +
2677
+ '(notice the capitals)',
2678
+ function () {
2679
+ return this.toISOString();
2680
+ }
2681
+ ),
2495
2682
 
2496
- toIsoString : function () {
2683
+ toISOString : function () {
2497
2684
  // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2498
2685
  var years = Math.abs(this.years()),
2499
2686
  months = Math.abs(this.months()),
@@ -2517,41 +2704,59 @@
2517
2704
  (hours ? hours + 'H' : '') +
2518
2705
  (minutes ? minutes + 'M' : '') +
2519
2706
  (seconds ? seconds + 'S' : '');
2707
+ },
2708
+
2709
+ localeData : function () {
2710
+ return this._locale;
2520
2711
  }
2521
2712
  });
2522
2713
 
2714
+ moment.duration.fn.toString = moment.duration.fn.toISOString;
2715
+
2523
2716
  function makeDurationGetter(name) {
2524
2717
  moment.duration.fn[name] = function () {
2525
2718
  return this._data[name];
2526
2719
  };
2527
2720
  }
2528
2721
 
2529
- function makeDurationAsGetter(name, factor) {
2530
- moment.duration.fn['as' + name] = function () {
2531
- return +this / factor;
2532
- };
2533
- }
2534
-
2535
2722
  for (i in unitMillisecondFactors) {
2536
- if (unitMillisecondFactors.hasOwnProperty(i)) {
2537
- makeDurationAsGetter(i, unitMillisecondFactors[i]);
2723
+ if (hasOwnProp(unitMillisecondFactors, i)) {
2538
2724
  makeDurationGetter(i.toLowerCase());
2539
2725
  }
2540
2726
  }
2541
2727
 
2542
- makeDurationAsGetter('Weeks', 6048e5);
2728
+ moment.duration.fn.asMilliseconds = function () {
2729
+ return this.as('ms');
2730
+ };
2731
+ moment.duration.fn.asSeconds = function () {
2732
+ return this.as('s');
2733
+ };
2734
+ moment.duration.fn.asMinutes = function () {
2735
+ return this.as('m');
2736
+ };
2737
+ moment.duration.fn.asHours = function () {
2738
+ return this.as('h');
2739
+ };
2740
+ moment.duration.fn.asDays = function () {
2741
+ return this.as('d');
2742
+ };
2743
+ moment.duration.fn.asWeeks = function () {
2744
+ return this.as('weeks');
2745
+ };
2543
2746
  moment.duration.fn.asMonths = function () {
2544
- return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
2747
+ return this.as('M');
2748
+ };
2749
+ moment.duration.fn.asYears = function () {
2750
+ return this.as('y');
2545
2751
  };
2546
-
2547
2752
 
2548
2753
  /************************************
2549
- Default Lang
2754
+ Default Locale
2550
2755
  ************************************/
2551
2756
 
2552
2757
 
2553
- // Set default language, other languages will inherit from English.
2554
- moment.lang('en', {
2758
+ // Set default locale, other locale will inherit from English.
2759
+ moment.locale('en', {
2555
2760
  ordinal : function (number) {
2556
2761
  var b = number % 10,
2557
2762
  output = (toInt(number % 100 / 10) === 1) ? 'th' :
@@ -2562,7 +2767,7 @@
2562
2767
  }
2563
2768
  });
2564
2769
 
2565
- /* EMBED_LANGUAGES */
2770
+ /* EMBED_LOCALES */
2566
2771
 
2567
2772
  /************************************
2568
2773
  Exposing Moment
@@ -2576,9 +2781,9 @@
2576
2781
  oldGlobalMoment = globalScope.moment;
2577
2782
  if (shouldDeprecate) {
2578
2783
  globalScope.moment = deprecate(
2579
- "Accessing Moment through the global scope is " +
2580
- "deprecated, and will be removed in an upcoming " +
2581
- "release.",
2784
+ 'Accessing Moment through the global scope is ' +
2785
+ 'deprecated, and will be removed in an upcoming ' +
2786
+ 'release.',
2582
2787
  moment);
2583
2788
  } else {
2584
2789
  globalScope.moment = moment;
@@ -2588,8 +2793,8 @@
2588
2793
  // CommonJS module is defined
2589
2794
  if (hasModule) {
2590
2795
  module.exports = moment;
2591
- } else if (typeof define === "function" && define.amd) {
2592
- define("moment", function (require, exports, module) {
2796
+ } else if (typeof define === 'function' && define.amd) {
2797
+ define('moment', function (require, exports, module) {
2593
2798
  if (module.config && module.config() && module.config().noGlobal === true) {
2594
2799
  // release the global variable
2595
2800
  globalScope.moment = oldGlobalMoment;