Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / pybind / mgr / dashboard / static / AdminLTE-2.3.7 / plugins / timepicker / bootstrap-timepicker.js
1 //TODO: move arrow styles and button click code into configurable items, with defaults matching the existing code
2
3 /*!
4 * Timepicker Component for Twitter Bootstrap
5 *
6 * Copyright 2013 Joris de Wit
7 *
8 * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors
9 *
10 * For the full copyright and license information, please view the LICENSE
11 * file that was distributed with this source code.
12 */
13 (function($, window, document, undefined) {
14   'use strict';
15
16   // TIMEPICKER PUBLIC CLASS DEFINITION
17   var Timepicker = function(element, options) {
18     this.widget = '';
19     this.$element = $(element);
20     this.defaultTime = options.defaultTime;
21     this.disableFocus = options.disableFocus;
22     this.isOpen = options.isOpen;
23     this.minuteStep = options.minuteStep;
24     this.modalBackdrop = options.modalBackdrop;
25     this.secondStep = options.secondStep;
26     this.showInputs = options.showInputs;
27     this.showMeridian = options.showMeridian;
28     this.showSeconds = options.showSeconds;
29     this.template = options.template;
30     this.appendWidgetTo = options.appendWidgetTo;
31         this.upArrowStyle = options.upArrowStyle;
32         this.downArrowStyle = options.downArrowStyle;
33         this.containerClass = options.containerClass;
34
35     this._init();
36   };
37
38   Timepicker.prototype = {
39
40     constructor: Timepicker,
41
42     _init: function() {
43       var self = this;
44
45       if (this.$element.parent().hasClass('input-append') || this.$element.parent().hasClass('input-prepend')) {
46                 if (this.$element.parent('.input-append, .input-prepend').find('.add-on').length) {
47                         this.$element.parent('.input-append, .input-prepend').find('.add-on').on({
48                           'click.timepicker': $.proxy(this.showWidget, this)
49                         });             
50                 } else {
51                         this.$element.closest(this.containerClass).find('.add-on').on({
52                           'click.timepicker': $.proxy(this.showWidget, this)
53                         });             
54                 }
55                 
56         this.$element.on({
57           'focus.timepicker': $.proxy(this.highlightUnit, this),
58           'click.timepicker': $.proxy(this.highlightUnit, this),
59           'keydown.timepicker': $.proxy(this.elementKeydown, this),
60           'blur.timepicker': $.proxy(this.blurElement, this)
61         });
62       } else {
63         if (this.template) {
64           this.$element.on({
65             'focus.timepicker': $.proxy(this.showWidget, this),
66             'click.timepicker': $.proxy(this.showWidget, this),
67             'blur.timepicker': $.proxy(this.blurElement, this)
68           });
69         } else {
70           this.$element.on({
71             'focus.timepicker': $.proxy(this.highlightUnit, this),
72             'click.timepicker': $.proxy(this.highlightUnit, this),
73             'keydown.timepicker': $.proxy(this.elementKeydown, this),
74             'blur.timepicker': $.proxy(this.blurElement, this)
75           });
76         }
77       }
78
79       if (this.template !== false) {
80         this.$widget = $(this.getTemplate()).prependTo(this.$element.parents(this.appendWidgetTo)).on('click', $.proxy(this.widgetClick, this));
81       } else {
82         this.$widget = false;
83       }
84
85       if (this.showInputs && this.$widget !== false) {
86         this.$widget.find('input').each(function() {
87           $(this).on({
88             'click.timepicker': function() { $(this).select(); },
89             'keydown.timepicker': $.proxy(self.widgetKeydown, self)
90           });
91         });
92       }
93
94       this.setDefaultTime(this.defaultTime);
95     },
96
97     blurElement: function() {
98       this.highlightedUnit = undefined;
99       this.updateFromElementVal();
100     },
101
102     decrementHour: function() {
103       if (this.showMeridian) {
104         if (this.hour === 1) {
105           this.hour = 12;
106         } else if (this.hour === 12) {
107           this.hour--;
108
109           return this.toggleMeridian();
110         } else if (this.hour === 0) {
111           this.hour = 11;
112
113           return this.toggleMeridian();
114         } else {
115           this.hour--;
116         }
117       } else {
118         if (this.hour === 0) {
119           this.hour = 23;
120         } else {
121           this.hour--;
122         }
123       }
124       this.update();
125     },
126
127     decrementMinute: function(step) {
128       var newVal;
129
130       if (step) {
131         newVal = this.minute - step;
132       } else {
133         newVal = this.minute - this.minuteStep;
134       }
135
136       if (newVal < 0) {
137         this.decrementHour();
138         this.minute = newVal + 60;
139       } else {
140         this.minute = newVal;
141       }
142       this.update();
143     },
144
145     decrementSecond: function() {
146       var newVal = this.second - this.secondStep;
147
148       if (newVal < 0) {
149         this.decrementMinute(true);
150         this.second = newVal + 60;
151       } else {
152         this.second = newVal;
153       }
154       this.update();
155     },
156
157     elementKeydown: function(e) {
158       switch (e.keyCode) {
159       case 9: //tab
160         this.updateFromElementVal();
161
162         switch (this.highlightedUnit) {
163         case 'hour':
164           e.preventDefault();
165           this.highlightNextUnit();
166           break;
167         case 'minute':
168           if (this.showMeridian || this.showSeconds) {
169             e.preventDefault();
170             this.highlightNextUnit();
171           }
172           break;
173         case 'second':
174           if (this.showMeridian) {
175             e.preventDefault();
176             this.highlightNextUnit();
177           }
178           break;
179         }
180         break;
181       case 27: // escape
182         this.updateFromElementVal();
183         break;
184       case 37: // left arrow
185         e.preventDefault();
186         this.highlightPrevUnit();
187         this.updateFromElementVal();
188         break;
189       case 38: // up arrow
190         e.preventDefault();
191         switch (this.highlightedUnit) {
192         case 'hour':
193           this.incrementHour();
194           this.highlightHour();
195           break;
196         case 'minute':
197           this.incrementMinute();
198           this.highlightMinute();
199           break;
200         case 'second':
201           this.incrementSecond();
202           this.highlightSecond();
203           break;
204         case 'meridian':
205           this.toggleMeridian();
206           this.highlightMeridian();
207           break;
208         }
209         break;
210       case 39: // right arrow
211         e.preventDefault();
212         this.updateFromElementVal();
213         this.highlightNextUnit();
214         break;
215       case 40: // down arrow
216         e.preventDefault();
217         switch (this.highlightedUnit) {
218         case 'hour':
219           this.decrementHour();
220           this.highlightHour();
221           break;
222         case 'minute':
223           this.decrementMinute();
224           this.highlightMinute();
225           break;
226         case 'second':
227           this.decrementSecond();
228           this.highlightSecond();
229           break;
230         case 'meridian':
231           this.toggleMeridian();
232           this.highlightMeridian();
233           break;
234         }
235         break;
236       }
237     },
238
239     formatTime: function(hour, minute, second, meridian) {
240       hour = hour < 10 ? '0' + hour : hour;
241       minute = minute < 10 ? '0' + minute : minute;
242       second = second < 10 ? '0' + second : second;
243
244       return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : '');
245     },
246
247     getCursorPosition: function() {
248       var input = this.$element.get(0);
249
250       if ('selectionStart' in input) {// Standard-compliant browsers
251
252         return input.selectionStart;
253       } else if (document.selection) {// IE fix
254         input.focus();
255         var sel = document.selection.createRange(),
256           selLen = document.selection.createRange().text.length;
257
258         sel.moveStart('character', - input.value.length);
259
260         return sel.text.length - selLen;
261       }
262     },
263
264     getTemplate: function() {
265       var template,
266         hourTemplate,
267         minuteTemplate,
268         secondTemplate,
269         meridianTemplate,
270         templateContent;
271
272       if (this.showInputs) {
273         hourTemplate = '<input type="text" name="hour" class="bootstrap-timepicker-hour form-control" maxlength="2"/>';
274         minuteTemplate = '<input type="text" name="minute" class="bootstrap-timepicker-minute form-control" maxlength="2"/>';
275         secondTemplate = '<input type="text" name="second" class="bootstrap-timepicker-second form-control" maxlength="2"/>';
276         meridianTemplate = '<input type="text" name="meridian" class="bootstrap-timepicker-meridian form-control" maxlength="2"/>';
277       } else {
278         hourTemplate = '<span class="bootstrap-timepicker-hour"></span>';
279         minuteTemplate = '<span class="bootstrap-timepicker-minute"></span>';
280         secondTemplate = '<span class="bootstrap-timepicker-second"></span>';
281         meridianTemplate = '<span class="bootstrap-timepicker-meridian"></span>';
282       }
283
284       templateContent = '<table>'+
285          '<tr>'+
286            '<td><a href="#" data-action="incrementHour"><i class="' + this.upArrowStyle + '"></i></a></td>'+
287            '<td class="separator">&nbsp;</td>'+
288            '<td><a href="#" data-action="incrementMinute"><i class="' + this.upArrowStyle + '"></i></a></td>'+
289            (this.showSeconds ?
290              '<td class="separator">&nbsp;</td>'+
291              '<td><a href="#" data-action="incrementSecond"><i class="' + this.upArrowStyle + '"></i></a></td>'
292            : '') +
293            (this.showMeridian ?
294              '<td class="separator">&nbsp;</td>'+
295              '<td class="meridian-column"><a href="#" data-action="toggleMeridian"><i class="' + this.upArrowStyle + '"></i></a></td>'
296            : '') +
297          '</tr>'+
298          '<tr>'+
299            '<td>'+ hourTemplate +'</td> '+
300            '<td class="separator">:</td>'+
301            '<td>'+ minuteTemplate +'</td> '+
302            (this.showSeconds ?
303             '<td class="separator">:</td>'+
304             '<td>'+ secondTemplate +'</td>'
305            : '') +
306            (this.showMeridian ?
307             '<td class="separator">&nbsp;</td>'+
308             '<td>'+ meridianTemplate +'</td>'
309            : '') +
310          '</tr>'+
311          '<tr>'+
312            '<td><a href="#" data-action="decrementHour"><i class="' + this.downArrowStyle + '"></i></a></td>'+
313            '<td class="separator"></td>'+
314            '<td><a href="#" data-action="decrementMinute"><i class="' + this.downArrowStyle + '"></i></a></td>'+
315            (this.showSeconds ?
316             '<td class="separator">&nbsp;</td>'+
317             '<td><a href="#" data-action="decrementSecond"><i class="' + this.downArrowStyle + '"></i></a></td>'
318            : '') +
319            (this.showMeridian ?
320             '<td class="separator">&nbsp;</td>'+
321             '<td><a href="#" data-action="toggleMeridian"><i class="' + this.downArrowStyle + '"></i></a></td>'
322            : '') +
323          '</tr>'+
324        '</table>';
325
326       switch(this.template) {
327       case 'modal':
328         template = '<div class="bootstrap-timepicker-widget modal hide fade in" data-backdrop="'+ (this.modalBackdrop ? 'true' : 'false') +'">'+
329           '<div class="modal-header">'+
330             '<a href="#" class="close" data-dismiss="modal">×</a>'+
331             '<h3>Pick a Time</h3>'+
332           '</div>'+
333           '<div class="modal-content">'+
334             templateContent +
335           '</div>'+
336           '<div class="modal-footer">'+
337             '<a href="#" class="btn btn-primary" data-dismiss="modal">OK</a>'+
338           '</div>'+
339         '</div>';
340         break;
341       case 'dropdown':
342         template = '<div class="bootstrap-timepicker-widget dropdown-menu">'+ templateContent +'</div>';
343         break;
344       }
345
346       return template;
347     },
348
349     getTime: function() {
350       return this.formatTime(this.hour, this.minute, this.second, this.meridian);
351     },
352
353     hideWidget: function() {
354       if (this.isOpen === false) {
355         return;
356       }
357
358                         if (this.showInputs) {
359                                 this.updateFromWidgetInputs();
360                         }
361
362       this.$element.trigger({
363         'type': 'hide.timepicker',
364         'time': {
365           'value': this.getTime(),
366           'hours': this.hour,
367           'minutes': this.minute,
368           'seconds': this.second,
369           'meridian': this.meridian
370         }
371       });
372
373       if (this.template === 'modal' && this.$widget.modal) {
374         this.$widget.modal('hide');
375       } else {
376         this.$widget.removeClass('open');
377       }
378
379       $(document).off('mousedown.timepicker');
380
381       this.isOpen = false;
382     },
383
384     highlightUnit: function() {
385       this.position = this.getCursorPosition();
386       if (this.position >= 0 && this.position <= 2) {
387         this.highlightHour();
388       } else if (this.position >= 3 && this.position <= 5) {
389         this.highlightMinute();
390       } else if (this.position >= 6 && this.position <= 8) {
391         if (this.showSeconds) {
392           this.highlightSecond();
393         } else {
394           this.highlightMeridian();
395         }
396       } else if (this.position >= 9 && this.position <= 11) {
397         this.highlightMeridian();
398       }
399     },
400
401     highlightNextUnit: function() {
402       switch (this.highlightedUnit) {
403       case 'hour':
404         this.highlightMinute();
405         break;
406       case 'minute':
407         if (this.showSeconds) {
408           this.highlightSecond();
409         } else if (this.showMeridian){
410           this.highlightMeridian();
411         } else {
412           this.highlightHour();
413         }
414         break;
415       case 'second':
416         if (this.showMeridian) {
417           this.highlightMeridian();
418         } else {
419           this.highlightHour();
420         }
421         break;
422       case 'meridian':
423         this.highlightHour();
424         break;
425       }
426     },
427
428     highlightPrevUnit: function() {
429       switch (this.highlightedUnit) {
430       case 'hour':
431         this.highlightMeridian();
432         break;
433       case 'minute':
434         this.highlightHour();
435         break;
436       case 'second':
437         this.highlightMinute();
438         break;
439       case 'meridian':
440         if (this.showSeconds) {
441           this.highlightSecond();
442         } else {
443           this.highlightMinute();
444         }
445         break;
446       }
447     },
448
449     highlightHour: function() {
450       var $element = this.$element.get(0);
451
452       this.highlightedUnit = 'hour';
453
454                         if ($element.setSelectionRange) {
455                                 setTimeout(function() {
456                                         $element.setSelectionRange(0,2);
457                                 }, 0);
458                         }
459     },
460
461     highlightMinute: function() {
462       var $element = this.$element.get(0);
463
464       this.highlightedUnit = 'minute';
465
466                         if ($element.setSelectionRange) {
467                                 setTimeout(function() {
468                                         $element.setSelectionRange(3,5);
469                                 }, 0);
470                         }
471     },
472
473     highlightSecond: function() {
474       var $element = this.$element.get(0);
475
476       this.highlightedUnit = 'second';
477
478                         if ($element.setSelectionRange) {
479                                 setTimeout(function() {
480                                         $element.setSelectionRange(6,8);
481                                 }, 0);
482                         }
483     },
484
485     highlightMeridian: function() {
486       var $element = this.$element.get(0);
487
488       this.highlightedUnit = 'meridian';
489
490                         if ($element.setSelectionRange) {
491                                 if (this.showSeconds) {
492                                         setTimeout(function() {
493                                                 $element.setSelectionRange(9,11);
494                                         }, 0);
495                                 } else {
496                                         setTimeout(function() {
497                                                 $element.setSelectionRange(6,8);
498                                         }, 0);
499                                 }
500                         }
501     },
502
503     incrementHour: function() {
504       if (this.showMeridian) {
505         if (this.hour === 11) {
506           this.hour++;
507           return this.toggleMeridian();
508         } else if (this.hour === 12) {
509           this.hour = 0;
510         }
511       }
512       if (this.hour === 23) {
513         this.hour = 0;
514
515         return;
516       }
517       this.hour++;
518       this.update();
519     },
520
521     incrementMinute: function(step) {
522       var newVal;
523
524       if (step) {
525         newVal = this.minute + step;
526       } else {
527         newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep);
528       }
529
530       if (newVal > 59) {
531         this.incrementHour();
532         this.minute = newVal - 60;
533       } else {
534         this.minute = newVal;
535       }
536       this.update();
537     },
538
539     incrementSecond: function() {
540       var newVal = this.second + this.secondStep - (this.second % this.secondStep);
541
542       if (newVal > 59) {
543         this.incrementMinute(true);
544         this.second = newVal - 60;
545       } else {
546         this.second = newVal;
547       }
548       this.update();
549     },
550
551     remove: function() {
552       $('document').off('.timepicker');
553       if (this.$widget) {
554         this.$widget.remove();
555       }
556       delete this.$element.data().timepicker;
557     },
558
559     setDefaultTime: function(defaultTime){
560       if (!this.$element.val()) {
561         if (defaultTime === 'current') {
562           var dTime = new Date(),
563             hours = dTime.getHours(),
564             minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep,
565             seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep,
566             meridian = 'AM';
567
568           if (this.showMeridian) {
569             if (hours === 0) {
570               hours = 12;
571             } else if (hours >= 12) {
572               if (hours > 12) {
573                 hours = hours - 12;
574               }
575               meridian = 'PM';
576             } else {
577               meridian = 'AM';
578             }
579           }
580
581           this.hour = hours;
582           this.minute = minutes;
583           this.second = seconds;
584           this.meridian = meridian;
585
586           this.update();
587
588         } else if (defaultTime === false) {
589           this.hour = 0;
590           this.minute = 0;
591           this.second = 0;
592           this.meridian = 'AM';
593         } else {
594           this.setTime(defaultTime);
595         }
596       } else {
597         this.updateFromElementVal();
598       }
599     },
600
601     setTime: function(time) {
602       var arr,
603         timeArray;
604
605       if (this.showMeridian) {
606         arr = time.split(' ');
607         timeArray = arr[0].split(':');
608         this.meridian = arr[1];
609       } else {
610         timeArray = time.split(':');
611       }
612
613       this.hour = parseInt(timeArray[0], 10);
614       this.minute = parseInt(timeArray[1], 10);
615       this.second = parseInt(timeArray[2], 10);
616
617       if (isNaN(this.hour)) {
618         this.hour = 0;
619       }
620       if (isNaN(this.minute)) {
621         this.minute = 0;
622       }
623
624       if (this.showMeridian) {
625         if (this.hour > 12) {
626           this.hour = 12;
627         } else if (this.hour < 1) {
628           this.hour = 12;
629         }
630
631         if (this.meridian === 'am' || this.meridian === 'a') {
632           this.meridian = 'AM';
633         } else if (this.meridian === 'pm' || this.meridian === 'p') {
634           this.meridian = 'PM';
635         }
636
637         if (this.meridian !== 'AM' && this.meridian !== 'PM') {
638           this.meridian = 'AM';
639         }
640       } else {
641         if (this.hour >= 24) {
642           this.hour = 23;
643         } else if (this.hour < 0) {
644           this.hour = 0;
645         }
646       }
647
648       if (this.minute < 0) {
649         this.minute = 0;
650       } else if (this.minute >= 60) {
651         this.minute = 59;
652       }
653
654       if (this.showSeconds) {
655         if (isNaN(this.second)) {
656           this.second = 0;
657         } else if (this.second < 0) {
658           this.second = 0;
659         } else if (this.second >= 60) {
660           this.second = 59;
661         }
662       }
663
664       this.update();
665     },
666
667     showWidget: function() {
668       if (this.isOpen) {
669         return;
670       }
671
672       if (this.$element.is(':disabled')) {
673         return;
674       }
675
676       var self = this;
677       $(document).on('mousedown.timepicker', function (e) {
678         // Clicked outside the timepicker, hide it
679         if ($(e.target).closest('.bootstrap-timepicker-widget').length === 0) {
680           self.hideWidget();
681         }
682       });
683
684       this.$element.trigger({
685         'type': 'show.timepicker',
686         'time': {
687           'value': this.getTime(),
688           'hours': this.hour,
689           'minutes': this.minute,
690           'seconds': this.second,
691           'meridian': this.meridian
692         }
693       });
694
695       if (this.disableFocus) {
696         this.$element.blur();
697       }
698
699       this.updateFromElementVal();
700
701       if (this.template === 'modal' && this.$widget.modal) {
702         this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this));
703       } else {
704         if (this.isOpen === false) {
705           this.$widget.addClass('open');
706         }
707       }
708
709       this.isOpen = true;
710     },
711
712     toggleMeridian: function() {
713       this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
714       this.update();
715     },
716
717     update: function() {
718       this.$element.trigger({
719         'type': 'changeTime.timepicker',
720         'time': {
721           'value': this.getTime(),
722           'hours': this.hour,
723           'minutes': this.minute,
724           'seconds': this.second,
725           'meridian': this.meridian
726         }
727       });
728
729       this.updateElement();
730       this.updateWidget();
731     },
732
733     updateElement: function() {
734       this.$element.val(this.getTime()).change();
735     },
736
737     updateFromElementVal: function() {
738                         var val = this.$element.val();
739
740                         if (val) {
741                                 this.setTime(val);
742                         }
743     },
744
745     updateWidget: function() {
746       if (this.$widget === false) {
747         return;
748       }
749
750       var hour = this.hour < 10 ? '0' + this.hour : this.hour,
751           minute = this.minute < 10 ? '0' + this.minute : this.minute,
752           second = this.second < 10 ? '0' + this.second : this.second;
753
754       if (this.showInputs) {
755         this.$widget.find('input.bootstrap-timepicker-hour').val(hour);
756         this.$widget.find('input.bootstrap-timepicker-minute').val(minute);
757
758         if (this.showSeconds) {
759           this.$widget.find('input.bootstrap-timepicker-second').val(second);
760         }
761         if (this.showMeridian) {
762           this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian);
763         }
764       } else {
765         this.$widget.find('span.bootstrap-timepicker-hour').text(hour);
766         this.$widget.find('span.bootstrap-timepicker-minute').text(minute);
767
768         if (this.showSeconds) {
769           this.$widget.find('span.bootstrap-timepicker-second').text(second);
770         }
771         if (this.showMeridian) {
772           this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian);
773         }
774       }
775     },
776
777     updateFromWidgetInputs: function() {
778       if (this.$widget === false) {
779         return;
780       }
781       var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' +
782         $('input.bootstrap-timepicker-minute', this.$widget).val() +
783         (this.showSeconds ? ':' + $('input.bootstrap-timepicker-second', this.$widget).val() : '') +
784         (this.showMeridian ? ' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val() : '');
785
786       this.setTime(time);
787     },
788
789     widgetClick: function(e) {
790       e.stopPropagation();
791       e.preventDefault();
792
793       var action = $(e.target).closest('a').data('action');
794       if (action) {
795         this[action]();
796       }
797     },
798
799     widgetKeydown: function(e) {
800       var $input = $(e.target).closest('input'),
801           name = $input.attr('name');
802
803       switch (e.keyCode) {
804       case 9: //tab
805         if (this.showMeridian) {
806           if (name === 'meridian') {
807             return this.hideWidget();
808           }
809         } else {
810           if (this.showSeconds) {
811             if (name === 'second') {
812               return this.hideWidget();
813             }
814           } else {
815             if (name === 'minute') {
816               return this.hideWidget();
817             }
818           }
819         }
820
821         this.updateFromWidgetInputs();
822         break;
823       case 27: // escape
824         this.hideWidget();
825         break;
826       case 38: // up arrow
827         e.preventDefault();
828         switch (name) {
829         case 'hour':
830           this.incrementHour();
831           break;
832         case 'minute':
833           this.incrementMinute();
834           break;
835         case 'second':
836           this.incrementSecond();
837           break;
838         case 'meridian':
839           this.toggleMeridian();
840           break;
841         }
842         break;
843       case 40: // down arrow
844         e.preventDefault();
845         switch (name) {
846         case 'hour':
847           this.decrementHour();
848           break;
849         case 'minute':
850           this.decrementMinute();
851           break;
852         case 'second':
853           this.decrementSecond();
854           break;
855         case 'meridian':
856           this.toggleMeridian();
857           break;
858         }
859         break;
860       }
861     }
862   };
863
864
865   //TIMEPICKER PLUGIN DEFINITION
866   $.fn.timepicker = function(option) {
867     var args = Array.apply(null, arguments);
868     args.shift();
869     return this.each(function() {
870       var $this = $(this),
871         data = $this.data('timepicker'),
872         options = typeof option === 'object' && option;
873
874       if (!data) {
875         $this.data('timepicker', (data = new Timepicker(this, $.extend({}, $.fn.timepicker.defaults, options, $(this).data()))));
876       }
877
878       if (typeof option === 'string') {
879         data[option].apply(data, args);
880       }
881     });
882   };
883
884   $.fn.timepicker.defaults = {
885     defaultTime: 'current',
886     disableFocus: false,
887     isOpen: false,
888     minuteStep: 15,
889     modalBackdrop: false,
890     secondStep: 15,
891     showSeconds: false,
892     showInputs: true,
893     showMeridian: true,
894     template: 'dropdown',
895     appendWidgetTo: '.bootstrap-timepicker',
896         upArrowStyle: 'glyphicon glyphicon-chevron-up',
897         downArrowStyle: 'glyphicon glyphicon-chevron-down',
898         containerClass: 'bootstrap-timepicker'
899   };
900
901   $.fn.timepicker.Constructor = Timepicker;
902
903 })(jQuery, window, document);