Issues (2687)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

html/template/install/dist/js/bootstrap.js (49 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
/*!
2
 * Bootstrap v3.2.0 (http://getbootstrap.com)
3
 * Copyright 2011-2014 Twitter, Inc.
4
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
 */
6
7
if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
8
9
/* ========================================================================
10
 * Bootstrap: transition.js v3.2.0
11
 * http://getbootstrap.com/javascript/#transitions
12
 * ========================================================================
13
 * Copyright 2011-2014 Twitter, Inc.
14
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15
 * ======================================================================== */
16
17
18
+function ($) {
19
  'use strict';
20
21
  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
22
  // ============================================================
23
24
  function transitionEnd() {
25
    var el = document.createElement('bootstrap')
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
26
27
    var transEndEventNames = {
28
      WebkitTransition : 'webkitTransitionEnd',
29
      MozTransition    : 'transitionend',
30
      OTransition      : 'oTransitionEnd otransitionend',
31
      transition       : 'transitionend'
32
    }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
33
34
    for (var name in transEndEventNames) {
35
      if (el.style[name] !== undefined) {
36
        return { end: transEndEventNames[name] }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
37
      }
38
    }
39
40
    return false // explicit for ie8 (  ._.)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
41
  }
42
43
  // http://blog.alexmaccaw.com/css-transitions
44
  $.fn.emulateTransitionEnd = function (duration) {
45
    var called = false
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
46
    var $el = this
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
47
    $(this).one('bsTransitionEnd', function () { called = true })
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
48
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
49
    setTimeout(callback, duration)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
50
    return this
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
51
  }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
52
53
  $(function () {
54
    $.support.transition = transitionEnd()
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
55
56
    if (!$.support.transition) return
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
57
58
    $.event.special.bsTransitionEnd = {
59
      bindType: $.support.transition.end,
60
      delegateType: $.support.transition.end,
61
      handle: function (e) {
62
        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
63
      }
64
    }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
65
  })
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
66
67
}(jQuery);
0 ignored issues
show
Did you forget to assign or call a function?

This error message can for example pop up if you forget to assign the result of a function call to a variable or pass it to another function:

function someFunction(x) {
    (x > 0) ? callFoo() : callBar();
}

// JSHint expects you to assign the result to a variable:
function someFunction(x) {
    var rs = (x > 0) ? callFoo() : callBar();
}

// If you do not use the result, you could also use if statements in the
// case above.
function someFunction(x) {
    if (x > 0) {
        callFoo();
    } else {
        callBar();
    }
}
Loading history...
68
69
/* ========================================================================
70
 * Bootstrap: alert.js v3.2.0
71
 * http://getbootstrap.com/javascript/#alerts
72
 * ========================================================================
73
 * Copyright 2011-2014 Twitter, Inc.
74
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
75
 * ======================================================================== */
76
77
78
+function ($) {
79
  'use strict';
80
81
  // ALERT CLASS DEFINITION
82
  // ======================
83
84
  var dismiss = '[data-dismiss="alert"]'
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
85
  var Alert   = function (el) {
86
    $(el).on('click', dismiss, this.close)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
87
  }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
88
89
  Alert.VERSION = '3.2.0'
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
90
91
  Alert.prototype.close = function (e) {
92
    var $this    = $(this)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
93
    var selector = $this.attr('data-target')
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
94
95
    if (!selector) {
96
      selector = $this.attr('href')
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
97
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
98
    }
99
100
    var $parent = $(selector)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
101
102
    if (e) e.preventDefault()
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
103
104
    if (!$parent.length) {
105
      $parent = $this.hasClass('alert') ? $this : $this.parent()
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
106
    }
107
108
    $parent.trigger(e = $.Event('close.bs.alert'))
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
109
110
    if (e.isDefaultPrevented()) return
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
111
112
    $parent.removeClass('in')
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
113
114
    function removeElement() {
115
      // detach from parent, fire event then clean up data
116
      $parent.detach().trigger('closed.bs.alert').remove()
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
117
    }
118
119
    $.support.transition && $parent.hasClass('fade') ?
120
      $parent
121
        .one('bsTransitionEnd', removeElement)
122
        .emulateTransitionEnd(150) :
123
      removeElement()
0 ignored issues
show
Did you forget to assign or call a function?

This error message can for example pop up if you forget to assign the result of a function call to a variable or pass it to another function:

function someFunction(x) {
    (x > 0) ? callFoo() : callBar();
}

// JSHint expects you to assign the result to a variable:
function someFunction(x) {
    var rs = (x > 0) ? callFoo() : callBar();
}

// If you do not use the result, you could also use if statements in the
// case above.
function someFunction(x) {
    if (x > 0) {
        callFoo();
    } else {
        callBar();
    }
}
Loading history...
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
124
  }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
125
126
127
  // ALERT PLUGIN DEFINITION
128
  // =======================
129
130
  function Plugin(option) {
131
    return this.each(function () {
132
      var $this = $(this)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
133
      var data  = $this.data('bs.alert')
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
134
135
      if (!data) $this.data('bs.alert', (data = new Alert(this)))
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
136
      if (typeof option == 'string') data[option].call($this)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
137
    })
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
138
  }
139
140
  var old = $.fn.alert
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
141
142
  $.fn.alert             = Plugin
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
143
  $.fn.alert.Constructor = Alert
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
144
145
146
  // ALERT NO CONFLICT
147
  // =================
148
149
  $.fn.alert.noConflict = function () {
150
    $.fn.alert = old
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
151
    return this
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
152
  }
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
153
154
155
  // ALERT DATA-API
156
  // ==============
157
158
  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
There were too many errors found in this file; checking aborted after 7%.

If JSHint finds too many errors in a file, it aborts checking altogether because it suspects a configuration issue.

Further Reading:

Loading history...
159
160
}(jQuery);
161
162
/* ========================================================================
163
 * Bootstrap: button.js v3.2.0
164
 * http://getbootstrap.com/javascript/#buttons
165
 * ========================================================================
166
 * Copyright 2011-2014 Twitter, Inc.
167
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
168
 * ======================================================================== */
169
170
171
+function ($) {
172
  'use strict';
173
174
  // BUTTON PUBLIC CLASS DEFINITION
175
  // ==============================
176
177
  var Button = function (element, options) {
178
    this.$element  = $(element)
179
    this.options   = $.extend({}, Button.DEFAULTS, options)
180
    this.isLoading = false
181
  }
182
183
  Button.VERSION  = '3.2.0'
184
185
  Button.DEFAULTS = {
186
    loadingText: 'loading...'
187
  }
188
189
  Button.prototype.setState = function (state) {
190
    var d    = 'disabled'
191
    var $el  = this.$element
192
    var val  = $el.is('input') ? 'val' : 'html'
193
    var data = $el.data()
194
195
    state = state + 'Text'
196
197
    if (data.resetText == null) $el.data('resetText', $el[val]())
198
199
    $el[val](data[state] == null ? this.options[state] : data[state])
200
201
    // push to event loop to allow forms to submit
202
    setTimeout($.proxy(function () {
203
      if (state == 'loadingText') {
204
        this.isLoading = true
205
        $el.addClass(d).attr(d, d)
206
      } else if (this.isLoading) {
207
        this.isLoading = false
208
        $el.removeClass(d).removeAttr(d)
209
      }
210
    }, this), 0)
211
  }
212
213
  Button.prototype.toggle = function () {
214
    var changed = true
215
    var $parent = this.$element.closest('[data-toggle="buttons"]')
216
217
    if ($parent.length) {
218
      var $input = this.$element.find('input')
219
      if ($input.prop('type') == 'radio') {
220
        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
221
        else $parent.find('.active').removeClass('active')
222
      }
223
      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
224
    }
225
226
    if (changed) this.$element.toggleClass('active')
227
  }
228
229
230
  // BUTTON PLUGIN DEFINITION
231
  // ========================
232
233
  function Plugin(option) {
234
    return this.each(function () {
235
      var $this   = $(this)
236
      var data    = $this.data('bs.button')
237
      var options = typeof option == 'object' && option
238
239
      if (!data) $this.data('bs.button', (data = new Button(this, options)))
240
241
      if (option == 'toggle') data.toggle()
242
      else if (option) data.setState(option)
243
    })
244
  }
245
246
  var old = $.fn.button
247
248
  $.fn.button             = Plugin
249
  $.fn.button.Constructor = Button
250
251
252
  // BUTTON NO CONFLICT
253
  // ==================
254
255
  $.fn.button.noConflict = function () {
256
    $.fn.button = old
257
    return this
258
  }
259
260
261
  // BUTTON DATA-API
262
  // ===============
263
264
  $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
265
    var $btn = $(e.target)
266
    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
267
    Plugin.call($btn, 'toggle')
268
    e.preventDefault()
269
  })
