rsence-pre 3.0.0.8 → 3.0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/client/conf/client_pkg.yaml +6 -2
  4. data/client/js/comm/queue/queue.js +32 -44
  5. data/client/js/comm/transporter/transporter.js +24 -16
  6. data/client/js/comm/values/values.js +27 -15
  7. data/client/js/controls/button/button.coffee +14 -5
  8. data/client/js/controls/button/themes/default/button.css +4 -2
  9. data/client/js/controls/checkbox/checkbox.js +4 -4
  10. data/client/js/controls/dialogs/sheet/sheet.js +11 -11
  11. data/client/js/controls/dialogs/sheet/themes/default/sheet.html +1 -1
  12. data/client/js/controls/imageview/imageview.js +15 -15
  13. data/client/js/controls/numerictextcontrol/numerictextcontrol.coffee +32 -10
  14. data/client/js/controls/onoffbutton/onoffbutton.coffee +5 -5
  15. data/client/js/controls/progress/progressbar/progressbar.js +6 -7
  16. data/client/js/controls/progress/progressbar/themes/default/progressbar.css +4 -4
  17. data/client/js/controls/progress/progressbar/themes/default/progressbar.html +1 -2
  18. data/client/js/controls/sliders/slider/slider.js +74 -79
  19. data/client/js/controls/stepper/stepper.js +31 -31
  20. data/client/js/controls/stringview/stringview.js +20 -8
  21. data/client/js/controls/tab/tab.js +57 -63
  22. data/client/js/controls/tab/themes/default/tab.html +4 -1
  23. data/client/js/controls/textcontrol/textcontrol.coffee +13 -3
  24. data/client/js/controls/validatorview/validatorview.js +4 -4
  25. data/client/js/controls/window/window.js +43 -56
  26. data/client/js/core/class/class.js +25 -23
  27. data/client/js/core/elem/elem.coffee +8 -1
  28. data/client/js/core/rsence_ns/rsence_ns.coffee +6 -2
  29. data/client/js/core/util/util_methods/util_methods.coffee +57 -15
  30. data/client/js/datetime/calendar/calendar.coffee +196 -199
  31. data/client/js/datetime/calendar/themes/default/calendar.css +81 -159
  32. data/client/js/datetime/calendar/themes/default/calendar.html +9 -18
  33. data/client/js/datetime/datepicker/datepicker.coffee +18 -3
  34. data/client/js/datetime/datetimepicker/datetimepicker.coffee +6 -1
  35. data/client/js/datetime/datetimevalue/datetimevalue.coffee +194 -0
  36. data/client/js/datetime/momentjs/momentjs.js +310 -76
  37. data/client/js/datetime/timepicker/timepicker.coffee +6 -1
  38. data/client/js/datetime/timesheet/timesheet.js +59 -61
  39. data/client/js/foundation/control/control.js +45 -44
  40. data/client/js/foundation/control/controldefaults/controldefaults.js +13 -9
  41. data/client/js/foundation/control/dyncontrol/dyncontrol.js +45 -57
  42. data/client/js/foundation/control/eventresponder/eventresponder.js +97 -97
  43. data/client/js/foundation/control/valuematrix/valuematrix.js +13 -13
  44. data/client/js/foundation/eventmanager/eventmanager.coffee +50 -32
  45. data/client/js/foundation/geom/rect/rect.js +43 -32
  46. data/client/js/foundation/locale_settings/locale_settings.js +36 -25
  47. data/client/js/foundation/system/system.js +79 -67
  48. data/client/js/foundation/thememanager/thememanager.coffee +11 -1
  49. data/client/js/foundation/value/pullvalue/pullvalue.coffee +7 -0
  50. data/client/js/foundation/value/pushvalue/pushvalue.coffee +25 -0
  51. data/client/js/foundation/value/value.js +22 -15
  52. data/client/js/foundation/view/view.js +94 -55
  53. data/client/js/foundation/view/viewdefaults/viewdefaults.js +5 -1
  54. data/client/js/lists/listitems/listitems.js +26 -4
  55. data/client/js/menus/combobox/combobox.coffee +55 -0
  56. data/client/js/menus/minimenu/minimenu.js +61 -30
  57. data/client/js/menus/minimenu/themes/default/minimenu.css +1 -6
  58. data/client/js/menus/minimenu/themes/default/minimenu.html +5 -4
  59. data/client/js/menus/minimenuitem/minimenuitem.js +6 -6
  60. data/client/js/menus/popupmenu/themes/default/popupmenu.css +1 -6
  61. data/client/js/menus/popupmenu/themes/default/popupmenu.html +5 -4
  62. data/client/js/tables/table/table.coffee +109 -64
  63. data/client/js/tables/table/themes/default/table.css +4 -0
  64. data/lib/rsence/msg.rb +64 -64
  65. data/lib/rsence/plugins/plugin.rb +68 -52
  66. data/lib/rsence/session/sequel_sessionstorage.rb +5 -5
  67. data/lib/rsence/value.rb +79 -59
  68. data/plugins/client_pkg/lib/client_pkg_build.rb +5 -1
  69. data/plugins/client_pkg/lib/client_pkg_serve.rb +40 -32
  70. data/plugins/main/js/main.js +46 -28
  71. metadata +6 -8
  72. data/client/js/datetime/calendar/themes/default/calendar_arrows.png +0 -0
  73. data/client/js/datetime/calendar/themes/default/calendar_bg.png +0 -0
  74. data/client/js/datetime/calendar/themes/default/calendar_parts1.png +0 -0
  75. data/client/js/datetime/calendar/themes/default/calendar_parts2.png +0 -0
  76. data/client/js/datetime/datetimepicker/datetimepicker.js +0 -210
  77. data/client/js/datetime/datetimevalue/datetimevalue.js +0 -265
