PageSourceSearch

https://edjoin.org/Scripts/plugins/bootstrapTimePicker/bootstrap-timepicker.js

js edjoin.org collected 2026-09-25 09:43:11 UTC 25,642 bytes, 883 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.