270
271
}(jQuery);
272
273
/* ========================================================================
274
 * Bootstrap: carousel.js v3.2.0
275
 * http://getbootstrap.com/javascript/#carousel
276
 * ========================================================================
277
 * Copyright 2011-2014 Twitter, Inc.
278
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
279
 * ======================================================================== */
280
281
282
+function ($) {
283
  'use strict';
284
285
  // CAROUSEL CLASS DEFINITION
286
  // =========================
287
288
  var Carousel = function (element, options) {
289
    this.$element    = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
290
    this.$indicators = this.$element.find('.carousel-indicators')
291
    this.options     = options
292
    this.paused      =
293
    this.sliding     =
294
    this.interval    =
295
    this.$active     =
296
    this.$items      = null
297
298
    this.options.pause == 'hover' && this.$element
299
      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
300
      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
301
  }
302
303
  Carousel.VERSION  = '3.2.0'
304
305
  Carousel.DEFAULTS = {
306
    interval: 5000,
307
    pause: 'hover',
308
    wrap: true
309
  }
310
311
  Carousel.prototype.keydown = function (e) {
312
    switch (e.which) {
313
      case 37: this.prev(); break
314
      case 39: this.next(); break
315
      default: return
316
    }
317
318
    e.preventDefault()
319
  }
320
321
  Carousel.prototype.cycle = function (e) {
322
    e || (this.paused = false)
323
324
    this.interval && clearInterval(this.interval)
325
326
    this.options.interval
327
      && !this.paused
328
      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
329
330
    return this
331
  }
332
333
  Carousel.prototype.getItemIndex = function (item) {
334
    this.$items = item.parent().children('.item')
335
    return this.$items.index(item || this.$active)
336
  }
337
338
  Carousel.prototype.to = function (pos) {
339
    var that        = this
340
    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
341
342
    if (pos > (this.$items.length - 1) || pos < 0) return
343
344
    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
345
    if (activeIndex == pos) return this.pause().cycle()
346
347
    return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
348
  }
349
350
  Carousel.prototype.pause = function (e) {
351
    e || (this.paused = true)
352
353
    if (this.$element.find('.next, .prev').length && $.support.transition) {
354
      this.$element.trigger($.support.transition.end)
355
      this.cycle(true)
356
    }
357
358
    this.interval = clearInterval(this.interval)
359
360
    return this
361
  }
362
363
  Carousel.prototype.next = function () {
364
    if (this.sliding) return
365
    return this.slide('next')
366
  }
367
368
  Carousel.prototype.prev = function () {
369
    if (this.sliding) return
370
    return this.slide('prev')
371
  }
372
373
  Carousel.prototype.slide = function (type, next) {
374
    var $active   = this.$element.find('.item.active')
375
    var $next     = next || $active[type]()
376
    var isCycling = this.interval
377
    var direction = type == 'next' ? 'left' : 'right'
378
    var fallback  = type == 'next' ? 'first' : 'last'
379
    var that      = this
380
381
    if (!$next.length) {
382
      if (!this.options.wrap) return
383
      $next = this.$element.find('.item')[fallback]()
384
    }
385
386
    if ($next.hasClass('active')) return (this.sliding = false)
387
388
    var relatedTarget = $next[0]
389
    var slideEvent = $.Event('slide.bs.carousel', {
390
      relatedTarget: relatedTarget,
391
      direction: direction
392
    })
393
    this.$element.trigger(slideEvent)
394
    if (slideEvent.isDefaultPrevented()) return
395
396
    this.sliding = true
397
398
    isCycling && this.pause()
399
400
    if (this.$indicators.length) {
401
      this.$indicators.find('.active').removeClass('active')
402
      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
403
      $nextIndicator && $nextIndicator.addClass('active')
404
    }
405
406
    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
407
    if ($.support.transition && this.$element.hasClass('slide')) {
408
      $next.addClass(type)
409
      $next[0].offsetWidth // force reflow
410
      $active.addClass(direction)
411
      $next.addClass(direction)
412
      $active
413
        .one('bsTransitionEnd', function () {
414
          $next.removeClass([type, direction].join(' ')).addClass('active')
415
          $active.removeClass(['active', direction].join(' '))
416
          that.sliding = false
417
          setTimeout(function () {
418
            that.$element.trigger(slidEvent)
419
          }, 0)
420
        })
421
        .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
422
    } else {
423
      $active.removeClass('active')
424
      $next.addClass('active')
425
      this.sliding = false
426
      this.$element.trigger(slidEvent)
427
    }
428
429
    isCycling && this.cycle()
430
431
    return this
432
  }
433
434
435
  // CAROUSEL PLUGIN DEFINITION
436
  // ==========================
437
438
  function Plugin(option) {
439
    return this.each(function () {
440
      var $this   = $(this)
441
      var data    = $this.data('bs.carousel')
442
      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
443
      var action  = typeof option == 'string' ? option : options.slide
444
445
      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
446
      if (typeof option == 'number') data.to(option)
447
      else if (action) data[action]()
448
      else if (options.interval) data.pause().cycle()
449
    })
450
  }
451
452
  var old = $.fn.carousel
453
454
  $.fn.carousel             = Plugin
455
  $.fn.carousel.Constructor = Carousel
456
457
458
  // CAROUSEL NO CONFLICT
459
  // ====================
460
461
  $.fn.carousel.noConflict = function () {
462
    $.fn.carousel = old
463
    return this
464
  }
465
466
467
  // CAROUSEL DATA-API
468
  // =================
469
470
  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
471
    var href
472
    var $this   = $(this)
473
    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
474
    if (!$target.hasClass('carousel')) return
475
    var options = $.extend({}, $target.data(), $this.data())
476
    var slideIndex = $this.attr('data-slide-to')
477
    if (slideIndex) options.interval = false
478
479
    Plugin.call($target, options)
480
481
    if (slideIndex) {
482
      $target.data('bs.carousel').to(slideIndex)
483
    }
484
485
    e.preventDefault()
486
  })
487
488
  $(window).on('load', function () {
489
    $('[data-ride="carousel"]').each(function () {
490
      var $carousel = $(this)
491
      Plugin.call($carousel, $carousel.data())
492
    })
493
  })
494
495
}(jQuery);
496
497
/* ========================================================================
498
 * Bootstrap: collapse.js v3.2.0
499
 * http://getbootstrap.com/javascript/#collapse
500
 * ========================================================================
501
 * Copyright 2011-2014 Twitter, Inc.
502
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
503
 * ======================================================================== */
