active_frontend 13.3.0 → 14.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.fasterer.yml +19 -0
  4. data/.reek +27 -0
  5. data/.rubocop.yml +38 -0
  6. data/.scss-lint.yml +27 -0
  7. data/Rakefile +1 -1
  8. data/active_frontend.gemspec +21 -18
  9. data/app/.DS_Store +0 -0
  10. data/app/assets/.DS_Store +0 -0
  11. data/app/assets/fonts/.DS_Store +0 -0
  12. data/app/assets/fonts/dripicons/.DS_Store +0 -0
  13. data/app/assets/fonts/dripicons/dripicons.woff +0 -0
  14. data/app/assets/fonts/fakt-pro/.DS_Store +0 -0
  15. data/app/assets/fonts/fakt-pro/fakt-pro-bold.woff +0 -0
  16. data/app/assets/fonts/fakt-pro/fakt-pro-normal.woff +0 -0
  17. data/app/assets/fonts/fakt-pro/fakt-pro-semibold.woff +0 -0
  18. data/app/assets/fonts/fakt-pro/fakt-pro-semilight.woff +0 -0
  19. data/app/assets/fonts/fakt-soft-pro/.DS_Store +0 -0
  20. data/app/assets/fonts/fakt-soft-pro/fakt-soft-pro-bold.woff +0 -0
  21. data/app/assets/fonts/fakt-soft-pro/fakt-soft-pro-normal.woff +0 -0
  22. data/app/assets/fonts/fakt-soft-pro/fakt-soft-pro-semibold.woff +0 -0
  23. data/app/assets/fonts/fakt-soft-pro/fakt-soft-pro-semilight.woff +0 -0
  24. data/app/assets/images/.DS_Store +0 -0
  25. data/app/assets/images/.keep +0 -0
  26. data/app/assets/images/placeholders/.DS_Store +0 -0
  27. data/app/assets/images/placeholders/camera-large.png +0 -0
  28. data/app/assets/images/placeholders/camera-small.png +0 -0
  29. data/app/assets/images/placeholders/camera.png +0 -0
  30. data/app/assets/images/placeholders/document-large.png +0 -0
  31. data/app/assets/images/placeholders/document-small.png +0 -0
  32. data/app/assets/images/placeholders/document.png +0 -0
  33. data/app/assets/images/placeholders/photo-large.png +0 -0
  34. data/app/assets/images/placeholders/{picture-small.png → photo-small.png} +0 -0
  35. data/app/assets/images/placeholders/photo.png +0 -0
  36. data/app/assets/images/placeholders/store-large.png +0 -0
  37. data/app/assets/images/placeholders/store-small.png +0 -0
  38. data/app/assets/images/placeholders/store.png +0 -0
  39. data/app/assets/images/placeholders/user-large.png +0 -0
  40. data/app/assets/images/placeholders/user-small.png +0 -0
  41. data/app/assets/images/placeholders/user.png +0 -0
  42. data/app/helpers/active_frontend_helper.rb +22 -37
  43. data/lib/.DS_Store +0 -0
  44. data/lib/active_frontend.rb +3 -4
  45. data/lib/active_frontend/.DS_Store +0 -0
  46. data/lib/active_frontend/version.rb +1 -1
  47. data/lib/generators/active_frontend/install_generator.rb +3 -3
  48. data/lib/generators/active_frontend/templates/install.js +35 -30
  49. data/lib/generators/active_frontend/templates/install.scss +55 -58
  50. data/vendor/.DS_Store +0 -0
  51. data/vendor/assets/.DS_Store +0 -0
  52. data/vendor/assets/javascripts/.DS_Store +0 -0
  53. data/vendor/assets/javascripts/active_frontend.js +35 -30
  54. data/vendor/assets/javascripts/base/_affix.js +170 -0
  55. data/vendor/assets/javascripts/base/_alert.js +80 -0
  56. data/vendor/assets/javascripts/base/_animation.js +106 -0
  57. data/vendor/assets/javascripts/base/_button.js +123 -0
  58. data/vendor/assets/javascripts/base/_carousel.js +237 -0
  59. data/vendor/assets/javascripts/base/_collapse.js +200 -0
  60. data/vendor/assets/javascripts/base/_colorpicker.js +147 -0
  61. data/vendor/assets/javascripts/base/_datepicker.js +1411 -0
  62. data/vendor/assets/javascripts/base/_dropdown.js +154 -0
  63. data/vendor/assets/javascripts/base/_filepicker.js +235 -0
  64. data/vendor/assets/javascripts/base/_hoverdown.js +116 -0
  65. data/vendor/assets/javascripts/base/_layout.js +126 -0
  66. data/vendor/assets/javascripts/base/_list.js +103 -0
  67. data/vendor/assets/javascripts/{_modal.js → base/_modal.js} +170 -167
  68. data/vendor/assets/javascripts/base/_popover.js +101 -0
  69. data/vendor/assets/javascripts/base/_scrollspy.js +161 -0
  70. data/vendor/assets/javascripts/base/_switch.js +160 -0
  71. data/vendor/assets/javascripts/base/_tab.js +139 -0
  72. data/vendor/assets/javascripts/base/_table.js +224 -0
  73. data/vendor/assets/javascripts/base/_timeago.js +270 -0
  74. data/vendor/assets/javascripts/base/_timepicker.js +541 -0
  75. data/vendor/assets/javascripts/base/_tooltip.js +525 -0
  76. data/vendor/assets/javascripts/base/_tour.js +268 -0
  77. data/vendor/assets/javascripts/base/_transition.js +52 -0
  78. data/vendor/assets/javascripts/base/_typeahead.js +362 -0
  79. data/vendor/assets/javascripts/extensions/_calendar.js +4709 -0
  80. data/vendor/assets/javascripts/extensions/_chart.js +9371 -0
  81. data/vendor/assets/javascripts/extensions/_map.js +2153 -0
  82. data/vendor/assets/stylesheets/.DS_Store +0 -0
  83. data/vendor/assets/stylesheets/{_mixin.scss → _utility.scss} +96 -10
  84. data/vendor/assets/stylesheets/_variable.scss +201 -19
  85. data/vendor/assets/stylesheets/active_frontend.scss +55 -58
  86. data/vendor/assets/stylesheets/blocks/_anchor.scss +15 -0
  87. data/vendor/assets/stylesheets/blocks/_button.scss +278 -0
  88. data/vendor/assets/stylesheets/blocks/_code.scss +144 -0
  89. data/vendor/assets/stylesheets/blocks/_common.scss +127 -0
  90. data/vendor/assets/stylesheets/blocks/_form.scss +508 -0
  91. data/vendor/assets/stylesheets/blocks/_icon.scss +359 -0
  92. data/vendor/assets/stylesheets/blocks/_list.scss +76 -0
  93. data/vendor/assets/stylesheets/blocks/_multimedia.scss +62 -0
  94. data/vendor/assets/stylesheets/blocks/_reset.scss +179 -0
  95. data/vendor/assets/stylesheets/blocks/_table.scss +211 -0
  96. data/vendor/assets/stylesheets/blocks/_typography.scss +204 -0
  97. data/vendor/assets/stylesheets/components/_ad.scss +78 -0
  98. data/vendor/assets/stylesheets/components/_affix.scss +14 -0
  99. data/vendor/assets/stylesheets/components/_alert.scss +50 -0
  100. data/vendor/assets/stylesheets/components/_animation.scss +1670 -0
  101. data/vendor/assets/stylesheets/components/_breadcrumb.scss +17 -0
  102. data/vendor/assets/stylesheets/components/_calendar.scss +213 -0
  103. data/vendor/assets/stylesheets/components/_card.scss +30 -0
  104. data/vendor/assets/stylesheets/components/_carousel.scss +135 -0
  105. data/vendor/assets/stylesheets/components/_chart.scss +10 -0
  106. data/vendor/assets/stylesheets/components/_collapse.scss +17 -0
  107. data/vendor/assets/stylesheets/components/_colorpicker.scss +38 -0
  108. data/vendor/assets/stylesheets/components/_datepicker.scss +80 -0
  109. data/vendor/assets/stylesheets/components/_dropmenu.scss +151 -0
  110. data/vendor/assets/stylesheets/components/_footer.scss +11 -0
  111. data/vendor/assets/stylesheets/components/_grid.scss +144 -0
  112. data/vendor/assets/stylesheets/components/_header.scss +99 -0
  113. data/vendor/assets/stylesheets/components/_label_and_badge.scss +57 -0
  114. data/vendor/assets/stylesheets/components/_layout.scss +63 -0
  115. data/vendor/assets/stylesheets/components/_map.scss +14 -0
  116. data/vendor/assets/stylesheets/components/_milestone.scss +49 -0
  117. data/vendor/assets/stylesheets/components/_missive.scss +40 -0
  118. data/vendor/assets/stylesheets/components/_modal.scss +126 -0
  119. data/vendor/assets/stylesheets/components/_nav_and_tab.scss +202 -0
  120. data/vendor/assets/stylesheets/components/_navbar.scss +66 -0
  121. data/vendor/assets/stylesheets/components/_pagination.scss +79 -0
  122. data/vendor/assets/stylesheets/components/_placeholder.scss +23 -0
  123. data/vendor/assets/stylesheets/components/_popover.scss +167 -0
  124. data/vendor/assets/stylesheets/components/_progress.scss +62 -0
  125. data/vendor/assets/stylesheets/components/_sidebar.scss +74 -0
  126. data/vendor/assets/stylesheets/components/_spinner.scss +83 -0
  127. data/vendor/assets/stylesheets/components/_switch.scss +150 -0
  128. data/vendor/assets/stylesheets/components/_timepicker.scss +30 -0
  129. data/vendor/assets/stylesheets/components/_tooltip.scss +93 -0
  130. data/vendor/assets/stylesheets/components/_transition.scss +12 -0
  131. data/vendor/assets/stylesheets/components/_typeahead.scss +18 -0
  132. metadata +150 -94
  133. data/app/assets/fonts/gotham/gotham-bold.woff +0 -0
  134. data/app/assets/fonts/gotham/gotham-book.woff +0 -0
  135. data/app/assets/fonts/gotham/gotham-light.woff +0 -0
  136. data/app/assets/fonts/gotham/gotham-medium.woff +0 -0
  137. data/app/assets/fonts/gotham/gotham-rounded-bold.woff +0 -0
  138. data/app/assets/fonts/gotham/gotham-rounded-book.woff +0 -0
  139. data/app/assets/fonts/gotham/gotham-rounded-light.woff +0 -0
  140. data/app/assets/fonts/gotham/gotham-rounded-medium.woff +0 -0
  141. data/app/assets/images/placeholders/archive-large.png +0 -0
  142. data/app/assets/images/placeholders/archive-small.png +0 -0
  143. data/app/assets/images/placeholders/archive.png +0 -0
  144. data/app/assets/images/placeholders/picture-large.png +0 -0
  145. data/app/assets/images/placeholders/picture.png +0 -0
  146. data/vendor/assets/javascripts/_affix.js +0 -153
  147. data/vendor/assets/javascripts/_alert.js +0 -85
  148. data/vendor/assets/javascripts/_animation.js +0 -103
  149. data/vendor/assets/javascripts/_button.js +0 -107
  150. data/vendor/assets/javascripts/_carousel.js +0 -228
  151. data/vendor/assets/javascripts/_chart.js +0 -3742
  152. data/vendor/assets/javascripts/_collapse.js +0 -202
  153. data/vendor/assets/javascripts/_color_picker.js +0 -108
  154. data/vendor/assets/javascripts/_date_picker.js +0 -1650
  155. data/vendor/assets/javascripts/_dropdown.js +0 -156
  156. data/vendor/assets/javascripts/_file_input.js +0 -71
  157. data/vendor/assets/javascripts/_hoverdown.js +0 -109
  158. data/vendor/assets/javascripts/_inputmask.js +0 -341
  159. data/vendor/assets/javascripts/_loader.js +0 -361
  160. data/vendor/assets/javascripts/_map.js +0 -2401
  161. data/vendor/assets/javascripts/_popover.js +0 -99
  162. data/vendor/assets/javascripts/_scrollspy.js +0 -163
  163. data/vendor/assets/javascripts/_slider.js +0 -1572
  164. data/vendor/assets/javascripts/_sort.js +0 -1432
  165. data/vendor/assets/javascripts/_swoggle.js +0 -415
  166. data/vendor/assets/javascripts/_tab.js +0 -146
  167. data/vendor/assets/javascripts/_tablespy.js +0 -1883
  168. data/vendor/assets/javascripts/_time_ago.js +0 -206
  169. data/vendor/assets/javascripts/_time_picker.js +0 -1088
  170. data/vendor/assets/javascripts/_tooltip.js +0 -504
  171. data/vendor/assets/javascripts/_transition.js +0 -50
  172. data/vendor/assets/javascripts/_typeahead.js +0 -366
  173. data/vendor/assets/stylesheets/_ad.scss +0 -63
  174. data/vendor/assets/stylesheets/_affix.scss +0 -14
  175. data/vendor/assets/stylesheets/_alert.scss +0 -114
  176. data/vendor/assets/stylesheets/_animation.scss +0 -1370
  177. data/vendor/assets/stylesheets/_breadcrumb.scss +0 -100
  178. data/vendor/assets/stylesheets/_button.scss +0 -386
  179. data/vendor/assets/stylesheets/_canvas.scss +0 -182
  180. data/vendor/assets/stylesheets/_carousel.scss +0 -158
  181. data/vendor/assets/stylesheets/_chart.scss +0 -15
  182. data/vendor/assets/stylesheets/_code.scss +0 -150
  183. data/vendor/assets/stylesheets/_collapse.scss +0 -14
  184. data/vendor/assets/stylesheets/_color.scss +0 -55
  185. data/vendor/assets/stylesheets/_colorpicker.scss +0 -63
  186. data/vendor/assets/stylesheets/_datepicker.scss +0 -122
  187. data/vendor/assets/stylesheets/_dropdown.scss +0 -248
  188. data/vendor/assets/stylesheets/_footer.scss +0 -71
  189. data/vendor/assets/stylesheets/_form.scss +0 -661
  190. data/vendor/assets/stylesheets/_grid.scss +0 -184
  191. data/vendor/assets/stylesheets/_header.scss +0 -156
  192. data/vendor/assets/stylesheets/_icon.scss +0 -362
  193. data/vendor/assets/stylesheets/_image.scss +0 -33
  194. data/vendor/assets/stylesheets/_label_and_badge.scss +0 -104
  195. data/vendor/assets/stylesheets/_link.scss +0 -55
  196. data/vendor/assets/stylesheets/_list.scss +0 -122
  197. data/vendor/assets/stylesheets/_loader.scss +0 -71
  198. data/vendor/assets/stylesheets/_map.scss +0 -44
  199. data/vendor/assets/stylesheets/_missive.scss +0 -74
  200. data/vendor/assets/stylesheets/_modal.scss +0 -204
  201. data/vendor/assets/stylesheets/_nav_and_tab.scss +0 -230
  202. data/vendor/assets/stylesheets/_navbar.scss +0 -73
  203. data/vendor/assets/stylesheets/_pagination.scss +0 -79
  204. data/vendor/assets/stylesheets/_panel.scss +0 -80
  205. data/vendor/assets/stylesheets/_placeholder.scss +0 -63
  206. data/vendor/assets/stylesheets/_popover.scss +0 -128
  207. data/vendor/assets/stylesheets/_progress.scss +0 -86
  208. data/vendor/assets/stylesheets/_reset.scss +0 -140
  209. data/vendor/assets/stylesheets/_sidebar.scss +0 -148
  210. data/vendor/assets/stylesheets/_slider.scss +0 -151
  211. data/vendor/assets/stylesheets/_spinner.scss +0 -572
  212. data/vendor/assets/stylesheets/_subheader.scss +0 -112
  213. data/vendor/assets/stylesheets/_swoggle.scss +0 -120
  214. data/vendor/assets/stylesheets/_table.scss +0 -210
  215. data/vendor/assets/stylesheets/_timepicker.scss +0 -77
  216. data/vendor/assets/stylesheets/_toolbar.scss +0 -130
  217. data/vendor/assets/stylesheets/_tooltip.scss +0 -105
  218. data/vendor/assets/stylesheets/_transition.scss +0 -11
  219. data/vendor/assets/stylesheets/_trunk.scss +0 -147
  220. data/vendor/assets/stylesheets/_typeahead.scss +0 -18
  221. data/vendor/assets/stylesheets/_typography.scss +0 -233
