twitter-bootstrap-rails-cdn 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile ~/.gitignore_global
6
+
7
+ # Ignore bundler config
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+
13
+ # Ignore all logfiles and tempfiles.
14
+ /log/*.log
15
+ /tmp
16
+ /public/assets/
17
+ /config/secret_settings.yml
18
+
19
+ *.log
20
+ .DS_Store
21
+ .sass-cache/
22
+ *.bak
23
+ *~
24
+ *.swp
25
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 201 Nicholas Barthelemy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # twitter-bootstrap-rails-cdn
2
+
3
+ Twitter Boostrap CDN support for Rails 3 and 4
4
+
5
+ Serving Bootstrap from a publicly available [CDN](http://en.wikipedia.org/wiki/Content_Delivery_Network) has clear benefits:
6
+
7
+ * **Speed**: Users will be able to download Bootstrap from the closest physical location.
8
+ * **Caching**: CDN is used so widely that potentially your users may not need to download Bootstrap at all.
9
+ * **Parallelism**: Browsers have a limitation on how many connections can be made to a single host. Using CDN for Bootstrap offloads a big one.
10
+
11
+ ## Features
12
+
13
+ This gem offers the following features:
14
+
15
+ * Supports netdna CDN, but other CDNs could be added
16
+ * Bootstrap version is defaulted to the most recent version, but other versions can be specified.
17
+ * Automatically fallback to local copy of Bootstrap when:
18
+ * You're on a development environment, so that you can work offline.
19
+ * The CDN is down or unreachable.
20
+
21
+ On top of that, if you're using asset pipeline, you may have noticed that the major chunks of the code in combined `application.js` is Bootstrap. Implications of externalizing Bootstrap from `application.js` are:
22
+
23
+ * Updating your JS code won't evict the entire cache in browsers.
24
+ * Cached Bootstrap in the client browsers will survive deployments.
25
+ * Your code changes more often than Bootstrap upgrades, right?
26
+ * `rake assets:precompile` will run faster and use less memory.
27
+
28
+ ## Installation
29
+
30
+ Add this line to your application's Gemfile:
31
+
32
+ ```ruby
33
+ gem 'twitter-bootstrap-rails-cdn'
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ This gem adds a few methods methods `twitter_bootstrap_javascript_include_tag`, `twitter_bootstrap_javascript_url`,
39
+ `twitter_bootstrap_stylesheet_link_tag` and `twitter_bootstrap_stylesheet_url`.
40
+
41
+ If you're using asset pipeline with Rails 3.1+ or 4.+,
42
+
43
+ - Remove any references to bootstrap from `application.js`.
44
+
45
+ Then in layout:
46
+
47
+ ```ruby
48
+ = twitter_bootstrap_stylesheet_link_tag
49
+ = stylesheet_link_tag 'application' ...
50
+ ```
51
+
52
+ ```ruby
53
+ = twitter_bootstrap_javascript_include_tag
54
+ = javascript_include_tag 'application' ...
55
+ ```
56
+
57
+ Note that valid CDN symbols are `:netdna`.
58
+
59
+ Now, it will generate the following on production:
60
+
61
+ ```html
62
+ <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" media="screen" rel="stylesheet" />
63
+ <script>
64
+ //<![CDATA[
65
+ $(function(){ $('body').css('color') === 'rgb(51, 51, 51)' || $('head').prepend('<link href="/stylesheets/bootstrap-2.3.2-combined.min.css" media="screen" rel="stylesheet" />'); });
66
+ //]]>
67
+ </script>
68
+ ```
69
+
70
+ ```html
71
+ <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
72
+ <script>
73
+ //<![CDATA[
74
+ typeof $().modal == 'function' || document.write(unescape('%3Cscript src="/javascripts/bootstrap-2.3.2.min.js">%3C/script>'))
75
+ //]]>
76
+ </script>
77
+ ```
78
+
79
+ on development:
80
+
81
+ ```html
82
+ <script src="/assets/bootstrap-2.3.2.css?body=1" type="text/javascript"></script>
83
+ ```
84
+
85
+ ```html
86
+ <script src="/assets/bootstrap-2.3.2.js?body=1" type="text/javascript"></script>
87
+ ```
88
+
89
+ If you want to check the production URL, you can pass `force: true` as an option.
90
+
91
+ ```ruby
92
+ twitter_bootstrap_stylesheet_link_tag :netdna, force: true
93
+ twitter_bootstrap_javascript_include_tag :netdna, force: true
94
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,69 @@
1
+ require 'twitter-bootstrap-rails-cdn/version'
2
+
3
+ module TwitterBootstrap::Rails::Cdn
4
+ module ActionViewExtensions
5
+ OFFLINE = ( Rails.env.development? or Rails.env.test? )
6
+ DEFAULT_HOST = :netdna
7
+ BOOTSTRAP_VERSIONS = [ '2.3.2' ]
8
+
9
+ def twitter_bootstrap_javascript_url(host = DEFAULT_HOST, options = {})
10
+ twitter_bootstrap_url(:js, host, options)
11
+ end
12
+
13
+ def twitter_bootstrap_stylesheet_url(host = DEFAULT_HOST, options = {})
14
+ twitter_bootstrap_url(:css, host, options)
15
+ end
16
+
17
+ def twitter_bootstrap_javascript_include_tag(host, options = {}, html_options = {})
18
+ local = twitter_bootstrap_javascript_url(:local, options)
19
+
20
+ if OFFLINE and !options.delete(:force)
21
+ javascript_include_tag(local, html_options)
22
+ else
23
+ [
24
+ javascript_include_tag(twitter_bootstrap_javascript_url(host, options), html_options),
25
+ javascript_tag("typeof $().modal == 'function' "+
26
+ "|| document.write(unescape('#{javascript_include_tag(local, html_options).gsub('<','%3C')}'))")
27
+ ].join("\n").html_safe
28
+ end
29
+ end
30
+
31
+ def twitter_bootstrap_stylesheet_include_tag(host, options = {}, html_options = {})
32
+ local = twitter_bootstrap_stylesheet_url(:local, options)
33
+
34
+ if OFFLINE and !options.delete(:force)
35
+ stylesheet_link_tag(local, options)
36
+ else
37
+ [ stylesheet_link_tag(twitter_bootstrap_stylesheet_url(host, options), html_options),
38
+ javascript_tag("$(function(){ $('body').css('color') === 'rgb(51, 51, 51)' "+
39
+ "|| $('head').prepend('#{stylesheet_link_tag(local, html_options)}'); });")
40
+ ].join("\n").html_safe
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def twitter_bootstrap_url(type, host, options = {})
47
+ version = options.delete(:version) || BOOTSTRAP_VERSIONS.first
48
+
49
+ ext = ''
50
+ if type == :css
51
+ ext << '-combined' unless options.delete(:responsive) == false
52
+ end
53
+ ext << '.min' unless options.delete(:compressed) == false
54
+
55
+ {
56
+ :netdna => "//netdna.bootstrapcdn.com/twitter-bootstrap/#{version}/#{type}/bootstrap#{ext}.#{type}",
57
+ :local => "bootstrap-#{version}#{ext}"
58
+ }[host]
59
+ end
60
+ end
61
+
62
+ class Railtie < Rails::Railtie
63
+ initializer 'twitter_bootstrap_rails_cdn.action_view' do |app|
64
+ ActiveSupport.on_load(:action_view) do
65
+ include TwitterBootstrap::Rails::Cdn::ActionViewExtensions
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,7 @@
1
+ module TwitterBootstrap
2
+ module Rails
3
+ module Cdn
4
+ VERSION = '1.0.1'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/twitter-bootstrap-rails-cdn/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Nicholas Barthelemy"]
6
+ gem.email = ["nicholas.barthelemy@gmail.com"]
7
+ gem.description = %q{Twitter Boostrap CDN support for Rails 3 and 4}
8
+ gem.summary = %q{Twitter Boostrap CDN support for Rails 3 and 4}
9
+ gem.homepage = "https://github.com/nbarthelemy/twitter-bootstrap-rails-cdn"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "twitter-bootstrap-rails-cdn"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = TwitterBootstrap::Rails::Cdn::VERSION
17
+ end
@@ -0,0 +1,2291 @@
1
+ /* ===================================================
2
+ * bootstrap-transition.js v2.3.2
3
+ * http://twitter.github.com/bootstrap/javascript.html#transitions
4
+ * ===================================================
5
+ * Copyright 2012 Twitter, Inc.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ========================================================== */
19
+
20
+
21
+ !function ($) {
22
+
23
+ "use strict"; // jshint ;_;
24
+
25
+
26
+ /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
27
+ * ======================================================= */
28
+
29
+ $(function () {
30
+
31
+ $.support.transition = (function () {
32
+
33
+ var transitionEnd = (function () {
34
+
35
+ var el = document.createElement('bootstrap')
36
+ , transEndEventNames = {
37
+ 'WebkitTransition' : 'webkitTransitionEnd'
38
+ , 'MozTransition' : 'transitionend'
39
+ , 'OTransition' : 'oTransitionEnd otransitionend'
40
+ , 'transition' : 'transitionend'
41
+ }
42
+ , name
43
+
44
+ for (name in transEndEventNames){
45
+ if (el.style[name] !== undefined) {
46
+ return transEndEventNames[name]
47
+ }
48
+ }
49
+
50
+ }())
51
+
52
+ return transitionEnd && {
53
+ end: transitionEnd
54
+ }
55
+
56
+ })()
57
+
58
+ })
59
+
60
+ }(window.jQuery);
61
+ /* =========================================================
62
+ * bootstrap-modal.js v2.3.2
63
+ * http://twitter.github.com/bootstrap/javascript.html#modals
64
+ * =========================================================
65
+ * Copyright 2012 Twitter, Inc.
66
+ *
67
+ * Licensed under the Apache License, Version 2.0 (the "License");
68
+ * you may not use this file except in compliance with the License.
69
+ * You may obtain a copy of the License at
70
+ *
71
+ * http://www.apache.org/licenses/LICENSE-2.0
72
+ *
73
+ * Unless required by applicable law or agreed to in writing, software
74
+ * distributed under the License is distributed on an "AS IS" BASIS,
75
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76
+ * See the License for the specific language governing permissions and
77
+ * limitations under the License.
78
+ * ========================================================= */
79
+
80
+
81
+ !function ($) {
82
+
83
+ "use strict"; // jshint ;_;
84
+
85
+
86
+ /* MODAL CLASS DEFINITION
87
+ * ====================== */
88
+
89
+ var Modal = function (element, options) {
90
+ this.options = options
91
+ this.$element = $(element)
92
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
93
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
94
+ }
95
+
96
+ Modal.prototype = {
97
+
98
+ constructor: Modal
99
+
100
+ , toggle: function () {
101
+ return this[!this.isShown ? 'show' : 'hide']()
102
+ }
103
+
104
+ , show: function () {
105
+ var that = this
106
+ , e = $.Event('show')
107
+
108
+ this.$element.trigger(e)
109
+
110
+ if (this.isShown || e.isDefaultPrevented()) return
111
+
112
+ this.isShown = true
113
+
114
+ this.escape()
115
+
116
+ this.backdrop(function () {
117
+ var transition = $.support.transition && that.$element.hasClass('fade')
118
+
119
+ if (!that.$element.parent().length) {
120
+ that.$element.appendTo(document.body) //don't move modals dom position
121
+ }
122
+
123
+ that.$element.show()
124
+
125
+ if (transition) {
126
+ that.$element[0].offsetWidth // force reflow
127
+ }
128
+
129
+ that.$element
130
+ .addClass('in')
131
+ .attr('aria-hidden', false)
132
+
133
+ that.enforceFocus()
134
+
135
+ transition ?
136
+ that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
137
+ that.$element.focus().trigger('shown')
138
+
139
+ })
140
+ }
141
+
142
+ , hide: function (e) {
143
+ e && e.preventDefault()
144
+
145
+ var that = this
146
+
147
+ e = $.Event('hide')
148
+
149
+ this.$element.trigger(e)
150
+
151
+ if (!this.isShown || e.isDefaultPrevented()) return
152
+
153
+ this.isShown = false
154
+
155
+ this.escape()
156
+
157
+ $(document).off('focusin.modal')
158
+
159
+ this.$element
160
+ .removeClass('in')
161
+ .attr('aria-hidden', true)
162
+
163
+ $.support.transition && this.$element.hasClass('fade') ?
164
+ this.hideWithTransition() :
165
+ this.hideModal()
166
+ }
167
+
168
+ , enforceFocus: function () {
169
+ var that = this
170
+ $(document).on('focusin.modal', function (e) {
171
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
172
+ that.$element.focus()
173
+ }
174
+ })
175
+ }
176
+
177
+ , escape: function () {
178
+ var that = this
179
+ if (this.isShown && this.options.keyboard) {
180
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
181
+ e.which == 27 && that.hide()
182
+ })
183
+ } else if (!this.isShown) {
184
+ this.$element.off('keyup.dismiss.modal')
185
+ }
186
+ }
187
+
188
+ , hideWithTransition: function () {
189
+ var that = this
190
+ , timeout = setTimeout(function () {
191
+ that.$element.off($.support.transition.end)
192
+ that.hideModal()
193
+ }, 500)
194
+
195
+ this.$element.one($.support.transition.end, function () {
196
+ clearTimeout(timeout)
197
+ that.hideModal()
198
+ })
199
+ }
200
+
201
+ , hideModal: function () {
202
+ var that = this
203
+ this.$element.hide()
204
+ this.backdrop(function () {
205
+ that.removeBackdrop()
206
+ that.$element.trigger('hidden')
207
+ })
208
+ }
209
+
210
+ , removeBackdrop: function () {
211
+ this.$backdrop && this.$backdrop.remove()
212
+ this.$backdrop = null
213
+ }
214
+
215
+ , backdrop: function (callback) {
216
+ var that = this
217
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
218
+
219
+ if (this.isShown && this.options.backdrop) {
220
+ var doAnimate = $.support.transition && animate
221
+
222
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
223
+ .appendTo(document.body)
224
+
225
+ this.$backdrop.click(
226
+ this.options.backdrop == 'static' ?
227
+ $.proxy(this.$element[0].focus, this.$element[0])
228
+ : $.proxy(this.hide, this)
229
+ )
230
+
231
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
232
+
233
+ this.$backdrop.addClass('in')
234
+
235
+ if (!callback) return
236
+
237
+ doAnimate ?
238
+ this.$backdrop.one($.support.transition.end, callback) :
239
+ callback()
240
+
241
+ } else if (!this.isShown && this.$backdrop) {
242
+ this.$backdrop.removeClass('in')
243
+
244
+ $.support.transition && this.$element.hasClass('fade')?
245
+ this.$backdrop.one($.support.transition.end, callback) :
246
+ callback()
247
+
248
+ } else if (callback) {
249
+ callback()
250
+ }
251
+ }
252
+ }
253
+
254
+
255
+ /* MODAL PLUGIN DEFINITION
256
+ * ======================= */
257
+
258
+ var old = $.fn.modal
259
+
260
+ $.fn.modal = function (option) {
261
+ return this.each(function () {
262
+ var $this = $(this)
263
+ , data = $this.data('modal')
264
+ , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
265
+ if (!data) $this.data('modal', (data = new Modal(this, options)))
266
+ if (typeof option == 'string') data[option]()
267
+ else if (options.show) data.show()
268
+ })
269
+ }
270
+
271
+ $.fn.modal.defaults = {
272
+ backdrop: true
273
+ , keyboard: true
274
+ , show: true
275
+ }
276
+
277
+ $.fn.modal.Constructor = Modal
278
+
279
+
280
+ /* MODAL NO CONFLICT
281
+ * ================= */
282
+
283
+ $.fn.modal.noConflict = function () {
284
+ $.fn.modal = old
285
+ return this
286
+ }
287
+
288
+
289
+ /* MODAL DATA-API
290
+ * ============== */
291
+
292
+ $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
293
+ var $this = $(this)
294
+ , href = $this.attr('href')
295
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
296
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
297
+
298
+ e.preventDefault()
299
+
300
+ $target
301
+ .modal(option)
302
+ .one('hide', function () {
303
+ $this.focus()
304
+ })
305
+ })
306
+
307
+ }(window.jQuery);
308
+
309
+ /* ============================================================
310
+ * bootstrap-dropdown.js v2.3.2
311
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
312
+ * ============================================================
313
+ * Copyright 2012 Twitter, Inc.
314
+ *
315
+ * Licensed under the Apache License, Version 2.0 (the "License");
316
+ * you may not use this file except in compliance with the License.
317
+ * You may obtain a copy of the License at
318
+ *
319
+ * http://www.apache.org/licenses/LICENSE-2.0
320
+ *
321
+ * Unless required by applicable law or agreed to in writing, software
322
+ * distributed under the License is distributed on an "AS IS" BASIS,
323
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
324
+ * See the License for the specific language governing permissions and
325
+ * limitations under the License.
326
+ * ============================================================ */
327
+
328
+
329
+ !function ($) {
330
+
331
+ "use strict"; // jshint ;_;
332
+
333
+
334
+ /* DROPDOWN CLASS DEFINITION
335
+ * ========================= */
336
+
337
+ var toggle = '[data-toggle=dropdown]'
338
+ , Dropdown = function (element) {
339
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
340
+ $('html').on('click.dropdown.data-api', function () {
341
+ $el.parent().removeClass('open')
342
+ })
343
+ }
344
+
345
+ Dropdown.prototype = {
346
+
347
+ constructor: Dropdown
348
+
349
+ , toggle: function (e) {
350
+ var $this = $(this)
351
+ , $parent
352
+ , isActive
353
+
354
+ if ($this.is('.disabled, :disabled')) return
355
+
356
+ $parent = getParent($this)
357
+
358
+ isActive = $parent.hasClass('open')
359
+
360
+ clearMenus()
361
+
362
+ if (!isActive) {
363
+ if ('ontouchstart' in document.documentElement) {
364
+ // if mobile we we use a backdrop because click events don't delegate
365
+ $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
366
+ }
367
+ $parent.toggleClass('open')
368
+ }
369
+
370
+ $this.focus()
371
+
372
+ return false
373
+ }
374
+
375
+ , keydown: function (e) {
376
+ var $this
377
+ , $items
378
+ , $active
379
+ , $parent
380
+ , isActive
381
+ , index
382
+
383
+ if (!/(38|40|27)/.test(e.keyCode)) return
384
+
385
+ $this = $(this)
386
+
387
+ e.preventDefault()
388
+ e.stopPropagation()
389
+
390
+ if ($this.is('.disabled, :disabled')) return
391
+
392
+ $parent = getParent($this)
393
+
394
+ isActive = $parent.hasClass('open')
395
+
396
+ if (!isActive || (isActive && e.keyCode == 27)) {
397
+ if (e.which == 27) $parent.find(toggle).focus()
398
+ return $this.click()
399
+ }
400
+
401
+ $items = $('[role=menu] li:not(.divider):visible a', $parent)
402
+
403
+ if (!$items.length) return
404
+
405
+ index = $items.index($items.filter(':focus'))
406
+
407
+ if (e.keyCode == 38 && index > 0) index-- // up
408
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
409
+ if (!~index) index = 0
410
+
411
+ $items
412
+ .eq(index)
413
+ .focus()
414
+ }
415
+
416
+ }
417
+
418
+ function clearMenus() {
419
+ $('.dropdown-backdrop').remove()
420
+ $(toggle).each(function () {
421
+ getParent($(this)).removeClass('open')
422
+ })
423
+ }
424
+
425
+ function getParent($this) {
426
+ var selector = $this.attr('data-target')
427
+ , $parent
428
+
429
+ if (!selector) {
430
+ selector = $this.attr('href')
431
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
432
+ }
433
+
434
+ $parent = selector && $(selector)
435
+
436
+ if (!$parent || !$parent.length) $parent = $this.parent()
437
+
438
+ return $parent
439
+ }
440
+
441
+
442
+ /* DROPDOWN PLUGIN DEFINITION
443
+ * ========================== */
444
+
445
+ var old = $.fn.dropdown
446
+
447
+ $.fn.dropdown = function (option) {
448
+ return this.each(function () {
449
+ var $this = $(this)
450
+ , data = $this.data('dropdown')
451
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
452
+ if (typeof option == 'string') data[option].call($this)
453
+ })
454
+ }
455
+
456
+ $.fn.dropdown.Constructor = Dropdown
457
+
458
+
459
+ /* DROPDOWN NO CONFLICT
460
+ * ==================== */
461
+
462
+ $.fn.dropdown.noConflict = function () {
463
+ $.fn.dropdown = old
464
+ return this
465
+ }
466
+
467
+
468
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
469
+ * =================================== */
470
+
471
+ $(document)
472
+ .on('click.dropdown.data-api', clearMenus)
473
+ .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
474
+ .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
475
+ .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
476
+
477
+ }(window.jQuery);
478
+
479
+ /* =============================================================
480
+ * bootstrap-scrollspy.js v2.3.2
481
+ * http://twitter.github.com/bootstrap/javascript.html#scrollspy
482
+ * =============================================================
483
+ * Copyright 2012 Twitter, Inc.
484
+ *
485
+ * Licensed under the Apache License, Version 2.0 (the "License");
486
+ * you may not use this file except in compliance with the License.
487
+ * You may obtain a copy of the License at
488
+ *
489
+ * http://www.apache.org/licenses/LICENSE-2.0
490
+ *
491
+ * Unless required by applicable law or agreed to in writing, software
492
+ * distributed under the License is distributed on an "AS IS" BASIS,
493
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
494
+ * See the License for the specific language governing permissions and
495
+ * limitations under the License.
496
+ * ============================================================== */
497
+
498
+
499
+ !function ($) {
500
+
501
+ "use strict"; // jshint ;_;
502
+
503
+
504
+ /* SCROLLSPY CLASS DEFINITION
505
+ * ========================== */
506
+
507
+ function ScrollSpy(element, options) {
508
+ var process = $.proxy(this.process, this)
509
+ , $element = $(element).is('body') ? $(window) : $(element)
510
+ , href
511
+ this.options = $.extend({}, $.fn.scrollspy.defaults, options)
512
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
513
+ this.selector = (this.options.target
514
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
515
+ || '') + ' .nav li > a'
516
+ this.$body = $('body')
517
+ this.refresh()
518
+ this.process()
519
+ }
520
+
521
+ ScrollSpy.prototype = {
522
+
523
+ constructor: ScrollSpy
524
+
525
+ , refresh: function () {
526
+ var self = this
527
+ , $targets
528
+
529
+ this.offsets = $([])
530
+ this.targets = $([])
531
+
532
+ $targets = this.$body
533
+ .find(this.selector)
534
+ .map(function () {
535
+ var $el = $(this)
536
+ , href = $el.data('target') || $el.attr('href')
537
+ , $href = /^#\w/.test(href) && $(href)
538
+ return ( $href
539
+ && $href.length
540
+ && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
541
+ })
542
+ .sort(function (a, b) { return a[0] - b[0] })
543
+ .each(function () {
544
+ self.offsets.push(this[0])
545
+ self.targets.push(this[1])
546
+ })
547
+ }
548
+
549
+ , process: function () {
550
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
551
+ , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
552
+ , maxScroll = scrollHeight - this.$scrollElement.height()
553
+ , offsets = this.offsets
554
+ , targets = this.targets
555
+ , activeTarget = this.activeTarget
556
+ , i
557
+
558
+ if (scrollTop >= maxScroll) {
559
+ return activeTarget != (i = targets.last()[0])
560
+ && this.activate ( i )
561
+ }
562
+
563
+ for (i = offsets.length; i--;) {
564
+ activeTarget != targets[i]
565
+ && scrollTop >= offsets[i]
566
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
567
+ && this.activate( targets[i] )
568
+ }
569
+ }
570
+
571
+ , activate: function (target) {
572
+ var active
573
+ , selector
574
+
575
+ this.activeTarget = target
576
+
577
+ $(this.selector)
578
+ .parent('.active')
579
+ .removeClass('active')
580
+
581
+ selector = this.selector
582
+ + '[data-target="' + target + '"],'
583
+ + this.selector + '[href="' + target + '"]'
584
+
585
+ active = $(selector)
586
+ .parent('li')
587
+ .addClass('active')
588
+
589
+ if (active.parent('.dropdown-menu').length) {
590
+ active = active.closest('li.dropdown').addClass('active')
591
+ }
592
+
593
+ active.trigger('activate')
594
+ }
595
+
596
+ }
597
+
598
+
599
+ /* SCROLLSPY PLUGIN DEFINITION
600
+ * =========================== */
601
+
602
+ var old = $.fn.scrollspy
603
+
604
+ $.fn.scrollspy = function (option) {
605
+ return this.each(function () {
606
+ var $this = $(this)
607
+ , data = $this.data('scrollspy')
608
+ , options = typeof option == 'object' && option
609
+ if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
610
+ if (typeof option == 'string') data[option]()
611
+ })
612
+ }
613
+
614
+ $.fn.scrollspy.Constructor = ScrollSpy
615
+
616
+ $.fn.scrollspy.defaults = {
617
+ offset: 10
618
+ }
619
+
620
+
621
+ /* SCROLLSPY NO CONFLICT
622
+ * ===================== */
623
+
624
+ $.fn.scrollspy.noConflict = function () {
625
+ $.fn.scrollspy = old
626
+ return this
627
+ }
628
+
629
+
630
+ /* SCROLLSPY DATA-API
631
+ * ================== */
632
+
633
+ $(window).on('load', function () {
634
+ $('[data-spy="scroll"]').each(function () {
635
+ var $spy = $(this)
636
+ $spy.scrollspy($spy.data())
637
+ })
638
+ })
639
+
640
+ }(window.jQuery);
641
+ /* ========================================================
642
+ * bootstrap-tab.js v2.3.2
643
+ * http://twitter.github.com/bootstrap/javascript.html#tabs
644
+ * ========================================================
645
+ * Copyright 2012 Twitter, Inc.
646
+ *
647
+ * Licensed under the Apache License, Version 2.0 (the "License");
648
+ * you may not use this file except in compliance with the License.
649
+ * You may obtain a copy of the License at
650
+ *
651
+ * http://www.apache.org/licenses/LICENSE-2.0
652
+ *
653
+ * Unless required by applicable law or agreed to in writing, software
654
+ * distributed under the License is distributed on an "AS IS" BASIS,
655
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
656
+ * See the License for the specific language governing permissions and
657
+ * limitations under the License.
658
+ * ======================================================== */
659
+
660
+
661
+ !function ($) {
662
+
663
+ "use strict"; // jshint ;_;
664
+
665
+
666
+ /* TAB CLASS DEFINITION
667
+ * ==================== */
668
+
669
+ var Tab = function (element) {
670
+ this.element = $(element)
671
+ }
672
+
673
+ Tab.prototype = {
674
+
675
+ constructor: Tab
676
+
677
+ , show: function () {
678
+ var $this = this.element
679
+ , $ul = $this.closest('ul:not(.dropdown-menu)')
680
+ , selector = $this.attr('data-target')
681
+ , previous
682
+ , $target
683
+ , e
684
+
685
+ if (!selector) {
686
+ selector = $this.attr('href')
687
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
688
+ }
689
+
690
+ if ( $this.parent('li').hasClass('active') ) return
691
+
692
+ previous = $ul.find('.active:last a')[0]
693
+
694
+ e = $.Event('show', {
695
+ relatedTarget: previous
696
+ })
697
+
698
+ $this.trigger(e)
699
+
700
+ if (e.isDefaultPrevented()) return
701
+
702
+ $target = $(selector)
703
+
704
+ this.activate($this.parent('li'), $ul)
705
+ this.activate($target, $target.parent(), function () {
706
+ $this.trigger({
707
+ type: 'shown'
708
+ , relatedTarget: previous
709
+ })
710
+ })
711
+ }
712
+
713
+ , activate: function ( element, container, callback) {
714
+ var $active = container.find('> .active')
715
+ , transition = callback
716
+ && $.support.transition
717
+ && $active.hasClass('fade')
718
+
719
+ function next() {
720
+ $active
721
+ .removeClass('active')
722
+ .find('> .dropdown-menu > .active')
723
+ .removeClass('active')
724
+
725
+ element.addClass('active')
726
+
727
+ if (transition) {
728
+ element[0].offsetWidth // reflow for transition
729
+ element.addClass('in')
730
+ } else {
731
+ element.removeClass('fade')
732
+ }
733
+
734
+ if ( element.parent('.dropdown-menu') ) {
735
+ element.closest('li.dropdown').addClass('active')
736
+ }
737
+
738
+ callback && callback()
739
+ }
740
+
741
+ transition ?
742
+ $active.one($.support.transition.end, next) :
743
+ next()
744
+
745
+ $active.removeClass('in')
746
+ }
747
+ }
748
+
749
+
750
+ /* TAB PLUGIN DEFINITION
751
+ * ===================== */
752
+
753
+ var old = $.fn.tab
754
+
755
+ $.fn.tab = function ( option ) {
756
+ return this.each(function () {
757
+ var $this = $(this)
758
+ , data = $this.data('tab')
759
+ if (!data) $this.data('tab', (data = new Tab(this)))
760
+ if (typeof option == 'string') data[option]()
761
+ })
762
+ }
763
+
764
+ $.fn.tab.Constructor = Tab
765
+
766
+
767
+ /* TAB NO CONFLICT
768
+ * =============== */
769
+
770
+ $.fn.tab.noConflict = function () {
771
+ $.fn.tab = old
772
+ return this
773
+ }
774
+
775
+
776
+ /* TAB DATA-API
777
+ * ============ */
778
+
779
+ $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
780
+ e.preventDefault()
781
+ $(this).tab('show')
782
+ })
783
+
784
+ }(window.jQuery);
785
+ /* ===========================================================
786
+ * bootstrap-tooltip.js v2.3.2
787
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
788
+ * Inspired by the original jQuery.tipsy by Jason Frame
789
+ * ===========================================================
790
+ * Copyright 2012 Twitter, Inc.
791
+ *
792
+ * Licensed under the Apache License, Version 2.0 (the "License");
793
+ * you may not use this file except in compliance with the License.
794
+ * You may obtain a copy of the License at
795
+ *
796
+ * http://www.apache.org/licenses/LICENSE-2.0
797
+ *
798
+ * Unless required by applicable law or agreed to in writing, software
799
+ * distributed under the License is distributed on an "AS IS" BASIS,
800
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
801
+ * See the License for the specific language governing permissions and
802
+ * limitations under the License.
803
+ * ========================================================== */
804
+
805
+
806
+ !function ($) {
807
+
808
+ "use strict"; // jshint ;_;
809
+
810
+
811
+ /* TOOLTIP PUBLIC CLASS DEFINITION
812
+ * =============================== */
813
+
814
+ var Tooltip = function (element, options) {
815
+ this.init('tooltip', element, options)
816
+ }
817
+
818
+ Tooltip.prototype = {
819
+
820
+ constructor: Tooltip
821
+
822
+ , init: function (type, element, options) {
823
+ var eventIn
824
+ , eventOut
825
+ , triggers
826
+ , trigger
827
+ , i
828
+
829
+ this.type = type
830
+ this.$element = $(element)
831
+ this.options = this.getOptions(options)
832
+ this.enabled = true
833
+
834
+ triggers = this.options.trigger.split(' ')
835
+
836
+ for (i = triggers.length; i--;) {
837
+ trigger = triggers[i]
838
+ if (trigger == 'click') {
839
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
840
+ } else if (trigger != 'manual') {
841
+ eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
842
+ eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
843
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
844
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
845
+ }
846
+ }
847
+
848
+ this.options.selector ?
849
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
850
+ this.fixTitle()
851
+ }
852
+
853
+ , getOptions: function (options) {
854
+ options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
855
+
856
+ if (options.delay && typeof options.delay == 'number') {
857
+ options.delay = {
858
+ show: options.delay
859
+ , hide: options.delay
860
+ }
861
+ }
862
+
863
+ return options
864
+ }
865
+
866
+ , enter: function (e) {
867
+ var defaults = $.fn[this.type].defaults
868
+ , options = {}
869
+ , self
870
+
871
+ this._options && $.each(this._options, function (key, value) {
872
+ if (defaults[key] != value) options[key] = value
873
+ }, this)
874
+
875
+ self = $(e.currentTarget)[this.type](options).data(this.type)
876
+
877
+ if (!self.options.delay || !self.options.delay.show) return self.show()
878
+
879
+ clearTimeout(this.timeout)
880
+ self.hoverState = 'in'
881
+ this.timeout = setTimeout(function() {
882
+ if (self.hoverState == 'in') self.show()
883
+ }, self.options.delay.show)
884
+ }
885
+
886
+ , leave: function (e) {
887
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
888
+
889
+ if (this.timeout) clearTimeout(this.timeout)
890
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
891
+
892
+ self.hoverState = 'out'
893
+ this.timeout = setTimeout(function() {
894
+ if (self.hoverState == 'out') self.hide()
895
+ }, self.options.delay.hide)
896
+ }
897
+
898
+ , show: function () {
899
+ var $tip
900
+ , pos
901
+ , actualWidth
902
+ , actualHeight
903
+ , placement
904
+ , tp
905
+ , e = $.Event('show')
906
+
907
+ if (this.hasContent() && this.enabled) {
908
+ this.$element.trigger(e)
909
+ if (e.isDefaultPrevented()) return
910
+ $tip = this.tip()
911
+ this.setContent()
912
+
913
+ if (this.options.animation) {
914
+ $tip.addClass('fade')
915
+ }
916
+
917
+ placement = typeof this.options.placement == 'function' ?
918
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
919
+ this.options.placement
920
+
921
+ $tip
922
+ .detach()
923
+ .css({ top: 0, left: 0, display: 'block' })
924
+
925
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
926
+
927
+ pos = this.getPosition()
928
+
929
+ actualWidth = $tip[0].offsetWidth
930
+ actualHeight = $tip[0].offsetHeight
931
+
932
+ switch (placement) {
933
+ case 'bottom':
934
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
935
+ break
936
+ case 'top':
937
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
938
+ break
939
+ case 'left':
940
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
941
+ break
942
+ case 'right':
943
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
944
+ break
945
+ }
946
+
947
+ this.applyPlacement(tp, placement)
948
+ this.$element.trigger('shown')
949
+ }
950
+ }
951
+
952
+ , applyPlacement: function(offset, placement){
953
+ var $tip = this.tip()
954
+ , width = $tip[0].offsetWidth
955
+ , height = $tip[0].offsetHeight
956
+ , actualWidth
957
+ , actualHeight
958
+ , delta
959
+ , replace
960
+
961
+ $tip
962
+ .offset(offset)
963
+ .addClass(placement)
964
+ .addClass('in')
965
+
966
+ actualWidth = $tip[0].offsetWidth
967
+ actualHeight = $tip[0].offsetHeight
968
+
969
+ if (placement == 'top' && actualHeight != height) {
970
+ offset.top = offset.top + height - actualHeight
971
+ replace = true
972
+ }
973
+
974
+ if (placement == 'bottom' || placement == 'top') {
975
+ delta = 0
976
+
977
+ if (offset.left < 0){
978
+ delta = offset.left * -2
979
+ offset.left = 0
980
+ $tip.offset(offset)
981
+ actualWidth = $tip[0].offsetWidth
982
+ actualHeight = $tip[0].offsetHeight
983
+ }
984
+
985
+ this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
986
+ } else {
987
+ this.replaceArrow(actualHeight - height, actualHeight, 'top')
988
+ }
989
+
990
+ if (replace) $tip.offset(offset)
991
+ }
992
+
993
+ , replaceArrow: function(delta, dimension, position){
994
+ this
995
+ .arrow()
996
+ .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
997
+ }
998
+
999
+ , setContent: function () {
1000
+ var $tip = this.tip()
1001
+ , title = this.getTitle()
1002
+
1003
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1004
+ $tip.removeClass('fade in top bottom left right')
1005
+ }
1006
+
1007
+ , hide: function () {
1008
+ var that = this
1009
+ , $tip = this.tip()
1010
+ , e = $.Event('hide')
1011
+
1012
+ this.$element.trigger(e)
1013
+ if (e.isDefaultPrevented()) return
1014
+
1015
+ $tip.removeClass('in')
1016
+
1017
+ function removeWithAnimation() {
1018
+ var timeout = setTimeout(function () {
1019
+ $tip.off($.support.transition.end).detach()
1020
+ }, 500)
1021
+
1022
+ $tip.one($.support.transition.end, function () {
1023
+ clearTimeout(timeout)
1024
+ $tip.detach()
1025
+ })
1026
+ }
1027
+
1028
+ $.support.transition && this.$tip.hasClass('fade') ?
1029
+ removeWithAnimation() :
1030
+ $tip.detach()
1031
+
1032
+ this.$element.trigger('hidden')
1033
+
1034
+ return this
1035
+ }
1036
+
1037
+ , fixTitle: function () {
1038
+ var $e = this.$element
1039
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1040
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1041
+ }
1042
+ }
1043
+
1044
+ , hasContent: function () {
1045
+ return this.getTitle()
1046
+ }
1047
+
1048
+ , getPosition: function () {
1049
+ var el = this.$element[0]
1050
+ return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
1051
+ width: el.offsetWidth
1052
+ , height: el.offsetHeight
1053
+ }, this.$element.offset())
1054
+ }
1055
+
1056
+ , getTitle: function () {
1057
+ var title
1058
+ , $e = this.$element
1059
+ , o = this.options
1060
+
1061
+ title = $e.attr('data-original-title')
1062
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1063
+
1064
+ return title
1065
+ }
1066
+
1067
+ , tip: function () {
1068
+ return this.$tip = this.$tip || $(this.options.template)
1069
+ }
1070
+
1071
+ , arrow: function(){
1072
+ return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
1073
+ }
1074
+
1075
+ , validate: function () {
1076
+ if (!this.$element[0].parentNode) {
1077
+ this.hide()
1078
+ this.$element = null
1079
+ this.options = null
1080
+ }
1081
+ }
1082
+
1083
+ , enable: function () {
1084
+ this.enabled = true
1085
+ }
1086
+
1087
+ , disable: function () {
1088
+ this.enabled = false
1089
+ }
1090
+
1091
+ , toggleEnabled: function () {
1092
+ this.enabled = !this.enabled
1093
+ }
1094
+
1095
+ , toggle: function (e) {
1096
+ var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
1097
+ self.tip().hasClass('in') ? self.hide() : self.show()
1098
+ }
1099
+
1100
+ , destroy: function () {
1101
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1102
+ }
1103
+
1104
+ }
1105
+
1106
+
1107
+ /* TOOLTIP PLUGIN DEFINITION
1108
+ * ========================= */
1109
+
1110
+ var old = $.fn.tooltip
1111
+
1112
+ $.fn.tooltip = function ( option ) {
1113
+ return this.each(function () {
1114
+ var $this = $(this)
1115
+ , data = $this.data('tooltip')
1116
+ , options = typeof option == 'object' && option
1117
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
1118
+ if (typeof option == 'string') data[option]()
1119
+ })
1120
+ }
1121
+
1122
+ $.fn.tooltip.Constructor = Tooltip
1123
+
1124
+ $.fn.tooltip.defaults = {
1125
+ animation: true
1126
+ , placement: 'top'
1127
+ , selector: false
1128
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1129
+ , trigger: 'hover focus'
1130
+ , title: ''
1131
+ , delay: 0
1132
+ , html: false
1133
+ , container: false
1134
+ }
1135
+
1136
+
1137
+ /* TOOLTIP NO CONFLICT
1138
+ * =================== */
1139
+
1140
+ $.fn.tooltip.noConflict = function () {
1141
+ $.fn.tooltip = old
1142
+ return this
1143
+ }
1144
+
1145
+ }(window.jQuery);
1146
+
1147
+ /* ===========================================================
1148
+ * bootstrap-popover.js v2.3.2
1149
+ * http://twitter.github.com/bootstrap/javascript.html#popovers
1150
+ * ===========================================================
1151
+ * Copyright 2012 Twitter, Inc.
1152
+ *
1153
+ * Licensed under the Apache License, Version 2.0 (the "License");
1154
+ * you may not use this file except in compliance with the License.
1155
+ * You may obtain a copy of the License at
1156
+ *
1157
+ * http://www.apache.org/licenses/LICENSE-2.0
1158
+ *
1159
+ * Unless required by applicable law or agreed to in writing, software
1160
+ * distributed under the License is distributed on an "AS IS" BASIS,
1161
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1162
+ * See the License for the specific language governing permissions and
1163
+ * limitations under the License.
1164
+ * =========================================================== */
1165
+
1166
+
1167
+ !function ($) {
1168
+
1169
+ "use strict"; // jshint ;_;
1170
+
1171
+
1172
+ /* POPOVER PUBLIC CLASS DEFINITION
1173
+ * =============================== */
1174
+
1175
+ var Popover = function (element, options) {
1176
+ this.init('popover', element, options)
1177
+ }
1178
+
1179
+
1180
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
1181
+ ========================================== */
1182
+
1183
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
1184
+
1185
+ constructor: Popover
1186
+
1187
+ , setContent: function () {
1188
+ var $tip = this.tip()
1189
+ , title = this.getTitle()
1190
+ , content = this.getContent()
1191
+
1192
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1193
+ $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
1194
+
1195
+ $tip.removeClass('fade top bottom left right in')
1196
+ }
1197
+
1198
+ , hasContent: function () {
1199
+ return this.getTitle() || this.getContent()
1200
+ }
1201
+
1202
+ , getContent: function () {
1203
+ var content
1204
+ , $e = this.$element
1205
+ , o = this.options
1206
+
1207
+ content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
1208
+ || $e.attr('data-content')
1209
+
1210
+ return content
1211
+ }
1212
+
1213
+ , tip: function () {
1214
+ if (!this.$tip) {
1215
+ this.$tip = $(this.options.template)
1216
+ }
1217
+ return this.$tip
1218
+ }
1219
+
1220
+ , destroy: function () {
1221
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1222
+ }
1223
+
1224
+ })
1225
+
1226
+
1227
+ /* POPOVER PLUGIN DEFINITION
1228
+ * ======================= */
1229
+
1230
+ var old = $.fn.popover
1231
+
1232
+ $.fn.popover = function (option) {
1233
+ return this.each(function () {
1234
+ var $this = $(this)
1235
+ , data = $this.data('popover')
1236
+ , options = typeof option == 'object' && option
1237
+ if (!data) $this.data('popover', (data = new Popover(this, options)))
1238
+ if (typeof option == 'string') data[option]()
1239
+ })
1240
+ }
1241
+
1242
+ $.fn.popover.Constructor = Popover
1243
+
1244
+ $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1245
+ placement: 'right'
1246
+ , trigger: 'click'
1247
+ , content: ''
1248
+ , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1249
+ })
1250
+
1251
+
1252
+ /* POPOVER NO CONFLICT
1253
+ * =================== */
1254
+
1255
+ $.fn.popover.noConflict = function () {
1256
+ $.fn.popover = old
1257
+ return this
1258
+ }
1259
+
1260
+ }(window.jQuery);
1261
+
1262
+ /* ==========================================================
1263
+ * bootstrap-affix.js v2.3.2
1264
+ * http://twitter.github.com/bootstrap/javascript.html#affix
1265
+ * ==========================================================
1266
+ * Copyright 2012 Twitter, Inc.
1267
+ *
1268
+ * Licensed under the Apache License, Version 2.0 (the "License");
1269
+ * you may not use this file except in compliance with the License.
1270
+ * You may obtain a copy of the License at
1271
+ *
1272
+ * http://www.apache.org/licenses/LICENSE-2.0
1273
+ *
1274
+ * Unless required by applicable law or agreed to in writing, software
1275
+ * distributed under the License is distributed on an "AS IS" BASIS,
1276
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1277
+ * See the License for the specific language governing permissions and
1278
+ * limitations under the License.
1279
+ * ========================================================== */
1280
+
1281
+
1282
+ !function ($) {
1283
+
1284
+ "use strict"; // jshint ;_;
1285
+
1286
+
1287
+ /* AFFIX CLASS DEFINITION
1288
+ * ====================== */
1289
+
1290
+ var Affix = function (element, options) {
1291
+ this.options = $.extend({}, $.fn.affix.defaults, options)
1292
+ this.$window = $(window)
1293
+ .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
1294
+ .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
1295
+ this.$element = $(element)
1296
+ this.checkPosition()
1297
+ }
1298
+
1299
+ Affix.prototype.checkPosition = function () {
1300
+ if (!this.$element.is(':visible')) return
1301
+
1302
+ var scrollHeight = $(document).height()
1303
+ , scrollTop = this.$window.scrollTop()
1304
+ , position = this.$element.offset()
1305
+ , offset = this.options.offset
1306
+ , offsetBottom = offset.bottom
1307
+ , offsetTop = offset.top
1308
+ , reset = 'affix affix-top affix-bottom'
1309
+ , affix
1310
+
1311
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
1312
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
1313
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
1314
+
1315
+ affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
1316
+ false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
1317
+ 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
1318
+ 'top' : false
1319
+
1320
+ if (this.affixed === affix) return
1321
+
1322
+ this.affixed = affix
1323
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
1324
+
1325
+ this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
1326
+ }
1327
+
1328
+
1329
+ /* AFFIX PLUGIN DEFINITION
1330
+ * ======================= */
1331
+
1332
+ var old = $.fn.affix
1333
+
1334
+ $.fn.affix = function (option) {
1335
+ return this.each(function () {
1336
+ var $this = $(this)
1337
+ , data = $this.data('affix')
1338
+ , options = typeof option == 'object' && option
1339
+ if (!data) $this.data('affix', (data = new Affix(this, options)))
1340
+ if (typeof option == 'string') data[option]()
1341
+ })
1342
+ }
1343
+
1344
+ $.fn.affix.Constructor = Affix
1345
+
1346
+ $.fn.affix.defaults = {
1347
+ offset: 0
1348
+ }
1349
+
1350
+
1351
+ /* AFFIX NO CONFLICT
1352
+ * ================= */
1353
+
1354
+ $.fn.affix.noConflict = function () {
1355
+ $.fn.affix = old
1356
+ return this
1357
+ }
1358
+
1359
+
1360
+ /* AFFIX DATA-API
1361
+ * ============== */
1362
+
1363
+ $(window).on('load', function () {
1364
+ $('[data-spy="affix"]').each(function () {
1365
+ var $spy = $(this)
1366
+ , data = $spy.data()
1367
+
1368
+ data.offset = data.offset || {}
1369
+
1370
+ data.offsetBottom && (data.offset.bottom = data.offsetBottom)
1371
+ data.offsetTop && (data.offset.top = data.offsetTop)
1372
+
1373
+ $spy.affix(data)
1374
+ })
1375
+ })
1376
+
1377
+
1378
+ }(window.jQuery);
1379
+ /* ==========================================================
1380
+ * bootstrap-alert.js v2.3.2
1381
+ * http://twitter.github.com/bootstrap/javascript.html#alerts
1382
+ * ==========================================================
1383
+ * Copyright 2012 Twitter, Inc.
1384
+ *
1385
+ * Licensed under the Apache License, Version 2.0 (the "License");
1386
+ * you may not use this file except in compliance with the License.
1387
+ * You may obtain a copy of the License at
1388
+ *
1389
+ * http://www.apache.org/licenses/LICENSE-2.0
1390
+ *
1391
+ * Unless required by applicable law or agreed to in writing, software
1392
+ * distributed under the License is distributed on an "AS IS" BASIS,
1393
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1394
+ * See the License for the specific language governing permissions and
1395
+ * limitations under the License.
1396
+ * ========================================================== */
1397
+
1398
+
1399
+ !function ($) {
1400
+
1401
+ "use strict"; // jshint ;_;
1402
+
1403
+
1404
+ /* ALERT CLASS DEFINITION
1405
+ * ====================== */
1406
+
1407
+ var dismiss = '[data-dismiss="alert"]'
1408
+ , Alert = function (el) {
1409
+ $(el).on('click', dismiss, this.close)
1410
+ }
1411
+
1412
+ Alert.prototype.close = function (e) {
1413
+ var $this = $(this)
1414
+ , selector = $this.attr('data-target')
1415
+ , $parent
1416
+
1417
+ if (!selector) {
1418
+ selector = $this.attr('href')
1419
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1420
+ }
1421
+
1422
+ $parent = $(selector)
1423
+
1424
+ e && e.preventDefault()
1425
+
1426
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
1427
+
1428
+ $parent.trigger(e = $.Event('close'))
1429
+
1430
+ if (e.isDefaultPrevented()) return
1431
+
1432
+ $parent.removeClass('in')
1433
+
1434
+ function removeElement() {
1435
+ $parent
1436
+ .trigger('closed')
1437
+ .remove()
1438
+ }
1439
+
1440
+ $.support.transition && $parent.hasClass('fade') ?
1441
+ $parent.on($.support.transition.end, removeElement) :
1442
+ removeElement()
1443
+ }
1444
+
1445
+
1446
+ /* ALERT PLUGIN DEFINITION
1447
+ * ======================= */
1448
+
1449
+ var old = $.fn.alert
1450
+
1451
+ $.fn.alert = function (option) {
1452
+ return this.each(function () {
1453
+ var $this = $(this)
1454
+ , data = $this.data('alert')
1455
+ if (!data) $this.data('alert', (data = new Alert(this)))
1456
+ if (typeof option == 'string') data[option].call($this)
1457
+ })
1458
+ }
1459
+
1460
+ $.fn.alert.Constructor = Alert
1461
+
1462
+
1463
+ /* ALERT NO CONFLICT
1464
+ * ================= */
1465
+
1466
+ $.fn.alert.noConflict = function () {
1467
+ $.fn.alert = old
1468
+ return this
1469
+ }
1470
+
1471
+
1472
+ /* ALERT DATA-API
1473
+ * ============== */
1474
+
1475
+ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
1476
+
1477
+ }(window.jQuery);
1478
+ /* ============================================================
1479
+ * bootstrap-button.js v2.3.2
1480
+ * http://twitter.github.com/bootstrap/javascript.html#buttons
1481
+ * ============================================================
1482
+ * Copyright 2012 Twitter, Inc.
1483
+ *
1484
+ * Licensed under the Apache License, Version 2.0 (the "License");
1485
+ * you may not use this file except in compliance with the License.
1486
+ * You may obtain a copy of the License at
1487
+ *
1488
+ * http://www.apache.org/licenses/LICENSE-2.0
1489
+ *
1490
+ * Unless required by applicable law or agreed to in writing, software
1491
+ * distributed under the License is distributed on an "AS IS" BASIS,
1492
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1493
+ * See the License for the specific language governing permissions and
1494
+ * limitations under the License.
1495
+ * ============================================================ */
1496
+
1497
+
1498
+ !function ($) {
1499
+
1500
+ "use strict"; // jshint ;_;
1501
+
1502
+
1503
+ /* BUTTON PUBLIC CLASS DEFINITION
1504
+ * ============================== */
1505
+
1506
+ var Button = function (element, options) {
1507
+ this.$element = $(element)
1508
+ this.options = $.extend({}, $.fn.button.defaults, options)
1509
+ }
1510
+
1511
+ Button.prototype.setState = function (state) {
1512
+ var d = 'disabled'
1513
+ , $el = this.$element
1514
+ , data = $el.data()
1515
+ , val = $el.is('input') ? 'val' : 'html'
1516
+
1517
+ state = state + 'Text'
1518
+ data.resetText || $el.data('resetText', $el[val]())
1519
+
1520
+ $el[val](data[state] || this.options[state])
1521
+
1522
+ // push to event loop to allow forms to submit
1523
+ setTimeout(function () {
1524
+ state == 'loadingText' ?
1525
+ $el.addClass(d).attr(d, d) :
1526
+ $el.removeClass(d).removeAttr(d)
1527
+ }, 0)
1528
+ }
1529
+
1530
+ Button.prototype.toggle = function () {
1531
+ var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
1532
+
1533
+ $parent && $parent
1534
+ .find('.active')
1535
+ .removeClass('active')
1536
+
1537
+ this.$element.toggleClass('active')
1538
+ }
1539
+
1540
+
1541
+ /* BUTTON PLUGIN DEFINITION
1542
+ * ======================== */
1543
+
1544
+ var old = $.fn.button
1545
+
1546
+ $.fn.button = function (option) {
1547
+ return this.each(function () {
1548
+ var $this = $(this)
1549
+ , data = $this.data('button')
1550
+ , options = typeof option == 'object' && option
1551
+ if (!data) $this.data('button', (data = new Button(this, options)))
1552
+ if (option == 'toggle') data.toggle()
1553
+ else if (option) data.setState(option)
1554
+ })
1555
+ }
1556
+
1557
+ $.fn.button.defaults = {
1558
+ loadingText: 'loading...'
1559
+ }
1560
+
1561
+ $.fn.button.Constructor = Button
1562
+
1563
+
1564
+ /* BUTTON NO CONFLICT
1565
+ * ================== */
1566
+
1567
+ $.fn.button.noConflict = function () {
1568
+ $.fn.button = old
1569
+ return this
1570
+ }
1571
+
1572
+
1573
+ /* BUTTON DATA-API
1574
+ * =============== */
1575
+
1576
+ $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
1577
+ var $btn = $(e.target)
1578
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
1579
+ $btn.button('toggle')
1580
+ })
1581
+
1582
+ }(window.jQuery);
1583
+ /* =============================================================
1584
+ * bootstrap-collapse.js v2.3.2
1585
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
1586
+ * =============================================================
1587
+ * Copyright 2012 Twitter, Inc.
1588
+ *
1589
+ * Licensed under the Apache License, Version 2.0 (the "License");
1590
+ * you may not use this file except in compliance with the License.
1591
+ * You may obtain a copy of the License at
1592
+ *
1593
+ * http://www.apache.org/licenses/LICENSE-2.0
1594
+ *
1595
+ * Unless required by applicable law or agreed to in writing, software
1596
+ * distributed under the License is distributed on an "AS IS" BASIS,
1597
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1598
+ * See the License for the specific language governing permissions and
1599
+ * limitations under the License.
1600
+ * ============================================================ */
1601
+
1602
+
1603
+ !function ($) {
1604
+
1605
+ "use strict"; // jshint ;_;
1606
+
1607
+
1608
+ /* COLLAPSE PUBLIC CLASS DEFINITION
1609
+ * ================================ */
1610
+
1611
+ var Collapse = function (element, options) {
1612
+ this.$element = $(element)
1613
+ this.options = $.extend({}, $.fn.collapse.defaults, options)
1614
+
1615
+ if (this.options.parent) {
1616
+ this.$parent = $(this.options.parent)
1617
+ }
1618
+
1619
+ this.options.toggle && this.toggle()
1620
+ }
1621
+
1622
+ Collapse.prototype = {
1623
+
1624
+ constructor: Collapse
1625
+
1626
+ , dimension: function () {
1627
+ var hasWidth = this.$element.hasClass('width')
1628
+ return hasWidth ? 'width' : 'height'
1629
+ }
1630
+
1631
+ , show: function () {
1632
+ var dimension
1633
+ , scroll
1634
+ , actives
1635
+ , hasData
1636
+
1637
+ if (this.transitioning || this.$element.hasClass('in')) return
1638
+
1639
+ dimension = this.dimension()
1640
+ scroll = $.camelCase(['scroll', dimension].join('-'))
1641
+ actives = this.$parent && this.$parent.find('> .accordion-group > .in')
1642
+
1643
+ if (actives && actives.length) {
1644
+ hasData = actives.data('collapse')
1645
+ if (hasData && hasData.transitioning) return
1646
+ actives.collapse('hide')
1647
+ hasData || actives.data('collapse', null)
1648
+ }
1649
+
1650
+ this.$element[dimension](0)
1651
+ this.transition('addClass', $.Event('show'), 'shown')
1652
+ $.support.transition && this.$element[dimension](this.$element[0][scroll])
1653
+ }
1654
+
1655
+ , hide: function () {
1656
+ var dimension
1657
+ if (this.transitioning || !this.$element.hasClass('in')) return
1658
+ dimension = this.dimension()
1659
+ this.reset(this.$element[dimension]())
1660
+ this.transition('removeClass', $.Event('hide'), 'hidden')
1661
+ this.$element[dimension](0)
1662
+ }
1663
+
1664
+ , reset: function (size) {
1665
+ var dimension = this.dimension()
1666
+
1667
+ this.$element
1668
+ .removeClass('collapse')
1669
+ [dimension](size || 'auto')
1670
+ [0].offsetWidth
1671
+
1672
+ this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
1673
+
1674
+ return this
1675
+ }
1676
+
1677
+ , transition: function (method, startEvent, completeEvent) {
1678
+ var that = this
1679
+ , complete = function () {
1680
+ if (startEvent.type == 'show') that.reset()
1681
+ that.transitioning = 0
1682
+ that.$element.trigger(completeEvent)
1683
+ }
1684
+
1685
+ this.$element.trigger(startEvent)
1686
+
1687
+ if (startEvent.isDefaultPrevented()) return
1688
+
1689
+ this.transitioning = 1
1690
+
1691
+ this.$element[method]('in')
1692
+
1693
+ $.support.transition && this.$element.hasClass('collapse') ?
1694
+ this.$element.one($.support.transition.end, complete) :
1695
+ complete()
1696
+ }
1697
+
1698
+ , toggle: function () {
1699
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
1700
+ }
1701
+
1702
+ }
1703
+
1704
+
1705
+ /* COLLAPSE PLUGIN DEFINITION
1706
+ * ========================== */
1707
+
1708
+ var old = $.fn.collapse
1709
+
1710
+ $.fn.collapse = function (option) {
1711
+ return this.each(function () {
1712
+ var $this = $(this)
1713
+ , data = $this.data('collapse')
1714
+ , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)
1715
+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))
1716
+ if (typeof option == 'string') data[option]()
1717
+ })
1718
+ }
1719
+
1720
+ $.fn.collapse.defaults = {
1721
+ toggle: true
1722
+ }
1723
+
1724
+ $.fn.collapse.Constructor = Collapse
1725
+
1726
+
1727
+ /* COLLAPSE NO CONFLICT
1728
+ * ==================== */
1729
+
1730
+ $.fn.collapse.noConflict = function () {
1731
+ $.fn.collapse = old
1732
+ return this
1733
+ }
1734
+
1735
+
1736
+ /* COLLAPSE DATA-API
1737
+ * ================= */
1738
+
1739
+ $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
1740
+ var $this = $(this), href
1741
+ , target = $this.attr('data-target')
1742
+ || e.preventDefault()
1743
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
1744
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
1745
+ $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
1746
+ $(target).collapse(option)
1747
+ })
1748
+
1749
+ }(window.jQuery);
1750
+ /* ==========================================================
1751
+ * bootstrap-carousel.js v2.3.2
1752
+ * http://twitter.github.com/bootstrap/javascript.html#carousel
1753
+ * ==========================================================
1754
+ * Copyright 2012 Twitter, Inc.
1755
+ *
1756
+ * Licensed under the Apache License, Version 2.0 (the "License");
1757
+ * you may not use this file except in compliance with the License.
1758
+ * You may obtain a copy of the License at
1759
+ *
1760
+ * http://www.apache.org/licenses/LICENSE-2.0
1761
+ *
1762
+ * Unless required by applicable law or agreed to in writing, software
1763
+ * distributed under the License is distributed on an "AS IS" BASIS,
1764
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1765
+ * See the License for the specific language governing permissions and
1766
+ * limitations under the License.
1767
+ * ========================================================== */
1768
+
1769
+
1770
+ !function ($) {
1771
+
1772
+ "use strict"; // jshint ;_;
1773
+
1774
+
1775
+ /* CAROUSEL CLASS DEFINITION
1776
+ * ========================= */
1777
+
1778
+ var Carousel = function (element, options) {
1779
+ this.$element = $(element)
1780
+ this.$indicators = this.$element.find('.carousel-indicators')
1781
+ this.options = options
1782
+ this.options.pause == 'hover' && this.$element
1783
+ .on('mouseenter', $.proxy(this.pause, this))
1784
+ .on('mouseleave', $.proxy(this.cycle, this))
1785
+ }
1786
+
1787
+ Carousel.prototype = {
1788
+
1789
+ cycle: function (e) {
1790
+ if (!e) this.paused = false
1791
+ if (this.interval) clearInterval(this.interval);
1792
+ this.options.interval
1793
+ && !this.paused
1794
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
1795
+ return this
1796
+ }
1797
+
1798
+ , getActiveIndex: function () {
1799
+ this.$active = this.$element.find('.item.active')
1800
+ this.$items = this.$active.parent().children()
1801
+ return this.$items.index(this.$active)
1802
+ }
1803
+
1804
+ , to: function (pos) {
1805
+ var activeIndex = this.getActiveIndex()
1806
+ , that = this
1807
+
1808
+ if (pos > (this.$items.length - 1) || pos < 0) return
1809
+
1810
+ if (this.sliding) {
1811
+ return this.$element.one('slid', function () {
1812
+ that.to(pos)
1813
+ })
1814
+ }
1815
+
1816
+ if (activeIndex == pos) {
1817
+ return this.pause().cycle()
1818
+ }
1819
+
1820
+ return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
1821
+ }
1822
+
1823
+ , pause: function (e) {
1824
+ if (!e) this.paused = true
1825
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
1826
+ this.$element.trigger($.support.transition.end)
1827
+ this.cycle(true)
1828
+ }
1829
+ clearInterval(this.interval)
1830
+ this.interval = null
1831
+ return this
1832
+ }
1833
+
1834
+ , next: function () {
1835
+ if (this.sliding) return
1836
+ return this.slide('next')
1837
+ }
1838
+
1839
+ , prev: function () {
1840
+ if (this.sliding) return
1841
+ return this.slide('prev')
1842
+ }
1843
+
1844
+ , slide: function (type, next) {
1845
+ var $active = this.$element.find('.item.active')
1846
+ , $next = next || $active[type]()
1847
+ , isCycling = this.interval
1848
+ , direction = type == 'next' ? 'left' : 'right'
1849
+ , fallback = type == 'next' ? 'first' : 'last'
1850
+ , that = this
1851
+ , e
1852
+
1853
+ this.sliding = true
1854
+
1855
+ isCycling && this.pause()
1856
+
1857
+ $next = $next.length ? $next : this.$element.find('.item')[fallback]()
1858
+
1859
+ e = $.Event('slide', {
1860
+ relatedTarget: $next[0]
1861
+ , direction: direction
1862
+ })
1863
+
1864
+ if ($next.hasClass('active')) return
1865
+
1866
+ if (this.$indicators.length) {
1867
+ this.$indicators.find('.active').removeClass('active')
1868
+ this.$element.one('slid', function () {
1869
+ var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
1870
+ $nextIndicator && $nextIndicator.addClass('active')
1871
+ })
1872
+ }
1873
+
1874
+ if ($.support.transition && this.$element.hasClass('slide')) {
1875
+ this.$element.trigger(e)
1876
+ if (e.isDefaultPrevented()) return
1877
+ $next.addClass(type)
1878
+ $next[0].offsetWidth // force reflow
1879
+ $active.addClass(direction)
1880
+ $next.addClass(direction)
1881
+ this.$element.one($.support.transition.end, function () {
1882
+ $next.removeClass([type, direction].join(' ')).addClass('active')
1883
+ $active.removeClass(['active', direction].join(' '))
1884
+ that.sliding = false
1885
+ setTimeout(function () { that.$element.trigger('slid') }, 0)
1886
+ })
1887
+ } else {
1888
+ this.$element.trigger(e)
1889
+ if (e.isDefaultPrevented()) return
1890
+ $active.removeClass('active')
1891
+ $next.addClass('active')
1892
+ this.sliding = false
1893
+ this.$element.trigger('slid')
1894
+ }
1895
+
1896
+ isCycling && this.cycle()
1897
+
1898
+ return this
1899
+ }
1900
+
1901
+ }
1902
+
1903
+
1904
+ /* CAROUSEL PLUGIN DEFINITION
1905
+ * ========================== */
1906
+
1907
+ var old = $.fn.carousel
1908
+
1909
+ $.fn.carousel = function (option) {
1910
+ return this.each(function () {
1911
+ var $this = $(this)
1912
+ , data = $this.data('carousel')
1913
+ , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
1914
+ , action = typeof option == 'string' ? option : options.slide
1915
+ if (!data) $this.data('carousel', (data = new Carousel(this, options)))
1916
+ if (typeof option == 'number') data.to(option)
1917
+ else if (action) data[action]()
1918
+ else if (options.interval) data.pause().cycle()
1919
+ })
1920
+ }
1921
+
1922
+ $.fn.carousel.defaults = {
1923
+ interval: 5000
1924
+ , pause: 'hover'
1925
+ }
1926
+
1927
+ $.fn.carousel.Constructor = Carousel
1928
+
1929
+
1930
+ /* CAROUSEL NO CONFLICT
1931
+ * ==================== */
1932
+
1933
+ $.fn.carousel.noConflict = function () {
1934
+ $.fn.carousel = old
1935
+ return this
1936
+ }
1937
+
1938
+ /* CAROUSEL DATA-API
1939
+ * ================= */
1940
+
1941
+ $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
1942
+ var $this = $(this), href
1943
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1944
+ , options = $.extend({}, $target.data(), $this.data())
1945
+ , slideIndex
1946
+
1947
+ $target.carousel(options)
1948
+
1949
+ if (slideIndex = $this.attr('data-slide-to')) {
1950
+ $target.data('carousel').pause().to(slideIndex).cycle()
1951
+ }
1952
+
1953
+ e.preventDefault()
1954
+ })
1955
+
1956
+ }(window.jQuery);
1957
+ /* =============================================================
1958
+ * bootstrap-typeahead.js v2.3.2
1959
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
1960
+ * =============================================================
1961
+ * Copyright 2012 Twitter, Inc.
1962
+ *
1963
+ * Licensed under the Apache License, Version 2.0 (the "License");
1964
+ * you may not use this file except in compliance with the License.
1965
+ * You may obtain a copy of the License at
1966
+ *
1967
+ * http://www.apache.org/licenses/LICENSE-2.0
1968
+ *
1969
+ * Unless required by applicable law or agreed to in writing, software
1970
+ * distributed under the License is distributed on an "AS IS" BASIS,
1971
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1972
+ * See the License for the specific language governing permissions and
1973
+ * limitations under the License.
1974
+ * ============================================================ */
1975
+
1976
+
1977
+ !function($){
1978
+
1979
+ "use strict"; // jshint ;_;
1980
+
1981
+
1982
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
1983
+ * ================================= */
1984
+
1985
+ var Typeahead = function (element, options) {
1986
+ this.$element = $(element)
1987
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
1988
+ this.matcher = this.options.matcher || this.matcher
1989
+ this.sorter = this.options.sorter || this.sorter
1990
+ this.highlighter = this.options.highlighter || this.highlighter
1991
+ this.updater = this.options.updater || this.updater
1992
+ this.source = this.options.source
1993
+ this.$menu = $(this.options.menu)
1994
+ this.shown = false
1995
+ this.listen()
1996
+ }
1997
+
1998
+ Typeahead.prototype = {
1999
+
2000
+ constructor: Typeahead
2001
+
2002
+ , select: function () {
2003
+ var val = this.$menu.find('.active').attr('data-value')
2004
+ this.$element
2005
+ .val(this.updater(val))
2006
+ .change()
2007
+ return this.hide()
2008
+ }
2009
+
2010
+ , updater: function (item) {
2011
+ return item
2012
+ }
2013
+
2014
+ , show: function () {
2015
+ var pos = $.extend({}, this.$element.position(), {
2016
+ height: this.$element[0].offsetHeight
2017
+ })
2018
+
2019
+ this.$menu
2020
+ .insertAfter(this.$element)
2021
+ .css({
2022
+ top: pos.top + pos.height
2023
+ , left: pos.left
2024
+ })
2025
+ .show()
2026
+
2027
+ this.shown = true
2028
+ return this
2029
+ }
2030
+
2031
+ , hide: function () {
2032
+ this.$menu.hide()
2033
+ this.shown = false
2034
+ return this
2035
+ }
2036
+
2037
+ , lookup: function (event) {
2038
+ var items
2039
+
2040
+ this.query = this.$element.val()
2041
+
2042
+ if (!this.query || this.query.length < this.options.minLength) {
2043
+ return this.shown ? this.hide() : this
2044
+ }
2045
+
2046
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
2047
+
2048
+ return items ? this.process(items) : this
2049
+ }
2050
+
2051
+ , process: function (items) {
2052
+ var that = this
2053
+
2054
+ items = $.grep(items, function (item) {
2055
+ return that.matcher(item)
2056
+ })
2057
+
2058
+ items = this.sorter(items)
2059
+
2060
+ if (!items.length) {
2061
+ return this.shown ? this.hide() : this
2062
+ }
2063
+
2064
+ return this.render(items.slice(0, this.options.items)).show()
2065
+ }
2066
+
2067
+ , matcher: function (item) {
2068
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
2069
+ }
2070
+
2071
+ , sorter: function (items) {
2072
+ var beginswith = []
2073
+ , caseSensitive = []
2074
+ , caseInsensitive = []
2075
+ , item
2076
+
2077
+ while (item = items.shift()) {
2078
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
2079
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
2080
+ else caseInsensitive.push(item)
2081
+ }
2082
+
2083
+ return beginswith.concat(caseSensitive, caseInsensitive)
2084
+ }
2085
+
2086
+ , highlighter: function (item) {
2087
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
2088
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
2089
+ return '<strong>' + match + '</strong>'
2090
+ })
2091
+ }
2092
+
2093
+ , render: function (items) {
2094
+ var that = this
2095
+
2096
+ items = $(items).map(function (i, item) {
2097
+ i = $(that.options.item).attr('data-value', item)
2098
+ i.find('a').html(that.highlighter(item))
2099
+ return i[0]
2100
+ })
2101
+
2102
+ items.first().addClass('active')
2103
+ this.$menu.html(items)
2104
+ return this
2105
+ }
2106
+
2107
+ , next: function (event) {
2108
+ var active = this.$menu.find('.active').removeClass('active')
2109
+ , next = active.next()
2110
+
2111
+ if (!next.length) {
2112
+ next = $(this.$menu.find('li')[0])
2113
+ }
2114
+
2115
+ next.addClass('active')
2116
+ }
2117
+
2118
+ , prev: function (event) {
2119
+ var active = this.$menu.find('.active').removeClass('active')
2120
+ , prev = active.prev()
2121
+
2122
+ if (!prev.length) {
2123
+ prev = this.$menu.find('li').last()
2124
+ }
2125
+
2126
+ prev.addClass('active')
2127
+ }
2128
+
2129
+ , listen: function () {
2130
+ this.$element
2131
+ .on('focus', $.proxy(this.focus, this))
2132
+ .on('blur', $.proxy(this.blur, this))
2133
+ .on('keypress', $.proxy(this.keypress, this))
2134
+ .on('keyup', $.proxy(this.keyup, this))
2135
+
2136
+ if (this.eventSupported('keydown')) {
2137
+ this.$element.on('keydown', $.proxy(this.keydown, this))
2138
+ }
2139
+
2140
+ this.$menu
2141
+ .on('click', $.proxy(this.click, this))
2142
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
2143
+ .on('mouseleave', 'li', $.proxy(this.mouseleave, this))
2144
+ }
2145
+
2146
+ , eventSupported: function(eventName) {
2147
+ var isSupported = eventName in this.$element
2148
+ if (!isSupported) {
2149
+ this.$element.setAttribute(eventName, 'return;')
2150
+ isSupported = typeof this.$element[eventName] === 'function'
2151
+ }
2152
+ return isSupported
2153
+ }
2154
+
2155
+ , move: function (e) {
2156
+ if (!this.shown) return
2157
+
2158
+ switch(e.keyCode) {
2159
+ case 9: // tab
2160
+ case 13: // enter
2161
+ case 27: // escape
2162
+ e.preventDefault()
2163
+ break
2164
+
2165
+ case 38: // up arrow
2166
+ e.preventDefault()
2167
+ this.prev()
2168
+ break
2169
+
2170
+ case 40: // down arrow
2171
+ e.preventDefault()
2172
+ this.next()
2173
+ break
2174
+ }
2175
+
2176
+ e.stopPropagation()
2177
+ }
2178
+
2179
+ , keydown: function (e) {
2180
+ this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
2181
+ this.move(e)
2182
+ }
2183
+
2184
+ , keypress: function (e) {
2185
+ if (this.suppressKeyPressRepeat) return
2186
+ this.move(e)
2187
+ }
2188
+
2189
+ , keyup: function (e) {
2190
+ switch(e.keyCode) {
2191
+ case 40: // down arrow
2192
+ case 38: // up arrow
2193
+ case 16: // shift
2194
+ case 17: // ctrl
2195
+ case 18: // alt
2196
+ break
2197
+
2198
+ case 9: // tab
2199
+ case 13: // enter
2200
+ if (!this.shown) return
2201
+ this.select()
2202
+ break
2203
+
2204
+ case 27: // escape
2205
+ if (!this.shown) return
2206
+ this.hide()
2207
+ break
2208
+
2209
+ default:
2210
+ this.lookup()
2211
+ }
2212
+
2213
+ e.stopPropagation()
2214
+ e.preventDefault()
2215
+ }
2216
+
2217
+ , focus: function (e) {
2218
+ this.focused = true
2219
+ }
2220
+
2221
+ , blur: function (e) {
2222
+ this.focused = false
2223
+ if (!this.mousedover && this.shown) this.hide()
2224
+ }
2225
+
2226
+ , click: function (e) {
2227
+ e.stopPropagation()
2228
+ e.preventDefault()
2229
+ this.select()
2230
+ this.$element.focus()
2231
+ }
2232
+
2233
+ , mouseenter: function (e) {
2234
+ this.mousedover = true
2235
+ this.$menu.find('.active').removeClass('active')
2236
+ $(e.currentTarget).addClass('active')
2237
+ }
2238
+
2239
+ , mouseleave: function (e) {
2240
+ this.mousedover = false
2241
+ if (!this.focused && this.shown) this.hide()
2242
+ }
2243
+
2244
+ }
2245
+
2246
+
2247
+ /* TYPEAHEAD PLUGIN DEFINITION
2248
+ * =========================== */
2249
+
2250
+ var old = $.fn.typeahead
2251
+
2252
+ $.fn.typeahead = function (option) {
2253
+ return this.each(function () {
2254
+ var $this = $(this)
2255
+ , data = $this.data('typeahead')
2256
+ , options = typeof option == 'object' && option
2257
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
2258
+ if (typeof option == 'string') data[option]()
2259
+ })
2260
+ }
2261
+
2262
+ $.fn.typeahead.defaults = {
2263
+ source: []
2264
+ , items: 8
2265
+ , menu: '<ul class="typeahead dropdown-menu"></ul>'
2266
+ , item: '<li><a href="#"></a></li>'
2267
+ , minLength: 1
2268
+ }
2269
+
2270
+ $.fn.typeahead.Constructor = Typeahead
2271
+
2272
+
2273
+ /* TYPEAHEAD NO CONFLICT
2274
+ * =================== */
2275
+
2276
+ $.fn.typeahead.noConflict = function () {
2277
+ $.fn.typeahead = old
2278
+ return this
2279
+ }
2280
+
2281
+
2282
+ /* TYPEAHEAD DATA-API
2283
+ * ================== */
2284
+
2285
+ $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
2286
+ var $this = $(this)
2287
+ if ($this.data('typeahead')) return
2288
+ $this.typeahead($this.data())
2289
+ })
2290
+
2291
+ }(window.jQuery);