504
505
506
+function ($) {
507
  'use strict';
508
509
  // COLLAPSE PUBLIC CLASS DEFINITION
510
  // ================================
511
512
  var Collapse = function (element, options) {
513
    this.$element      = $(element)
514
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
515
    this.transitioning = null
516
517
    if (this.options.parent) this.$parent = $(this.options.parent)
518
    if (this.options.toggle) this.toggle()
519
  }
520
521
  Collapse.VERSION  = '3.2.0'
522
523
  Collapse.DEFAULTS = {
524
    toggle: true
525
  }
526
527
  Collapse.prototype.dimension = function () {
528
    var hasWidth = this.$element.hasClass('width')
529
    return hasWidth ? 'width' : 'height'
530
  }
531
532
  Collapse.prototype.show = function () {
533
    if (this.transitioning || this.$element.hasClass('in')) return
534
535
    var startEvent = $.Event('show.bs.collapse')
536
    this.$element.trigger(startEvent)
537
    if (startEvent.isDefaultPrevented()) return
538
539
    var actives = this.$parent && this.$parent.find('> .panel > .in')
540
541
    if (actives && actives.length) {
542
      var hasData = actives.data('bs.collapse')
543
      if (hasData && hasData.transitioning) return
544
      Plugin.call(actives, 'hide')
545
      hasData || actives.data('bs.collapse', null)
546
    }
547
548
    var dimension = this.dimension()
549
550
    this.$element
551
      .removeClass('collapse')
552
      .addClass('collapsing')[dimension](0)
553
554
    this.transitioning = 1
555
556
    var complete = function () {
557
      this.$element
558
        .removeClass('collapsing')
559
        .addClass('collapse in')[dimension]('')
560
      this.transitioning = 0
561
      this.$element
562
        .trigger('shown.bs.collapse')
563
    }
564
565
    if (!$.support.transition) return complete.call(this)
566
567
    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
568
569
    this.$element
570
      .one('bsTransitionEnd', $.proxy(complete, this))
571
      .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
572
  }
573
574
  Collapse.prototype.hide = function () {
575
    if (this.transitioning || !this.$element.hasClass('in')) return
576
577
    var startEvent = $.Event('hide.bs.collapse')
578
    this.$element.trigger(startEvent)
579
    if (startEvent.isDefaultPrevented()) return
580
581
    var dimension = this.dimension()
582
583
    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
584
585
    this.$element
586
      .addClass('collapsing')
587
      .removeClass('collapse')
588
      .removeClass('in')
589
590
    this.transitioning = 1
591
592
    var complete = function () {
593
      this.transitioning = 0
594
      this.$element
595
        .trigger('hidden.bs.collapse')
596
        .removeClass('collapsing')
597
        .addClass('collapse')
598
    }
599
600
    if (!$.support.transition) return complete.call(this)
601
602
    this.$element
603
      [dimension](0)
604
      .one('bsTransitionEnd', $.proxy(complete, this))
605
      .emulateTransitionEnd(350)
606
  }
607
608
  Collapse.prototype.toggle = function () {
609
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
610
  }
611
612
613
  // COLLAPSE PLUGIN DEFINITION
614
  // ==========================
615
616
  function Plugin(option) {
617
    return this.each(function () {
618
      var $this   = $(this)
619
      var data    = $this.data('bs.collapse')
620
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
621
622
      if (!data && options.toggle && option == 'show') option = !option
623
      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
624
      if (typeof option == 'string') data[option]()
625
    })
626
  }
627
628
  var old = $.fn.collapse
629
630
  $.fn.collapse             = Plugin
631
  $.fn.collapse.Constructor = Collapse
632
633
634
  // COLLAPSE NO CONFLICT
635
  // ====================
636
637
  $.fn.collapse.noConflict = function () {
638
    $.fn.collapse = old
639
    return this
640
  }
641
642
643
  // COLLAPSE DATA-API
644
  // =================
645
646
  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
647
    var href
648
    var $this   = $(this)
649
    var target  = $this.attr('data-target')
650
        || e.preventDefault()
651
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
652
    var $target = $(target)
653
    var data    = $target.data('bs.collapse')
654
    var option  = data ? 'toggle' : $this.data()
655
    var parent  = $this.attr('data-parent')
656
    var $parent = parent && $(parent)
657
658
    if (!data || !data.transitioning) {
659
      if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
660
      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
661
    }
662
663
    Plugin.call($target, option)
664
  })
665
666
}(jQuery);
667
668
/* ========================================================================
669
 * Bootstrap: dropdown.js v3.2.0
670
 * http://getbootstrap.com/javascript/#dropdowns
671
 * ========================================================================
672
 * Copyright 2011-2014 Twitter, Inc.
673
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
674
 * ======================================================================== */
675
676
677
+function ($) {
678
  'use strict';
679
680
  // DROPDOWN CLASS DEFINITION
681
  // =========================
682
683
  var backdrop = '.dropdown-backdrop'
684
  var toggle   = '[data-toggle="dropdown"]'
685
  var Dropdown = function (element) {
686
    $(element).on('click.bs.dropdown', this.toggle)
687
  }
688
689
  Dropdown.VERSION = '3.2.0'
690
691
  Dropdown.prototype.toggle = function (e) {
692
    var $this = $(this)
693
694
    if ($this.is('.disabled, :disabled')) return
695
696
    var $parent  = getParent($this)
697
    var isActive = $parent.hasClass('open')
698
699
    clearMenus()
700
701
    if (!isActive) {
702
      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
703
        // if mobile we use a backdrop because click events don't delegate
704
        $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
705
      }
706
707
      var relatedTarget = { relatedTarget: this }
708
      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
709
710
      if (e.isDefaultPrevented()) return
711
712
      $this.trigger('focus')
713
714
      $parent
715
        .toggleClass('open')
716
        .trigger('shown.bs.dropdown', relatedTarget)
717
    }
718
719
    return false
720
  }
721
722
  Dropdown.prototype.keydown = function (e) {
723
    if (!/(38|40|27)/.test(e.keyCode)) return
724
725
    var $this = $(this)
726
727
    e.preventDefault()
728
    e.stopPropagation()
729
730
    if ($this.is('.disabled, :disabled')) return
731
732
    var $parent  = getParent($this)
733
    var isActive = $parent.hasClass('open')
734
735
    if (!isActive || (isActive && e.keyCode == 27)) {
736
      if (e.which == 27) $parent.find(toggle).trigger('focus')
737
      return $this.trigger('click')
738
    }
739
740
    var desc = ' li:not(.divider):visible a'
741
    var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
742
743
    if (!$items.length) return
744
745
    var index = $items.index($items.filter(':focus'))
746
747
    if (e.keyCode == 38 && index > 0)                 index--                        // up
748
    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
749
    if (!~index)                                      index = 0
750
751
    $items.eq(index).trigger('focus')
752
  }
753
754
  function clearMenus(e) {
755
    if (e && e.which === 3) return
756
    $(backdrop).remove()
757
    $(toggle).each(function () {
758
      var $parent = getParent($(this))
759
      var relatedTarget = { relatedTarget: this }
760
      if (!$parent.hasClass('open')) return
761
      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
762
      if (e.isDefaultPrevented()) return
763
      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
764
    })
765
  }
766
767
  function getParent($this) {
768
    var selector = $this.attr('data-target')
769
770
    if (!selector) {
771
      selector = $this.attr('href')
772
      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
773
    }
774
775
    var $parent = selector && $(selector)
776
777
    return $parent && $parent.length ? $parent : $this.parent()
778
  }
779
780
781
  // DROPDOWN PLUGIN DEFINITION
782
  // ==========================
783
784
  function Plugin(option) {
785
    return this.each(function () {
786
      var $this = $(this)
787
      var data  = $this.data('bs.dropdown')
788
789
      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
790
      if (typeof option == 'string') data[option].call($this)
791
    })
792
  }