@@ -21,9 +21,10 @@
21
21
 
22
22
  // ASP.NET json date format regex
23
23
  aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
24
+ aspNetTimeSpanJsonRegex = /(\-)?(\d*)?\.?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
24
25
 
25
26
  // format tokens
26
- formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
27
+ formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
27
28
  localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
28
29
 
29
30
  // parsing tokens
@@ -35,7 +36,7 @@
35
36
  parseTokenThreeDigits = /\d{3}/, // 000 - 999
36
37
  parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
37
38
  parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
38
- parseTokenWord = /[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i, // any word (or two) characters or numbers including two word month in arabic.
39
+ parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
39
40
  parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
40
41
  parseTokenT = /T/i, // T (ISO seperator)
41
42
  parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
@@ -57,7 +58,7 @@
57
58
  parseTimezoneChunker = /([\+\-]|\d\d)/gi,
58
59
 
59
60
  // getter and setter names
60
- proxyGettersAndSetters = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
61
+ proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
61
62
  unitMillisecondFactors = {
62
63
  'Milliseconds' : 1,
63
64
  'Seconds' : 1e3,
@@ -68,6 +69,17 @@
68
69
  'Years' : 31536e6
69
70
  },
70
71
 
72
+ unitAliases = {
73
+ ms : 'millisecond',
74
+ s : 'second',
75
+ m : 'minute',
76
+ h : 'hour',
77
+ d : 'day',
78
+ w : 'week',
79
+ M : 'month',
80
+ y : 'year'
81
+ },
82
+
71
83
  // format function strings
72
84
  formatFunctions = {},
73
85
 
@@ -118,6 +130,30 @@
118
130
  YYYYY : function () {
119
131
  return leftZeroFill(this.year(), 5);
120
132
  },
133
+ gg : function () {
134
+ return leftZeroFill(this.weekYear() % 100, 2);
135
+ },
136
+ gggg : function () {
137
+ return this.weekYear();
138
+ },
139
+ ggggg : function () {
140
+ return leftZeroFill(this.weekYear(), 5);
141
+ },
142
+ GG : function () {
143
+ return leftZeroFill(this.isoWeekYear() % 100, 2);
144
+ },
145
+ GGGG : function () {
146
+ return this.isoWeekYear();
147
+ },
148
+ GGGGG : function () {
149
+ return leftZeroFill(this.isoWeekYear(), 5);
150
+ },
151
+ e : function () {
152
+ return this.weekday();
153
+ },
154
+ E : function () {
155
+ return this.isoWeekday();
156
+ },
121
157
  a : function () {
122
158
  return this.lang().meridiem(this.hours(), this.minutes(), true);
123
159
  },
@@ -163,6 +199,12 @@
163
199
  }