@@ -0,0 +1,1411 @@
1
+ +function ($) {
2
+ 'use strict';
3
+
4
+ // DATEPICKER PUBLIC CLASS DEFINITION
5
+ // ==================================
6
+
7
+ var Datepicker = function (element, options) {
8
+ this.$element = $(element);
9
+ this.$element.data('datepicker', this);
10
+ this.options = $.extend({}, Datepicker.DEFAULTS, options);
11
+
12
+ this.$allowUpdate = true;
13
+
14
+ this.updateOptions(options);
15
+
16
+ this.$dates = new DateArray();
17
+ this.$viewDate = this.$Options.defaultViewDate;
18
+ this.$widget = $(this.initWidget());
19
+
20
+ this.addTemplateArrows();
21
+ this.buildEvents();
22
+ this.unapplyEvents(this.$events);
23
+ this.applyEvents(this.$events);
24
+
25
+ this.$viewMode = this.$Options.startView;
26
+ this.$allowUpdate = false;
27
+
28
+ this.setStartDate(this.$Options.startDate);
29
+ this.setEndDate(this.$Options.endDate);
30
+ this.setDaysOfWeekDisabled(this.$Options.daysOfWeekDisabled);
31
+ this.setDaysOfWeekHighlighted(this.$Options.daysOfWeekHighlighted);
32
+ this.setDatesDisabled(this.$Options.datesDisabled);
33
+ this.fillDays();
34
+ this.fillMonths();
35
+
36
+ this.$allowUpdate = true;
37
+
38
+ this.update();
39
+ this.updateWidgetMode();
40
+ };
41
+
42
+ Datepicker.VERSION = '1.0.0';
43
+ Datepicker.DEFAULTS = {
44
+ assumeNearbyYear: false,
45
+ calendarWeeks: false,
46
+ datesDisabled: [],
47
+ daysOfWeekDisabled: [],
48
+ daysOfWeekHighlighted: [],
49
+ endDate: Infinity,
50
+ forceParse: true,
51
+ format: 'mm/dd/yyyy',
52
+ maxViewMode: 2,
53
+ menu: '<div class="datepicker dropmenu caret"></div>',
54
+ minViewMode: 0,
55
+ multidate: false,
56
+ multidateSeparator: ',',
57
+ startDate: -Infinity,
58
+ startView: 0,
59
+ templates: {
60
+ leftArrow: '<i class="icon-chevron-left"></i>',
61
+ rightArrow: '<i class="icon-chevron-right"></i>'
62
+ },
63
+ text: {
64
+ titleFormat: 'MM yyyy',
65
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
66
+ daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
67
+ daysMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
68
+ months: ['January','February','March','April','May','June','July','August','September','October','November','December'],
69
+ monthsShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
70
+ },
71
+ toggleActive: false,
72
+ weekStart: 0
73
+ };
74
+
75
+ Datepicker.prototype.constructor = Datepicker;
76
+
77
+ Datepicker.prototype.updateOptions = function (options) {
78
+ this.$Options = $.extend({}, this.options, options);
79
+
80
+ this.$Options.startView = this.resolveViewName(this.$Options.startView, 0);
81
+ this.$Options.minViewMode = this.resolveViewName(this.$Options.minViewMode, 0);
82
+ this.$Options.maxViewMode = this.resolveViewName(this.$Options.maxViewMode, 4);
83
+ this.$Options.startView = Math.min(this.$Options.startView, this.$Options.maxViewMode);
84
+ this.$Options.startView = Math.max(this.$Options.startView, this.$Options.minViewMode);
85
+
86
+ if (this.$Options.multidate !== true) {
87
+ this.$Options.multidate = Number(this.$Options.multidate) || false;
88
+
89
+ if (this.$Options.multidate !== false) {
90
+ this.$Options.multidate = Math.max(0, this.$Options.multidate);
91
+ }
92
+ }
93
+
94
+ this.$Options.multidateSeparator = String(this.$Options.multidateSeparator);
95
+ this.$Options.weekStart %= 7;
96
+ this.$Options.weekEnd = (this.$Options.weekStart + 6) % 7;
97
+
98
+ var format = this.parseFormat(this.$Options.format);
99
+
100
+ if (this.$Options.startDate !== -Infinity) {
101
+ if (!!this.$Options.startDate) {
102
+ if (this.$Options.startDate instanceof Date) {
103
+ this.$Options.startDate = this.localToUtc(this.zeroTime(this.$Options.startDate));
104
+ } else {
105
+ this.$Options.startDate = this.parseDate(this.$Options.startDate, format, this.$Options.assumeNearbyYear);
106
+ }
107
+ } else {
108
+ this.$Options.startDate = -Infinity;
109
+ }
110
+ }
111
+ if (this.$Options.endDate !== Infinity) {
112
+ if (!!this.$Options.endDate) {
113
+ if (this.$Options.endDate instanceof Date) {
114
+ this.$Options.endDate = this.localToUtc(this.zeroTime(this.$Options.endDate));
115
+ } else {
116
+ this.$Options.endDate = this.parseDate(this.$Options.endDate, format, this.$Options.assumeNearbyYear);
117
+ }
118
+ } else {
119
+ this.$Options.endDate = Infinity;
120
+ }
121
+ }
122
+
123
+ this.$Options.daysOfWeekDisabled = this.$Options.daysOfWeekDisabled || [];
124
+
125
+ if (!$.isArray(this.$Options.daysOfWeekDisabled)) {
126
+ this.$Options.daysOfWeekDisabled = this.$Options.daysOfWeekDisabled.split(/[,\s]*/);
127
+ }
128
+
129
+ this.$Options.daysOfWeekDisabled = $.map(this.$Options.daysOfWeekDisabled, function (date) {
130
+ return parseInt(date, 10);
131
+ });
132
+
133
+ this.$Options.daysOfWeekHighlighted = this.$Options.daysOfWeekHighlighted || [];
134
+
135
+ if (!$.isArray(this.$Options.daysOfWeekHighlighted)) {
136
+ this.$Options.daysOfWeekHighlighted = this.$Options.daysOfWeekHighlighted.split(/[,\s]*/);
137
+ }
138
+
139
+ this.$Options.daysOfWeekHighlighted = $.map(this.$Options.daysOfWeekHighlighted, function (date) {
140
+ return parseInt(date, 10);
141
+ });
142
+
143
+ this.$Options.datesDisabled = this.$Options.datesDisabled || [];
144
+
145
+ if (!$.isArray(this.$Options.datesDisabled)) {
146
+ this.$Options.datesDisabled = [this.$Options.datesDisabled];
147
+ }
148
+
149
+ this.$Options.datesDisabled = $.map(this.$Options.datesDisabled,function (date) {
150
+ return this.parseDate(date, format, this.$Options.assumeNearbyYear);
151
+ });
152
+
153
+ if (this.$Options.defaultViewDate) {
154
+ var year = this.$Options.defaultViewDate.year || new Date().getFullYear();
155
+ var month = this.$Options.defaultViewDate.month || 0;
156
+ var day = this.$Options.defaultViewDate.day || 1;
157
+
158
+ this.$Options.defaultViewDate = this.utcDate(year, month, day);
159
+ } else {
160
+ this.$Options.defaultViewDate = this.utcToday();
161
+ }
162
+ };
163
+
164
+ Datepicker.prototype.resolveViewName = function (view, value) {
165
+ if (view === 0 || view === 'days' || view === 'month') return 0;
166
+ if (view === 1 || view === 'months' || view === 'year') return 1;
167
+ if (view === 2 || view === 'years' || view === 'decade') return 2;
168
+ if (view === 3 || view === 'decades' || view === 'century') return 3;
169
+ if (view === 4 || view === 'centuries' || view === 'millennium') return 4;
170
+
171
+ return value === undefined ? false : value;
172
+ };
173
+
174
+ Datepicker.prototype.checkTemplate = function (tmp) {
175
+ try {
176
+ if (tmp === undefined || tmp === '') return false;
177
+ if ((tmp.match(/[<>]/g) || []).length <= 0) return true;
178
+
179
+ return $(tmp).length > 0;
180
+ } catch (e) {
181
+ return false;
182
+ }
183
+ };
184
+
185
+ Datepicker.prototype.buildEvents = function () {
186
+ this.$events = [
187
+ [this.$element, {
188
+ 'focus.bs.datepicker': $.proxy(this.showWidget, this),
189
+ 'click.bs.datepicker': $.proxy(this.showWidget, this)
190
+ }]
191
+ ];
192
+
193
+ this.$eventsAlt = [
194
+ [this.$widget, {
195
+ 'click.bs.datepicker': $.proxy(this.clickWidget, this)
196
+ }],
197
+ [$(document), {
198
+ 'mousedown.bs.datepicker, touchend.bs.datepicker': $.proxy(function (e) {
199
+ if (!(
200
+ this.$element.is(e.target) ||
201
+ this.$element.find(e.target).length ||
202
+ this.$widget.is(e.target) ||
203
+ this.$widget.find(e.target).length
204
+ )) {
205
+ this.hideWidget();
206
+ }
207
+ }, this)
208
+ }]
209
+ ];
210
+ };
211
+
212
+ Datepicker.prototype.applyEvents = function (evs) {
213
+ for (var i = 0, el, ch, ev; i < evs.length; i++) {
214
+ el = evs[i][0];
215
+
216
+ if (evs[i].length === 2) {
217
+ ch = undefined;
218
+ ev = evs[i][1];
219
+ } else if (evs[i].length === 3) {
220
+ ch = evs[i][1];
221
+ ev = evs[i][2];
222
+ }
223
+
224
+ el.on(ev, ch);
225
+ }
226
+ };
227
+
228
+ Datepicker.prototype.unapplyEvents = function (evs) {
229
+ for (var i = 0, el, ev, ch; i < evs.length; i++) {
230
+ el = evs[i][0];
231
+
232
+ if (evs[i].length === 2) {
233
+ ch = undefined;
234
+ ev = evs[i][1];
235
+ } else if (evs[i].length === 3) {
236
+ ch = evs[i][1];
237
+ ev = evs[i][2];
238
+ }
239
+
240
+ el.off(ev, ch);
241
+ }
242
+ };
243
+
244
+ Datepicker.prototype.utcToLocal = function (utc) {
245
+ return utc && new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000));
246
+ };
247
+
248
+ Datepicker.prototype.localToUtc = function (local) {
249
+ return local && new Date(local.getTime() - (local.getTimezoneOffset() * 60000));
250
+ };
251
+
252
+ Datepicker.prototype.zeroTime = function (local) {
253
+ return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
254
+ };
255
+
256
+ Datepicker.prototype.zeroUtcTime = function (utc) {
257
+ return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
258
+ };
259
+
260
+ Datepicker.prototype.getDates = function () {
261
+ return $.map(this.$dates, this.utcToLocal);
262
+ };
263
+
264
+ Datepicker.prototype.getUTCDates = function () {
265
+ return $.map(this.$dates, function (date) {
266
+ return new Date(date);
267
+ });
268
+ };
269
+
270
+ Datepicker.prototype.getDate = function () {
271
+ return this.utcToLocal(this.getUTCDate());
272
+ };
273
+
274
+ Datepicker.prototype.getUTCDate = function () {
275
+ var selected_date = this.$dates.get(-1);
276
+
277
+ if (typeof(selected_date) !== 'undefined') {
278
+ return new Date(selected_date);
279
+ } else {
280
+ return null;
281
+ }
282
+ };
283
+
284
+ Datepicker.prototype.setValue = function () {
285
+ this.$element.val(this.getFormattedDate());
286
+ };
287
+
288
+ Datepicker.prototype.setDate = function (date, which) {
289
+ if (!which || which === 'date') this.toggleMultidate(date && new Date(date));
290
+ if (!which || which === 'view') this.$viewDate = date && new Date(date);
291
+
292
+ this.fill();
293
+ this.setValue();
294
+
295
+ if (!which || which !== 'view') this.triggerEvent('changeDate');
296
+ if (this.$element) this.$element.change();
297
+ if (!which || which === 'date') this.hideWidget();
298
+ };
299
+
300
+ Datepicker.prototype.clearDates = function () {
301
+ if (this.$element) this.$element.val('');
302
+
303
+ this.update();
304
+ this.triggerEvent('changeDate');
305
+ this.hideWidget();
306
+ };
307
+
308
+ Datepicker.prototype.getFormattedDate = function (format) {
309
+ if (format === undefined) {
310
+ format = this.$Options.format;
311
+ }
312
+
313
+ var _self = this;
314
+ return $.map(this.$dates, function (date) {
315
+ return _self.formatDate(date, format);
316
+ }).join(this.$Options.multidateSeparator);
317
+ };
318
+
319
+ Datepicker.prototype.setUTCDate = function () {
320
+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
321
+
322
+ this.update.apply(this, $.map(args, this.utcToLocal));
323
+ this.triggerEvent('changeDate');
324
+ this.setValue();
325
+ };
326
+
327
+ Datepicker.prototype.updateAll = function () {
328
+ this.update();
329
+ this.updateWidgetArrows();
330
+ };
331
+
332
+ Datepicker.prototype.setStartDate = function (startDate) {
333
+ this.updateOptions({ 'startDate': startDate });
334
+ this.updateAll();
335
+ };
336
+
337
+ Datepicker.prototype.setEndDate = function (endDate) {
338
+ this.updateOptions({ 'endDate': endDate });
339
+ this.updateAll();
340
+ };
341
+
342
+ Datepicker.prototype.setDaysOfWeekDisabled = function (daysOfWeekDisabled) {
343
+ this.updateOptions({ 'daysOfWeekDisabled': daysOfWeekDisabled });
344
+ this.updateAll();
345
+ };
346
+
347
+ Datepicker.prototype.setDaysOfWeekHighlighted = function (daysOfWeekHighlighted) {
348
+ this.updateOptions({ 'daysOfWeekHighlighted': daysOfWeekHighlighted });
349
+ this.updateAll();
350
+ };
351
+
352
+ Datepicker.prototype.setDatesDisabled = function (datesDisabled) {
353
+ this.updateOptions({ 'datesDisabled': datesDisabled });
354
+ this.updateAll();
355
+ };
356
+
357
+ Datepicker.prototype.setRange = function (range) {
358
+ if (!range || !range.length) {
359
+ delete this.$range;
360
+ } else {
361
+ this.$range = $.map(range, function (date) {
362
+ return date.valueOf();
363
+ });
364
+ }
365
+
366
+ this.fill();
367
+ };
368
+
369
+ Datepicker.prototype.moveDay = function (date, dir) {
370
+ var newDate = new Date(date);
371
+
372
+ newDate.setUTCDate(date.getUTCDate() + dir);
373
+
374
+ return newDate;
375
+ };
376
+
377
+ Datepicker.prototype.moveWeek = function (date, dir) {
378
+ return this.moveDay(date, dir * 7);
379
+ };
380
+
381
+ Datepicker.prototype.moveMonth = function (date, dir) {
382
+ if (!this.isValidDate(date)) return this.$Options.defaultViewDate;
383
+ if (!dir) return date;
384
+
385
+ var newMonth, test;
386
+ var newDate = new Date(date.valueOf());
387
+ var day = newDate.getUTCDate();
388
+ var month = newDate.getUTCMonth();
389
+ var mag = Math.abs(dir);
390
+
391
+ dir = dir > 0 ? 1 : -1;
392
+
393
+ if (mag === 1) {
394
+ test = dir === -1 ? function () {
395
+ return newDate.getUTCMonth() === month;
396
+ } : function () {
397
+ return newDate.getUTCMonth() !== newMonth;
398
+ };
399
+
400
+ newMonth = month + dir;
401
+ newDate.setUTCMonth(newMonth);
402
+
403
+ if (newMonth < 0 || newMonth > 11) {
404
+ newMonth = (newMonth + 12) % 12;
405
+ }
406
+ } else {
407
+ for (var i = 0; i < mag; i++) {
408
+ newDate = this.moveMonth(newDate, dir);
409
+ newMonth = newDate.getUTCMonth();
410
+ newDate.setUTCDate(day);
411
+ }
412
+
413
+ test = function () {
414
+ return newMonth !== newDate.getUTCMonth();
415
+ };
416
+ } while (test()) {
417
+ newDate.setUTCDate(--day);
418
+ newDate.setUTCMonth(newMonth);
419
+ }
420
+
421
+ return newDate;
422
+ };
423
+
424
+ Datepicker.prototype.moveYear = function (date, dir) {
425
+ return this.moveMonth(date, dir * 12);
426
+ };
427
+
428
+ Datepicker.prototype.moveAvailableDate = function (date, dir, fn) {
429
+ do {
430
+ date = this[fn](date, dir);
431
+
432
+ if (!this.dateWithinRange(date)) return false;
433
+
434
+ fn = 'moveDay';
435
+ } while (this.dateIsDisabled(date));
436
+
437
+ return date;
438
+ };
439
+
440
+ Datepicker.prototype.weekOfDateIsDisabled = function (date) {
441
+ return $.inArray(date.getUTCDay(), this.$Options.daysOfWeekDisabled) !== -1;
442
+ };
443
+
444
+ Datepicker.prototype.dateIsDisabled = function (date) {
445
+ return this.weekOfDateIsDisabled(date) ||
446
+ $.grep(this.$Options.datesDisabled, function (d) {
447
+ return this.isUTCEquals(date, d);
448
+ }).length > 0;
449
+ };
450
+
451
+ Datepicker.prototype.dateWithinRange = function (date) {
452
+ return date >= this.$Options.startDate && date <= this.$Options.endDate;
453
+ };
454
+
455
+ Datepicker.prototype.toggleMultidate = function (date) {
456
+ var ix = this.$dates.contains(date);
457
+
458
+ if (!date) this.$dates.clear();
459
+
460
+ if (ix !== -1) {
461
+ if (this.$Options.multidate === true || this.$Options.multidate > 1 || this.$Options.toggleActive) {
462
+ this.$dates.remove(ix);
463
+ }
464
+ } else if (this.$Options.multidate === false) {
465
+ this.$dates.clear();
466
+ this.$dates.push(date);
467
+ } else {
468
+ this.$dates.push(date);
469
+ }
470
+
471
+ if (typeof this.$Options.multidate === 'number') {
472
+ while (this.$dates.length > this.$Options.multidate) this.$dates.remove(0);
473
+ }
474
+ };
475
+
476
+ Datepicker.prototype.getClassNames = function (date) {
477
+ var cls = [];
478
+ var year = this.$viewDate.getUTCFullYear();
479
+ var month = this.$viewDate.getUTCMonth();
480
+ var today = new Date();
481
+
482
+ if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)) {
483
+ cls.push('old');
484
+ } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)) {
485
+ cls.push('new');
486
+ }
487
+
488
+ if (date.getUTCFullYear() === today.getFullYear() &&
489
+ date.getUTCMonth() === today.getMonth() &&
490
+ date.getUTCDate() === today.getDate()) {
491
+ cls.push('today');
492
+ }
493
+
494
+ if (this.$dates.contains(date) !== -1) cls.push('active');
495
+ if (!this.dateWithinRange(date)) cls.push('disabled');
496
+ if (this.dateIsDisabled(date)) cls.push('disabled', 'disabled-date');
497
+ if ($.inArray(date.getUTCDay(), this.$Options.daysOfWeekHighlighted) !== -1) cls.push('highlighted');
498
+
499
+ if (this.$range) {
500
+ if (date > this.$range[0] && date < this.$range[this.$range.length-1]) cls.push('range');
501
+ if ($.inArray(date.valueOf(), this.$range) !== -1) cls.push('selected');
502
+ if (date.valueOf() === this.$range[0]) cls.push('range-start');
503
+ if (date.valueOf() === this.$range[this.$range.length-1]) cls.push('range-end');
504
+ }
505
+
506
+ return cls;
507
+ };
508
+
509
+ Datepicker.prototype.fill = function () {
510
+ var date = new Date(this.$viewDate);
511
+ var year = date.getUTCFullYear();
512
+ var month = date.getUTCMonth();
513
+
514
+ if (isNaN(year) || isNaN(month)) return;
515
+
516
+ var startYear = this.$Options.startDate !== -Infinity ? this.$Options.startDate.getUTCFullYear() : -Infinity;
517
+ var startMonth = this.$Options.startDate !== -Infinity ? this.$Options.startDate.getUTCMonth() : -Infinity;
518
+ var endYear = this.$Options.endDate !== Infinity ? this.$Options.endDate.getUTCFullYear() : Infinity;
519
+ var endMonth = this.$Options.endDate !== Infinity ? this.$Options.endDate.getUTCMonth() : Infinity;
520
+ var titleFormat = this.$Options.text.titleFormat;
521
+
522
+ this.$widget
523
+ .find('.datepicker-days .datepicker-switch')
524
+ .text(this.formatDate(date, titleFormat));
525
+
526
+ this.updateWidgetArrows();
527
+ this.fillMonths();
528
+
529
+ var prevMonth = this.utcDate(year, month - 1, 28);
530
+ var day = this.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
531
+
532
+ prevMonth.setUTCDate(day);
533
+ prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.$Options.weekStart + 7) % 7);
534
+
535
+ var nextMonth = new Date(prevMonth);
536
+
537
+ if (prevMonth.getUTCFullYear() < 100) nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
538
+
539
+ nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
540
+ nextMonth = nextMonth.valueOf();
541
+
542
+ var html = [];
543
+ var clsName;
544
+
545
+ while (prevMonth.valueOf() < nextMonth) {
546
+ if (prevMonth.getUTCDay() === this.$Options.weekStart) {
547
+ html.push('<tr>');
548
+
549
+ if (this.$Options.calendarWeeks) {
550
+ var ws = new Date(+prevMonth + (this.$Options.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5);
551
+ var th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5);
552
+ var yth = new Date(Number(yth = this.utcDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5);
553
+ var calWeek = (th - yth) / 864e5 / 7 + 1;
554
+
555
+ html.push('<td class="cw">'+ calWeek +'</td>');
556
+ }
557
+ }
558
+
559
+ clsName = this.getClassNames(prevMonth);
560
+ clsName.push('day');
561
+
562
+ clsName = $.unique(clsName);
563
+ html.push('<td class="' + clsName.join(' ') + '">' + prevMonth.getUTCDate() + '</td>');
564
+
565
+ if (prevMonth.getUTCDay() === this.$Options.weekEnd) html.push('</tr>');
566
+
567
+ prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
568
+ }
569
+
570
+ this.$widget
571
+ .find('.datepicker-days tbody')
572
+ .empty()
573
+ .append(html.join(''));
574
+
575
+ var monthsTitle = this.$Options.text.monthsTitle || 'Months';
576
+ var months = this.$widget
577
+ .find('.datepicker-months')
578
+ .find('.datepicker-switch')
579
+ .text(this.$Options.maxViewMode < 2 ? monthsTitle : year)
580
+ .end()
581
+ .find('span')
582
+ .removeClass('active');
583
+
584
+ $.each(this.$dates, function (i, date) {
585
+ if (date.getUTCFullYear() === year) months.eq(date.getUTCMonth()).addClass('active');
586
+ });
587
+
588
+ if (year < startYear || year > endYear) months.addClass('disabled');
589
+ if (year === startYear) months.slice(0, startMonth).addClass('disabled');
590
+ if (year === endYear) months.slice(endMonth + 1).addClass('disabled');
591
+
592
+ this.fillYears('.datepicker-years', 'year', 10, 1, year, startYear, endYear);
593
+ this.fillYears('.datepicker-decades', 'decade', 100, 10, year, startYear, endYear);
594
+ this.fillYears('.datepicker-centuries', 'century', 1000, 100, year, startYear, endYear);
595
+ };
596
+
597
+ Datepicker.prototype.fillDays = function () {
598
+ var dayCount = this.$Options.weekStart;
599
+ var html = '<tr>';
600
+
601
+ if (this.$Options.calendarWeeks) {
602
+ this.$widget
603
+ .find('.datepicker-days .datepicker-switch')
604
+ .attr('colspan', function (i, val) {
605
+ return parseInt(val) + 1;
606
+ });
607
+
608
+ html += '<th class="cw">&#160;</th>';
609
+ }
610
+
611
+ while (dayCount < this.$Options.weekStart + 7) {
612
+ html += '<th class="dow';
613
+
614
+ if ($.inArray(dayCount, this.$Options.daysOfWeekDisabled) > -1) {
615
+ html += ' disabled';
616
+ }
617
+
618
+ html += '">' + this.$Options.text.daysMin[(dayCount++) % 7] + '</th>';
619
+ }
620
+
621
+ html += '</tr>';
622
+ this.$widget.find('.datepicker-days thead').append(html);
623
+ };
624
+
625
+ Datepicker.prototype.fillMonths = function () {
626
+ var localDate = this.utcToLocal(this.$viewDate);
627
+ var html = '';
628
+ var i = 0;
629
+
630
+ while (i < 12) {
631
+ var focused = localDate && localDate.getMonth() === i ? ' focused' : '';
632
+
633
+ html += '<span class="month' + focused + '">' + this.$Options.text.monthsShort[i++] + '</span>';
634
+ }
635
+
636
+ this.$widget.find('.datepicker-months td').html(html);
637
+ };
638
+
639
+ Datepicker.prototype.fillYears = function (selector, cssClass, factor, step, currentYear, startYear, endYear) {
640
+ var year = parseInt(currentYear / factor, 10) * factor;
641
+ var startStep = parseInt(startYear / step, 10) * step;
642
+ var endStep = parseInt(endYear / step, 10) * step;
643
+ var view = this.$widget.find(selector);
644
+ var steps = $.map(this.$dates, function (date) {
645
+ return parseInt(date.getUTCFullYear() / step, 10) * step;
646
+ });
647
+ var thisYear = year - step;
648
+ var html = '';
649
+ var i, classes;
650
+
651
+ view.find('.datepicker-switch').text(year + '-' + (year + step * 9));
652
+
653
+ for (i = -1; i < 11; i += 1) {
654
+ classes = [cssClass];
655
+
656
+ if (i === -1) {
657
+ classes.push('old');
658
+ } else if (i === 10) {
659
+ classes.push('new');
660
+ }
661
+
662
+ if ($.inArray(thisYear, steps) !== -1) classes.push('active');
663
+ if (thisYear < startStep || thisYear > endStep) classes.push('disabled');
664
+ if (thisYear === this.$viewDate.getFullYear()) classes.push('focused');
665
+
666
+ html += '<span class="' + classes.join(' ') + '">' + thisYear + '</span>';
667
+ thisYear += step;
668
+ }
669
+
670
+ view.find('td').html(html);
671
+ };
672
+
673
+ Datepicker.prototype.update = function () {
674
+ if (!this.$allowUpdate) return;
675
+
676
+ var dates = [];
677
+ var oldDates = this.$dates.copy();
678
+ var fromArgs = false;
679
+
680
+ if (arguments.length) {
681
+ $.each(arguments, $.proxy(function (i, date) {
682
+ if (date instanceof Date) {
683
+ date = this.localToUtc(date);
684
+ }
685
+
686
+ dates.push(date);
687
+ }, this));
688
+
689
+ fromArgs = true;
690
+ } else {
691
+ dates = this.$element.val();
692
+
693
+ if (dates && this.$Options.multidate) {
694
+ dates = dates.split(this.$Options.multidateSeparator);
695
+ } else {
696
+ dates = [dates];
697
+ }
698
+
699
+ delete this.$element.data().date;
700
+ }
701
+
702
+ dates = $.map(dates, $.proxy(function (date) {
703
+ return this.parseDate(date, this.$Options.format, this.$Options.assumeNearbyYear);
704
+ }, this));
705
+
706
+ dates = $.grep(dates, $.proxy(function (date) {
707
+ return !this.dateWithinRange(date) || !date;
708
+ }, this), true);
709
+
710
+ this.$dates.replace(dates);
711
+
712
+ if (this.$dates.length) {
713
+ this.$viewDate = new Date(this.$dates.get(-1));
714
+ } else if (this.$viewDate < this.$Options.startDate) {
715
+ this.$viewDate = new Date(this.$Options.startDate);
716
+ } else if (this.$viewDate > this.$Options.endDate) {
717
+ this.$viewDate = new Date(this.$Options.endDate);
718
+ } else {
719
+ this.$viewDate = this.$Options.defaultViewDate;
720
+ }
721
+
722
+ if (fromArgs) {
723
+ this.setValue();
724
+ } else if (dates.length) {
725
+ if (String(oldDates) !== String(this.$dates)) this.triggerEvent('changeDate');
726
+ }
727
+
728
+ if (!this.$dates.length && oldDates.length) this.triggerEvent('clearDate');
729
+
730
+ this.fill();
731
+ this.$element.change();
732
+ };
733
+
734
+ Datepicker.prototype.triggerEvent = function (event, altDate) {
735
+ var date = altDate || this.$dates.get(-1);
736
+ var localDate = this.utcToLocal(date);
737
+
738
+ this.$element.trigger({
739
+ type: event,
740
+ date: localDate,
741
+ dates: $.map(this.$dates, this.utcToLocal),
742
+ format: $.proxy(function (ix, format) {
743
+ if (arguments.length === 0) {
744
+ ix = this.$dates.length - 1;
745
+ format = this.$Options.format;
746
+ } else if (typeof(ix) === 'string') {
747
+ format = ix;
748
+ ix = this.$dates.length - 1;
749
+ }
750
+
751
+ return this.formatDate(this.$dates.get(ix), format || this.$Options.format);
752
+ }, this)
753
+ });
754
+ };
755
+
756
+ Datepicker.prototype.showWidget = function () {
757
+ if (this.$element.prop('disabled') || this.$element.prop('readonly')) return;
758
+ if (this.$widget.is(':visible')) return;
759
+
760
+ this.$container = $('<span>')
761
+ .addClass('btn-group dropdown open bsDatepicker')
762
+ .css({
763
+ height: 0,
764
+ position: 'absolute',
765
+ width: 0
766
+ });
767
+
768
+ this.$container.append(this.$widget);
769
+ this.$element.after(this.$container);
770
+
771
+ this.unapplyEvents(this.$eventsAlt);
772
+ this.applyEvents(this.$eventsAlt);
773
+ this.triggerEvent('showWidget');
774
+ };
775
+
776
+ Datepicker.prototype.clickWidget = function (e) {
777
+ e.preventDefault();
778
+ e.stopPropagation();
779
+
780
+ var dir, day, year, month, monthChanged, yearChanged;
781
+ var target = $(e.target);
782
+
783
+ if (target.hasClass('datepicker-switch')) this.updateWidgetMode(1);
784
+
785
+ var navArrow = target.closest('.prev, .next');
786
+
787
+ if (navArrow.length > 0) {
788
+ dir = this.modes(this.$viewMode).navStep * (navArrow.hasClass('prev') ? -1 : 1);
789
+
790
+ if (this.$viewMode === 0) {
791
+ this.$viewDate = this.moveMonth(this.$viewDate, dir);
792
+ this.triggerEvent('changeMonth', this.$viewDate);
793
+ } else {
794
+ this.$viewDate = this.moveYear(this.$viewDate, dir);
795
+
796
+ if (this.$viewMode === 1) this.triggerEvent('changeYear', this.$viewDate);
797
+ }
798
+
799
+ this.fill();
800
+ }
801
+
802
+ if (!target.hasClass('disabled')) {
803
+ if (target.hasClass('day')) {
804
+ day = parseInt(target.text(), 10) || 1;
805
+ year = this.$viewDate.getUTCFullYear();
806
+ month = this.$viewDate.getUTCMonth();
807
+
808
+ if (target.hasClass('old')) {
809
+ if (month === 0) {
810
+ month = 11;
811
+ year = year - 1;
812
+ monthChanged = true;
813
+ yearChanged = true;
814
+ } else {
815
+ month = month - 1;
816
+ monthChanged = true;
817
+ }
818
+ }
819
+ if (target.hasClass('new')) {
820
+ if (month === 11) {
821
+ month = 0;
822
+ year = year + 1;
823
+ monthChanged = true;
824
+ yearChanged = true;
825
+ } else {
826
+ month = month + 1;
827
+ monthChanged = true;
828
+ }
829
+ }
830
+
831
+ this.setDate(this.utcDate(year, month, day));
832
+
833
+ if (yearChanged) this.triggerEvent('changeYear', this.$viewDate);
834
+ if (monthChanged) this.triggerEvent('changeMonth', this.$viewDate);
835
+ }
836
+
837
+ if (target.hasClass('month')) {
838
+ this.$viewDate.setUTCDate(1);
839
+
840
+ day = 1;
841
+ month = target.parent().find('span').index(target);
842
+ year = this.$viewDate.getUTCFullYear();
843
+
844
+ this.$viewDate.setUTCMonth(month);
845
+ this.triggerEvent('changeMonth', this.$viewDate);
846
+
847
+ if (this.$Options.minViewMode === 1) {
848
+ this.setDate(this.utcDate(year, month, day));
849
+ this.updateWidgetMode();
850
+ } else {
851
+ this.updateWidgetMode(-1);
852
+ }
853
+
854
+ this.fill();
855
+ }
856
+
857
+ if (target.hasClass('year') || target.hasClass('decade') || target.hasClass('century')) {
858
+ this.$viewDate.setUTCDate(1);
859
+
860
+ day = 1;
861
+ month = 0;
862
+ year = parseInt(target.text(), 10) || 0;
863
+
864
+ this.$viewDate.setUTCFullYear(year);
865
+
866
+ if (target.hasClass('year')) {
867
+ this.triggerEvent('changeYear', this.$viewDate);
868
+ if (this.$Options.minViewMode === 2) this.setDate(this.utcDate(year, month, day));
869
+ }
870
+ if (target.hasClass('decade')) {
871
+ this.triggerEvent('changeDecade', this.$viewDate);
872
+ if (this.$Options.minViewMode === 3) this.setDate(this.utcDate(year, month, day));
873
+ }
874
+ if (target.hasClass('century')) {
875
+ this.triggerEvent('changeCentury', this.$viewDate);
876
+ if (this.$Options.minViewMode === 4) this.setDate(this.utcDate(year, month, day));
877
+ }
878
+
879
+ this.updateWidgetMode(-1);
880
+ this.fill();
881
+ }
882
+ }
883
+ };
884
+
885
+ Datepicker.prototype.updateWidgetArrows = function () {
886
+ if (!this.$allowUpdate) return;
887
+
888
+ var date = new Date(this.$viewDate);
889
+ var year = date.getUTCFullYear();
890
+ var month = date.getUTCMonth();
891
+ var prev = this.$widget.find('.prev');
892
+ var next = this.$widget.find('.next');
893
+ var hiddenCss = { visibility: 'hidden' };
894
+ var visibleCss = { visibility: 'visible' };
895
+
896
+ switch (this.$viewMode) {
897
+ case 0:
898
+ if (this.$Options.startDate !== -Infinity && year <= this.$Options.startDate.getUTCFullYear() && month <= this.$Options.startDate.getUTCMonth()) {
899
+ prev.css(hiddenCss);
900
+ } else {
901
+ prev.css(visibleCss);
902
+ }
903
+ if (this.$Options.endDate !== Infinity && year >= this.$Options.endDate.getUTCFullYear() && month >= this.$Options.endDate.getUTCMonth()) {
904
+ next.css(hiddenCss);
905
+ } else {
906
+ next.css(visibleCss);
907
+ }
908
+
909
+ break;
910
+ case 1:
911
+ case 2:
912
+ case 3:
913
+ case 4:
914
+ if (this.$Options.startDate !== -Infinity && year <= this.$Options.startDate.getUTCFullYear() || this.$Options.maxViewMode < 2) {
915
+ prev.css(hiddenCss);
916
+ } else {
917
+ prev.css(visibleCss);
918
+ }
919
+ if (this.$Options.endDate !== Infinity && year >= this.$Options.endDate.getUTCFullYear() || this.$Options.maxViewMode < 2) {
920
+ next.css(hiddenCss);
921
+ } else {
922
+ next.css(visibleCss);
923
+ }
924
+
925
+ break;
926
+ }
927
+ };
928
+
929
+ Datepicker.prototype.updateWidgetMode = function (dir) {
930
+ if (dir) {
931
+ this.$viewMode = Math.max(this.$Options.minViewMode, Math.min(this.$Options.maxViewMode, this.$viewMode + dir));
932
+ }
933
+
934
+ this.$widget
935
+ .children('div')
936
+ .hide()
937
+ .filter('.datepicker-' + this.modes(this.$viewMode).clsName)
938
+ .show();
939
+
940
+ this.updateWidgetArrows();
941
+ };
942
+
943
+ Datepicker.prototype.hideWidget = function () {
944
+ if (!this.$widget.is(':visible')) return;
945
+
946
+ this.unapplyEvents(this.$eventsAlt);
947
+ this.$viewMode = this.$Options.startView;
948
+
949
+ if (this.$Options.forceParse) this.setValue();
950
+
951
+ this.updateWidgetMode();
952
+ this.$widget.detach();
953
+ this.$container.remove();
954
+ this.triggerEvent('hideWidget');
955
+ };
956
+
957
+ Datepicker.prototype.addTemplateArrows = function (view, value) {
958
+ if (this.checkTemplate(this.$Options.templates.leftArrow)) {
959
+ this.$widget.find('.prev').html(this.$Options.templates.leftArrow);
960
+ }
961
+ if (this.checkTemplate(this.$Options.templates.rightArrow)) {
962
+ this.$widget.find('.next').html(this.$Options.templates.rightArrow);
963
+ }
964
+ };
965
+
966
+ Datepicker.prototype.templateContainer = function (klass) {
967
+ var table = $('<table>')
968
+ .append(this.templateHeader())
969
+ .append(this.templateBody(klass));
970
+ var container = $('<div class="' + klass + '">')
971
+ .append(table);
972
+
973
+ return container;
974
+ };
975
+
976
+ Datepicker.prototype.templateHeader = function () {
977
+ var row = $('<tr>')
978
+ .append('<th class="prev">' + this.$Options.templates.leftArrow + '</th>')
979
+ .append('<th colspan="5" class="datepicker-switch"></th>')
980
+ .append('<th class="next">' + this.$Options.templates.rightArrow + '</th>');
981
+ var header = $('<thead>')
982
+ .append(row);
983
+
984
+ return header;
985
+ };
986
+
987
+ Datepicker.prototype.templateBody = function (klass) {
988
+ var body = $('<tbody>');
989
+ if (klass !== 'datepicker-days') body.append('<tr><td colspan="7"></td></tr>');
990
+ return body;
991
+ };
992
+
993
+ Datepicker.prototype.initWidget = function () {
994
+ var menu = $(this.$Options.menu)
995
+ .append(this.templateContainer('datepicker-days'))
996
+ .append(this.templateContainer('datepicker-months'))
997
+ .append(this.templateContainer('datepicker-years'))
998
+ .append(this.templateContainer('datepicker-decades'))
999
+ .append(this.templateContainer('datepicker-centuries'));
1000
+
1001
+ return menu;
1002
+ };
1003
+
1004
+ Datepicker.prototype.modes = function (mode) {
1005
+ var modes = [
1006
+ { clsName: 'days', navFnc: 'Month', navStep: 1 },
1007
+ { clsName: 'months', navFnc: 'FullYear', navStep: 1 },
1008
+ { clsName: 'years', navFnc: 'FullYear', navStep: 10 },
1009
+ { clsName: 'decades', navFnc: 'FullDecade', navStep: 100 },
1010
+ { clsName: 'centuries', navFnc: 'FullCentury', navStep: 1000 }
1011
+ ];
1012
+
1013
+ return modes[mode];
1014
+ };
1015
+
1016
+ Datepicker.prototype.formatDate = function (date, format) {
1017
+ if (!date) return '';
1018
+ if (typeof format === 'string') format = this.parseFormat(format);
1019
+
1020
+ var seps = $.extend([], format.separators);
1021
+ var val = {
1022
+ d: date.getUTCDate(),
1023
+ D: this.$Options.text.daysShort[date.getUTCDay()],
1024
+ DD: this.$Options.text.days[date.getUTCDay()],
1025
+ m: date.getUTCMonth() + 1,
1026
+ M: this.$Options.text.monthsShort[date.getUTCMonth()],
1027
+ MM: this.$Options.text.months[date.getUTCMonth()],
1028
+ yy: date.getUTCFullYear().toString().substring(2),
1029
+ yyyy: date.getUTCFullYear()
1030
+ };
1031
+
1032
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
1033
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
1034
+
1035
+ date = [];
1036
+
1037
+ for (var i = 0, cnt = format.parts.length; i <= cnt; i++) {
1038
+ if (seps.length) date.push(seps.shift());
1039
+
1040
+ date.push(val[format.parts[i]]);
1041
+ }
1042
+
1043
+ return date.join('');
1044
+ };
1045
+
1046
+ Datepicker.prototype.getDaysInMonth = function (year, month) {
1047
+ return [31, (this.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1048
+ };
1049
+
1050
+ Datepicker.prototype.isLeapYear = function (year) {
1051
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1052
+ };
1053
+
1054
+ Datepicker.prototype.parseFormat = function (format) {
1055
+ var regex = /dd?|DD?|mm?|MM?|yy(?:yy)?/g;
1056
+ var separators = format.replace(regex, '\0').split('\0');
1057
+ var parts = format.match(regex);
1058
+
1059
+ if (!separators || !separators.length || !parts || parts.length === 0) {
1060
+ throw new Error('Invalid date format.');
1061
+ }
1062
+
1063
+ return { separators: separators, parts: parts };
1064
+ };
1065
+
1066
+ Datepicker.prototype.parseDate = function (date, format, assumeNearby) {
1067
+ if (!date) return undefined;
1068
+ if (date instanceof Date) return date;
1069
+
1070
+ if (typeof format === 'string') {
1071
+ format = this.parseFormat(format);
1072
+ }
1073
+
1074
+ var part, dir, i, fn;
1075
+ var partRe = /([\-+]\d+)([dmwy])/;
1076
+ var parts = date.match(/([\-+]\d+)([dmwy])/g);
1077
+ var fnMap = { d: 'moveDay', m: 'moveMonth', w: 'moveWeek', y: 'moveYear' };
1078
+ var dateAliases = { yesterday: '-1d', today: '+0d', tomorrow: '+1d' };
1079
+
1080
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
1081
+ date = new Date();
1082
+
1083
+ for (i = 0; i < parts.length; i++) {
1084
+ part = partRe.exec(parts[i]);
1085
+ dir = parseInt(part[1]);
1086
+ fn = fnMap[part[2]];
1087
+ date = Datepicker.prototype[fn](date, dir);
1088
+ }
1089
+
1090
+ return this.utcDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1091
+ }
1092
+
1093
+ if (typeof dateAliases[date] !== 'undefined') {
1094
+ date = dateAliases[date];
1095
+ parts = date.match(/([\-+]\d+)([dmwy])/g);
1096
+
1097
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
1098
+ date = new Date();
1099
+
1100
+ for (i = 0; i < parts.length; i++) {
1101
+ part = partRe.exec(parts[i]);
1102
+ dir = parseInt(part[1]);
1103
+ fn = fnMap[part[2]];
1104
+ date = Datepicker.prototype[fn](date, dir);
1105
+ }
1106
+
1107
+ return this.utcDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1108
+ }
1109
+ }
1110
+
1111
+ parts = date && date.match(/[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g) || [];
1112
+ date = new Date();
1113
+
1114
+ function applyNearbyYear(year, threshold) {
1115
+ if (threshold === true) threshold = 10;
1116
+
1117
+ if (year < 100) {
1118
+ year += 2000;
1119
+
1120
+ if (year > ((new Date()).getFullYear()+threshold)) {
1121
+ year -= 100;
1122
+ }
1123
+ }
1124
+
1125
+ return year;
1126
+ }
1127
+
1128
+ var val, filtered;
1129
+ var parsed = {};
1130
+ var setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'];
1131
+ var setters_map = {
1132
+ yyyy: function (d,v) {
1133
+ return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1134
+ },
1135
+ yy: function (d,v) {
1136
+ return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1137
+ },
1138
+ m: function (d,v) {
1139
+ if (isNaN(d)) return d;
1140
+
1141
+ v -= 1;
1142
+ while (v < 0) v += 12;
1143
+ v %= 12;
1144
+
1145
+ d.setUTCMonth(v);
1146
+ while (d.getUTCMonth() !== v) d.setUTCDate(d.getUTCDate()-1);
1147
+
1148
+ return d;
1149
+ },
1150
+ d: function (d,v) {
1151
+ return d.setUTCDate(v);
1152
+ }
1153
+ };
1154
+
1155
+ setters_map.M = setters_map.MM = setters_map.mm = setters_map.m;
1156
+ setters_map.dd = setters_map.d;
1157
+
1158
+ date = this.utcToday();
1159
+
1160
+ var fparts = format.parts.slice();
1161
+
1162
+ if (parts.length !== fparts.length) {
1163
+ fparts = $(fparts).filter(function (i, p) {
1164
+ return $.inArray(p, setters_order) !== -1;
1165
+ }).toArray();
1166
+ }
1167
+
1168
+ function match_part() {
1169
+ var m = this.slice(0, parts[i].length);
1170
+ var p = parts[i].slice(0, m.length);
1171
+
1172
+ return m.toLowerCase() === p.toLowerCase();
1173
+ }
1174
+
1175
+ if (parts.length === fparts.length) {
1176
+ var cnt, _date, s;
1177
+
1178
+ for (i = 0, cnt = fparts.length; i < cnt; i++) {
1179
+ val = parseInt(parts[i], 10);
1180
+ part = fparts[i];
1181
+
1182
+ if (isNaN(val)) {
1183
+ switch (part) {
1184
+ case 'MM':
1185
+ filtered = $(this.text.months).filter(match_part);
1186
+ val = $.inArray(filtered[0], this.text.months) + 1;
1187
+ break;
1188
+
1189
+ case 'M':
1190
+ filtered = $(this.text.monthsShort).filter(match_part);
1191
+ val = $.inArray(filtered[0], this.text.monthsShort) + 1;
1192
+ break;
1193
+ }
1194
+ }
1195
+
1196
+ parsed[part] = val;
1197
+ }
1198
+
1199
+ for (i = 0; i < setters_order.length; i++) {
1200
+ s = setters_order[i];
1201
+
1202
+ if (s in parsed && !isNaN(parsed[s])) {
1203
+ _date = new Date(date);
1204
+ setters_map[s](_date, parsed[s]);
1205
+
1206
+ if (!isNaN(_date)) {
1207
+ date = _date;
1208
+ }
1209
+ }
1210
+ }
1211
+ }
1212
+
1213
+ return date;
1214
+ };
1215
+
1216
+ Datepicker.prototype.utcDate = function () {
1217
+ return new Date(Date.UTC.apply(Date, arguments));
1218
+ };
1219
+
1220
+ Datepicker.prototype.utcToday = function () {
1221
+ var today = new Date();
1222
+ return this.utcDate(today.getFullYear(), today.getMonth(), today.getDate());
1223
+ };
1224
+
1225
+ Datepicker.prototype.isUTCEquals = function (date1, date2) {
1226
+ return date1.getUTCFullYear() === date2.getUTCFullYear() &&
1227
+ date1.getUTCMonth() === date2.getUTCMonth() &&
1228
+ date1.getUTCDate() === date2.getUTCDate();
1229
+ };
1230
+
1231
+ Datepicker.prototype.isValidDate = function (date) {
1232
+ return date && !isNaN(date.getTime());
1233
+ };
1234
+
1235
+ // DATERANGEPICKER PUBLIC CLASS DEFINITION
1236
+ // =======================================
1237
+
1238
+ var DateRangepicker = function (element, options) {
1239
+ this.$element = $(element);
1240
+ this.$element.data('datepicker', this);
1241
+ this.options = $.extend({}, Datepicker.DEFAULTS, options);
1242
+
1243
+ this.parseInputs();
1244
+
1245
+ delete this.options.inputs;
1246
+
1247
+ this.proxyUpdate();
1248
+ this.getRangePickers();
1249
+ this.updateDates();
1250
+ };
1251
+
1252
+ DateRangepicker.prototype.constructor = DateRangepicker;
1253
+
1254
+ DateRangepicker.prototype.proxyUpdate = function () {
1255
+ Plugin.call($(this.$inputs), this.options)
1256
+ .on('changeDate', $.proxy(this.dateUpdated, this));
1257
+ };
1258
+
1259
+ DateRangepicker.prototype.parseInputs = function () {
1260
+ this.$inputs = $.map(this.options.inputs, function (input) {
1261
+ return input.jquery ? input[0] : input;
1262
+ });
1263
+ };
1264
+
1265
+ DateRangepicker.prototype.getRangePickers = function () {
1266
+ this.$pickers = $.map(this.$inputs, function (input) {
1267
+ return $(input).data('datepicker');
1268
+ });
1269
+ };
1270
+
1271
+ DateRangepicker.prototype.updateDates = function () {
1272
+ this.$dates = $.map(this.$pickers, function (picker) {
1273
+ return picker.getUTCDate();
1274
+ });
1275
+
1276
+ this.updateRanges();
1277
+ };
1278
+
1279
+ DateRangepicker.prototype.updateRanges = function () {
1280
+ var range = $.map(this.$dates, function (date) {
1281
+ return date.valueOf();
1282
+ });
1283
+
1284
+ $.each(this.$pickers, function (i, picker) {
1285
+ picker.setRange(range);
1286
+ });
1287
+ };
1288
+
1289
+ DateRangepicker.prototype.dateUpdated = function (e) {
1290
+ if (this.$active) return;
1291
+
1292
+ this.$active = true;
1293
+
1294
+ var picker = $(e.target).data('datepicker');
1295
+
1296
+ if (typeof(picker) === 'undefined') return;
1297
+
1298
+ var i = $.inArray(e.target, this.$inputs);
1299
+
1300
+ if (i === -1) return;
1301
+
1302
+ var date = picker.getUTCDate();
1303
+ var j = i - 1;
1304
+ var k = i + 1;
1305
+ var l = this.$inputs.length;
1306
+
1307
+ $.each(this.$pickers, function (i, p) {
1308
+ if (!p.getUTCDate()) p.setUTCDate(date);
1309
+ });
1310
+
1311
+ if (date < this.$dates[j]) {
1312
+ while (j >= 0 && date < this.$dates[j]) this.$pickers[j--].setUTCDate(date);
1313
+ } else if (date > this.$dates[k]) {
1314
+ while (k < l && date > this.$dates[k]) this.$pickers[k++].setUTCDate(date);
1315
+ }
1316
+
1317
+ this.updateDates();
1318
+
1319
+ delete this.$active;
1320
+ };
1321
+
1322
+ var DateArray = (function () {
1323
+ var extras = {
1324
+ get: function (i) {
1325
+ return this.slice(i)[0];
1326
+ },
1327
+ contains: function (date) {
1328
+ var val = date && date.valueOf();
1329
+
1330
+ for (var i = 0, l = this.length; i < l; i++) {
1331
+ if (this[i].valueOf() === val) return i;
1332
+ }
1333
+
1334
+ return -1;
1335
+ },
1336
+ remove: function (i) {
1337
+ this.splice(i, 1);
1338
+ },
1339
+ replace: function (array) {
1340
+ if (!array) return;
1341
+ if (!$.isArray(array)) array = [array];
1342
+
1343
+ this.clear();
1344
+ this.push.apply(this, array);
1345
+ },
1346
+ clear: function () {
1347
+ this.length = 0;
1348
+ },
1349
+ copy: function () {
1350
+ var array = new DateArray();
1351
+ array.replace(this);
1352
+ return array;
1353
+ }
1354
+ };
1355
+
1356
+ return function () {
1357
+ var array = [];
1358
+ array.push.apply(array, arguments);
1359
+ $.extend(array, extras);
1360
+ return array;
1361
+ };
1362
+ })();
1363
+
1364
+ // DATEPICKER PLUGIN DEFINITION
1365
+ // ============================
1366
+
1367
+ function Plugin(option) {
1368
+ return this.each(function () {
1369
+ var $this = $(this);
1370
+ var data = $this.data('bs.datepicker');
1371
+ var options = typeof option === 'object' && option;
1372
+
1373
+ if (!data) {
1374
+ if ($this.hasClass('datepicker-range')) {
1375
+ $.extend(options, {
1376
+ inputs: $this.find('input').toArray(),
1377
+ });
1378
+
1379
+ $this.data('bs.datepicker', (data = new DateRangepicker(this, options)));
1380
+ } else {
1381
+ $this.data('bs.datepicker', (data = new Datepicker(this, options)));
1382
+ }
1383
+ }
1384
+
1385
+ if (typeof option === 'string') data[option]();
1386
+ });
1387
+ }
1388
+
1389
+ var old = $.fn.datepicker;
1390
+
1391
+ $.fn.datepicker = Plugin;
1392
+ $.fn.datepicker.Constructor = Datepicker;
1393
+
1394
+ // DATEPICKER NO CONFLICT
1395
+ // ======================
1396
+
1397
+ $.fn.datepicker.noConflict = function () {
1398
+ $.fn.datepicker = old;
1399
+ return this;
1400
+ };
1401
+
1402
+ // DATEPICKER DATA-API
1403
+ // ===================
1404
+
1405
+ $(document).on('focus.bs.datepicker.data-api click.bs.datepicker.data-api', '[data-toggle="datepicker"]', function (e) {
1406
+ var $this = $(this);
1407
+ if ($this.data('datepicker')) return;
1408
+ Plugin.call($this, $this.data());
1409
+ });
1410
+
1411
+ }(jQuery);