793
794
  var old = $.fn.dropdown
795
796
  $.fn.dropdown             = Plugin
797
  $.fn.dropdown.Constructor = Dropdown
798
799
800
  // DROPDOWN NO CONFLICT
801
  // ====================
802
803
  $.fn.dropdown.noConflict = function () {
804
    $.fn.dropdown = old
805
    return this
806
  }
807
808
809
  // APPLY TO STANDARD DROPDOWN ELEMENTS
810
  // ===================================
811
812
  $(document)
813
    .on('click.bs.dropdown.data-api', clearMenus)
814
    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
815
    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
816
    .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
817
818
}(jQuery);
819
820
/* ========================================================================
821
 * Bootstrap: modal.js v3.2.0
822
 * http://getbootstrap.com/javascript/#modals
823
 * ========================================================================
824
 * Copyright 2011-2014 Twitter, Inc.
825
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
826
 * ======================================================================== */
827
828
829
+function ($) {
830
  'use strict';
831
832
  // MODAL CLASS DEFINITION
833
  // ======================
834
835
  var Modal = function (element, options) {
836
    this.options        = options
837
    this.$body          = $(document.body)
838
    this.$element       = $(element)
839
    this.$backdrop      =
840
    this.isShown        = null
841
    this.scrollbarWidth = 0
842
843
    if (this.options.remote) {
844
      this.$element
845
        .find('.modal-content')
846
        .load(this.options.remote, $.proxy(function () {
847
          this.$element.trigger('loaded.bs.modal')
848
        }, this))
849
    }
850
  }
851
852
  Modal.VERSION  = '3.2.0'
853
854
  Modal.DEFAULTS = {
855
    backdrop: true,
856
    keyboard: true,
857
    show: true
858
  }
859
860
  Modal.prototype.toggle = function (_relatedTarget) {
861
    return this.isShown ? this.hide() : this.show(_relatedTarget)
862
  }
863
864
  Modal.prototype.show = function (_relatedTarget) {
865
    var that = this
866
    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
867
868
    this.$element.trigger(e)
869
870
    if (this.isShown || e.isDefaultPrevented()) return
871
872
    this.isShown = true
873
874
    this.checkScrollbar()
875
    this.$body.addClass('modal-open')
876
877
    this.setScrollbar()
878
    this.escape()
879
880
    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
881
882
    this.backdrop(function () {
883
      var transition = $.support.transition && that.$element.hasClass('fade')
884
885
      if (!that.$element.parent().length) {
886
        that.$element.appendTo(that.$body) // don't move modals dom position
887
      }
888
889
      that.$element
890
        .show()
891
        .scrollTop(0)
892
893
      if (transition) {
894
        that.$element[0].offsetWidth // force reflow
895
      }
896
897
      that.$element
898
        .addClass('in')
899
        .attr('aria-hidden', false)
900
901
      that.enforceFocus()
902
903
      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
904
905
      transition ?
906
        that.$element.find('.modal-dialog') // wait for modal to slide in
907
          .one('bsTransitionEnd', function () {
908
            that.$element.trigger('focus').trigger(e)
909
          })
910
          .emulateTransitionEnd(300) :
911
        that.$element.trigger('focus').trigger(e)
912
    })
913
  }
914
915
  Modal.prototype.hide = function (e) {
916
    if (e) e.preventDefault()
917
918
    e = $.Event('hide.bs.modal')
919
920
    this.$element.trigger(e)
921
922
    if (!this.isShown || e.isDefaultPrevented()) return
923
924
    this.isShown = false
925
926
    this.$body.removeClass('modal-open')
927
928
    this.resetScrollbar()
929
    this.escape()
930
931
    $(document).off('focusin.bs.modal')
932
933
    this.$element
934
      .removeClass('in')
935
      .attr('aria-hidden', true)
936
      .off('click.dismiss.bs.modal')
937
938
    $.support.transition && this.$element.hasClass('fade') ?
939
      this.$element
940
        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
941
        .emulateTransitionEnd(300) :
942
      this.hideModal()
943
  }
944
945
  Modal.prototype.enforceFocus = function () {
946
    $(document)
947
      .off('focusin.bs.modal') // guard against infinite focus loop
948
      .on('focusin.bs.modal', $.proxy(function (e) {
949
        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
950
          this.$element.trigger('focus')
951
        }
952
      }, this))
953
  }
954
955
  Modal.prototype.escape = function () {
956
    if (this.isShown && this.options.keyboard) {
957
      this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
958
        e.which == 27 && this.hide()
959
      }, this))
960
    } else if (!this.isShown) {
961
      this.$element.off('keyup.dismiss.bs.modal')
962
    }
963
  }
964
965
  Modal.prototype.hideModal = function () {
966
    var that = this
967
    this.$element.hide()
968
    this.backdrop(function () {
969
      that.$element.trigger('hidden.bs.modal')
970
    })
971
  }
972
973
  Modal.prototype.removeBackdrop = function () {
974
    this.$backdrop && this.$backdrop.remove()
975
    this.$backdrop = null
976
  }
977
978
  Modal.prototype.backdrop = function (callback) {
979
    var that = this
980
    var animate = this.$element.hasClass('fade') ? 'fade' : ''
981
982
    if (this.isShown && this.options.backdrop) {
983
      var doAnimate = $.support.transition && animate
984
985
      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
986
        .appendTo(this.$body)
987
988
      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
989
        if (e.target !== e.currentTarget) return
990
        this.options.backdrop == 'static'
991
          ? this.$element[0].focus.call(this.$element[0])
992
          : this.hide.call(this)
993
      }, this))
994
995
      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
996
997
      this.$backdrop.addClass('in')
998
999
      if (!callback) return
1000
1001
      doAnimate ?
1002
        this.$backdrop
1003
          .one('bsTransitionEnd', callback)
1004
          .emulateTransitionEnd(150) :
1005
        callback()
1006
1007
    } else if (!this.isShown && this.$backdrop) {
1008
      this.$backdrop.removeClass('in')
1009
1010
      var callbackRemove = function () {
1011
        that.removeBackdrop()
1012
        callback && callback()
1013
      }
1014
      $.support.transition && this.$element.hasClass('fade') ?
1015
        this.$backdrop
1016
          .one('bsTransitionEnd', callbackRemove)
1017
          .emulateTransitionEnd(150) :
1018
        callbackRemove()
1019
1020
    } else if (callback) {
1021
      callback()
1022
    }
1023
  }
1024
1025
  Modal.prototype.checkScrollbar = function () {
1026
    if (document.body.clientWidth >= window.innerWidth) return
1027
    this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
1028
  }
1029
1030
  Modal.prototype.setScrollbar = function () {
1031
    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
1032
    if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
1033
  }
1034
1035
  Modal.prototype.resetScrollbar = function () {
1036
    this.$body.css('padding-right', '')
1037
  }
1038
1039
  Modal.prototype.measureScrollbar = function () { // thx walsh
1040
    var scrollDiv = document.createElement('div')
1041
    scrollDiv.className = 'modal-scrollbar-measure'
1042
    this.$body.append(scrollDiv)
1043
    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
1044
    this.$body[0].removeChild(scrollDiv)
1045
    return scrollbarWidth
1046
  }
1047
1048
1049
  // MODAL PLUGIN DEFINITION
1050
  // =======================
1051
1052
  function Plugin(option, _relatedTarget) {
1053
    return this.each(function () {
1054
      var $this   = $(this)
1055
      var data    = $this.data('bs.modal')
1056
      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
1057
1058
      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
1059
      if (typeof option == 'string') data[option](_relatedTarget)
1060
      else if (options.show) data.show(_relatedTarget)
1061
    })
1062
  }