164
200
  return b + leftZeroFill(~~(10 * a / 6), 4);
165
201
  },
202
+ z : function () {
203
+ return this.zoneAbbr();
204
+ },
205
+ zz : function () {
206
+ return this.zoneName();
207
+ },
166
208
  X : function () {
167
209
  return this.unix();
168
210
  }
@@ -173,15 +215,15 @@
173
215
  return leftZeroFill(func.call(this, a), count);
174
216
  };
175
217
  }
176
- function ordinalizeToken(func) {
218
+ function ordinalizeToken(func, period) {
177
219
  return function (a) {
178
- return this.lang().ordinal(func.call(this, a));
220
+ return this.lang().ordinal(func.call(this, a), period);
179
221
  };
180
222
  }
181
223
 
182
224
  while (ordinalizeTokens.length) {
183
225
  i = ordinalizeTokens.pop();
184
- formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i]);
226
+ formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
185
227
  }
186
228
  while (paddedTokens.length) {
187
229
  i = paddedTokens.pop();
@@ -289,24 +331,39 @@
289
331
  }
290
332
 
291
333
  // helper function for _.addTime and _.subtractTime
292
- function addOrSubtractDurationFromMoment(mom, duration, isAdding) {
293
- var ms = duration._milliseconds,
294
- d = duration._days,
295
- M = duration._months,
334
+ function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
335
+ var milliseconds = duration._milliseconds,
336
+ days = duration._days,
337
+ months = duration._months,
338
+ minutes,
339
+ hours,
296
340
  currentDate;
297
341
 
298
- if (ms) {
299
- mom._d.setTime(+mom + ms * isAdding);
342
+ if (milliseconds) {
343
+ mom._d.setTime(+mom._d + milliseconds * isAdding);
344
+ }
345
+ // store the minutes and hours so we can restore them
346
+ if (days || months) {
347
+ minutes = mom.minute();
348
+ hours = mom.hour();
300
349
  }
301
- if (d) {
302
- mom.date(mom.date() + d * isAdding);
350
+ if (days) {
351
+ mom.date(mom.date() + days * isAdding);
303
352
  }
304
- if (M) {
353
+ if (months) {
305
354
  currentDate = mom.date();
306
355
  mom.date(1)
307
- .month(mom.month() + M * isAdding)
356
+ .month(mom.month() + months * isAdding)
308
357
  .date(Math.min(currentDate, mom.daysInMonth()));
309
358
  }
359
+ if (milliseconds && !ignoreUpdateOffset) {
360
+ moment.updateOffset(mom);
361
+ }
362
+ // restore the minutes and hours after possibly changing dst
363
+ if (days || months) {
364
+ mom.minute(minutes);
365
+ mom.hour(hours);
366
+ }
310
367
  }
311
368
 
312
369
  // check if is an array
@@ -328,6 +385,10 @@
328
385
  return diffs + lengthDiff;
329
386
  }
330
387
 
388
+ function normalizeUnits(units) {
389
+ return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
390
+ }
391
+
331
392
 
332
393
  /************************************
333
394
  Languages
@@ -358,7 +419,7 @@
358
419
  },
359
420
 
360
421
  monthsParse : function (monthName) {
361
- var i, mom, regex, output;
422
+ var i, mom, regex;
362
423
 
363
424
  if (!this._monthsParse) {
364
425
  this._monthsParse = [];
@@ -393,6 +454,27 @@
393
454
  return this._weekdaysMin[m.day()];
394
455
  },
395
456
 
457
+ weekdaysParse : function (weekdayName) {
458
+ var i, mom, regex;
459
+
460
+ if (!this._weekdaysParse) {
461
+ this._weekdaysParse = [];
462
+ }
463
+
464
+ for (i = 0; i < 7; i++) {
465
+ // make the regex if we don't have it already
466
+ if (!this._weekdaysParse[i]) {
467
+ mom = moment([2000, 1]).day(i);
468
+ regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
469
+ this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
470
+ }
471
+ // test the regex
472
+ if (this._weekdaysParse[i].test(weekdayName)) {
473
+ return i;
474
+ }
475
+ }
476
+ },
477
+
396
478
  _longDateFormat : {
397
479
  LT : "h:mm A",
398
480
  L : "MM/DD/YYYY",
@@ -411,6 +493,11 @@
411
493
  return output;
412
494
  },
413
495
 
496
+ isPM : function (input) {
497
+ return ((input + '').toLowerCase()[0] === 'p');
498
+ },
499
+
500
+ _meridiemParse : /[ap]\.?m?\.?/i,
414
501
  meridiem : function (hours, minutes, isLower) {
415
502
  if (hours > 11) {
416
503
  return isLower ? 'pm' : 'PM';
@@ -424,7 +511,7 @@
424
511
  nextDay : '[Tomorrow at] LT',
425
512
  nextWeek : 'dddd [at] LT',
426
513
  lastDay : '[Yesterday at] LT',
427
- lastWeek : '[last] dddd [at] LT',
514
+ lastWeek : '[Last] dddd [at] LT',
428
515
  sameElse : 'L'
429
516
  },
430
517
  calendar : function (key, mom) {
@@ -472,7 +559,7 @@
472
559
  },
473
560
 
474
561
  week : function (mom) {
475
- return weekOfYear(mom, this._week.dow, this._week.doy);
562
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
476
563
  },
477
564
  _week : {
478
565
  dow : 0, // Sunday is the first day of the week.
@@ -536,7 +623,7 @@
536
623
  return function (mom) {
537
624
  var output = "";
538
625
  for (i = 0; i < length; i++) {
539
- output += typeof array[i].call === 'function' ? array[i].call(mom, format) : array[i];
626
+ output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
540
627
  }
541
628
  return output;
542
629
  };
@@ -568,7 +655,7 @@
568
655
 
569
656
 
570
657
  // get the regex to find the next token
571
- function getParseRegexForToken(token) {
658
+ function getParseRegexForToken(token, config) {
572
659
  switch (token) {
573
660
  case 'DDDD':
574
661
  return parseTokenThreeDigits;
@@ -586,9 +673,10 @@
586
673
  case 'dd':
587
674
  case 'ddd':
588
675
  case 'dddd':
676
+ return parseTokenWord;
589
677
  case 'a':
590
678
  case 'A':
591
- return parseTokenWord;
679
+ return getLangDefinition(config._l)._meridiemParse;
592
680
  case 'X':
593
681
  return parseTokenTimestampMs;
594
682
  case 'Z':
@@ -616,6 +704,14 @@
616
704
  }
617
705
  }
618
706
 
707
+ function timezoneMinutesFromString(string) {
708
+ var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
709
+ parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
710
+ minutes = +(parts[1] * 60) + ~~parts[2];
711
+
712
+ return parts[0] === '+' ? -minutes : minutes;
713
+ }
714
+
619
715
  // function to convert string input to date
620
716
  function addTimeToArrayFromToken(token, input, config) {
621
717
  var a, b,
@@ -657,7 +753,7 @@
657
753
  // AM / PM
658
754
  case 'a' : // fall through to A
659
755
  case 'A' :
660
- config._isPm = ((input + '').toLowerCase() === 'pm');
756
+ config._isPm = getLangDefinition(config._l).isPM(input);
661
757
  break;
662
758
  // 24 HOUR
663
759
  case 'H' : // fall through to hh
@@ -690,18 +786,7 @@
690
786
  case 'Z' : // fall through to ZZ
691
787
  case 'ZZ' :
692
788
  config._useUTC = true;
693
- a = (input + '').match(parseTimezoneChunker);
694
- if (a && a[1]) {
695
- config._tzh = ~~a[1];
696
- }
697
- if (a && a[2]) {
698
- config._tzm = ~~a[2];
699
- }
700
- // reverse offsets
701
- if (a && a[0] === '+') {
702
- config._tzh = -config._tzh;
703
- config._tzm = -config._tzm;
704
- }
789
+ config._tzm = timezoneMinutesFromString(input);
705
790
  break;
706
791
  }
707
792
 
@@ -727,8 +812,8 @@
727
812
  }
728
813
 
729
814
  // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
730
- input[3] += config._tzh || 0;
731
- input[4] += config._tzm || 0;
815
+ input[3] += ~~((config._tzm || 0) / 60);
816
+ input[4] += ~~((config._tzm || 0) % 60);
732
817
 
733
818
  date = new Date(0);
734
819
 
@@ -753,7 +838,7 @@
753
838
  config._a = [];
754
839
 
755
840
  for (i = 0; i < tokens.length; i++) {
756
- parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0];
841
+ parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
757
842
  if (parsedInput) {
758
843
  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
759
844
  }
@@ -762,6 +847,12 @@
762
847
  addTimeToArrayFromToken(tokens[i], parsedInput, config);
763
848
  }
764
849
  }
850
+
851
+ // add remaining unparsed input to the string
852
+ if (string) {
853
+ config._il = string;
854
+ }
855
+
765
856
  // handle am pm
766
857
  if (config._isPm && config._a[3] < 12) {
767
858
  config._a[3] += 12;
@@ -782,22 +873,22 @@
782
873
 
783
874
  scoreToBeat = 99,
784
875
  i,
785
- currentDate,
786
876
  currentScore;
787
877
 
788
- while (config._f.length) {
878
+ for (i = 0; i < config._f.length; i++) {
789
879
  tempConfig = extend({}, config);
790
- tempConfig._f = config._f.pop();
880
+ tempConfig._f = config._f[i];
791
881
  makeDateFromStringAndFormat(tempConfig);
792
882
  tempMoment = new Moment(tempConfig);
793
883
 
794
- if (tempMoment.isValid()) {
795
- bestMoment = tempMoment;
796
- break;
797
- }
798
-
799
884
  currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
800
885
 
886
+ // if there is any input that was not parsed
887
+ // add a penalty for that format
888
+ if (tempMoment._il) {
889
+ currentScore += tempMoment._il.length;
890
+ }
891
+
801
892
  if (currentScore < scoreToBeat) {
802
893
  scoreToBeat = currentScore;
803
894
  bestMoment = tempMoment;
@@ -810,9 +901,12 @@
810
901
  // date from iso format
811
902
  function makeDateFromString(config) {
812
903
  var i,
813
- string = config._i;
814
- if (isoRegex.exec(string)) {
815
- config._f = 'YYYY-MM-DDT';
904
+ string = config._i,
905
+ match = isoRegex.exec(string);
906
+
907
+ if (match) {
908
+ // match[2] should be "T" or undefined
909
+ config._f = 'YYYY-MM-DD' + (match[2] || " ");
816
910
  for (i = 0; i < 4; i++) {
817
911
  if (isoTimes[i][1].exec(string)) {
818
912
  config._f += isoTimes[i][0];
@@ -894,7 +988,8 @@
894
988
  // (eg. ISO weeks use thursday (4))
895
989
  function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
896
990
  var end = firstDayOfWeekOfYear - firstDayOfWeek,
897
- daysToDayOfWeek = firstDayOfWeekOfYear - mom.day();
991
+ daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
992
+ adjustedMoment;
898
993
 
899
994
 
900
995
  if (daysToDayOfWeek > end) {
@@ -905,7 +1000,11 @@
905
1000
  daysToDayOfWeek += 7;
906
1001
  }
907
1002
 
908
- return Math.ceil(moment(mom).add('d', daysToDayOfWeek).dayOfYear() / 7);
1003
+ adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
1004
+ return {
1005
+ week: Math.ceil(adjustedMoment.dayOfYear() / 7),
1006
+ year: adjustedMoment.year()
1007
+ };
909
1008
  }
910
1009
 
911
1010
 
@@ -971,6 +1070,8 @@
971
1070
  var isDuration = moment.isDuration(input),
972
1071
  isNumber = (typeof input === 'number'),
973
1072
  duration = (isDuration ? input._data : (isNumber ? {} : input)),
1073
+ matched = aspNetTimeSpanJsonRegex.exec(input),
1074
+ sign,
974
1075
  ret;
975
1076
 
976
1077
  if (isNumber) {
@@ -979,6 +1080,16 @@
979
1080
  } else {
980
1081
  duration.milliseconds = input;
981
1082
  }
1083
+ } else if (matched) {
1084
+ sign = (matched[1] === "-") ? -1 : 1;
1085
+ duration = {
1086
+ y: 0,
1087
+ d: ~~matched[2] * sign,
1088
+ h: ~~matched[3] * sign,
1089
+ m: ~~matched[4] * sign,
1090
+ s: ~~matched[5] * sign,
1091
+ ms: ~~matched[6] * sign
1092
+ };
982
1093
  }
983
1094
 
984
1095
  ret = new Duration(duration);
@@ -996,6 +1107,10 @@
996
1107
  // default format
997
1108
  moment.defaultFormat = isoFormat;
998
1109
 
1110
+ // This function will be called whenever a moment is mutated.
1111
+ // It is intended to keep the offset in sync with the timezone.
1112
+ moment.updateOffset = function () {};
1113
+
999
1114
  // This function will load languages and then set the global language. If
1000
1115
  // no arguments are passed in, it will simply return the current global
1001
1116
  // language key.
@@ -1044,11 +1159,11 @@
1044
1159
  },
1045
1160
 
1046
1161
  valueOf : function () {
1047
- return +this._d;
1162
+ return +this._d + ((this._offset || 0) * 60000);
1048
1163
  },
1049
1164
 
1050
1165
  unix : function () {
1051
- return Math.floor(+this._d / 1000);
1166
+ return Math.floor(+this / 1000);
1052
1167
  },
1053
1168
 
1054
1169
  toString : function () {
@@ -1056,11 +1171,11 @@
1056
1171
  },
1057
1172
 
1058
1173
  toDate : function () {
1059
- return this._d;
1174
+ return this._offset ? new Date(+this) : this._d;
1060
1175
  },
1061
1176
 
1062
- toJSON : function () {
1063
- return moment.utc(this).format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1177
+ toISOString : function () {
1178
+ return formatMoment(moment(this).utc(), 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
1064
1179
  },
1065
1180
 
1066
1181
  toArray : function () {
@@ -1088,11 +1203,11 @@
1088
1203
  },
1089
1204
 
1090
1205
  utc : function () {
1091
- this._isUTC = true;
1092
- return this;
1206
+ return this.zone(0);
1093
1207
  },
1094
1208
 
1095
1209
  local : function () {
1210
+ this.zone(0);
1096
1211
  this._isUTC = false;
1097
1212
  return this;
1098
1213
  },
@@ -1127,14 +1242,11 @@
1127
1242
  },
1128
1243
 
1129
1244
  diff : function (input, units, asFloat) {
1130
- var that = this._isUTC ? moment(input).utc() : moment(input).local(),
1245
+ var that = this._isUTC ? moment(input).zone(this._offset || 0) : moment(input).local(),
1131
1246
  zoneDiff = (this.zone() - that.zone()) * 6e4,
1132
1247
  diff, output;
1133
1248
 
1134
- if (units) {
1135
- // standardize on singular form
1136
- units = units.replace(/s$/, '');
1137
- }
1249
+ units = normalizeUnits(units);
1138
1250
 
1139
1251
  if (units === 'year' || units === 'month') {
1140
1252
  diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
@@ -1180,18 +1292,44 @@
1180
1292
  },
1181
1293
 
1182
1294
  isDST : function () {
1183
- return (this.zone() < moment([this.year()]).zone() ||
1184
- this.zone() < moment([this.year(), 5]).zone());
1295
+ return (this.zone() < this.clone().month(0).zone() ||
1296
+ this.zone() < this.clone().month(5).zone());
1185
1297
  },
1186
1298
 
1187
1299
  day : function (input) {
1188
1300
  var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1189
- return input == null ? day :
1190
- this.add({ d : input - day });
1301
+ if (input != null) {
1302
+ if (typeof input === 'string') {
1303
+ input = this.lang().weekdaysParse(input);
1304
+ if (typeof input !== 'number') {
1305
+ return this;
1306
+ }
1307
+ }
1308
+ return this.add({ d : input - day });
1309
+ } else {
1310
+ return day;
1311
+ }
1312
+ },
1313
+
1314
+ month : function (input) {
1315
+ var utc = this._isUTC ? 'UTC' : '';
1316
+ if (input != null) {
1317
+ if (typeof input === 'string') {
1318
+ input = this.lang().monthsParse(input);
1319
+ if (typeof input !== 'number') {
1320
+ return this;
1321
+ }
1322
+ }
1323
+ this._d['set' + utc + 'Month'](input);
1324
+ moment.updateOffset(this);
1325
+ return this;
1326
+ } else {
1327
+ return this._d['get' + utc + 'Month']();
1328
+ }
1191
1329
  },
1192
1330
 
1193
1331
  startOf: function (units) {
1194
- units = units.replace(/s$/, '');
1332
+ units = normalizeUnits(units);
1195
1333
  // the following switch intentionally omits break keywords
1196
1334
  // to utilize falling through the cases.
1197
1335
  switch (units) {
@@ -1218,14 +1356,14 @@
1218
1356
 
1219
1357
  // weeks are a special case
1220
1358
  if (units === 'week') {
1221
- this.day(0);
1359
+ this.weekday(0);
1222
1360
  }
1223
1361
 
1224
1362
  return this;
1225
1363
  },
1226
1364
 
1227
1365
  endOf: function (units) {
1228
- return this.startOf(units).add(units.replace(/s?$/, 's'), 1).subtract('ms', 1);
1366
+ return this.startOf(units).add(units, 1).subtract('ms', 1);
1229
1367
  },
1230
1368
 
1231
1369
  isAfter: function (input, units) {
@@ -1243,8 +1381,42 @@
1243
1381
  return +this.clone().startOf(units) === +moment(input).startOf(units);
1244
1382
  },
1245
1383
 
1246
- zone : function () {
1247
- return this._isUTC ? 0 : this._d.getTimezoneOffset();
1384
+ min: function (other) {
1385
+ other = moment.apply(null, arguments);
1386
+ return other < this ? this : other;
1387
+ },
1388
+
1389
+ max: function (other) {
1390
+ other = moment.apply(null, arguments);
1391
+ return other > this ? this : other;
1392
+ },
1393
+
1394
+ zone : function (input) {
1395
+ var offset = this._offset || 0;
1396
+ if (input != null) {
1397
+ if (typeof input === "string") {
1398
+ input = timezoneMinutesFromString(input);
1399
+ }
1400
+ if (Math.abs(input) < 16) {
1401
+ input = input * 60;
1402
+ }
1403
+ this._offset = input;
1404
+ this._isUTC = true;
1405
+ if (offset !== input) {
1406
+ addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
1407
+ }
1408
+ } else {
1409
+ return this._isUTC ? offset : this._d.getTimezoneOffset();
1410
+ }
1411
+ return this;
1412
+ },
1413
+
1414
+ zoneAbbr : function () {
1415
+ return this._isUTC ? "UTC" : "";
1416
+ },
1417
+
1418
+ zoneName : function () {
1419
+ return this._isUTC ? "Coordinated Universal Time" : "";
1248
1420
  },
1249
1421
 
1250
1422
  daysInMonth : function () {
@@ -1256,9 +1428,14 @@
1256
1428
  return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
1257
1429
  },
1258
1430
 
1259
- isoWeek : function (input) {
1260
- var week = weekOfYear(this, 1, 4);
1261
- return input == null ? week : this.add("d", (input - week) * 7);
1431
+ weekYear : function (input) {
1432
+ var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
1433
+ return input == null ? year : this.add("y", (input - year));
1434
+ },
1435
+
1436
+ isoWeekYear : function (input) {
1437
+ var year = weekOfYear(this, 1, 4).year;
1438
+ return input == null ? year : this.add("y", (input - year));
1262
1439
  },
1263
1440
 
1264
1441
  week : function (input) {
@@ -1266,6 +1443,23 @@
1266
1443
  return input == null ? week : this.add("d", (input - week) * 7);
1267
1444
  },
1268
1445
 
1446
+ isoWeek : function (input) {
1447
+ var week = weekOfYear(this, 1, 4).week;
1448
+ return input == null ? week : this.add("d", (input - week) * 7);
1449
+ },
1450
+
1451
+ weekday : function (input) {
1452
+ var weekday = (this._d.getDay() + 7 - this.lang()._week.dow) % 7;
1453
+ return input == null ? weekday : this.add("d", input - weekday);
1454
+ },
1455
+
1456
+ isoWeekday : function (input) {
1457
+ // iso weeks start on monday, which is 1, so we subtract 1 (and add
1458
+ // 7 for negative mod to work).
1459
+ var weekday = (this._d.getDay() + 6) % 7;
1460
+ return input == null ? weekday : this.add("d", input - weekday);
1461
+ },
1462
+
1269
1463
  // If passed a language key, it will set the language for this
1270
1464
  // instance. Otherwise, it will return the language configuration
1271
1465
  // variables for this instance.
@@ -1285,6 +1479,7 @@
1285
1479
  var utc = this._isUTC ? 'UTC' : '';
1286
1480
  if (input != null) {
1287
1481
  this._d['set' + utc + key](input);
1482
+ moment.updateOffset(this);
1288
1483
  return this;
1289
1484
  } else {
1290
1485
  return this._d['get' + utc + key]();
@@ -1302,9 +1497,13 @@
1302
1497
 
1303
1498
  // add plural methods
1304
1499
  moment.fn.days = moment.fn.day;
1500
+ moment.fn.months = moment.fn.month;
1305
1501
  moment.fn.weeks = moment.fn.week;
1306
1502
  moment.fn.isoWeeks = moment.fn.isoWeek;
1307
1503
 
1504
+ // add aliased format methods
1505
+ moment.fn.toJSON = moment.fn.toISOString;
1506
+
1308
1507
  /************************************
1309
1508
  Duration Prototype
1310
1509
  ************************************/
@@ -1318,7 +1517,8 @@
1318
1517
  valueOf : function () {
1319
1518
  return this._milliseconds +
1320
1519
  this._days * 864e5 +
1321
- this._months * 2592e6;
1520
+ (this._months % 12) * 2592e6 +
1521
+ ~~(this._months / 12) * 31536e6;
1322
1522
  },
1323
1523
 
1324
1524
  humanize : function (withSuffix) {
@@ -1332,6 +1532,37 @@
1332
1532
  return this.lang().postformat(output);
1333
1533
  },
1334
1534
 
1535
+ add : function (input, val) {
1536
+ // supports only 2.0-style add(1, 's') or add(moment)
1537
+ var dur = moment.duration(input, val);
1538
+
1539
+ this._milliseconds += dur._milliseconds;
1540
+ this._days += dur._days;
1541
+ this._months += dur._months;
1542
+
1543
+ return this;
1544
+ },
1545
+
1546
+ subtract : function (input, val) {
1547
+ var dur = moment.duration(input, val);
1548
+
1549
+ this._milliseconds -= dur._milliseconds;
1550
+ this._days -= dur._days;
1551
+ this._months -= dur._months;
1552
+
1553
+ return this;
1554
+ },
1555
+
1556
+ get : function (units) {
1557
+ units = normalizeUnits(units);
1558
+ return this[units.toLowerCase() + 's']();
1559
+ },
1560
+
1561
+ as : function (units) {
1562
+ units = normalizeUnits(units);
1563
+ return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
1564
+ },
1565
+
1335
1566
  lang : moment.fn.lang
1336
1567
  };
1337
1568
 
@@ -1355,6 +1586,9 @@
1355
1586
  }
1356
1587
 
1357
1588
  makeDurationAsGetter('Weeks', 6048e5);
1589
+ moment.duration.fn.asMonths = function () {
1590
+ return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
1591
+ };
1358
1592
 
1359
1593
 
1360
1594
  /************************************