1063
1064
  var old = $.fn.modal
1065
1066
  $.fn.modal             = Plugin
1067
  $.fn.modal.Constructor = Modal
1068
1069
1070
  // MODAL NO CONFLICT
1071
  // =================
1072
1073
  $.fn.modal.noConflict = function () {
1074
    $.fn.modal = old
1075
    return this
1076
  }
1077
1078
1079
  // MODAL DATA-API
1080
  // ==============
1081
1082
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
1083
    var $this   = $(this)
1084
    var href    = $this.attr('href')
1085
    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
1086
    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1087
1088
    if ($this.is('a')) e.preventDefault()
1089
1090
    $target.one('show.bs.modal', function (showEvent) {
1091
      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
1092
      $target.one('hidden.bs.modal', function () {
1093
        $this.is(':visible') && $this.trigger('focus')
1094
      })
1095
    })
1096
    Plugin.call($target, option, this)
1097
  })
1098
1099
}(jQuery);
1100
1101
/* ========================================================================
1102
 * Bootstrap: tooltip.js v3.2.0
1103
 * http://getbootstrap.com/javascript/#tooltip
1104
 * Inspired by the original jQuery.tipsy by Jason Frame
1105
 * ========================================================================
1106
 * Copyright 2011-2014 Twitter, Inc.
1107
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1108
 * ======================================================================== */
1109
1110
1111
+function ($) {
1112
  'use strict';
1113
1114
  // TOOLTIP PUBLIC CLASS DEFINITION
1115
  // ===============================
1116
1117
  var Tooltip = function (element, options) {
1118
    this.type       =
1119
    this.options    =
1120
    this.enabled    =
1121
    this.timeout    =
1122
    this.hoverState =
1123
    this.$element   = null
1124
1125
    this.init('tooltip', element, options)
1126
  }
1127
1128
  Tooltip.VERSION  = '3.2.0'
1129
1130
  Tooltip.DEFAULTS = {
1131
    animation: true,
1132
    placement: 'top',
1133
    selector: false,
1134
    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1135
    trigger: 'hover focus',
1136
    title: '',
1137
    delay: 0,
1138
    html: false,
1139
    container: false,
1140
    viewport: {
1141
      selector: 'body',
1142
      padding: 0
1143
    }
1144
  }
1145
1146
  Tooltip.prototype.init = function (type, element, options) {
1147
    this.enabled   = true
1148
    this.type      = type
1149
    this.$element  = $(element)
1150
    this.options   = this.getOptions(options)
1151
    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
1152
1153
    var triggers = this.options.trigger.split(' ')
1154
1155
    for (var i = triggers.length; i--;) {
1156
      var trigger = triggers[i]
1157
1158
      if (trigger == 'click') {
1159
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1160
      } else if (trigger != 'manual') {
1161
        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
1162
        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
1163
1164
        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1165
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
1166
      }
1167
    }
1168
1169
    this.options.selector ?
1170
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
1171
      this.fixTitle()
1172
  }
1173
1174
  Tooltip.prototype.getDefaults = function () {
1175
    return Tooltip.DEFAULTS
1176
  }
1177
1178
  Tooltip.prototype.getOptions = function (options) {
1179
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
1180
1181
    if (options.delay && typeof options.delay == 'number') {
1182
      options.delay = {
1183
        show: options.delay,
1184
        hide: options.delay
1185
      }
1186
    }
1187
1188
    return options
1189
  }
1190
1191
  Tooltip.prototype.getDelegateOptions = function () {
1192
    var options  = {}
1193
    var defaults = this.getDefaults()
1194
1195
    this._options && $.each(this._options, function (key, value) {
1196
      if (defaults[key] != value) options[key] = value
1197
    })
1198
1199
    return options
1200
  }
1201
1202
  Tooltip.prototype.enter = function (obj) {
1203
    var self = obj instanceof this.constructor ?
1204
      obj : $(obj.currentTarget).data('bs.' + this.type)
1205
1206
    if (!self) {
1207
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1208
      $(obj.currentTarget).data('bs.' + this.type, self)
1209
    }
1210
1211
    clearTimeout(self.timeout)
1212
1213
    self.hoverState = 'in'
1214
1215
    if (!self.options.delay || !self.options.delay.show) return self.show()
1216
1217
    self.timeout = setTimeout(function () {
1218
      if (self.hoverState == 'in') self.show()
1219
    }, self.options.delay.show)
1220
  }
1221
1222
  Tooltip.prototype.leave = function (obj) {
1223
    var self = obj instanceof this.constructor ?
1224
      obj : $(obj.currentTarget).data('bs.' + this.type)
1225
1226
    if (!self) {
1227
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1228
      $(obj.currentTarget).data('bs.' + this.type, self)
1229
    }
1230
1231
    clearTimeout(self.timeout)
1232
1233
    self.hoverState = 'out'
1234
1235
    if (!self.options.delay || !self.options.delay.hide) return self.hide()
1236
1237
    self.timeout = setTimeout(function () {
1238
      if (self.hoverState == 'out') self.hide()
1239
    }, self.options.delay.hide)
1240
  }
1241
1242
  Tooltip.prototype.show = function () {
1243
    var e = $.Event('show.bs.' + this.type)
1244
1245
    if (this.hasContent() && this.enabled) {
1246
      this.$element.trigger(e)
1247
1248
      var inDom = $.contains(document.documentElement, this.$element[0])
1249
      if (e.isDefaultPrevented() || !inDom) return
1250
      var that = this
1251
1252
      var $tip = this.tip()
1253
1254
      var tipId = this.getUID(this.type)
1255
1256
      this.setContent()
1257
      $tip.attr('id', tipId)
1258
      this.$element.attr('aria-describedby', tipId)
1259
1260
      if (this.options.animation) $tip.addClass('fade')
1261
1262
      var placement = typeof this.options.placement == 'function' ?
1263
        this.options.placement.call(this, $tip[0], this.$element[0]) :
1264
        this.options.placement
1265
1266
      var autoToken = /\s?auto?\s?/i
1267
      var autoPlace = autoToken.test(placement)
1268
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1269
1270
      $tip
1271
        .detach()
1272
        .css({ top: 0, left: 0, display: 'block' })
1273
        .addClass(placement)
1274
        .data('bs.' + this.type, this)
1275
1276
      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
1277
1278
      var pos          = this.getPosition()
1279
      var actualWidth  = $tip[0].offsetWidth
1280
      var actualHeight = $tip[0].offsetHeight
1281
1282
      if (autoPlace) {
1283
        var orgPlacement = placement
1284
        var $parent      = this.$element.parent()
1285
        var parentDim    = this.getPosition($parent)
1286
1287
        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
1288
                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < 0                                   ? 'bottom' :
1289
                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
1290
                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
1291
                    placement
1292
1293
        $tip
1294
          .removeClass(orgPlacement)
1295
          .addClass(placement)
1296
      }
1297
1298
      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1299
1300
      this.applyPlacement(calculatedOffset, placement)
1301
1302
      var complete = function () {
1303
        that.$element.trigger('shown.bs.' + that.type)
1304
        that.hoverState = null
1305
      }
1306
1307
      $.support.transition && this.$tip.hasClass('fade') ?
1308
        $tip
1309
          .one('bsTransitionEnd', complete)
1310
          .emulateTransitionEnd(150) :
1311
        complete()
1312
    }
1313
  }
1314
1315
  Tooltip.prototype.applyPlacement = function (offset, placement) {
1316
    var $tip   = this.tip()
1317
    var width  = $tip[0].offsetWidth
1318
    var height = $tip[0].offsetHeight
1319
1320
    // manually read margins because getBoundingClientRect includes difference
1321
    var marginTop = parseInt($tip.css('margin-top'), 10)
1322
    var marginLeft = parseInt($tip.css('margin-left'), 10)
1323
1324
    // we must check for NaN for ie 8/9
1325
    if (isNaN(marginTop))  marginTop  = 0
1326
    if (isNaN(marginLeft)) marginLeft = 0
1327
1328
    offset.top  = offset.top  + marginTop
1329
    offset.left = offset.left + marginLeft
1330
1331
    // $.fn.offset doesn't round pixel values
1332
    // so we use setOffset directly with our own function B-0
1333
    $.offset.setOffset($tip[0], $.extend({
1334
      using: function (props) {
1335
        $tip.css({
1336
          top: Math.round(props.top),
1337
          left: Math.round(props.left)
1338
        })
1339
      }
1340
    }, offset), 0)
1341
1342
    $tip.addClass('in')
1343
1344
    // check to see if placing tip in new offset caused the tip to resize itself
1345
    var actualWidth  = $tip[0].offsetWidth
1346
    var actualHeight = $tip[0].offsetHeight
1347
1348
    if (placement == 'top' && actualHeight != height) {
1349
      offset.top = offset.top + height - actualHeight
1350
    }
1351
1352
    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
1353
1354
    if (delta.left) offset.left += delta.left
1355
    else offset.top += delta.top
1356
1357
    var arrowDelta          = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
1358
    var arrowPosition       = delta.left ? 'left'        : 'top'
1359
    var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
1360
1361
    $tip.offset(offset)
1362
    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
1363
  }
1364
1365
  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
1366
    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
1367
  }
1368
1369
  Tooltip.prototype.setContent = function () {
1370
    var $tip  = this.tip()
1371
    var title = this.getTitle()
1372
1373
    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1374
    $tip.removeClass('fade in top bottom left right')
1375
  }
1376
1377
  Tooltip.prototype.hide = function () {
1378
    var that = this
1379
    var $tip = this.tip()
1380
    var e    = $.Event('hide.bs.' + this.type)
1381
1382
    this.$element.removeAttr('aria-describedby')
1383
1384
    function complete() {
1385
      if (that.hoverState != 'in') $tip.detach()
1386
      that.$element.trigger('hidden.bs.' + that.type)
1387
    }
1388
1389
    this.$element.trigger(e)
1390
1391
    if (e.isDefaultPrevented()) return
1392
1393
    $tip.removeClass('in')
1394
1395
    $.support.transition && this.$tip.hasClass('fade') ?
1396
      $tip
1397
        .one('bsTransitionEnd', complete)
1398
        .emulateTransitionEnd(150) :
1399
      complete()
1400
1401
    this.hoverState = null
1402
1403
    return this
1404
  }
1405
1406
  Tooltip.prototype.fixTitle = function () {
1407
    var $e = this.$element
1408
    if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
1409
      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1410
    }
1411
  }
1412
1413
  Tooltip.prototype.hasContent = function () {
1414
    return this.getTitle()
1415
  }
1416
1417
  Tooltip.prototype.getPosition = function ($element) {
1418
    $element   = $element || this.$element
1419
    var el     = $element[0]
1420
    var isBody = el.tagName == 'BODY'
1421
    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
1422
      scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
1423
      width:  isBody ? $(window).width()  : $element.outerWidth(),
1424
      height: isBody ? $(window).height() : $element.outerHeight()
1425
    }, isBody ? { top: 0, left: 0 } : $element.offset())
1426
  }
1427
1428
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
1429
    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
1430
           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
1431
           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
1432
        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
1433
1434
  }
1435
1436
  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
1437
    var delta = { top: 0, left: 0 }
1438
    if (!this.$viewport) return delta
1439
1440
    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
1441
    var viewportDimensions = this.getPosition(this.$viewport)
1442
1443
    if (/right|left/.test(placement)) {
1444
      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
1445
      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
1446
      if (topEdgeOffset < viewportDimensions.top) { // top overflow
1447
        delta.top = viewportDimensions.top - topEdgeOffset
1448
      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
1449
        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
1450
      }
1451
    } else {
1452
      var leftEdgeOffset  = pos.left - viewportPadding
1453
      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
1454
      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
1455
        delta.left = viewportDimensions.left - leftEdgeOffset
1456
      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
1457
        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1458
      }
1459
    }
1460
1461
    return delta
1462
  }
1463
1464
  Tooltip.prototype.getTitle = function () {
1465
    var title
1466
    var $e = this.$element
1467
    var o  = this.options
1468
1469
    title = $e.attr('data-original-title')
1470
      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
1471
1472
    return title
1473
  }
1474
1475
  Tooltip.prototype.getUID = function (prefix) {
1476
    do prefix += ~~(Math.random() * 1000000)
1477
    while (document.getElementById(prefix))
1478
    return prefix
1479
  }
1480
1481
  Tooltip.prototype.tip = function () {
1482
    return (this.$tip = this.$tip || $(this.options.template))
1483
  }
1484
1485
  Tooltip.prototype.arrow = function () {
1486
    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
1487
  }
1488
1489
  Tooltip.prototype.validate = function () {
1490
    if (!this.$element[0].parentNode) {
1491
      this.hide()
1492
      this.$element = null
1493
      this.options  = null
1494
    }
1495
  }
1496
1497
  Tooltip.prototype.enable = function () {
1498
    this.enabled = true
1499
  }
1500
1501
  Tooltip.prototype.disable = function () {
1502
    this.enabled = false
1503
  }
1504
1505
  Tooltip.prototype.toggleEnabled = function () {
1506
    this.enabled = !this.enabled
1507
  }
1508
1509
  Tooltip.prototype.toggle = function (e) {
1510
    var self = this
1511
    if (e) {
1512
      self = $(e.currentTarget).data('bs.' + this.type)
1513
      if (!self) {
1514
        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
1515
        $(e.currentTarget).data('bs.' + this.type, self)
1516
      }
1517
    }
1518
1519
    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1520
  }
1521
1522
  Tooltip.prototype.destroy = function () {
1523
    clearTimeout(this.timeout)
1524
    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
1525
  }
1526
1527
1528
  // TOOLTIP PLUGIN DEFINITION
1529
  // =========================
1530
1531
  function Plugin(option) {
1532
    return this.each(function () {
1533
      var $this   = $(this)
1534
      var data    = $this.data('bs.tooltip')
1535
      var options = typeof option == 'object' && option
1536
1537
      if (!data && option == 'destroy') return
1538
      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
1539
      if (typeof option == 'string') data[option]()
1540
    })
1541
  }
1542
1543
  var old = $.fn.tooltip
1544
1545
  $.fn.tooltip             = Plugin
1546
  $.fn.tooltip.Constructor = Tooltip
1547
1548
1549
  // TOOLTIP NO CONFLICT
1550
  // ===================
1551
1552
  $.fn.tooltip.noConflict = function () {
1553
    $.fn.tooltip = old
1554
    return this
1555
  }
1556
1557
}(jQuery);
1558
1559
/* ========================================================================
1560
 * Bootstrap: popover.js v3.2.0
1561
 * http://getbootstrap.com/javascript/#popovers
1562
 * ========================================================================
1563
 * Copyright 2011-2014 Twitter, Inc.
1564
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1565
 * ======================================================================== */
1566
1567
1568
+function ($) {
1569
  'use strict';
1570
1571
  // POPOVER PUBLIC CLASS DEFINITION
1572
  // ===============================
1573
1574
  var Popover = function (element, options) {
1575
    this.init('popover', element, options)
1576
  }
1577
1578
  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1579
1580
  Popover.VERSION  = '3.2.0'
1581
1582
  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
1583
    placement: 'right',
1584
    trigger: 'click',
1585
    content: '',
1586
    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1587
  })
1588
1589
1590
  // NOTE: POPOVER EXTENDS tooltip.js
1591
  // ================================
1592
1593
  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
1594
1595
  Popover.prototype.constructor = Popover
1596
1597
  Popover.prototype.getDefaults = function () {
1598
    return Popover.DEFAULTS
1599
  }
1600
1601
  Popover.prototype.setContent = function () {
1602
    var $tip    = this.tip()
1603
    var title   = this.getTitle()
1604
    var content = this.getContent()
1605
1606
    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1607
    $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
1608
      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
1609
    ](content)
1610
1611
    $tip.removeClass('fade top bottom left right in')
1612
1613
    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1614
    // this manually by checking the contents.
1615
    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
1616
  }
1617
1618
  Popover.prototype.hasContent = function () {
1619
    return this.getTitle() || this.getContent()
1620
  }
1621
1622
  Popover.prototype.getContent = function () {
1623
    var $e = this.$element
1624
    var o  = this.options
1625
1626
    return $e.attr('data-content')
1627
      || (typeof o.content == 'function' ?
1628
            o.content.call($e[0]) :
1629
            o.content)
1630
  }
1631
1632
  Popover.prototype.arrow = function () {
1633
    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
1634
  }
1635
1636
  Popover.prototype.tip = function () {
1637
    if (!this.$tip) this.$tip = $(this.options.template)
1638
    return this.$tip
1639
  }
1640
1641
1642
  // POPOVER PLUGIN DEFINITION
1643
  // =========================
1644
1645
  function Plugin(option) {
1646
    return this.each(function () {
1647
      var $this   = $(this)
1648
      var data    = $this.data('bs.popover')
1649
      var options = typeof option == 'object' && option
1650
1651
      if (!data && option == 'destroy') return
1652
      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
1653
      if (typeof option == 'string') data[option]()
1654
    })
1655
  }
1656
1657
  var old = $.fn.popover
1658
1659
  $.fn.popover             = Plugin
1660
  $.fn.popover.Constructor = Popover
1661
1662
1663
  // POPOVER NO CONFLICT
1664
  // ===================
1665
1666
  $.fn.popover.noConflict = function () {
1667
    $.fn.popover = old
1668
    return this
1669
  }
1670
1671
}(jQuery);
1672
1673
/* ========================================================================
1674
 * Bootstrap: scrollspy.js v3.2.0
1675
 * http://getbootstrap.com/javascript/#scrollspy
1676
 * ========================================================================
1677
 * Copyright 2011-2014 Twitter, Inc.
1678
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1679
 * ======================================================================== */
1680
1681
1682
+function ($) {
1683
  'use strict';
1684
1685
  // SCROLLSPY CLASS DEFINITION
1686
  // ==========================
1687
1688
  function ScrollSpy(element, options) {
1689
    var process  = $.proxy(this.process, this)
1690
1691
    this.$body          = $('body')
1692
    this.$scrollElement = $(element).is('body') ? $(window) : $(element)
1693
    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
1694
    this.selector       = (this.options.target || '') + ' .nav li > a'
1695
    this.offsets        = []
1696
    this.targets        = []
1697
    this.activeTarget   = null
1698
    this.scrollHeight   = 0
1699
1700
    this.$scrollElement.on('scroll.bs.scrollspy', process)
1701
    this.refresh()
1702
    this.process()
1703
  }
1704
1705
  ScrollSpy.VERSION  = '3.2.0'
1706
1707
  ScrollSpy.DEFAULTS = {
1708
    offset: 10
1709
  }
1710
1711
  ScrollSpy.prototype.getScrollHeight = function () {
1712
    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
1713
  }
1714
1715
  ScrollSpy.prototype.refresh = function () {
1716
    var offsetMethod = 'offset'
1717
    var offsetBase   = 0
1718
1719
    if (!$.isWindow(this.$scrollElement[0])) {
1720
      offsetMethod = 'position'
1721
      offsetBase   = this.$scrollElement.scrollTop()
1722
    }
1723
1724
    this.offsets = []
1725
    this.targets = []
1726
    this.scrollHeight = this.getScrollHeight()
1727
1728
    var self     = this
1729
1730
    this.$body
1731
      .find(this.selector)
1732
      .map(function () {
1733
        var $el   = $(this)
1734
        var href  = $el.data('target') || $el.attr('href')
1735
        var $href = /^#./.test(href) && $(href)
1736
1737
        return ($href
1738
          && $href.length
1739
          && $href.is(':visible')
1740
          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
1741
      })
1742
      .sort(function (a, b) { return a[0] - b[0] })
1743
      .each(function () {
1744
        self.offsets.push(this[0])
1745
        self.targets.push(this[1])
1746
      })
1747
  }
1748
1749
  ScrollSpy.prototype.process = function () {
1750
    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
1751
    var scrollHeight = this.getScrollHeight()
1752
    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
1753
    var offsets      = this.offsets
1754
    var targets      = this.targets
1755
    var activeTarget = this.activeTarget
1756
    var i
1757
1758
    if (this.scrollHeight != scrollHeight) {
1759
      this.refresh()
1760
    }
1761
1762
    if (scrollTop >= maxScroll) {
1763
      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
1764
    }
1765
1766
    if (activeTarget && scrollTop <= offsets[0]) {
1767
      return activeTarget != (i = targets[0]) && this.activate(i)
1768
    }
1769
1770
    for (i = offsets.length; i--;) {
1771
      activeTarget != targets[i]
1772
        && scrollTop >= offsets[i]
1773
        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1774
        && this.activate(targets[i])
1775
    }
1776
  }
1777
1778
  ScrollSpy.prototype.activate = function (target) {
1779
    this.activeTarget = target
1780
1781
    $(this.selector)
1782
      .parentsUntil(this.options.target, '.active')
1783
      .removeClass('active')
1784
1785
    var selector = this.selector +
1786
        '[data-target="' + target + '"],' +
1787
        this.selector + '[href="' + target + '"]'
1788
1789
    var active = $(selector)
1790
      .parents('li')
1791
      .addClass('active')
1792
1793
    if (active.parent('.dropdown-menu').length) {
1794
      active = active
1795
        .closest('li.dropdown')
1796
        .addClass('active')
1797
    }
1798
1799
    active.trigger('activate.bs.scrollspy')
1800
  }
1801
1802
1803
  // SCROLLSPY PLUGIN DEFINITION
1804
  // ===========================
1805
1806
  function Plugin(option) {
1807
    return this.each(function () {
1808
      var $this   = $(this)
1809
      var data    = $this.data('bs.scrollspy')
1810
      var options = typeof option == 'object' && option
1811
1812
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
1813
      if (typeof option == 'string') data[option]()
1814
    })
1815
  }
1816
1817
  var old = $.fn.scrollspy
1818
1819
  $.fn.scrollspy             = Plugin
1820
  $.fn.scrollspy.Constructor = ScrollSpy
1821
1822
1823
  // SCROLLSPY NO CONFLICT
1824
  // =====================
1825
1826
  $.fn.scrollspy.noConflict = function () {
1827
    $.fn.scrollspy = old
1828
    return this
1829
  }
1830
1831
1832
  // SCROLLSPY DATA-API
1833
  // ==================
1834
1835
  $(window).on('load.bs.scrollspy.data-api', function () {
1836
    $('[data-spy="scroll"]').each(function () {
1837
      var $spy = $(this)
1838
      Plugin.call($spy, $spy.data())
1839
    })
1840
  })
1841
1842
}(jQuery);
1843
1844
/* ========================================================================
1845
 * Bootstrap: tab.js v3.2.0
1846
 * http://getbootstrap.com/javascript/#tabs
1847
 * ========================================================================
1848
 * Copyright 2011-2014 Twitter, Inc.
1849
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1850
 * ======================================================================== */
1851
1852
1853
+function ($) {
1854
  'use strict';
1855
1856
  // TAB CLASS DEFINITION
1857
  // ====================
1858
1859
  var Tab = function (element) {
1860
    this.element = $(element)
1861
  }
1862
1863
  Tab.VERSION = '3.2.0'
1864
1865
  Tab.prototype.show = function () {
1866
    var $this    = this.element
1867
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
1868
    var selector = $this.data('target')
1869
1870
    if (!selector) {
1871
      selector = $this.attr('href')
1872
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
1873
    }
1874
1875
    if ($this.parent('li').hasClass('active')) return
1876
1877
    var previous = $ul.find('.active:last a')[0]
1878
    var e        = $.Event('show.bs.tab', {
1879
      relatedTarget: previous
1880
    })
1881
1882
    $this.trigger(e)
1883
1884
    if (e.isDefaultPrevented()) return
1885
1886
    var $target = $(selector)
1887
1888
    this.activate($this.closest('li'), $ul)
1889
    this.activate($target, $target.parent(), function () {
1890
      $this.trigger({
1891
        type: 'shown.bs.tab',
1892
        relatedTarget: previous
1893
      })
1894
    })
1895
  }
1896
1897
  Tab.prototype.activate = function (element, container, callback) {
1898
    var $active    = container.find('> .active')
1899
    var transition = callback
1900
      && $.support.transition
1901
      && $active.hasClass('fade')
1902
1903
    function next() {
1904
      $active
1905
        .removeClass('active')
1906
        .find('> .dropdown-menu > .active')
1907
        .removeClass('active')
1908
1909
      element.addClass('active')
1910
1911
      if (transition) {
1912
        element[0].offsetWidth // reflow for transition
1913
        element.addClass('in')
1914
      } else {
1915
        element.removeClass('fade')
1916
      }
1917
1918
      if (element.parent('.dropdown-menu')) {
1919
        element.closest('li.dropdown').addClass('active')
1920
      }
1921
1922
      callback && callback()
1923
    }
1924
1925
    transition ?
1926
      $active
1927
        .one('bsTransitionEnd', next)
1928
        .emulateTransitionEnd(150) :
1929
      next()
1930
1931
    $active.removeClass('in')
1932
  }
1933
1934
1935
  // TAB PLUGIN DEFINITION
1936
  // =====================
1937
1938
  function Plugin(option) {
1939
    return this.each(function () {
1940
      var $this = $(this)
1941
      var data  = $this.data('bs.tab')
1942
1943
      if (!data) $this.data('bs.tab', (data = new Tab(this)))
1944
      if (typeof option == 'string') data[option]()
1945
    })
1946
  }
1947
1948
  var old = $.fn.tab
1949
1950
  $.fn.tab             = Plugin
1951
  $.fn.tab.Constructor = Tab
1952
1953
1954
  // TAB NO CONFLICT
1955
  // ===============
1956
1957
  $.fn.tab.noConflict = function () {
1958
    $.fn.tab = old
1959
    return this
1960
  }
1961
1962
1963
  // TAB DATA-API
1964
  // ============
1965
1966
  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1967
    e.preventDefault()
1968
    Plugin.call($(this), 'show')
1969
  })
1970
1971
}(jQuery);
1972
1973
/* ========================================================================
1974
 * Bootstrap: affix.js v3.2.0
1975
 * http://getbootstrap.com/javascript/#affix
1976
 * ========================================================================
1977
 * Copyright 2011-2014 Twitter, Inc.
1978
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1979
 * ======================================================================== */
1980
1981
1982
+function ($) {
1983
  'use strict';
1984
1985
  // AFFIX CLASS DEFINITION
1986
  // ======================
1987
1988
  var Affix = function (element, options) {
1989
    this.options = $.extend({}, Affix.DEFAULTS, options)
1990
1991
    this.$target = $(this.options.target)
1992
      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
1993
      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
1994
1995
    this.$element     = $(element)
1996
    this.affixed      =
1997
    this.unpin        =
1998
    this.pinnedOffset = null
1999
2000
    this.checkPosition()
2001
  }
2002
2003
  Affix.VERSION  = '3.2.0'
2004
2005
  Affix.RESET    = 'affix affix-top affix-bottom'
2006
2007
  Affix.DEFAULTS = {
2008
    offset: 0,
2009
    target: window
2010
  }
2011
2012
  Affix.prototype.getPinnedOffset = function () {
2013
    if (this.pinnedOffset) return this.pinnedOffset
2014
    this.$element.removeClass(Affix.RESET).addClass('affix')
2015
    var scrollTop = this.$target.scrollTop()
2016
    var position  = this.$element.offset()
2017
    return (this.pinnedOffset = position.top - scrollTop)
2018
  }
2019
2020
  Affix.prototype.checkPositionWithEventLoop = function () {
2021
    setTimeout($.proxy(this.checkPosition, this), 1)
2022
  }
2023
2024
  Affix.prototype.checkPosition = function () {
2025
    if (!this.$element.is(':visible')) return
2026
2027
    var scrollHeight = $(document).height()
2028
    var scrollTop    = this.$target.scrollTop()
2029
    var position     = this.$element.offset()
2030
    var offset       = this.options.offset
2031
    var offsetTop    = offset.top
2032
    var offsetBottom = offset.bottom
2033
2034
    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
2035
    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
2036
    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
2037
2038
    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :
2039
                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
2040
                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false
2041
2042
    if (this.affixed === affix) return
2043
    if (this.unpin != null) this.$element.css('top', '')
2044
2045
    var affixType = 'affix' + (affix ? '-' + affix : '')
2046
    var e         = $.Event(affixType + '.bs.affix')
2047
2048
    this.$element.trigger(e)
2049
2050
    if (e.isDefaultPrevented()) return
2051
2052
    this.affixed = affix
2053
    this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
2054
2055
    this.$element
2056
      .removeClass(Affix.RESET)
2057
      .addClass(affixType)
2058
      .trigger($.Event(affixType.replace('affix', 'affixed')))
2059
2060
    if (affix == 'bottom') {
2061
      this.$element.offset({
2062
        top: scrollHeight - this.$element.height() - offsetBottom
2063
      })
2064
    }
2065
  }
2066
2067
2068
  // AFFIX PLUGIN DEFINITION
2069
  // =======================
2070
2071
  function Plugin(option) {
2072
    return this.each(function () {
2073
      var $this   = $(this)
2074
      var data    = $this.data('bs.affix')
2075
      var options = typeof option == 'object' && option
2076
2077
      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
2078
      if (typeof option == 'string') data[option]()
2079
    })
2080
  }
2081
2082
  var old = $.fn.affix
2083
2084
  $.fn.affix             = Plugin
2085
  $.fn.affix.Constructor = Affix
2086
2087
2088
  // AFFIX NO CONFLICT
2089
  // =================
2090
2091
  $.fn.affix.noConflict = function () {
2092
    $.fn.affix = old
2093
    return this
2094
  }
2095
2096
2097
  // AFFIX DATA-API
2098
  // ==============
2099
2100
  $(window).on('load', function () {
2101
    $('[data-spy="affix"]').each(function () {
2102
      var $spy = $(this)
2103
      var data = $spy.data()
2104
2105
      data.offset = data.offset || {}
2106
2107
      if (data.offsetBottom) data.offset.bottom = data.offsetBottom
2108
      if (data.offsetTop)    data.offset.top    = data.offsetTop
2109
2110
      Plugin.call($spy, data)
2111
    })
2112
  })
2113
2114
}(jQuery);
2115